av6-core 1.3.6 → 1.3.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/dist/index.d.mts CHANGED
@@ -42,6 +42,26 @@ interface FieldRules {
42
42
  values?: string[];
43
43
  iso?: boolean;
44
44
  schema?: Record<string, unknown>;
45
+ precision?: number;
46
+ precisionFrom?: "ctx.decimalPrecision";
47
+ minDate?: "today" | "now";
48
+ minDateFieldRef?: string;
49
+ when?: {
50
+ ref: string;
51
+ is: string | number | boolean | (string | number | boolean)[];
52
+ then?: {
53
+ presence?: "required" | "optional";
54
+ rules?: FieldRules;
55
+ };
56
+ otherwise?: {
57
+ presence?: "required" | "optional";
58
+ rules?: FieldRules;
59
+ };
60
+ };
61
+ compare?: {
62
+ ref: string;
63
+ op: "gt" | "gte" | "lt" | "lte" | "eq" | "neq";
64
+ };
45
65
  }
46
66
  interface FieldConfig {
47
67
  name: string;
@@ -407,6 +427,7 @@ type Store = {
407
427
  };
408
428
  level1Id?: number;
409
429
  level2Id?: number;
430
+ defaultPrecision: number | null;
410
431
  [key: string]: any;
411
432
  };
412
433
  interface Context {
package/dist/index.d.ts CHANGED
@@ -42,6 +42,26 @@ interface FieldRules {
42
42
  values?: string[];
43
43
  iso?: boolean;
44
44
  schema?: Record<string, unknown>;
45
+ precision?: number;
46
+ precisionFrom?: "ctx.decimalPrecision";
47
+ minDate?: "today" | "now";
48
+ minDateFieldRef?: string;
49
+ when?: {
50
+ ref: string;
51
+ is: string | number | boolean | (string | number | boolean)[];
52
+ then?: {
53
+ presence?: "required" | "optional";
54
+ rules?: FieldRules;
55
+ };
56
+ otherwise?: {
57
+ presence?: "required" | "optional";
58
+ rules?: FieldRules;
59
+ };
60
+ };
61
+ compare?: {
62
+ ref: string;
63
+ op: "gt" | "gte" | "lt" | "lte" | "eq" | "neq";
64
+ };
45
65
  }
46
66
  interface FieldConfig {
47
67
  name: string;
@@ -407,6 +427,7 @@ type Store = {
407
427
  };
408
428
  level1Id?: number;
409
429
  level2Id?: number;
430
+ defaultPrecision: number | null;
410
431
  [key: string]: any;
411
432
  };
412
433
  interface Context {
package/dist/index.js CHANGED
@@ -1056,7 +1056,41 @@ var commonCreateUpdateRepository = (serviceDeps) => {
1056
1056
 
1057
1057
  // src/utils/dynamicJoiBuilder.utils.ts
1058
1058
  var import_joi = __toESM(require("joi"));
1059
- var buildScalar = (f) => {
1059
+ var import_dayjs = __toESM(require("dayjs"));
1060
+ function applyNumberCompare(schema, op, ref) {
1061
+ const r = import_joi.default.ref(ref);
1062
+ switch (op) {
1063
+ case "gt":
1064
+ return schema.greater(r);
1065
+ case "gte":
1066
+ return schema.min(r);
1067
+ case "lt":
1068
+ return schema.less(r);
1069
+ case "lte":
1070
+ return schema.max(r);
1071
+ case "eq":
1072
+ return schema.valid(r);
1073
+ // not perfect; better use custom if you need strict equality
1074
+ case "neq":
1075
+ return schema.invalid(r);
1076
+ default:
1077
+ return schema;
1078
+ }
1079
+ }
1080
+ function resolvePrecision(rule, ctx) {
1081
+ if (typeof rule.precision === "number") return rule.precision;
1082
+ if (rule.precisionFrom === "ctx.decimalPrecision") {
1083
+ return typeof ctx.decimalPrecision === "number" ? ctx.decimalPrecision : void 0;
1084
+ }
1085
+ return void 0;
1086
+ }
1087
+ function resolveMinDate(rule) {
1088
+ if (!rule.minDate) return void 0;
1089
+ if (rule.minDate === "now") return /* @__PURE__ */ new Date();
1090
+ if (rule.minDate === "today") return (0, import_dayjs.default)().startOf("day").toDate();
1091
+ return void 0;
1092
+ }
1093
+ var buildScalar = (f, ctx) => {
1060
1094
  const rules = f.rules ?? {};
1061
1095
  let s;
1062
1096
  switch (f.type) {
@@ -1074,6 +1108,11 @@ var buildScalar = (f) => {
1074
1108
  if (rules.integer) j = j.integer();
1075
1109
  if (typeof rules.min === "number") j = j.min(rules.min);
1076
1110
  if (typeof rules.max === "number") j = j.max(rules.max);
1111
+ const p = resolvePrecision(rules, ctx);
1112
+ if (typeof p === "number") s = j.precision(p);
1113
+ if (rules.compare?.ref && rules.compare?.op) {
1114
+ s = applyNumberCompare(j, rules.compare.op, rules.compare.ref);
1115
+ }
1077
1116
  s = j;
1078
1117
  break;
1079
1118
  }
@@ -1082,7 +1121,11 @@ var buildScalar = (f) => {
1082
1121
  break;
1083
1122
  case "date": {
1084
1123
  let j = import_joi.default.date();
1085
- if (rules.iso) j = j.iso();
1124
+ const minD = resolveMinDate(rules);
1125
+ if (minD) s = j.min(minD);
1126
+ if (rules.minDateFieldRef) {
1127
+ s = j.min(import_joi.default.ref(rules.minDateFieldRef));
1128
+ }
1086
1129
  s = j;
1087
1130
  break;
1088
1131
  }
@@ -1103,32 +1146,46 @@ var buildScalar = (f) => {
1103
1146
  }
1104
1147
  if (f.allowNull) s = s.allow(null);
1105
1148
  if (f.default !== void 0) s = s.default(f.default);
1149
+ if (rules.when?.ref) {
1150
+ const isVal = Array.isArray(rules.when.is) ? rules.when.is : [rules.when.is];
1151
+ const thenPresence = rules.when.then?.presence;
1152
+ const otherwisePresence = rules.when.otherwise?.presence;
1153
+ const thenRules = rules.when.then?.rules;
1154
+ const otherwiseRules = rules.when.otherwise?.rules;
1155
+ const thenSchema = thenRules ? buildScalar({ ...f, rules: { ...rules, ...thenRules } }, ctx) : s;
1156
+ const otherwiseSchema = otherwiseRules ? buildScalar({ ...f, rules: { ...rules, ...otherwiseRules } }, ctx) : s;
1157
+ s = import_joi.default.when(rules.when.ref, {
1158
+ is: import_joi.default.valid(...isVal),
1159
+ then: applyPresence(thenSchema, thenPresence),
1160
+ otherwise: applyPresence(otherwiseSchema, otherwisePresence)
1161
+ });
1162
+ }
1106
1163
  if (f.messages) s = s.messages(f.messages);
1107
1164
  return s;
1108
1165
  };
1109
- var applyPresence = (schema, presence) => {
1166
+ function applyPresence(schema, presence) {
1110
1167
  if (presence === "required") return schema.required();
1111
1168
  if (presence === "forbidden") return schema.forbidden();
1112
1169
  return schema.optional();
1113
- };
1114
- var buildRelationSchema = (rel, op) => {
1170
+ }
1171
+ var buildRelationSchema = (rel, op, ctx) => {
1115
1172
  const itemShape = {};
1116
1173
  for (const f of rel.items.fields) {
1117
- const scalar = buildScalar(f);
1174
+ const scalar = buildScalar(f, ctx);
1118
1175
  itemShape[f.db] = applyPresence(scalar, f.presence[op]);
1119
1176
  }
1120
1177
  const itemSchema = import_joi.default.object(itemShape);
1121
1178
  const base = rel.kind === "many" ? import_joi.default.array().items(itemSchema) : itemSchema;
1122
1179
  return applyPresence(base, rel.presence[op]);
1123
1180
  };
1124
- var buildJoiSchemaForOp = (cfg, op) => {
1181
+ var buildJoiSchemaForOp = (cfg, op, ctx) => {
1125
1182
  const shape = {};
1126
1183
  for (const f of cfg.fields) {
1127
- const scalar = buildScalar(f);
1184
+ const scalar = buildScalar(f, ctx);
1128
1185
  shape[f.db] = applyPresence(scalar, f.presence[op]);
1129
1186
  }
1130
1187
  for (const rel of cfg.relations ?? []) {
1131
- shape[rel.db] = buildRelationSchema(rel, op);
1188
+ shape[rel.db] = buildRelationSchema(rel, op, ctx);
1132
1189
  }
1133
1190
  return import_joi.default.object(shape).prefs({
1134
1191
  abortEarly: cfg.validation.abortEarly,
@@ -1519,7 +1576,7 @@ var commonService = (serviceDeps) => {
1519
1576
  throw new ErrorHandler(500, `Configuration not found for short code: ${shortCodeData.shortCode}`);
1520
1577
  }
1521
1578
  const ctx = { userId: currentUser ?? void 0, vars: {} };
1522
- const schema = buildJoiSchemaForOp(cfg, "create");
1579
+ const schema = buildJoiSchemaForOp(cfg, "create", { decimalPrecision: store?.defaultPrecision ?? 2 });
1523
1580
  const validated = await schema.validateAsync(createParams.body);
1524
1581
  if (validationMapping && validationMapping[shortCodeData.shortCode] && validationMapping[shortCodeData.shortCode].create) {
1525
1582
  await validationMapping[shortCodeData.shortCode].create?.(validated);
@@ -1561,7 +1618,7 @@ var commonService = (serviceDeps) => {
1561
1618
  throw new ErrorHandler(500, `Configuration not found for short code: ${shortCodeData.shortCode}`);
1562
1619
  }
1563
1620
  const ctx = { userId: currentUser ?? void 0, vars: {} };
1564
- const schema = buildJoiSchemaForOp(cfg, "update");
1621
+ const schema = buildJoiSchemaForOp(cfg, "update", { decimalPrecision: store?.defaultPrecision ?? 2 });
1565
1622
  let validated = await schema.validateAsync(updateParams.body);
1566
1623
  if (validationMapping && validationMapping[shortCodeData.shortCode] && validationMapping[shortCodeData.shortCode].update) {
1567
1624
  validated = { ...validated, id: updateParams.id };
@@ -1805,7 +1862,7 @@ var uinConfigServiceValidation = (uinDeps) => {
1805
1862
  };
1806
1863
 
1807
1864
  // src/services/uinConfig.service.ts
1808
- var import_dayjs = __toESM(require("dayjs"));
1865
+ var import_dayjs2 = __toESM(require("dayjs"));
1809
1866
  var import_node_cron = __toESM(require("node-cron"));
1810
1867
  var MS_IN_A_DAY = 24 * 36e5;
1811
1868
  function buildFromSegments(segments, seqValue) {
@@ -1819,7 +1876,7 @@ function buildFromSegments(segments, seqValue) {
1819
1876
  break;
1820
1877
  case "dateFormat":
1821
1878
  try {
1822
- out += (0, import_dayjs.default)(/* @__PURE__ */ new Date()).format(seg.value);
1879
+ out += (0, import_dayjs2.default)(/* @__PURE__ */ new Date()).format(seg.value);
1823
1880
  } catch {
1824
1881
  console.error("Invalid dateFormat:", seg.value);
1825
1882
  }
package/dist/index.mjs CHANGED
@@ -1006,7 +1006,41 @@ var commonCreateUpdateRepository = (serviceDeps) => {
1006
1006
 
1007
1007
  // src/utils/dynamicJoiBuilder.utils.ts
1008
1008
  import Joi from "joi";
1009
- var buildScalar = (f) => {
1009
+ import dayjs from "dayjs";
1010
+ function applyNumberCompare(schema, op, ref) {
1011
+ const r = Joi.ref(ref);
1012
+ switch (op) {
1013
+ case "gt":
1014
+ return schema.greater(r);
1015
+ case "gte":
1016
+ return schema.min(r);
1017
+ case "lt":
1018
+ return schema.less(r);
1019
+ case "lte":
1020
+ return schema.max(r);
1021
+ case "eq":
1022
+ return schema.valid(r);
1023
+ // not perfect; better use custom if you need strict equality
1024
+ case "neq":
1025
+ return schema.invalid(r);
1026
+ default:
1027
+ return schema;
1028
+ }
1029
+ }
1030
+ function resolvePrecision(rule, ctx) {
1031
+ if (typeof rule.precision === "number") return rule.precision;
1032
+ if (rule.precisionFrom === "ctx.decimalPrecision") {
1033
+ return typeof ctx.decimalPrecision === "number" ? ctx.decimalPrecision : void 0;
1034
+ }
1035
+ return void 0;
1036
+ }
1037
+ function resolveMinDate(rule) {
1038
+ if (!rule.minDate) return void 0;
1039
+ if (rule.minDate === "now") return /* @__PURE__ */ new Date();
1040
+ if (rule.minDate === "today") return dayjs().startOf("day").toDate();
1041
+ return void 0;
1042
+ }
1043
+ var buildScalar = (f, ctx) => {
1010
1044
  const rules = f.rules ?? {};
1011
1045
  let s;
1012
1046
  switch (f.type) {
@@ -1024,6 +1058,11 @@ var buildScalar = (f) => {
1024
1058
  if (rules.integer) j = j.integer();
1025
1059
  if (typeof rules.min === "number") j = j.min(rules.min);
1026
1060
  if (typeof rules.max === "number") j = j.max(rules.max);
1061
+ const p = resolvePrecision(rules, ctx);
1062
+ if (typeof p === "number") s = j.precision(p);
1063
+ if (rules.compare?.ref && rules.compare?.op) {
1064
+ s = applyNumberCompare(j, rules.compare.op, rules.compare.ref);
1065
+ }
1027
1066
  s = j;
1028
1067
  break;
1029
1068
  }
@@ -1032,7 +1071,11 @@ var buildScalar = (f) => {
1032
1071
  break;
1033
1072
  case "date": {
1034
1073
  let j = Joi.date();
1035
- if (rules.iso) j = j.iso();
1074
+ const minD = resolveMinDate(rules);
1075
+ if (minD) s = j.min(minD);
1076
+ if (rules.minDateFieldRef) {
1077
+ s = j.min(Joi.ref(rules.minDateFieldRef));
1078
+ }
1036
1079
  s = j;
1037
1080
  break;
1038
1081
  }
@@ -1053,32 +1096,46 @@ var buildScalar = (f) => {
1053
1096
  }
1054
1097
  if (f.allowNull) s = s.allow(null);
1055
1098
  if (f.default !== void 0) s = s.default(f.default);
1099
+ if (rules.when?.ref) {
1100
+ const isVal = Array.isArray(rules.when.is) ? rules.when.is : [rules.when.is];
1101
+ const thenPresence = rules.when.then?.presence;
1102
+ const otherwisePresence = rules.when.otherwise?.presence;
1103
+ const thenRules = rules.when.then?.rules;
1104
+ const otherwiseRules = rules.when.otherwise?.rules;
1105
+ const thenSchema = thenRules ? buildScalar({ ...f, rules: { ...rules, ...thenRules } }, ctx) : s;
1106
+ const otherwiseSchema = otherwiseRules ? buildScalar({ ...f, rules: { ...rules, ...otherwiseRules } }, ctx) : s;
1107
+ s = Joi.when(rules.when.ref, {
1108
+ is: Joi.valid(...isVal),
1109
+ then: applyPresence(thenSchema, thenPresence),
1110
+ otherwise: applyPresence(otherwiseSchema, otherwisePresence)
1111
+ });
1112
+ }
1056
1113
  if (f.messages) s = s.messages(f.messages);
1057
1114
  return s;
1058
1115
  };
1059
- var applyPresence = (schema, presence) => {
1116
+ function applyPresence(schema, presence) {
1060
1117
  if (presence === "required") return schema.required();
1061
1118
  if (presence === "forbidden") return schema.forbidden();
1062
1119
  return schema.optional();
1063
- };
1064
- var buildRelationSchema = (rel, op) => {
1120
+ }
1121
+ var buildRelationSchema = (rel, op, ctx) => {
1065
1122
  const itemShape = {};
1066
1123
  for (const f of rel.items.fields) {
1067
- const scalar = buildScalar(f);
1124
+ const scalar = buildScalar(f, ctx);
1068
1125
  itemShape[f.db] = applyPresence(scalar, f.presence[op]);
1069
1126
  }
1070
1127
  const itemSchema = Joi.object(itemShape);
1071
1128
  const base = rel.kind === "many" ? Joi.array().items(itemSchema) : itemSchema;
1072
1129
  return applyPresence(base, rel.presence[op]);
1073
1130
  };
1074
- var buildJoiSchemaForOp = (cfg, op) => {
1131
+ var buildJoiSchemaForOp = (cfg, op, ctx) => {
1075
1132
  const shape = {};
1076
1133
  for (const f of cfg.fields) {
1077
- const scalar = buildScalar(f);
1134
+ const scalar = buildScalar(f, ctx);
1078
1135
  shape[f.db] = applyPresence(scalar, f.presence[op]);
1079
1136
  }
1080
1137
  for (const rel of cfg.relations ?? []) {
1081
- shape[rel.db] = buildRelationSchema(rel, op);
1138
+ shape[rel.db] = buildRelationSchema(rel, op, ctx);
1082
1139
  }
1083
1140
  return Joi.object(shape).prefs({
1084
1141
  abortEarly: cfg.validation.abortEarly,
@@ -1469,7 +1526,7 @@ var commonService = (serviceDeps) => {
1469
1526
  throw new ErrorHandler(500, `Configuration not found for short code: ${shortCodeData.shortCode}`);
1470
1527
  }
1471
1528
  const ctx = { userId: currentUser ?? void 0, vars: {} };
1472
- const schema = buildJoiSchemaForOp(cfg, "create");
1529
+ const schema = buildJoiSchemaForOp(cfg, "create", { decimalPrecision: store?.defaultPrecision ?? 2 });
1473
1530
  const validated = await schema.validateAsync(createParams.body);
1474
1531
  if (validationMapping && validationMapping[shortCodeData.shortCode] && validationMapping[shortCodeData.shortCode].create) {
1475
1532
  await validationMapping[shortCodeData.shortCode].create?.(validated);
@@ -1511,7 +1568,7 @@ var commonService = (serviceDeps) => {
1511
1568
  throw new ErrorHandler(500, `Configuration not found for short code: ${shortCodeData.shortCode}`);
1512
1569
  }
1513
1570
  const ctx = { userId: currentUser ?? void 0, vars: {} };
1514
- const schema = buildJoiSchemaForOp(cfg, "update");
1571
+ const schema = buildJoiSchemaForOp(cfg, "update", { decimalPrecision: store?.defaultPrecision ?? 2 });
1515
1572
  let validated = await schema.validateAsync(updateParams.body);
1516
1573
  if (validationMapping && validationMapping[shortCodeData.shortCode] && validationMapping[shortCodeData.shortCode].update) {
1517
1574
  validated = { ...validated, id: updateParams.id };
@@ -1755,7 +1812,7 @@ var uinConfigServiceValidation = (uinDeps) => {
1755
1812
  };
1756
1813
 
1757
1814
  // src/services/uinConfig.service.ts
1758
- import dayjs from "dayjs";
1815
+ import dayjs2 from "dayjs";
1759
1816
  import cron from "node-cron";
1760
1817
  var MS_IN_A_DAY = 24 * 36e5;
1761
1818
  function buildFromSegments(segments, seqValue) {
@@ -1769,7 +1826,7 @@ function buildFromSegments(segments, seqValue) {
1769
1826
  break;
1770
1827
  case "dateFormat":
1771
1828
  try {
1772
- out += dayjs(/* @__PURE__ */ new Date()).format(seg.value);
1829
+ out += dayjs2(/* @__PURE__ */ new Date()).format(seg.value);
1773
1830
  } catch {
1774
1831
  console.error("Invalid dateFormat:", seg.value);
1775
1832
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "av6-core",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",