@monorise/core 3.0.4 → 3.2.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.
package/dist/index.js CHANGED
@@ -17,6 +17,18 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
20
32
  var __export = (target, all) => {
21
33
  for (var name in all)
22
34
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -107,6 +119,10 @@ var setupCommonRoutes = (container) => {
107
119
  "/entity/:entityType/unique/:uniqueField/:uniqueFieldValue",
108
120
  container.getEntityByUniqueFieldController.controller
109
121
  );
122
+ app.post(
123
+ "/entity/:entityType/:entityId/adjust",
124
+ container.adjustEntityController.controller
125
+ );
110
126
  app.get(
111
127
  "/entity/:entityType/:entityId",
112
128
  container.getEntityController.controller
@@ -250,6 +266,47 @@ var Repository = class {
250
266
  };
251
267
  return updateAttributes;
252
268
  }
269
+ toAdjustUpdate(adjustments, constraints, prefix = "data") {
270
+ const parts = [];
271
+ const conditionParts = [];
272
+ const expressionAttributeNames = {};
273
+ const expressionAttributeValues = {};
274
+ expressionAttributeNames[`#${prefix}`] = prefix;
275
+ for (const field of Object.keys(adjustments)) {
276
+ const namePlaceholder = `#${field}`;
277
+ const valuePlaceholder = `:${field}`;
278
+ const fieldExpr = `if_not_exists(#${prefix}.${namePlaceholder}, :zero)`;
279
+ parts.push(
280
+ `#${prefix}.${namePlaceholder} = ${fieldExpr} + ${valuePlaceholder}`
281
+ );
282
+ expressionAttributeNames[namePlaceholder] = field;
283
+ expressionAttributeValues[valuePlaceholder] = adjustments[field];
284
+ if (constraints == null ? void 0 : constraints[field]) {
285
+ const constraint = constraints[field];
286
+ const delta = adjustments[field];
287
+ const currentFieldRef = `#${prefix}.${namePlaceholder}`;
288
+ if (constraint.min !== void 0 && delta < 0) {
289
+ const thresholdPlaceholder = `:${field}_min_threshold`;
290
+ conditionParts.push(`${currentFieldRef} >= ${thresholdPlaceholder}`);
291
+ expressionAttributeValues[thresholdPlaceholder] = constraint.min - delta;
292
+ }
293
+ if (constraint.max !== void 0 && delta > 0) {
294
+ const thresholdPlaceholder = `:${field}_max_threshold`;
295
+ conditionParts.push(`${currentFieldRef} <= ${thresholdPlaceholder}`);
296
+ expressionAttributeValues[thresholdPlaceholder] = constraint.max - delta;
297
+ }
298
+ }
299
+ }
300
+ expressionAttributeValues[":zero"] = 0;
301
+ return __spreadProps(__spreadValues({
302
+ UpdateExpression: `SET ${parts.join(", ")}`
303
+ }, conditionParts.length > 0 && {
304
+ ConditionExpression: conditionParts.join(" AND ")
305
+ }), {
306
+ ExpressionAttributeNames: expressionAttributeNames,
307
+ ExpressionAttributeValues: marshall(expressionAttributeValues)
308
+ });
309
+ }
253
310
  };
254
311
 
255
312
  // data/Entity.ts
@@ -717,6 +774,22 @@ var EntityRepository = class extends Repository {
717
774
  } catch (err) {
718
775
  if (err instanceof TransactionCanceledException) {
719
776
  const [updateErr, ...uniqueFieldErr] = err.CancellationReasons || [];
777
+ if ((updateErr == null ? void 0 : updateErr.Code) === BatchStatementErrorCodeEnum.ConditionalCheckFailed) {
778
+ if (opts == null ? void 0 : opts.ConditionExpression) {
779
+ throw new StandardError(
780
+ StandardErrorCode.CONDITIONAL_CHECK_FAILED,
781
+ "Conditional check failed",
782
+ err,
783
+ { entityId, toUpdate }
784
+ );
785
+ }
786
+ throw new StandardError(
787
+ StandardErrorCode.ENTITY_NOT_FOUND,
788
+ "Entity not found",
789
+ err,
790
+ { entityId, toUpdate }
791
+ );
792
+ }
720
793
  for (let i = 0; i < uniqueFieldErr.length; i++) {
721
794
  if (i % 2 === 1 && uniqueFieldErr[i].Code === BatchStatementErrorCodeEnum.ConditionalCheckFailed) {
722
795
  const field = updatedUniqueFields[Math.floor(i / 2)];
@@ -737,6 +810,14 @@ var EntityRepository = class extends Repository {
737
810
  return updatedEntity;
738
811
  } catch (err) {
739
812
  if (err instanceof ConditionalCheckFailedException) {
813
+ if (opts == null ? void 0 : opts.ConditionExpression) {
814
+ throw new StandardError(
815
+ StandardErrorCode.CONDITIONAL_CHECK_FAILED,
816
+ "Conditional check failed",
817
+ err,
818
+ { entityId, toUpdate }
819
+ );
820
+ }
740
821
  throw new StandardError(
741
822
  StandardErrorCode.ENTITY_NOT_FOUND,
742
823
  "Entity not found",
@@ -751,6 +832,25 @@ var EntityRepository = class extends Repository {
751
832
  }
752
833
  });
753
834
  }
835
+ adjustEntity(entityType, entityId, adjustments, constraints) {
836
+ return __async(this, null, function* () {
837
+ const entity = new Entity(entityType, entityId);
838
+ const { UpdateExpression, ConditionExpression, ExpressionAttributeNames, ExpressionAttributeValues } = this.toAdjustUpdate(adjustments, constraints);
839
+ const updatedAtExpression = ", #updatedAt = :updatedAt";
840
+ ExpressionAttributeNames["#updatedAt"] = "updatedAt";
841
+ ExpressionAttributeValues[":updatedAt"] = { S: (/* @__PURE__ */ new Date()).toISOString() };
842
+ const resp = yield this.dynamodbClient.updateItem(__spreadProps(__spreadValues({
843
+ TableName: this.TABLE_NAME,
844
+ Key: entity.keys(),
845
+ UpdateExpression: UpdateExpression + updatedAtExpression
846
+ }, ConditionExpression && { ConditionExpression }), {
847
+ ExpressionAttributeNames,
848
+ ExpressionAttributeValues,
849
+ ReturnValues: "ALL_NEW"
850
+ }));
851
+ return Entity.fromItem(resp.Attributes);
852
+ });
853
+ }
754
854
  deleteEntity(entityType, entityId) {
755
855
  return __async(this, null, function* () {
756
856
  try {
@@ -2850,6 +2950,7 @@ var CreateEntityController = class {
2850
2950
  const entity = yield this.entityService.createEntity({
2851
2951
  entityType,
2852
2952
  entityPayload: body,
2953
+ entityId: body.entityId,
2853
2954
  accountId,
2854
2955
  options: {
2855
2956
  createAndUpdateDatetime: body.createdAt
@@ -6986,10 +7087,11 @@ var UpdateEntityController = class {
6986
7087
  constructor(entityService) {
6987
7088
  this.entityService = entityService;
6988
7089
  this.controller = createMiddleware8((c) => __async(this, null, function* () {
6989
- var _a;
7090
+ var _b;
6990
7091
  const accountId = c.req.header("account-id");
6991
7092
  const { entityType, entityId } = c.req.param();
6992
7093
  const body = yield c.req.json();
7094
+ const _a = body, { $where: where } = _a, entityPayload = __objRest(_a, ["$where"]);
6993
7095
  const errorContext = {
6994
7096
  accountId,
6995
7097
  "req.params": c.req.param(),
@@ -6999,14 +7101,15 @@ var UpdateEntityController = class {
6999
7101
  const entity = yield this.entityService.updateEntity({
7000
7102
  entityType,
7001
7103
  entityId,
7002
- entityPayload: body,
7003
- accountId
7104
+ entityPayload,
7105
+ accountId,
7106
+ where
7004
7107
  });
7005
7108
  errorContext.entity = entity;
7006
7109
  c.status(httpStatus8.OK);
7007
7110
  return c.json(entity);
7008
7111
  } catch (err) {
7009
- if (((_a = err.constructor) == null ? void 0 : _a.name) === "ZodError") {
7112
+ if (((_b = err.constructor) == null ? void 0 : _b.name) === "ZodError") {
7010
7113
  c.status(httpStatus8.BAD_REQUEST);
7011
7114
  return c.json({
7012
7115
  code: "API_VALIDATION_ERROR",
@@ -7022,6 +7125,10 @@ var UpdateEntityController = class {
7022
7125
  c.status(httpStatus8.BAD_REQUEST);
7023
7126
  return c.json(__spreadValues({}, err.toJSON()));
7024
7127
  }
7128
+ if (err instanceof StandardError && err.code === StandardErrorCode.CONDITIONAL_CHECK_FAILED) {
7129
+ c.status(httpStatus8.CONFLICT);
7130
+ return c.json(__spreadValues({}, err.toJSON()));
7131
+ }
7025
7132
  console.log(
7026
7133
  "====UPDATE_ENTITY_CONTROLLER_ERROR",
7027
7134
  err,
@@ -7033,15 +7140,63 @@ var UpdateEntityController = class {
7033
7140
  }
7034
7141
  };
7035
7142
 
7036
- // controllers/entity/upsert-entity.controller.ts
7143
+ // controllers/entity/adjust-entity.controller.ts
7037
7144
  import { createMiddleware as createMiddleware9 } from "hono/factory";
7038
7145
  import httpStatus9 from "http-status";
7146
+ var AdjustEntityController = class {
7147
+ constructor(entityService) {
7148
+ this.entityService = entityService;
7149
+ this.controller = createMiddleware9((c) => __async(this, null, function* () {
7150
+ var _a;
7151
+ const accountId = c.req.header("account-id") || "";
7152
+ const { entityType, entityId } = c.req.param();
7153
+ const body = yield c.req.json();
7154
+ for (const [key, value] of Object.entries(body)) {
7155
+ if (typeof value !== "number") {
7156
+ c.status(httpStatus9.BAD_REQUEST);
7157
+ return c.json({
7158
+ code: "API_VALIDATION_ERROR",
7159
+ message: `Field "${key}" must be a number, got ${typeof value}`
7160
+ });
7161
+ }
7162
+ }
7163
+ try {
7164
+ const entity = yield this.entityService.adjustEntity({
7165
+ entityType,
7166
+ entityId,
7167
+ adjustments: body,
7168
+ accountId
7169
+ });
7170
+ c.status(httpStatus9.OK);
7171
+ return c.json(entity.toJSON());
7172
+ } catch (err) {
7173
+ if (err instanceof StandardError && err.code === StandardErrorCode.ENTITY_IS_UNDEFINED) {
7174
+ c.status(httpStatus9.NOT_FOUND);
7175
+ return c.json(__spreadValues({}, err.toJSON()));
7176
+ }
7177
+ if ((err == null ? void 0 : err.name) === "ConditionalCheckFailedException" || ((_a = err == null ? void 0 : err.__type) == null ? void 0 : _a.includes("ConditionalCheckFailed"))) {
7178
+ c.status(httpStatus9.CONFLICT);
7179
+ return c.json({
7180
+ code: "ADJUSTMENT_CONSTRAINT_VIOLATED",
7181
+ message: "Adjustment would violate entity constraints"
7182
+ });
7183
+ }
7184
+ console.log("====ADJUST_ENTITY_CONTROLLER_ERROR", err);
7185
+ throw err;
7186
+ }
7187
+ }));
7188
+ }
7189
+ };
7190
+
7191
+ // controllers/entity/upsert-entity.controller.ts
7192
+ import { createMiddleware as createMiddleware10 } from "hono/factory";
7193
+ import httpStatus10 from "http-status";
7039
7194
  var UpsertEntityController = class {
7040
7195
  constructor(EntityConfig, entityRepository, publishEvent2) {
7041
7196
  this.EntityConfig = EntityConfig;
7042
7197
  this.entityRepository = entityRepository;
7043
7198
  this.publishEvent = publishEvent2;
7044
- this.controller = createMiddleware9((c) => __async(this, null, function* () {
7199
+ this.controller = createMiddleware10((c) => __async(this, null, function* () {
7045
7200
  var _a, _b;
7046
7201
  const accountId = c.req.header("account-id");
7047
7202
  const { entityType, entityId } = c.req.param();
@@ -7097,7 +7252,7 @@ var UpsertEntityController = class {
7097
7252
  return c.json(entity);
7098
7253
  } catch (err) {
7099
7254
  if (err instanceof ZodError) {
7100
- c.status(httpStatus9.BAD_REQUEST);
7255
+ c.status(httpStatus10.BAD_REQUEST);
7101
7256
  return c.json({
7102
7257
  code: "API_VALIDATION_ERROR",
7103
7258
  message: "API validation failed",
@@ -7105,7 +7260,7 @@ var UpsertEntityController = class {
7105
7260
  });
7106
7261
  }
7107
7262
  if (err instanceof StandardError && err.code === StandardErrorCode.EMAIL_EXISTS) {
7108
- c.status(httpStatus9.BAD_REQUEST);
7263
+ c.status(httpStatus10.BAD_REQUEST);
7109
7264
  return c.json(__spreadValues({}, err.toJSON()));
7110
7265
  }
7111
7266
  throw err;
@@ -7115,12 +7270,12 @@ var UpsertEntityController = class {
7115
7270
  };
7116
7271
 
7117
7272
  // controllers/mutual/create-mutual.controller.ts
7118
- import { createMiddleware as createMiddleware10 } from "hono/factory";
7119
- import httpStatus10 from "http-status";
7273
+ import { createMiddleware as createMiddleware11 } from "hono/factory";
7274
+ import httpStatus11 from "http-status";
7120
7275
  var CreateMutualController = class {
7121
7276
  constructor(mutualService) {
7122
7277
  this.mutualService = mutualService;
7123
- this.controller = createMiddleware10((c) => __async(this, null, function* () {
7278
+ this.controller = createMiddleware11((c) => __async(this, null, function* () {
7124
7279
  const accountId = c.req.header("account-id");
7125
7280
  const { byEntityType, byEntityId, entityType, entityId } = c.req.param();
7126
7281
  const asEntity = c.req.query("asEntity");
@@ -7140,7 +7295,7 @@ var CreateMutualController = class {
7140
7295
  return c.json(mutual);
7141
7296
  } catch (err) {
7142
7297
  if (err instanceof ZodError) {
7143
- c.status(httpStatus10.BAD_REQUEST);
7298
+ c.status(httpStatus11.BAD_REQUEST);
7144
7299
  return c.json({
7145
7300
  code: "API_VALIDATION_ERROR",
7146
7301
  message: "API validation failed",
@@ -7148,11 +7303,11 @@ var CreateMutualController = class {
7148
7303
  });
7149
7304
  }
7150
7305
  if (err instanceof StandardError && err.code === StandardErrorCode.MUTUAL_EXISTS) {
7151
- c.status(httpStatus10.BAD_REQUEST);
7306
+ c.status(httpStatus11.BAD_REQUEST);
7152
7307
  return c.json(__spreadValues({}, err.toJSON()));
7153
7308
  }
7154
7309
  if (err instanceof StandardError && err.code === StandardErrorCode.ENTITY_IS_UNDEFINED) {
7155
- c.status(httpStatus10.BAD_REQUEST);
7310
+ c.status(httpStatus11.BAD_REQUEST);
7156
7311
  return c.json(__spreadValues({}, err.toJSON()));
7157
7312
  }
7158
7313
  throw err;
@@ -7162,12 +7317,12 @@ var CreateMutualController = class {
7162
7317
  };
7163
7318
 
7164
7319
  // controllers/mutual/delete-mutual.controller.ts
7165
- import { createMiddleware as createMiddleware11 } from "hono/factory";
7166
- import httpStatus11 from "http-status";
7320
+ import { createMiddleware as createMiddleware12 } from "hono/factory";
7321
+ import httpStatus12 from "http-status";
7167
7322
  var DeleteMutualController = class {
7168
7323
  constructor(mutualService) {
7169
7324
  this.mutualService = mutualService;
7170
- this.controller = createMiddleware11((c) => __async(this, null, function* () {
7325
+ this.controller = createMiddleware12((c) => __async(this, null, function* () {
7171
7326
  const accountId = c.req.header("account-id");
7172
7327
  const { byEntityType, byEntityId, entityType, entityId } = c.req.param();
7173
7328
  try {
@@ -7181,7 +7336,7 @@ var DeleteMutualController = class {
7181
7336
  return c.json(mutual);
7182
7337
  } catch (err) {
7183
7338
  if (err instanceof StandardError && err.code === StandardErrorCode.MUTUAL_NOT_FOUND) {
7184
- c.status(httpStatus11.BAD_REQUEST);
7339
+ c.status(httpStatus12.BAD_REQUEST);
7185
7340
  return c.json(__spreadValues({}, err.toJSON()));
7186
7341
  }
7187
7342
  throw err;
@@ -7191,12 +7346,12 @@ var DeleteMutualController = class {
7191
7346
  };
7192
7347
 
7193
7348
  // controllers/mutual/get-mutual.controller.ts
7194
- import { createMiddleware as createMiddleware12 } from "hono/factory";
7195
- import httpStatus12 from "http-status";
7349
+ import { createMiddleware as createMiddleware13 } from "hono/factory";
7350
+ import httpStatus13 from "http-status";
7196
7351
  var GetMutualController = class {
7197
7352
  constructor(associateRepository) {
7198
7353
  this.associateRepository = associateRepository;
7199
- this.controller = createMiddleware12((c) => __async(this, null, function* () {
7354
+ this.controller = createMiddleware13((c) => __async(this, null, function* () {
7200
7355
  const { byEntityType, byEntityId, entityType, entityId } = c.req.param();
7201
7356
  try {
7202
7357
  const associate = yield this.associateRepository.getMutual(
@@ -7208,7 +7363,7 @@ var GetMutualController = class {
7208
7363
  return c.json(associate);
7209
7364
  } catch (err) {
7210
7365
  if (err instanceof StandardError && err.code === StandardErrorCode.MUTUAL_IS_UNDEFINED) {
7211
- c.status(httpStatus12.NOT_FOUND);
7366
+ c.status(httpStatus13.NOT_FOUND);
7212
7367
  return c.json({
7213
7368
  code: "MUTUAL_NOT_FOUND",
7214
7369
  message: "Mutual not found"
@@ -7221,11 +7376,11 @@ var GetMutualController = class {
7221
7376
  };
7222
7377
 
7223
7378
  // controllers/mutual/list-entities-by-entity.controller.ts
7224
- import { createMiddleware as createMiddleware13 } from "hono/factory";
7379
+ import { createMiddleware as createMiddleware14 } from "hono/factory";
7225
7380
  var ListEntitiesByEntityController = class {
7226
7381
  constructor(associateRepository) {
7227
7382
  this.associateRepository = associateRepository;
7228
- this.controller = createMiddleware13((c) => __async(this, null, function* () {
7383
+ this.controller = createMiddleware14((c) => __async(this, null, function* () {
7229
7384
  const { byEntityType, byEntityId, entityType } = c.req.param();
7230
7385
  const querySchema3 = external_exports.object({
7231
7386
  chainEntityQuery: external_exports.string().optional(),
@@ -7283,12 +7438,12 @@ var ListEntitiesByEntityController = class {
7283
7438
  };
7284
7439
 
7285
7440
  // controllers/mutual/update-mutual.controller.ts
7286
- import { createMiddleware as createMiddleware14 } from "hono/factory";
7287
- import httpStatus13 from "http-status";
7441
+ import { createMiddleware as createMiddleware15 } from "hono/factory";
7442
+ import httpStatus14 from "http-status";
7288
7443
  var UpdateMutualController = class {
7289
7444
  constructor(mutualService) {
7290
7445
  this.mutualService = mutualService;
7291
- this.controller = createMiddleware14((c) => __async(this, null, function* () {
7446
+ this.controller = createMiddleware15((c) => __async(this, null, function* () {
7292
7447
  const accountId = c.req.header("account-id");
7293
7448
  const { byEntityType, byEntityId, entityType, entityId } = c.req.param();
7294
7449
  const body = yield c.req.json();
@@ -7307,7 +7462,7 @@ var UpdateMutualController = class {
7307
7462
  return c.json(mutual);
7308
7463
  } catch (err) {
7309
7464
  if (err instanceof ZodError) {
7310
- c.status(httpStatus13.BAD_REQUEST);
7465
+ c.status(httpStatus14.BAD_REQUEST);
7311
7466
  return c.json({
7312
7467
  code: "API_VALIDATION_ERROR",
7313
7468
  message: "API validation failed",
@@ -7315,7 +7470,7 @@ var UpdateMutualController = class {
7315
7470
  });
7316
7471
  }
7317
7472
  if (err instanceof StandardError && err.code === StandardErrorCode.MUTUAL_NOT_FOUND) {
7318
- c.status(httpStatus13.BAD_REQUEST);
7473
+ c.status(httpStatus14.BAD_REQUEST);
7319
7474
  return c.json(__spreadValues({}, err.toJSON()));
7320
7475
  }
7321
7476
  throw err;
@@ -7324,6 +7479,67 @@ var UpdateMutualController = class {
7324
7479
  }
7325
7480
  };
7326
7481
 
7482
+ // data/utils/build-condition-expression.ts
7483
+ import { marshall as marshall5 } from "@aws-sdk/util-dynamodb";
7484
+ function buildConditionExpression(where) {
7485
+ const conditions = ["attribute_exists(PK)"];
7486
+ const expressionAttributeNames = { "#data": "data" };
7487
+ const expressionAttributeValues = {};
7488
+ for (const [field, clause] of Object.entries(where)) {
7489
+ const namePlaceholder = `#where_${field}`;
7490
+ expressionAttributeNames[namePlaceholder] = field;
7491
+ const fieldRef = `#data.${namePlaceholder}`;
7492
+ if (clause === null || clause === void 0) continue;
7493
+ if (typeof clause !== "object") {
7494
+ const valPlaceholder = `:where_${field}`;
7495
+ expressionAttributeValues[valPlaceholder] = clause;
7496
+ conditions.push(`${fieldRef} = ${valPlaceholder}`);
7497
+ continue;
7498
+ }
7499
+ const op = clause;
7500
+ if ("$eq" in op) {
7501
+ const valPlaceholder = `:where_${field}_eq`;
7502
+ expressionAttributeValues[valPlaceholder] = op.$eq;
7503
+ conditions.push(`${fieldRef} = ${valPlaceholder}`);
7504
+ } else if ("$ne" in op) {
7505
+ const valPlaceholder = `:where_${field}_ne`;
7506
+ expressionAttributeValues[valPlaceholder] = op.$ne;
7507
+ conditions.push(`${fieldRef} <> ${valPlaceholder}`);
7508
+ } else if ("$gt" in op) {
7509
+ const valPlaceholder = `:where_${field}_gt`;
7510
+ expressionAttributeValues[valPlaceholder] = op.$gt;
7511
+ conditions.push(`${fieldRef} > ${valPlaceholder}`);
7512
+ } else if ("$lt" in op) {
7513
+ const valPlaceholder = `:where_${field}_lt`;
7514
+ expressionAttributeValues[valPlaceholder] = op.$lt;
7515
+ conditions.push(`${fieldRef} < ${valPlaceholder}`);
7516
+ } else if ("$gte" in op) {
7517
+ const valPlaceholder = `:where_${field}_gte`;
7518
+ expressionAttributeValues[valPlaceholder] = op.$gte;
7519
+ conditions.push(`${fieldRef} >= ${valPlaceholder}`);
7520
+ } else if ("$lte" in op) {
7521
+ const valPlaceholder = `:where_${field}_lte`;
7522
+ expressionAttributeValues[valPlaceholder] = op.$lte;
7523
+ conditions.push(`${fieldRef} <= ${valPlaceholder}`);
7524
+ } else if ("$exists" in op) {
7525
+ if (op.$exists) {
7526
+ conditions.push(`attribute_exists(${fieldRef})`);
7527
+ } else {
7528
+ conditions.push(`attribute_not_exists(${fieldRef})`);
7529
+ }
7530
+ } else if ("$beginsWith" in op) {
7531
+ const valPlaceholder = `:where_${field}_beginsWith`;
7532
+ expressionAttributeValues[valPlaceholder] = op.$beginsWith;
7533
+ conditions.push(`begins_with(${fieldRef}, ${valPlaceholder})`);
7534
+ }
7535
+ }
7536
+ return {
7537
+ ConditionExpression: conditions.join(" AND "),
7538
+ ExpressionAttributeNames: expressionAttributeNames,
7539
+ ExpressionAttributeValues: marshall5(expressionAttributeValues)
7540
+ };
7541
+ }
7542
+
7327
7543
  // services/entity.service.ts
7328
7544
  var EntityService = class {
7329
7545
  constructor(EntityConfig, EmailAuthEnabledEntities, entityRepository, publishEvent2, entityServiceLifeCycle) {
@@ -7375,11 +7591,57 @@ var EntityService = class {
7375
7591
  );
7376
7592
  return entity;
7377
7593
  });
7594
+ this.adjustEntity = (_0) => __async(this, [_0], function* ({
7595
+ entityType,
7596
+ entityId,
7597
+ adjustments,
7598
+ accountId
7599
+ }) {
7600
+ var _a, _b, _c, _d;
7601
+ const rawConstraints = (_a = this.EntityConfig[entityType]) == null ? void 0 : _a.adjustmentConstraints;
7602
+ let resolvedConstraints = rawConstraints;
7603
+ if (rawConstraints) {
7604
+ const hasDynamicFields = Object.values(rawConstraints).some(
7605
+ (c) => c.minField || c.maxField
7606
+ );
7607
+ if (hasDynamicFields) {
7608
+ const currentEntity = yield this.entityRepository.getEntity(entityType, entityId);
7609
+ const data = (_b = currentEntity == null ? void 0 : currentEntity.data) != null ? _b : {};
7610
+ resolvedConstraints = {};
7611
+ for (const [field, constraint] of Object.entries(rawConstraints)) {
7612
+ const resolved = {};
7613
+ if (constraint.min !== void 0) resolved.min = constraint.min;
7614
+ if (constraint.max !== void 0) resolved.max = constraint.max;
7615
+ if (constraint.minField) resolved.min = (_c = data[constraint.minField]) != null ? _c : 0;
7616
+ if (constraint.maxField) resolved.max = (_d = data[constraint.maxField]) != null ? _d : Number.MAX_SAFE_INTEGER;
7617
+ resolvedConstraints[field] = resolved;
7618
+ }
7619
+ }
7620
+ }
7621
+ const entity = yield this.entityRepository.adjustEntity(
7622
+ entityType,
7623
+ entityId,
7624
+ adjustments,
7625
+ resolvedConstraints
7626
+ );
7627
+ yield this.publishEvent({
7628
+ event: EVENT.CORE.ENTITY_UPDATED,
7629
+ payload: {
7630
+ entityType,
7631
+ entityId,
7632
+ data: entity.data,
7633
+ updatedByAccountId: accountId,
7634
+ publishedAt: entity.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
7635
+ }
7636
+ });
7637
+ return entity;
7638
+ });
7378
7639
  this.updateEntity = (_0) => __async(this, [_0], function* ({
7379
7640
  entityType,
7380
7641
  entityId,
7381
7642
  entityPayload,
7382
- accountId
7643
+ accountId,
7644
+ where
7383
7645
  }) {
7384
7646
  var _a, _b;
7385
7647
  const errorContext = {};
@@ -7395,10 +7657,12 @@ var EntityService = class {
7395
7657
  const parsedEntityPayload = entitySchema.parse(entityPayload);
7396
7658
  const parsedMutualPayload = mutualSchema == null ? void 0 : mutualSchema.parse(entityPayload);
7397
7659
  errorContext.parsedMutualPayload = parsedMutualPayload;
7660
+ const opts = where && Object.keys(where).length > 0 ? buildConditionExpression(where) : void 0;
7398
7661
  const entity = yield this.entityRepository.updateEntity(
7399
7662
  entityType,
7400
7663
  entityId,
7401
- { data: parsedEntityPayload }
7664
+ { data: parsedEntityPayload },
7665
+ opts
7402
7666
  );
7403
7667
  errorContext.entity = entity;
7404
7668
  if (parsedMutualPayload) {
@@ -7657,7 +7921,7 @@ var MutualService = class {
7657
7921
  };
7658
7922
 
7659
7923
  // controllers/tag/list-tags.controller.ts
7660
- import { createMiddleware as createMiddleware15 } from "hono/factory";
7924
+ import { createMiddleware as createMiddleware16 } from "hono/factory";
7661
7925
  var querySchema2 = external_exports.object({
7662
7926
  group: external_exports.string().optional(),
7663
7927
  query: external_exports.string().optional(),
@@ -7669,7 +7933,7 @@ var querySchema2 = external_exports.object({
7669
7933
  var ListTagsController = class {
7670
7934
  constructor(tagRepository) {
7671
7935
  this.tagRepository = tagRepository;
7672
- this.controller = createMiddleware15((c) => __async(this, null, function* () {
7936
+ this.controller = createMiddleware16((c) => __async(this, null, function* () {
7673
7937
  const errorContext = {};
7674
7938
  try {
7675
7939
  errorContext.params = c.req.param();
@@ -7865,6 +8129,12 @@ var DependencyContainer = class {
7865
8129
  this.entityService
7866
8130
  );
7867
8131
  }
8132
+ get adjustEntityController() {
8133
+ return this.createCachedInstance(
8134
+ AdjustEntityController,
8135
+ this.entityService
8136
+ );
8137
+ }
7868
8138
  get deleteEntityController() {
7869
8139
  return this.createCachedInstance(
7870
8140
  DeleteEntityController,