@twin.org/entity 0.10.1-next.1 → 0.10.1-next.11

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.
@@ -31,7 +31,7 @@ export const ComparisonOperator = {
31
31
  LessThanOrEqual: "less-than-or-equal",
32
32
  /**
33
33
  * Includes.
34
- * A string in a substring.
34
+ * A string in a substring, this is a scan and cannot use an index.
35
35
  * A set contains an element.
36
36
  * A list contains an element.
37
37
  */
@@ -43,6 +43,11 @@ export const ComparisonOperator = {
43
43
  * A list does not contain an element.
44
44
  */
45
45
  NotIncludes: "not-includes",
46
+ /**
47
+ * Starts With.
48
+ * A string begins with a prefix, the anchored match can use an index.
49
+ */
50
+ StartsWith: "starts-with",
46
51
  /**
47
52
  * In.
48
53
  * A element is in a set.
@@ -1 +1 @@
1
- {"version":3,"file":"comparisonOperator.js","sourceRoot":"","sources":["../../../src/models/comparisonOperator.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;GAEG;AACH,gEAAgE;AAChE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,SAAS,EAAE,YAAY;IAEvB;;OAEG;IACH,WAAW,EAAE,cAAc;IAE3B;;OAEG;IACH,kBAAkB,EAAE,uBAAuB;IAE3C;;OAEG;IACH,QAAQ,EAAE,WAAW;IAErB;;OAEG;IACH,eAAe,EAAE,oBAAoB;IAErC;;;;;OAKG;IACH,QAAQ,EAAE,UAAU;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,cAAc;IAE3B;;;OAGG;IACH,EAAE,EAAE,IAAI;CACC,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The types of comparisons.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const ComparisonOperator = {\n\t/**\n\t * Equals.\n\t */\n\tEquals: \"equals\",\n\n\t/**\n\t * Not Equals.\n\t */\n\tNotEquals: \"not-equals\",\n\n\t/**\n\t * Greater Than.\n\t */\n\tGreaterThan: \"greater-than\",\n\n\t/**\n\t * Greater Than Or Equal.\n\t */\n\tGreaterThanOrEqual: \"greater-than-or-equal\",\n\n\t/**\n\t * Less Than.\n\t */\n\tLessThan: \"less-than\",\n\n\t/**\n\t * Less Than Or Equal.\n\t */\n\tLessThanOrEqual: \"less-than-or-equal\",\n\n\t/**\n\t * Includes.\n\t * A string in a substring.\n\t * A set contains an element.\n\t * A list contains an element.\n\t */\n\tIncludes: \"includes\",\n\n\t/**\n\t * Not Includes.\n\t * A string not in a substring.\n\t * A set does not contain an element.\n\t * A list does not contain an element.\n\t */\n\tNotIncludes: \"not-includes\",\n\n\t/**\n\t * In.\n\t * A element is in a set.\n\t */\n\tIn: \"in\"\n} as const;\n\n/**\n * The types of comparisons.\n */\nexport type ComparisonOperator = (typeof ComparisonOperator)[keyof typeof ComparisonOperator];\n"]}
1
+ {"version":3,"file":"comparisonOperator.js","sourceRoot":"","sources":["../../../src/models/comparisonOperator.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;GAEG;AACH,gEAAgE;AAChE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,SAAS,EAAE,YAAY;IAEvB;;OAEG;IACH,WAAW,EAAE,cAAc;IAE3B;;OAEG;IACH,kBAAkB,EAAE,uBAAuB;IAE3C;;OAEG;IACH,QAAQ,EAAE,WAAW;IAErB;;OAEG;IACH,eAAe,EAAE,oBAAoB;IAErC;;;;;OAKG;IACH,QAAQ,EAAE,UAAU;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,cAAc;IAE3B;;;OAGG;IACH,UAAU,EAAE,aAAa;IAEzB;;;OAGG;IACH,EAAE,EAAE,IAAI;CACC,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The types of comparisons.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const ComparisonOperator = {\n\t/**\n\t * Equals.\n\t */\n\tEquals: \"equals\",\n\n\t/**\n\t * Not Equals.\n\t */\n\tNotEquals: \"not-equals\",\n\n\t/**\n\t * Greater Than.\n\t */\n\tGreaterThan: \"greater-than\",\n\n\t/**\n\t * Greater Than Or Equal.\n\t */\n\tGreaterThanOrEqual: \"greater-than-or-equal\",\n\n\t/**\n\t * Less Than.\n\t */\n\tLessThan: \"less-than\",\n\n\t/**\n\t * Less Than Or Equal.\n\t */\n\tLessThanOrEqual: \"less-than-or-equal\",\n\n\t/**\n\t * Includes.\n\t * A string in a substring, this is a scan and cannot use an index.\n\t * A set contains an element.\n\t * A list contains an element.\n\t */\n\tIncludes: \"includes\",\n\n\t/**\n\t * Not Includes.\n\t * A string not in a substring.\n\t * A set does not contain an element.\n\t * A list does not contain an element.\n\t */\n\tNotIncludes: \"not-includes\",\n\n\t/**\n\t * Starts With.\n\t * A string begins with a prefix, the anchored match can use an index.\n\t */\n\tStartsWith: \"starts-with\",\n\n\t/**\n\t * In.\n\t * A element is in a set.\n\t */\n\tIn: \"in\"\n} as const;\n\n/**\n * The types of comparisons.\n */\nexport type ComparisonOperator = (typeof ComparisonOperator)[keyof typeof ComparisonOperator];\n"]}
@@ -55,136 +55,133 @@ export class EntityConditions {
55
55
  * @returns True if the entity matches.
56
56
  */
57
57
  static compare(entity, comparator) {
58
- const val = ObjectHelper.propertyGet(entity, comparator.property);
58
+ const value = ObjectHelper.propertyGet(entity, comparator.property);
59
59
  const conditionValue = comparator.value;
60
+ const comparison = comparator.comparison;
60
61
  if (Is.undefined(conditionValue)) {
61
- const valUndefined = Is.undefined(val);
62
- if (valUndefined && comparator.comparison === ComparisonOperator.Equals) {
63
- return true;
64
- }
65
- else if (!valUndefined && comparator.comparison === ComparisonOperator.NotEquals) {
66
- return true;
67
- }
68
- return false;
62
+ return EntityConditions.matchEquality(Is.undefined(value), comparison);
69
63
  }
70
- else if (conditionValue === null) {
71
- const valNull = val === null;
72
- if (valNull && comparator.comparison === ComparisonOperator.Equals) {
73
- return true;
74
- }
75
- else if (!valNull && comparator.comparison === ComparisonOperator.NotEquals) {
76
- return true;
77
- }
78
- return false;
79
- }
80
- else if (Is.string(val)) {
81
- if (Is.string(conditionValue)) {
82
- if (!((comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||
83
- (comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue) ||
84
- (comparator.comparison === ComparisonOperator.GreaterThan && val > conditionValue) ||
85
- (comparator.comparison === ComparisonOperator.LessThan && val < conditionValue) ||
86
- (comparator.comparison === ComparisonOperator.GreaterThanOrEqual &&
87
- val >= conditionValue) ||
88
- (comparator.comparison === ComparisonOperator.LessThanOrEqual && val <= conditionValue) ||
89
- (comparator.comparison === ComparisonOperator.Includes && val.includes(conditionValue)) ||
90
- (comparator.comparison === ComparisonOperator.NotIncludes &&
91
- !val.includes(conditionValue)))) {
92
- return false;
93
- }
94
- return true;
95
- }
96
- else if (Is.array(conditionValue)) {
97
- if (!(comparator.comparison === ComparisonOperator.In && conditionValue.includes(val))) {
98
- return false;
99
- }
100
- return true;
101
- }
102
- return false;
103
- }
104
- else if (Is.number(val)) {
105
- if (Is.number(conditionValue)) {
106
- if (!((comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||
107
- (comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue) ||
108
- (comparator.comparison === ComparisonOperator.GreaterThan && val > conditionValue) ||
109
- (comparator.comparison === ComparisonOperator.LessThan && val < conditionValue) ||
110
- (comparator.comparison === ComparisonOperator.GreaterThanOrEqual &&
111
- val >= conditionValue) ||
112
- (comparator.comparison === ComparisonOperator.LessThanOrEqual && val <= conditionValue))) {
113
- return false;
114
- }
115
- return true;
116
- }
117
- else if (Is.array(conditionValue)) {
118
- if (!(comparator.comparison === ComparisonOperator.In && conditionValue.includes(val))) {
119
- return false;
120
- }
121
- return true;
122
- }
123
- return false;
64
+ if (conditionValue === null) {
65
+ return EntityConditions.matchEquality(value === null, comparison);
124
66
  }
125
- else if (Is.boolean(val)) {
126
- if (Is.boolean(conditionValue)) {
127
- if (!((comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||
128
- (comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue))) {
129
- return false;
130
- }
131
- return true;
132
- }
133
- return false;
134
- }
135
- else if (Is.array(val)) {
136
- if (Is.array(conditionValue)) {
137
- if (comparator.comparison === ComparisonOperator.Equals ||
138
- comparator.comparison === ComparisonOperator.NotEquals) {
139
- const matches = ArrayHelper.matches(val, conditionValue);
140
- if (!((comparator.comparison === ComparisonOperator.Equals && matches) ||
141
- (comparator.comparison === ComparisonOperator.NotEquals && !matches))) {
142
- return false;
143
- }
144
- return true;
145
- }
146
- return false;
147
- }
148
- else if (Is.number(conditionValue) || Is.string(conditionValue)) {
149
- if (comparator.comparison === ComparisonOperator.Includes ||
150
- comparator.comparison === ComparisonOperator.NotIncludes ||
151
- comparator.comparison === ComparisonOperator.In) {
152
- const includes = val.includes(conditionValue);
153
- if (!((comparator.comparison === ComparisonOperator.Includes && includes) ||
154
- (comparator.comparison === ComparisonOperator.NotIncludes && !includes) ||
155
- (comparator.comparison === ComparisonOperator.In && includes))) {
156
- return false;
157
- }
158
- return true;
159
- }
160
- return false;
161
- }
162
- else if (Is.object(conditionValue)) {
163
- if (comparator.comparison === ComparisonOperator.Includes) {
164
- for (const v of val) {
165
- if (ObjectHelper.equal(v, conditionValue)) {
166
- return true;
167
- }
168
- }
169
- }
170
- else if (comparator.comparison === ComparisonOperator.NotIncludes) {
171
- for (const v of val) {
172
- if (ObjectHelper.equal(v, conditionValue)) {
173
- return false;
174
- }
175
- }
176
- return true;
177
- }
178
- }
179
- return false;
67
+ if (Is.string(value)) {
68
+ return Is.string(conditionValue)
69
+ ? EntityConditions.compareString(value, conditionValue, comparison)
70
+ : EntityConditions.compareIn(value, conditionValue, comparison);
180
71
  }
181
- else if (Is.object(val)) {
182
- if (comparator.comparison === ComparisonOperator.Equals) {
183
- return ObjectHelper.equal(val, conditionValue);
184
- }
185
- else if (comparator.comparison === ComparisonOperator.NotEquals) {
186
- return !ObjectHelper.equal(val, conditionValue);
187
- }
72
+ if (Is.number(value)) {
73
+ return Is.number(conditionValue)
74
+ ? EntityConditions.compareOrdered(value, conditionValue, comparison)
75
+ : EntityConditions.compareIn(value, conditionValue, comparison);
76
+ }
77
+ if (Is.boolean(value)) {
78
+ return Is.boolean(conditionValue)
79
+ ? EntityConditions.matchEquality(value === conditionValue, comparison)
80
+ : EntityConditions.compareIn(value, conditionValue, comparison);
81
+ }
82
+ if (Is.array(value)) {
83
+ return EntityConditions.compareArray(value, conditionValue, comparison);
84
+ }
85
+ if (Is.object(value)) {
86
+ return EntityConditions.matchEquality(ObjectHelper.equal(value, conditionValue), comparison);
87
+ }
88
+ return false;
89
+ }
90
+ /**
91
+ * Resolve an equality result for the equals and not equals operators.
92
+ * @param isEqual Whether the two values are equal.
93
+ * @param comparison The comparison to perform.
94
+ * @returns True if the comparison is satisfied.
95
+ * @internal
96
+ */
97
+ static matchEquality(isEqual, comparison) {
98
+ return ((comparison === ComparisonOperator.Equals && isEqual) ||
99
+ (comparison === ComparisonOperator.NotEquals && !isEqual));
100
+ }
101
+ /**
102
+ * Resolve an inclusion result for the includes and not includes operators.
103
+ * @param isIncluded Whether the value is included.
104
+ * @param comparison The comparison to perform.
105
+ * @returns True if the comparison is satisfied.
106
+ * @internal
107
+ */
108
+ static matchInclusion(isIncluded, comparison) {
109
+ return ((comparison === ComparisonOperator.Includes && isIncluded) ||
110
+ (comparison === ComparisonOperator.NotIncludes && !isIncluded));
111
+ }
112
+ /**
113
+ * Compare a value with the in operator against a list of condition values.
114
+ * @param value The value to test.
115
+ * @param conditionValue The condition value which should be a list.
116
+ * @param comparison The comparison to perform.
117
+ * @returns True if the comparison is satisfied.
118
+ * @internal
119
+ */
120
+ static compareIn(value, conditionValue, comparison) {
121
+ return (comparison === ComparisonOperator.In &&
122
+ Is.array(conditionValue) &&
123
+ conditionValue.includes(value));
124
+ }
125
+ /**
126
+ * Compare two values which support ordering.
127
+ * @param value The value to test.
128
+ * @param conditionValue The condition value to test against.
129
+ * @param comparison The comparison to perform.
130
+ * @returns True if the comparison is satisfied.
131
+ * @internal
132
+ */
133
+ static compareOrdered(value, conditionValue, comparison) {
134
+ switch (comparison) {
135
+ case ComparisonOperator.GreaterThan:
136
+ return value > conditionValue;
137
+ case ComparisonOperator.LessThan:
138
+ return value < conditionValue;
139
+ case ComparisonOperator.GreaterThanOrEqual:
140
+ return value >= conditionValue;
141
+ case ComparisonOperator.LessThanOrEqual:
142
+ return value <= conditionValue;
143
+ default:
144
+ return EntityConditions.matchEquality(value === conditionValue, comparison);
145
+ }
146
+ }
147
+ /**
148
+ * Compare two string values.
149
+ * @param value The value to test.
150
+ * @param conditionValue The condition value to test against.
151
+ * @param comparison The comparison to perform.
152
+ * @returns True if the comparison is satisfied.
153
+ * @internal
154
+ */
155
+ static compareString(value, conditionValue, comparison) {
156
+ if (comparison === ComparisonOperator.StartsWith) {
157
+ return value.startsWith(conditionValue);
158
+ }
159
+ if (comparison === ComparisonOperator.Includes ||
160
+ comparison === ComparisonOperator.NotIncludes) {
161
+ return EntityConditions.matchInclusion(value.includes(conditionValue), comparison);
162
+ }
163
+ return EntityConditions.compareOrdered(value, conditionValue, comparison);
164
+ }
165
+ /**
166
+ * Compare an array value against a condition value.
167
+ * @param value The array to test.
168
+ * @param conditionValue The condition value to test against.
169
+ * @param comparison The comparison to perform.
170
+ * @returns True if the comparison is satisfied.
171
+ * @internal
172
+ */
173
+ static compareArray(value, conditionValue, comparison) {
174
+ if (Is.array(conditionValue)) {
175
+ return EntityConditions.matchEquality(ArrayHelper.matches(value, conditionValue), comparison);
176
+ }
177
+ if (Is.string(conditionValue) || Is.number(conditionValue)) {
178
+ const isIncluded = value.includes(conditionValue);
179
+ return comparison === ComparisonOperator.In
180
+ ? isIncluded
181
+ : EntityConditions.matchInclusion(isIncluded, comparison);
182
+ }
183
+ if (Is.object(conditionValue)) {
184
+ return EntityConditions.matchInclusion(value.some(v => ObjectHelper.equal(v, conditionValue)), comparison);
188
185
  }
189
186
  return false;
190
187
  }
@@ -1 +1 @@
1
- {"version":3,"file":"entityConditions.js","sourceRoot":"","sources":["../../../src/utils/entityConditions.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ArrayHelper, Is, ObjectHelper } from \"@twin.org/core\";\nimport { ComparisonOperator } from \"../models/comparisonOperator.js\";\nimport type { EntityCondition } from \"../models/entityCondition.js\";\nimport type { IComparator } from \"../models/IComparator.js\";\nimport { LogicalOperator } from \"../models/logicalOperator.js\";\n\n/**\n * Class to perform condition checks.\n */\nexport class EntityConditions {\n\t/**\n\t * See if the entity matches the conditions.\n\t * @param entity The entity to test.\n\t * @param condition The conditions to test.\n\t * @returns True if the entity matches.\n\t */\n\tpublic static check<T>(entity: T, condition?: EntityCondition<T>): boolean {\n\t\t// If no conditions are defined then it's a match\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\t// It's a group of comparisons, so check the individual items and combine with the logical operator\n\t\t\tconst results: boolean[] = condition.conditions.map(c => EntityConditions.check(entity, c));\n\t\t\tif ((condition.logicalOperator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\t\treturn results.every(Boolean);\n\t\t\t}\n\t\t\treturn results.some(Boolean);\n\t\t}\n\n\t\tif (condition.property.includes(\".\")) {\n\t\t\t// It's a child property comparison, so evaluate the child property\n\t\t\t// and then compare it to the conditions\n\t\t\tconst path = condition.property.split(\".\");\n\n\t\t\tconst child = ObjectHelper.propertyGet(entity, path[0]);\n\n\t\t\t// If the child is an array then check each item\n\t\t\tif (Is.array(child)) {\n\t\t\t\tfor (const c of child) {\n\t\t\t\t\tconst check = EntityConditions.check(c, {\n\t\t\t\t\t\t...condition,\n\t\t\t\t\t\tproperty: path.slice(1).join(\".\")\n\t\t\t\t\t});\n\t\t\t\t\tif (check) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// It's a single value so just check the condition\n\t\treturn EntityConditions.compare(entity, condition);\n\t}\n\n\t/**\n\t * See if the entity matches the conditions.\n\t * @param entity The entity to test.\n\t * @param comparator The condition to test.\n\t * @returns True if the entity matches.\n\t */\n\tpublic static compare<T>(entity: T, comparator: IComparator): boolean {\n\t\tconst val = ObjectHelper.propertyGet(entity, comparator.property);\n\t\tconst conditionValue = comparator.value;\n\n\t\tif (Is.undefined(conditionValue)) {\n\t\t\tconst valUndefined = Is.undefined(val);\n\t\t\tif (valUndefined && comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn true;\n\t\t\t} else if (!valUndefined && comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (conditionValue === null) {\n\t\t\tconst valNull = val === null;\n\t\t\tif (valNull && comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn true;\n\t\t\t} else if (!valNull && comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (Is.string(val)) {\n\t\t\tif (Is.string(conditionValue)) {\n\t\t\t\tif (!(\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.GreaterThan && val > conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.LessThan && val < conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.GreaterThanOrEqual &&\n\t\t\t\t\t\tval >= conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.LessThanOrEqual && val <= conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.Includes && val.includes(conditionValue)) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotIncludes &&\n\t\t\t\t\t\t!val.includes(conditionValue))\n\t\t\t\t)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t} else if (Is.array(conditionValue)) {\n\t\t\t\tif (!(comparator.comparison === ComparisonOperator.In && conditionValue.includes(val))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (Is.number(val)) {\n\t\t\tif (Is.number(conditionValue)) {\n\t\t\t\tif (!(\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.GreaterThan && val > conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.LessThan && val < conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.GreaterThanOrEqual &&\n\t\t\t\t\t\tval >= conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.LessThanOrEqual && val <= conditionValue)\n\t\t\t\t)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t} else if (Is.array(conditionValue)) {\n\t\t\t\tif (!(comparator.comparison === ComparisonOperator.In && conditionValue.includes(val))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (Is.boolean(val)) {\n\t\t\tif (Is.boolean(conditionValue)) {\n\t\t\t\tif (!(\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.Equals && val === conditionValue) ||\n\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotEquals && val !== conditionValue)\n\t\t\t\t)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (Is.array(val)) {\n\t\t\tif (Is.array(conditionValue)) {\n\t\t\t\tif (\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.Equals ||\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.NotEquals\n\t\t\t\t) {\n\t\t\t\t\tconst matches = ArrayHelper.matches(val, conditionValue);\n\t\t\t\t\tif (!(\n\t\t\t\t\t\t(comparator.comparison === ComparisonOperator.Equals && matches) ||\n\t\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotEquals && !matches)\n\t\t\t\t\t)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else if (Is.number(conditionValue) || Is.string(conditionValue)) {\n\t\t\t\tif (\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.Includes ||\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.NotIncludes ||\n\t\t\t\t\tcomparator.comparison === ComparisonOperator.In\n\t\t\t\t) {\n\t\t\t\t\tconst includes = val.includes(conditionValue);\n\t\t\t\t\tif (!(\n\t\t\t\t\t\t(comparator.comparison === ComparisonOperator.Includes && includes) ||\n\t\t\t\t\t\t(comparator.comparison === ComparisonOperator.NotIncludes && !includes) ||\n\t\t\t\t\t\t(comparator.comparison === ComparisonOperator.In && includes)\n\t\t\t\t\t)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else if (Is.object(conditionValue)) {\n\t\t\t\tif (comparator.comparison === ComparisonOperator.Includes) {\n\t\t\t\t\tfor (const v of val) {\n\t\t\t\t\t\tif (ObjectHelper.equal(v, conditionValue)) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (comparator.comparison === ComparisonOperator.NotIncludes) {\n\t\t\t\t\tfor (const v of val) {\n\t\t\t\t\t\tif (ObjectHelper.equal(v, conditionValue)) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if (Is.object(val)) {\n\t\t\tif (comparator.comparison === ComparisonOperator.Equals) {\n\t\t\t\treturn ObjectHelper.equal(val, conditionValue);\n\t\t\t} else if (comparator.comparison === ComparisonOperator.NotEquals) {\n\t\t\t\treturn !ObjectHelper.equal(val, conditionValue);\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n"]}
1
+ {"version":3,"file":"entityConditions.js","sourceRoot":"","sources":["../../../src/utils/entityConditions.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ArrayHelper, Is, ObjectHelper } from \"@twin.org/core\";\nimport { ComparisonOperator } from \"../models/comparisonOperator.js\";\nimport type { EntityCondition } from \"../models/entityCondition.js\";\nimport type { IComparator } from \"../models/IComparator.js\";\nimport { LogicalOperator } from \"../models/logicalOperator.js\";\n\n/**\n * Class to perform condition checks.\n */\nexport class EntityConditions {\n\t/**\n\t * See if the entity matches the conditions.\n\t * @param entity The entity to test.\n\t * @param condition The conditions to test.\n\t * @returns True if the entity matches.\n\t */\n\tpublic static check<T>(entity: T, condition?: EntityCondition<T>): boolean {\n\t\t// If no conditions are defined then it's a match\n\t\tif (Is.undefined(condition)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (\"conditions\" in condition) {\n\t\t\t// It's a group of comparisons, so check the individual items and combine with the logical operator\n\t\t\tconst results: boolean[] = condition.conditions.map(c => EntityConditions.check(entity, c));\n\t\t\tif ((condition.logicalOperator ?? LogicalOperator.And) === LogicalOperator.And) {\n\t\t\t\treturn results.every(Boolean);\n\t\t\t}\n\t\t\treturn results.some(Boolean);\n\t\t}\n\n\t\tif (condition.property.includes(\".\")) {\n\t\t\t// It's a child property comparison, so evaluate the child property\n\t\t\t// and then compare it to the conditions\n\t\t\tconst path = condition.property.split(\".\");\n\n\t\t\tconst child = ObjectHelper.propertyGet(entity, path[0]);\n\n\t\t\t// If the child is an array then check each item\n\t\t\tif (Is.array(child)) {\n\t\t\t\tfor (const c of child) {\n\t\t\t\t\tconst check = EntityConditions.check(c, {\n\t\t\t\t\t\t...condition,\n\t\t\t\t\t\tproperty: path.slice(1).join(\".\")\n\t\t\t\t\t});\n\t\t\t\t\tif (check) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// It's a single value so just check the condition\n\t\treturn EntityConditions.compare(entity, condition);\n\t}\n\n\t/**\n\t * See if the entity matches the conditions.\n\t * @param entity The entity to test.\n\t * @param comparator The condition to test.\n\t * @returns True if the entity matches.\n\t */\n\tpublic static compare<T>(entity: T, comparator: IComparator): boolean {\n\t\tconst value = ObjectHelper.propertyGet(entity, comparator.property);\n\t\tconst conditionValue = comparator.value;\n\t\tconst comparison = comparator.comparison;\n\n\t\tif (Is.undefined(conditionValue)) {\n\t\t\treturn EntityConditions.matchEquality(Is.undefined(value), comparison);\n\t\t}\n\n\t\tif (conditionValue === null) {\n\t\t\treturn EntityConditions.matchEquality(value === null, comparison);\n\t\t}\n\n\t\tif (Is.string(value)) {\n\t\t\treturn Is.string(conditionValue)\n\t\t\t\t? EntityConditions.compareString(value, conditionValue, comparison)\n\t\t\t\t: EntityConditions.compareIn(value, conditionValue, comparison);\n\t\t}\n\n\t\tif (Is.number(value)) {\n\t\t\treturn Is.number(conditionValue)\n\t\t\t\t? EntityConditions.compareOrdered(value, conditionValue, comparison)\n\t\t\t\t: EntityConditions.compareIn(value, conditionValue, comparison);\n\t\t}\n\n\t\tif (Is.boolean(value)) {\n\t\t\treturn Is.boolean(conditionValue)\n\t\t\t\t? EntityConditions.matchEquality(value === conditionValue, comparison)\n\t\t\t\t: EntityConditions.compareIn(value, conditionValue, comparison);\n\t\t}\n\n\t\tif (Is.array(value)) {\n\t\t\treturn EntityConditions.compareArray(value, conditionValue, comparison);\n\t\t}\n\n\t\tif (Is.object(value)) {\n\t\t\treturn EntityConditions.matchEquality(ObjectHelper.equal(value, conditionValue), comparison);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Resolve an equality result for the equals and not equals operators.\n\t * @param isEqual Whether the two values are equal.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static matchEquality(isEqual: boolean, comparison: ComparisonOperator): boolean {\n\t\treturn (\n\t\t\t(comparison === ComparisonOperator.Equals && isEqual) ||\n\t\t\t(comparison === ComparisonOperator.NotEquals && !isEqual)\n\t\t);\n\t}\n\n\t/**\n\t * Resolve an inclusion result for the includes and not includes operators.\n\t * @param isIncluded Whether the value is included.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static matchInclusion(isIncluded: boolean, comparison: ComparisonOperator): boolean {\n\t\treturn (\n\t\t\t(comparison === ComparisonOperator.Includes && isIncluded) ||\n\t\t\t(comparison === ComparisonOperator.NotIncludes && !isIncluded)\n\t\t);\n\t}\n\n\t/**\n\t * Compare a value with the in operator against a list of condition values.\n\t * @param value The value to test.\n\t * @param conditionValue The condition value which should be a list.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static compareIn(\n\t\tvalue: unknown,\n\t\tconditionValue: unknown,\n\t\tcomparison: ComparisonOperator\n\t): boolean {\n\t\treturn (\n\t\t\tcomparison === ComparisonOperator.In &&\n\t\t\tIs.array(conditionValue) &&\n\t\t\tconditionValue.includes(value)\n\t\t);\n\t}\n\n\t/**\n\t * Compare two values which support ordering.\n\t * @param value The value to test.\n\t * @param conditionValue The condition value to test against.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static compareOrdered<U extends string | number>(\n\t\tvalue: U,\n\t\tconditionValue: U,\n\t\tcomparison: ComparisonOperator\n\t): boolean {\n\t\tswitch (comparison) {\n\t\t\tcase ComparisonOperator.GreaterThan:\n\t\t\t\treturn value > conditionValue;\n\t\t\tcase ComparisonOperator.LessThan:\n\t\t\t\treturn value < conditionValue;\n\t\t\tcase ComparisonOperator.GreaterThanOrEqual:\n\t\t\t\treturn value >= conditionValue;\n\t\t\tcase ComparisonOperator.LessThanOrEqual:\n\t\t\t\treturn value <= conditionValue;\n\t\t\tdefault:\n\t\t\t\treturn EntityConditions.matchEquality(value === conditionValue, comparison);\n\t\t}\n\t}\n\n\t/**\n\t * Compare two string values.\n\t * @param value The value to test.\n\t * @param conditionValue The condition value to test against.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static compareString(\n\t\tvalue: string,\n\t\tconditionValue: string,\n\t\tcomparison: ComparisonOperator\n\t): boolean {\n\t\tif (comparison === ComparisonOperator.StartsWith) {\n\t\t\treturn value.startsWith(conditionValue);\n\t\t}\n\n\t\tif (\n\t\t\tcomparison === ComparisonOperator.Includes ||\n\t\t\tcomparison === ComparisonOperator.NotIncludes\n\t\t) {\n\t\t\treturn EntityConditions.matchInclusion(value.includes(conditionValue), comparison);\n\t\t}\n\n\t\treturn EntityConditions.compareOrdered(value, conditionValue, comparison);\n\t}\n\n\t/**\n\t * Compare an array value against a condition value.\n\t * @param value The array to test.\n\t * @param conditionValue The condition value to test against.\n\t * @param comparison The comparison to perform.\n\t * @returns True if the comparison is satisfied.\n\t * @internal\n\t */\n\tprivate static compareArray(\n\t\tvalue: unknown[],\n\t\tconditionValue: unknown,\n\t\tcomparison: ComparisonOperator\n\t): boolean {\n\t\tif (Is.array(conditionValue)) {\n\t\t\treturn EntityConditions.matchEquality(ArrayHelper.matches(value, conditionValue), comparison);\n\t\t}\n\n\t\tif (Is.string(conditionValue) || Is.number(conditionValue)) {\n\t\t\tconst isIncluded = value.includes(conditionValue);\n\t\t\treturn comparison === ComparisonOperator.In\n\t\t\t\t? isIncluded\n\t\t\t\t: EntityConditions.matchInclusion(isIncluded, comparison);\n\t\t}\n\n\t\tif (Is.object(conditionValue)) {\n\t\t\treturn EntityConditions.matchInclusion(\n\t\t\t\tvalue.some(v => ObjectHelper.equal(v, conditionValue)),\n\t\t\t\tcomparison\n\t\t\t);\n\t\t}\n\n\t\treturn false;\n\t}\n}\n"]}
@@ -50,10 +50,10 @@ export class EntitySorter {
50
50
  res = 0;
51
51
  }
52
52
  else if (b1) {
53
- res = -1;
53
+ res = 1;
54
54
  }
55
55
  else {
56
- res = 1;
56
+ res = -1;
57
57
  }
58
58
  }
59
59
  else if (type === "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"entitySorter.js","sourceRoot":"","sources":["../../../src/utils/entitySorter.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAGpC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D;;GAEG;AACH,MAAM,OAAO,YAAY;IACxB;;;;;OAKG;IACI,MAAM,CAAC,IAAI,CAAI,QAAa,EAAE,aAAgC;QACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YACzD,OAAO,QAAQ,CAAC;QACjB,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC7B,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CACzC,CAAC,EACD,CAAC,EACD,YAAY,CAAC,QAAQ,EACrB,YAAY,CAAC,IAAI,EACjB,YAAY,CAAC,aAAa,CAC1B,CAAC;gBACF,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO,aAAa,CAAC;gBACtB,CAAC;YACF,CAAC;YACD,OAAO,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,OAAO,CACpB,OAAU,EACV,OAAU,EACV,IAAa,EACb,IAA8B,EAC9B,YAA2B,aAAa,CAAC,SAAS;QAElD,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1C,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7C,GAAG,GAAI,OAAO,CAAC,IAAI,CAAuB,GAAI,OAAO,CAAC,IAAI,CAAuB,CAAC;YACnF,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAuB,CAAC;gBAC/C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAuB,CAAC;gBAC/C,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;oBACf,GAAG,GAAG,CAAC,CAAC;gBACT,CAAC;qBAAM,IAAI,EAAE,EAAE,CAAC;oBACf,GAAG,GAAG,CAAC,CAAC,CAAC;gBACV,CAAC;qBAAM,CAAC;oBACP,GAAG,GAAG,CAAC,CAAC;gBACT,CAAC;YACF,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,GAAG,GAAI,OAAO,CAAC,IAAI,CAAuB,CAAC,aAAa,CACvD,OAAO,CAAC,IAAI,CAAsB,CAClC,CAAC;YACH,CAAC;QACF,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACrB,GAAG,GAAG,CAAC,CAAC,CAAC;QACV,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACrB,GAAG,GAAG,CAAC,CAAC;QACT,CAAC;QAED,OAAO,SAAS,KAAK,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/D,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"@twin.org/core\";\nimport type { EntitySchemaPropertyType } from \"../models/entitySchemaPropertyType.js\";\nimport type { IEntitySort } from \"../models/IEntitySort.js\";\nimport { SortDirection } from \"../models/sortDirection.js\";\n\n/**\n * Class to perform sort operations on entities.\n */\nexport class EntitySorter {\n\t/**\n\t * Sort a list of entities using multiple keys and direction.\n\t * @param entities The list of entities.\n\t * @param entitySorters The sort keys to use.\n\t * @returns The sorted list.\n\t */\n\tpublic static sort<T>(entities: T[], entitySorters?: IEntitySort<T>[]): T[] {\n\t\tif (!Is.arrayValue(entities) || Is.empty(entitySorters)) {\n\t\t\treturn entities;\n\t\t}\n\n\t\treturn entities.sort((a, b) => {\n\t\t\tfor (const entitySorter of entitySorters) {\n\t\t\t\tconst compareResult = EntitySorter.compare(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tentitySorter.property,\n\t\t\t\t\tentitySorter.type,\n\t\t\t\t\tentitySorter.sortDirection\n\t\t\t\t);\n\t\t\t\tif (compareResult !== 0) {\n\t\t\t\t\treturn compareResult;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 0;\n\t\t});\n\t}\n\n\t/**\n\t * Compare two properties.\n\t * @param entity1 The first entity.\n\t * @param entity2 The second entity.\n\t * @param prop The property to compare.\n\t * @param type The type of the property.\n\t * @param direction The direction of the sort.\n\t * @returns The result of the comparison.\n\t */\n\tpublic static compare<T>(\n\t\tentity1: T,\n\t\tentity2: T,\n\t\tprop: keyof T,\n\t\ttype: EntitySchemaPropertyType,\n\t\tdirection: SortDirection = SortDirection.Ascending\n\t): number {\n\t\tlet res = 0;\n\t\tconst hasProp1 = !Is.empty(entity1[prop]);\n\t\tconst hasProp2 = !Is.empty(entity2[prop]);\n\n\t\tif (hasProp1 && hasProp2) {\n\t\t\tif (type === \"number\" || type === \"integer\") {\n\t\t\t\tres = (entity1[prop] as unknown as number) - (entity2[prop] as unknown as number);\n\t\t\t} else if (type === \"boolean\") {\n\t\t\t\tconst b1 = entity1[prop] as unknown as boolean;\n\t\t\t\tconst b2 = entity2[prop] as unknown as boolean;\n\t\t\t\tif (b1 === b2) {\n\t\t\t\t\tres = 0;\n\t\t\t\t} else if (b1) {\n\t\t\t\t\tres = -1;\n\t\t\t\t} else {\n\t\t\t\t\tres = 1;\n\t\t\t\t}\n\t\t\t} else if (type === \"string\") {\n\t\t\t\tres = (entity1[prop] as unknown as string).localeCompare(\n\t\t\t\t\tentity2[prop] as unknown as string\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (hasProp1) {\n\t\t\tres = -1;\n\t\t} else if (hasProp2) {\n\t\t\tres = 1;\n\t\t}\n\n\t\treturn direction === SortDirection.Ascending ? res : res * -1;\n\t}\n}\n"]}
1
+ {"version":3,"file":"entitySorter.js","sourceRoot":"","sources":["../../../src/utils/entitySorter.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAGpC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D;;GAEG;AACH,MAAM,OAAO,YAAY;IACxB;;;;;OAKG;IACI,MAAM,CAAC,IAAI,CAAI,QAAa,EAAE,aAAgC;QACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YACzD,OAAO,QAAQ,CAAC;QACjB,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC7B,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CACzC,CAAC,EACD,CAAC,EACD,YAAY,CAAC,QAAQ,EACrB,YAAY,CAAC,IAAI,EACjB,YAAY,CAAC,aAAa,CAC1B,CAAC;gBACF,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO,aAAa,CAAC;gBACtB,CAAC;YACF,CAAC;YACD,OAAO,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,OAAO,CACpB,OAAU,EACV,OAAU,EACV,IAAa,EACb,IAA8B,EAC9B,YAA2B,aAAa,CAAC,SAAS;QAElD,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1C,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7C,GAAG,GAAI,OAAO,CAAC,IAAI,CAAuB,GAAI,OAAO,CAAC,IAAI,CAAuB,CAAC;YACnF,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAuB,CAAC;gBAC/C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAuB,CAAC;gBAC/C,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;oBACf,GAAG,GAAG,CAAC,CAAC;gBACT,CAAC;qBAAM,IAAI,EAAE,EAAE,CAAC;oBACf,GAAG,GAAG,CAAC,CAAC;gBACT,CAAC;qBAAM,CAAC;oBACP,GAAG,GAAG,CAAC,CAAC,CAAC;gBACV,CAAC;YACF,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,GAAG,GAAI,OAAO,CAAC,IAAI,CAAuB,CAAC,aAAa,CACvD,OAAO,CAAC,IAAI,CAAsB,CAClC,CAAC;YACH,CAAC;QACF,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACrB,GAAG,GAAG,CAAC,CAAC,CAAC;QACV,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACrB,GAAG,GAAG,CAAC,CAAC;QACT,CAAC;QAED,OAAO,SAAS,KAAK,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/D,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { Is } from \"@twin.org/core\";\nimport type { EntitySchemaPropertyType } from \"../models/entitySchemaPropertyType.js\";\nimport type { IEntitySort } from \"../models/IEntitySort.js\";\nimport { SortDirection } from \"../models/sortDirection.js\";\n\n/**\n * Class to perform sort operations on entities.\n */\nexport class EntitySorter {\n\t/**\n\t * Sort a list of entities using multiple keys and direction.\n\t * @param entities The list of entities.\n\t * @param entitySorters The sort keys to use.\n\t * @returns The sorted list.\n\t */\n\tpublic static sort<T>(entities: T[], entitySorters?: IEntitySort<T>[]): T[] {\n\t\tif (!Is.arrayValue(entities) || Is.empty(entitySorters)) {\n\t\t\treturn entities;\n\t\t}\n\n\t\treturn entities.sort((a, b) => {\n\t\t\tfor (const entitySorter of entitySorters) {\n\t\t\t\tconst compareResult = EntitySorter.compare(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tentitySorter.property,\n\t\t\t\t\tentitySorter.type,\n\t\t\t\t\tentitySorter.sortDirection\n\t\t\t\t);\n\t\t\t\tif (compareResult !== 0) {\n\t\t\t\t\treturn compareResult;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 0;\n\t\t});\n\t}\n\n\t/**\n\t * Compare two properties.\n\t * @param entity1 The first entity.\n\t * @param entity2 The second entity.\n\t * @param prop The property to compare.\n\t * @param type The type of the property.\n\t * @param direction The direction of the sort.\n\t * @returns The result of the comparison.\n\t */\n\tpublic static compare<T>(\n\t\tentity1: T,\n\t\tentity2: T,\n\t\tprop: keyof T,\n\t\ttype: EntitySchemaPropertyType,\n\t\tdirection: SortDirection = SortDirection.Ascending\n\t): number {\n\t\tlet res = 0;\n\t\tconst hasProp1 = !Is.empty(entity1[prop]);\n\t\tconst hasProp2 = !Is.empty(entity2[prop]);\n\n\t\tif (hasProp1 && hasProp2) {\n\t\t\tif (type === \"number\" || type === \"integer\") {\n\t\t\t\tres = (entity1[prop] as unknown as number) - (entity2[prop] as unknown as number);\n\t\t\t} else if (type === \"boolean\") {\n\t\t\t\tconst b1 = entity1[prop] as unknown as boolean;\n\t\t\t\tconst b2 = entity2[prop] as unknown as boolean;\n\t\t\t\tif (b1 === b2) {\n\t\t\t\t\tres = 0;\n\t\t\t\t} else if (b1) {\n\t\t\t\t\tres = 1;\n\t\t\t\t} else {\n\t\t\t\t\tres = -1;\n\t\t\t\t}\n\t\t\t} else if (type === \"string\") {\n\t\t\t\tres = (entity1[prop] as unknown as string).localeCompare(\n\t\t\t\t\tentity2[prop] as unknown as string\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (hasProp1) {\n\t\t\tres = -1;\n\t\t} else if (hasProp2) {\n\t\t\tres = 1;\n\t\t}\n\n\t\treturn direction === SortDirection.Ascending ? res : res * -1;\n\t}\n}\n"]}
@@ -28,7 +28,7 @@ export declare const ComparisonOperator: {
28
28
  readonly LessThanOrEqual: "less-than-or-equal";
29
29
  /**
30
30
  * Includes.
31
- * A string in a substring.
31
+ * A string in a substring, this is a scan and cannot use an index.
32
32
  * A set contains an element.
33
33
  * A list contains an element.
34
34
  */
@@ -40,6 +40,11 @@ export declare const ComparisonOperator: {
40
40
  * A list does not contain an element.
41
41
  */
42
42
  readonly NotIncludes: "not-includes";
43
+ /**
44
+ * Starts With.
45
+ * A string begins with a prefix, the anchored match can use an index.
46
+ */
47
+ readonly StartsWith: "starts-with";
43
48
  /**
44
49
  * In.
45
50
  * A element is in a set.
package/docs/changelog.md CHANGED
@@ -1,5 +1,247 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.1-next.11](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.10...entity-v0.10.1-next.11) (2026-09-25)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **entity:** Synchronize repo versions
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/core bumped from 0.10.1-next.10 to 0.10.1-next.11
16
+ * @twin.org/nameof bumped from 0.10.1-next.10 to 0.10.1-next.11
17
+ * devDependencies
18
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.10 to 0.10.1-next.11
19
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.10 to 0.10.1-next.11
20
+ * @twin.org/validate-locales bumped from 0.10.1-next.10 to 0.10.1-next.11
21
+
22
+ ## [0.10.1-next.10](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.9...entity-v0.10.1-next.10) (2026-09-22)
23
+
24
+
25
+ ### Miscellaneous Chores
26
+
27
+ * **entity:** Synchronize repo versions
28
+
29
+
30
+ ### Dependencies
31
+
32
+ * The following workspace dependencies were updated
33
+ * dependencies
34
+ * @twin.org/core bumped from 0.10.1-next.9 to 0.10.1-next.10
35
+ * @twin.org/nameof bumped from 0.10.1-next.9 to 0.10.1-next.10
36
+ * devDependencies
37
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.9 to 0.10.1-next.10
38
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.9 to 0.10.1-next.10
39
+ * @twin.org/validate-locales bumped from 0.10.1-next.9 to 0.10.1-next.10
40
+
41
+ ## [0.10.1-next.9](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.8...entity-v0.10.1-next.9) (2026-09-21)
42
+
43
+
44
+ ### Features
45
+
46
+ * add IEntitySchemaDiff and entitySchemaDiff utility ([#282](https://github.com/iotaledger/twin-framework/issues/282)) ([9d63e94](https://github.com/iotaledger/twin-framework/commit/9d63e94021ee2ffc138004ee68cf53d08a6b17f9))
47
+ * add StartsWith comparison operator ([#517](https://github.com/iotaledger/twin-framework/issues/517)) ([5c39b5b](https://github.com/iotaledger/twin-framework/commit/5c39b5b77bb5d59199e6dad2000d1806e7f4035d))
48
+ * add support for null in EntityConditions.compare ([922c4ba](https://github.com/iotaledger/twin-framework/commit/922c4ba8af578b4e7eaaf21b3c37a9d788941487))
49
+ * add version field to IEntitySchema and EntitySchemaHelper.getVersion for migration support ([#346](https://github.com/iotaledger/twin-framework/issues/346)) ([e74557e](https://github.com/iotaledger/twin-framework/commit/e74557e4ccbda5b9971f4cfcd0852ba5957cead0))
50
+ * composite indexes ([b506d95](https://github.com/iotaledger/twin-framework/commit/b506d957a5eff6ff6012be773e98af36e750be4a))
51
+ * composite indexes ([#509](https://github.com/iotaledger/twin-framework/issues/509)) ([44b3327](https://github.com/iotaledger/twin-framework/commit/44b33270e6c8dabcc81cc4aa8d27a69255a5e7d4))
52
+ * dev tools ([#500](https://github.com/iotaledger/twin-framework/issues/500)) ([0879e55](https://github.com/iotaledger/twin-framework/commit/0879e558c71dca5e992d14914c6bde560a191df2))
53
+ * entity conditions boolean in ([#530](https://github.com/iotaledger/twin-framework/issues/530)) ([50cc09a](https://github.com/iotaledger/twin-framework/commit/50cc09aa7b32e0dd7936ed0c2f074b0b166bcbf5))
54
+ * entity max string lengths ([#497](https://github.com/iotaledger/twin-framework/issues/497)) ([7fc91e2](https://github.com/iotaledger/twin-framework/commit/7fc91e2a49b9f1e2113bfe10983e083298ef2539))
55
+ * entity schema decorators default value ([33397c2](https://github.com/iotaledger/twin-framework/commit/33397c2e24978a91257371a4c63ce7f6a7125d0c))
56
+ * entity schema diff updates ([#294](https://github.com/iotaledger/twin-framework/issues/294)) ([7a7a94d](https://github.com/iotaledger/twin-framework/commit/7a7a94d14ea5e785dd68fd6de1c5a84941721d28))
57
+ * linting and dependency update ([676b4e9](https://github.com/iotaledger/twin-framework/commit/676b4e9d9bce158065200bbf875bb31da81d166d))
58
+ * native enhancements ([#527](https://github.com/iotaledger/twin-framework/issues/527)) ([dc77328](https://github.com/iotaledger/twin-framework/commit/dc77328df201ff77809d8e8792c27780bfb6d8c4))
59
+ * optimistic locking version property for schemas ([#443](https://github.com/iotaledger/twin-framework/issues/443)) ([1b90987](https://github.com/iotaledger/twin-framework/commit/1b909875dc915a0ec133d8424d013ae7e4ddfb48))
60
+ * refactor EntityConditions compare ([576f894](https://github.com/iotaledger/twin-framework/commit/576f894f67186353d112a95ff57c94bc92e7f93c))
61
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
62
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
63
+
64
+
65
+ ### Bug Fixes
66
+
67
+ * allow vacuous truth to match SQL semantics ([5bbc5e5](https://github.com/iotaledger/twin-framework/commit/5bbc5e53069f90bd39485a74a284eda9e5864e66))
68
+ * coerce and includes ([#429](https://github.com/iotaledger/twin-framework/issues/429)) ([98c9132](https://github.com/iotaledger/twin-framework/commit/98c9132316c0393ede9d6e634bbae9e5ece2d6b9))
69
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
70
+ * update copyright year ([#260](https://github.com/iotaledger/twin-framework/issues/260)) ([c4ad930](https://github.com/iotaledger/twin-framework/commit/c4ad930fcc84ba6b5447a8074574329870b4c3f5))
71
+ * vacuous entity condition ([#385](https://github.com/iotaledger/twin-framework/issues/385)) ([e1082bf](https://github.com/iotaledger/twin-framework/commit/e1082bff4a66ac270efc9c6654d974c19f889d2d))
72
+
73
+
74
+ ### Dependencies
75
+
76
+ * The following workspace dependencies were updated
77
+ * dependencies
78
+ * @twin.org/core bumped from 0.10.1-next.8 to 0.10.1-next.9
79
+ * @twin.org/nameof bumped from 0.10.1-next.8 to 0.10.1-next.9
80
+ * devDependencies
81
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.8 to 0.10.1-next.9
82
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.8 to 0.10.1-next.9
83
+ * @twin.org/validate-locales bumped from 0.10.1-next.8 to 0.10.1-next.9
84
+
85
+ ## [0.10.1-next.8](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.7...entity-v0.10.1-next.8) (2026-09-21)
86
+
87
+
88
+ ### Features
89
+
90
+ * add IEntitySchemaDiff and entitySchemaDiff utility ([#282](https://github.com/iotaledger/twin-framework/issues/282)) ([9d63e94](https://github.com/iotaledger/twin-framework/commit/9d63e94021ee2ffc138004ee68cf53d08a6b17f9))
91
+ * add StartsWith comparison operator ([#517](https://github.com/iotaledger/twin-framework/issues/517)) ([5c39b5b](https://github.com/iotaledger/twin-framework/commit/5c39b5b77bb5d59199e6dad2000d1806e7f4035d))
92
+ * add support for null in EntityConditions.compare ([922c4ba](https://github.com/iotaledger/twin-framework/commit/922c4ba8af578b4e7eaaf21b3c37a9d788941487))
93
+ * add version field to IEntitySchema and EntitySchemaHelper.getVersion for migration support ([#346](https://github.com/iotaledger/twin-framework/issues/346)) ([e74557e](https://github.com/iotaledger/twin-framework/commit/e74557e4ccbda5b9971f4cfcd0852ba5957cead0))
94
+ * composite indexes ([b506d95](https://github.com/iotaledger/twin-framework/commit/b506d957a5eff6ff6012be773e98af36e750be4a))
95
+ * composite indexes ([#509](https://github.com/iotaledger/twin-framework/issues/509)) ([44b3327](https://github.com/iotaledger/twin-framework/commit/44b33270e6c8dabcc81cc4aa8d27a69255a5e7d4))
96
+ * dev tools ([#500](https://github.com/iotaledger/twin-framework/issues/500)) ([0879e55](https://github.com/iotaledger/twin-framework/commit/0879e558c71dca5e992d14914c6bde560a191df2))
97
+ * entity conditions boolean in ([#530](https://github.com/iotaledger/twin-framework/issues/530)) ([50cc09a](https://github.com/iotaledger/twin-framework/commit/50cc09aa7b32e0dd7936ed0c2f074b0b166bcbf5))
98
+ * entity max string lengths ([#497](https://github.com/iotaledger/twin-framework/issues/497)) ([7fc91e2](https://github.com/iotaledger/twin-framework/commit/7fc91e2a49b9f1e2113bfe10983e083298ef2539))
99
+ * entity schema decorators default value ([33397c2](https://github.com/iotaledger/twin-framework/commit/33397c2e24978a91257371a4c63ce7f6a7125d0c))
100
+ * entity schema diff updates ([#294](https://github.com/iotaledger/twin-framework/issues/294)) ([7a7a94d](https://github.com/iotaledger/twin-framework/commit/7a7a94d14ea5e785dd68fd6de1c5a84941721d28))
101
+ * linting and dependency update ([676b4e9](https://github.com/iotaledger/twin-framework/commit/676b4e9d9bce158065200bbf875bb31da81d166d))
102
+ * native enhancements ([#527](https://github.com/iotaledger/twin-framework/issues/527)) ([dc77328](https://github.com/iotaledger/twin-framework/commit/dc77328df201ff77809d8e8792c27780bfb6d8c4))
103
+ * optimistic locking version property for schemas ([#443](https://github.com/iotaledger/twin-framework/issues/443)) ([1b90987](https://github.com/iotaledger/twin-framework/commit/1b909875dc915a0ec133d8424d013ae7e4ddfb48))
104
+ * refactor EntityConditions compare ([576f894](https://github.com/iotaledger/twin-framework/commit/576f894f67186353d112a95ff57c94bc92e7f93c))
105
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
106
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
107
+
108
+
109
+ ### Bug Fixes
110
+
111
+ * allow vacuous truth to match SQL semantics ([5bbc5e5](https://github.com/iotaledger/twin-framework/commit/5bbc5e53069f90bd39485a74a284eda9e5864e66))
112
+ * coerce and includes ([#429](https://github.com/iotaledger/twin-framework/issues/429)) ([98c9132](https://github.com/iotaledger/twin-framework/commit/98c9132316c0393ede9d6e634bbae9e5ece2d6b9))
113
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
114
+ * update copyright year ([#260](https://github.com/iotaledger/twin-framework/issues/260)) ([c4ad930](https://github.com/iotaledger/twin-framework/commit/c4ad930fcc84ba6b5447a8074574329870b4c3f5))
115
+ * vacuous entity condition ([#385](https://github.com/iotaledger/twin-framework/issues/385)) ([e1082bf](https://github.com/iotaledger/twin-framework/commit/e1082bff4a66ac270efc9c6654d974c19f889d2d))
116
+
117
+
118
+ ### Dependencies
119
+
120
+ * The following workspace dependencies were updated
121
+ * dependencies
122
+ * @twin.org/core bumped from 0.10.1-next.7 to 0.10.1-next.8
123
+ * @twin.org/nameof bumped from 0.10.1-next.7 to 0.10.1-next.8
124
+ * devDependencies
125
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.7 to 0.10.1-next.8
126
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.7 to 0.10.1-next.8
127
+ * @twin.org/validate-locales bumped from 0.10.1-next.7 to 0.10.1-next.8
128
+
129
+ ## [0.10.1-next.7](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.6...entity-v0.10.1-next.7) (2026-09-21)
130
+
131
+
132
+ ### Features
133
+
134
+ * dev tools ([#500](https://github.com/iotaledger/twin-framework/issues/500)) ([0879e55](https://github.com/iotaledger/twin-framework/commit/0879e558c71dca5e992d14914c6bde560a191df2))
135
+ * entity conditions boolean in ([#530](https://github.com/iotaledger/twin-framework/issues/530)) ([50cc09a](https://github.com/iotaledger/twin-framework/commit/50cc09aa7b32e0dd7936ed0c2f074b0b166bcbf5))
136
+ * refactor EntityConditions compare ([576f894](https://github.com/iotaledger/twin-framework/commit/576f894f67186353d112a95ff57c94bc92e7f93c))
137
+
138
+
139
+ ### Dependencies
140
+
141
+ * The following workspace dependencies were updated
142
+ * dependencies
143
+ * @twin.org/core bumped from 0.10.1-next.6 to 0.10.1-next.7
144
+ * @twin.org/nameof bumped from 0.10.1-next.6 to 0.10.1-next.7
145
+ * devDependencies
146
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.6 to 0.10.1-next.7
147
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.6 to 0.10.1-next.7
148
+ * @twin.org/validate-locales bumped from 0.10.1-next.6 to 0.10.1-next.7
149
+
150
+ ## [0.10.1-next.6](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.5...entity-v0.10.1-next.6) (2026-09-21)
151
+
152
+
153
+ ### Features
154
+
155
+ * native enhancements ([#527](https://github.com/iotaledger/twin-framework/issues/527)) ([dc77328](https://github.com/iotaledger/twin-framework/commit/dc77328df201ff77809d8e8792c27780bfb6d8c4))
156
+
157
+
158
+ ### Dependencies
159
+
160
+ * The following workspace dependencies were updated
161
+ * dependencies
162
+ * @twin.org/core bumped from 0.10.1-next.5 to 0.10.1-next.6
163
+ * @twin.org/nameof bumped from 0.10.1-next.5 to 0.10.1-next.6
164
+ * devDependencies
165
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.5 to 0.10.1-next.6
166
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.5 to 0.10.1-next.6
167
+ * @twin.org/validate-locales bumped from 0.10.1-next.5 to 0.10.1-next.6
168
+
169
+ ## [0.10.1-next.5](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.4...entity-v0.10.1-next.5) (2026-09-18)
170
+
171
+
172
+ ### Miscellaneous Chores
173
+
174
+ * **entity:** Synchronize repo versions
175
+
176
+
177
+ ### Dependencies
178
+
179
+ * The following workspace dependencies were updated
180
+ * dependencies
181
+ * @twin.org/core bumped from 0.10.1-next.4 to 0.10.1-next.5
182
+ * @twin.org/nameof bumped from 0.10.1-next.4 to 0.10.1-next.5
183
+ * devDependencies
184
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.4 to 0.10.1-next.5
185
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.4 to 0.10.1-next.5
186
+ * @twin.org/validate-locales bumped from 0.10.1-next.4 to 0.10.1-next.5
187
+
188
+ ## [0.10.1-next.4](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.3...entity-v0.10.1-next.4) (2026-09-18)
189
+
190
+
191
+ ### Miscellaneous Chores
192
+
193
+ * **entity:** Synchronize repo versions
194
+
195
+
196
+ ### Dependencies
197
+
198
+ * The following workspace dependencies were updated
199
+ * dependencies
200
+ * @twin.org/core bumped from 0.10.1-next.3 to 0.10.1-next.4
201
+ * @twin.org/nameof bumped from 0.10.1-next.3 to 0.10.1-next.4
202
+ * devDependencies
203
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.3 to 0.10.1-next.4
204
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.3 to 0.10.1-next.4
205
+ * @twin.org/validate-locales bumped from 0.10.1-next.3 to 0.10.1-next.4
206
+
207
+ ## [0.10.1-next.3](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.2...entity-v0.10.1-next.3) (2026-09-18)
208
+
209
+
210
+ ### Features
211
+
212
+ * add StartsWith comparison operator ([#517](https://github.com/iotaledger/twin-framework/issues/517)) ([5c39b5b](https://github.com/iotaledger/twin-framework/commit/5c39b5b77bb5d59199e6dad2000d1806e7f4035d))
213
+
214
+
215
+ ### Dependencies
216
+
217
+ * The following workspace dependencies were updated
218
+ * dependencies
219
+ * @twin.org/core bumped from 0.10.1-next.2 to 0.10.1-next.3
220
+ * @twin.org/nameof bumped from 0.10.1-next.2 to 0.10.1-next.3
221
+ * devDependencies
222
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.2 to 0.10.1-next.3
223
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.2 to 0.10.1-next.3
224
+ * @twin.org/validate-locales bumped from 0.10.1-next.2 to 0.10.1-next.3
225
+
226
+ ## [0.10.1-next.2](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.1...entity-v0.10.1-next.2) (2026-09-17)
227
+
228
+
229
+ ### Miscellaneous Chores
230
+
231
+ * **entity:** Synchronize repo versions
232
+
233
+
234
+ ### Dependencies
235
+
236
+ * The following workspace dependencies were updated
237
+ * dependencies
238
+ * @twin.org/core bumped from 0.10.1-next.1 to 0.10.1-next.2
239
+ * @twin.org/nameof bumped from 0.10.1-next.1 to 0.10.1-next.2
240
+ * devDependencies
241
+ * @twin.org/nameof-transformer bumped from 0.10.1-next.1 to 0.10.1-next.2
242
+ * @twin.org/nameof-vitest-plugin bumped from 0.10.1-next.1 to 0.10.1-next.2
243
+ * @twin.org/validate-locales bumped from 0.10.1-next.1 to 0.10.1-next.2
244
+
3
245
  ## [0.10.1-next.1](https://github.com/iotaledger/twin-framework/compare/entity-v0.10.1-next.0...entity-v0.10.1-next.1) (2026-09-17)
4
246
 
5
247
 
@@ -47,7 +47,7 @@ Less Than Or Equal.
47
47
  > `readonly` **Includes**: `"includes"` = `"includes"`
48
48
 
49
49
  Includes.
50
- A string in a substring.
50
+ A string in a substring, this is a scan and cannot use an index.
51
51
  A set contains an element.
52
52
  A list contains an element.
53
53
 
@@ -60,6 +60,13 @@ A string not in a substring.
60
60
  A set does not contain an element.
61
61
  A list does not contain an element.
62
62
 
63
+ ### StartsWith {#startswith}
64
+
65
+ > `readonly` **StartsWith**: `"starts-with"` = `"starts-with"`
66
+
67
+ Starts With.
68
+ A string begins with a prefix, the anchored match can use an index.
69
+
63
70
  ### In {#in}
64
71
 
65
72
  > `readonly` **In**: `"in"` = `"in"`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/entity",
3
- "version": "0.10.1-next.1",
3
+ "version": "0.10.1-next.11",
4
4
  "description": "Helpers for defining and working with entities",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,8 @@
14
14
  "node": ">=24.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/core": "0.10.1-next.1",
18
- "@twin.org/nameof": "0.10.1-next.1",
17
+ "@twin.org/core": "0.10.1-next.11",
18
+ "@twin.org/nameof": "0.10.1-next.11",
19
19
  "reflect-metadata": "0.2.2",
20
20
  "tslib": "2.8.1"
21
21
  },