bruce-models 4.9.9 → 5.0.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.
@@ -4092,61 +4092,228 @@
4092
4092
  EValueType[EValueType["RandomColor"] = 5] = "RandomColor";
4093
4093
  })(EValueType = Calculator.EValueType || (Calculator.EValueType = {}));
4094
4094
  /**
4095
- * Calculates the value of arbitrary field options.
4096
- * The context calling this should validate results and parse stuff if needed.
4097
- * @deprecated use specific calls: eg GetColor or GetNumber.
4098
- * @param fields
4099
- * @param entity
4100
- * @param tags
4101
- * @returns
4095
+ * Calculates a value-type 'T' based on given set of fields.
4096
+ * The supplied data + tags are fed into the calculation.
4097
+ * When a value fails to be calculated, the 'defaultValue' is returned.
4098
+ * If no 'defaultValue' is provided, then 'null' is returned.
4102
4099
  */
4103
- function GetValue(fields, entity, tags) {
4104
- if (!(fields === null || fields === void 0 ? void 0 : fields.length)) {
4105
- return null;
4100
+ function Calculate(params) {
4101
+ let { fields, tags, data, defaultValue, type } = params;
4102
+ if (fields == null) {
4103
+ return defaultValue;
4104
+ }
4105
+ if (data == null || typeof data != "object") {
4106
+ data = {};
4106
4107
  }
4107
- if (!tags) {
4108
+ if (tags == null || !Array.isArray(tags)) {
4108
4109
  tags = [];
4109
4110
  }
4110
- if (!entity) {
4111
- entity = {};
4111
+ if (type == null) {
4112
+ type = "any";
4113
+ }
4114
+ // Normalize fields to be an array of options.
4115
+ let fieldsArr = [];
4116
+ if (Array.isArray(fields)) {
4117
+ fieldsArr = fields;
4112
4118
  }
4113
- for (let i = 0; i < fields.length; i++) {
4114
- const field = fields[i];
4115
- let value;
4119
+ else {
4120
+ fieldsArr = [fields];
4121
+ }
4122
+ // Indicator for old data.
4123
+ // When a range is provided in older data, it is expected that invalid/failed mappings should default to the minimum value.
4124
+ // We are deprecating this logic.
4125
+ // The first step of deprecation is to avoid using this logic when multiple calculations are provided.
4126
+ // TODO: When we've reviewed all existing uses, we can remove this logic entirely and just update the needed style records.
4127
+ let shouldRangesDefaultToMin = true;
4128
+ // This reduce totals the number of mappings and gradients.
4129
+ // >1 means we should not default to min as there are multiple calculations.
4130
+ if (fieldsArr.reduce((acc, field) => acc += (field.type == EValueType.Mapping || field.type == EValueType.Gradient) ? 1 : 0, 0) > 1) {
4131
+ shouldRangesDefaultToMin = false;
4132
+ }
4133
+ const assertColor = (color) => {
4134
+ if (color && typeof color == "string") {
4135
+ color = exports.Color.ColorFromStr(color);
4136
+ }
4137
+ if (color && typeof color == "object" && !isNaN(color.red) && color.red != null) {
4138
+ return color;
4139
+ }
4140
+ return null;
4141
+ };
4142
+ const isColor = (value) => {
4143
+ if (value && typeof value == "object" && !isNaN(value.red) && value.red != null) {
4144
+ return true;
4145
+ }
4146
+ return false;
4147
+ };
4148
+ // Calculate the value.
4149
+ let value = null;
4150
+ for (let i = 0; i < fieldsArr.length; i++) {
4151
+ let field = fieldsArr[i];
4152
+ if (field) {
4153
+ // Dereference.
4154
+ // We do this because we'll be modifying the field to fix bad data.
4155
+ field = JSON.parse(JSON.stringify(field));
4156
+ }
4157
+ // Bad data has it set to 'color' but expects the input to be a number.
4158
+ if (type == "number" && field.type == EValueType.Color) {
4159
+ field.type = EValueType.Input;
4160
+ }
4116
4161
  switch (field.type) {
4117
4162
  case EValueType.Color:
4163
+ if (type === "number") {
4164
+ break;
4165
+ }
4118
4166
  value = field.value;
4119
- if (value) {
4120
- value = exports.Color.ColorFromStr(value);
4167
+ value = assertColor(value);
4168
+ if (value && type == "string") {
4169
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
4121
4170
  }
4122
4171
  break;
4123
4172
  case EValueType.Gradient:
4124
- value = GetGradientValue(field.value, entity);
4125
- break;
4126
- case EValueType.Input:
4127
- value = GetInputValue(field.value, entity);
4128
- break;
4129
- case EValueType.Mapping:
4130
- value = GetMappingValue(field.value, entity);
4173
+ if (type === "number") {
4174
+ break;
4175
+ }
4176
+ value = GetGradientValue(field.value, data, shouldRangesDefaultToMin);
4177
+ value = assertColor(value);
4178
+ if (value && type == "string") {
4179
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
4180
+ }
4131
4181
  break;
4132
4182
  case EValueType.RandomColor:
4183
+ if (type === "number") {
4184
+ break;
4185
+ }
4133
4186
  value = exports.Color.RandomColor();
4187
+ value = assertColor(value);
4188
+ if (value && type == "string") {
4189
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
4190
+ }
4134
4191
  break;
4135
4192
  case EValueType.TagColor:
4193
+ if (type === "number") {
4194
+ break;
4195
+ }
4136
4196
  for (let i = 0; i < tags.length; i++) {
4137
4197
  const tag = tags[i];
4138
4198
  if (tag.Color) {
4139
4199
  value = exports.Color.ColorFromStr(tag.Color);
4140
- break;
4200
+ value = assertColor(value);
4201
+ if (value) {
4202
+ break;
4203
+ }
4204
+ }
4205
+ }
4206
+ if (value && type == "string") {
4207
+ const cColor = value;
4208
+ value = `rgba(${cColor.red},${cColor.green},${cColor.blue},${cColor.alpha})`;
4209
+ }
4210
+ break;
4211
+ // Input can be an arbitrary value.
4212
+ // Eg: Result is a colour, a number, a string.
4213
+ // This means we first calculate the value, then validate it in the context of the desired type.
4214
+ case EValueType.Input:
4215
+ value = GetInputValue(field.value, data);
4216
+ if (value != null) {
4217
+ if (type == "number") {
4218
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
4219
+ value = Number(value);
4220
+ }
4221
+ else if (typeof value != "number") {
4222
+ value = null;
4223
+ }
4224
+ }
4225
+ else if (type == "string") {
4226
+ if (typeof value == "number") {
4227
+ value = String(value);
4228
+ }
4229
+ else if (typeof value == "object") {
4230
+ if (isColor(value)) {
4231
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
4232
+ }
4233
+ else {
4234
+ value = null;
4235
+ }
4236
+ }
4237
+ }
4238
+ else if (type == "color") {
4239
+ value = assertColor(value);
4240
+ }
4241
+ }
4242
+ break;
4243
+ // Mapping can be an arbitrary value.
4244
+ // Eg: mapping a value to a Client File ID, or a colour, or a number.
4245
+ // This means we first calculate the value, then validate it in the context of the desired type.
4246
+ case EValueType.Mapping:
4247
+ value = GetMappingValue(field.value, data);
4248
+ if (value != null) {
4249
+ if (type == "number") {
4250
+ if (typeof value == "string" && value != "" && value != null && value != undefined) {
4251
+ value = Number(value);
4252
+ }
4253
+ else if (typeof value != "number") {
4254
+ value = null;
4255
+ }
4256
+ }
4257
+ else if (type == "string") {
4258
+ if (typeof value == "number") {
4259
+ value = String(value);
4260
+ }
4261
+ else if (typeof value == "object") {
4262
+ if (isColor(value)) {
4263
+ value = `rgba(${value.red},${value.green},${value.blue},${value.alpha})`;
4264
+ }
4265
+ else {
4266
+ value = null;
4267
+ }
4268
+ }
4269
+ }
4270
+ else if (type == "color") {
4271
+ value = assertColor(typeof value === "number" ? String(value) : value);
4141
4272
  }
4142
4273
  }
4143
4274
  break;
4144
4275
  }
4145
- if (value || value == 0) {
4146
- return value;
4276
+ // Extra layer of validation.
4277
+ // This is a backup in case some branch above failed to convert into the right type.
4278
+ if (type == "number") {
4279
+ if (typeof value !== "number" || isNaN(value)) {
4280
+ value = null;
4281
+ }
4282
+ }
4283
+ else if (type == "color") {
4284
+ if (typeof value !== "object" || !value) {
4285
+ value = null;
4286
+ }
4287
+ }
4288
+ else if (type == "string") {
4289
+ if (typeof value !== "string" || !value) {
4290
+ value = null;
4291
+ }
4292
+ }
4293
+ if (value != null) {
4294
+ break;
4147
4295
  }
4148
4296
  }
4149
- return null;
4297
+ // Return the value or default.
4298
+ return value != null ? value : defaultValue;
4299
+ }
4300
+ Calculator.Calculate = Calculate;
4301
+ /**
4302
+ * Calculates the value of arbitrary field options.
4303
+ * The context calling this should validate results and parse stuff if needed.
4304
+ * @param fields
4305
+ * @param entity
4306
+ * @param tags
4307
+ * @returns
4308
+ */
4309
+ function GetValue(fields, entity = {}, tags = []) {
4310
+ return Calculate({
4311
+ fields: fields,
4312
+ data: entity,
4313
+ defaultValue: null,
4314
+ tags: tags,
4315
+ type: "any"
4316
+ });
4150
4317
  }
4151
4318
  Calculator.GetValue = GetValue;
4152
4319
  /**
@@ -4156,53 +4323,14 @@
4156
4323
  * @param entity
4157
4324
  * @param tags
4158
4325
  */
4159
- function GetColor(fields, entity, tags) {
4160
- if (!(fields === null || fields === void 0 ? void 0 : fields.length)) {
4161
- return null;
4162
- }
4163
- if (!tags) {
4164
- tags = [];
4165
- }
4166
- if (!entity) {
4167
- entity = {};
4168
- }
4169
- for (let i = 0; i < fields.length; i++) {
4170
- const field = fields[i];
4171
- let value;
4172
- switch (field.type) {
4173
- case EValueType.Color:
4174
- value = field.value;
4175
- break;
4176
- case EValueType.Gradient:
4177
- value = GetGradientValue(field.value, entity);
4178
- break;
4179
- case EValueType.Input:
4180
- value = GetInputValue(field.value, entity);
4181
- break;
4182
- case EValueType.Mapping:
4183
- value = GetMappingValue(field.value, entity);
4184
- break;
4185
- case EValueType.RandomColor:
4186
- value = exports.Color.RandomColor();
4187
- break;
4188
- case EValueType.TagColor:
4189
- for (let i = 0; i < tags.length; i++) {
4190
- const tag = tags[i];
4191
- if (tag.Color) {
4192
- value = exports.Color.ColorFromStr(tag.Color);
4193
- break;
4194
- }
4195
- }
4196
- break;
4197
- }
4198
- if (typeof value === "string") {
4199
- value = exports.Color.ColorFromStr(value);
4200
- }
4201
- if (value && typeof value === "object" && (value.red || value.red == 0)) {
4202
- return value;
4203
- }
4204
- }
4205
- return null;
4326
+ function GetColor(fields, entity = {}, tags = []) {
4327
+ return Calculate({
4328
+ fields: fields,
4329
+ data: entity,
4330
+ defaultValue: null,
4331
+ tags: tags,
4332
+ type: "color"
4333
+ });
4206
4334
  }
4207
4335
  Calculator.GetColor = GetColor;
4208
4336
  /**
@@ -4213,39 +4341,14 @@
4213
4341
  * @param tags
4214
4342
  * @returns
4215
4343
  */
4216
- function GetNumber(fields, entity, tags) {
4217
- if (!(fields === null || fields === void 0 ? void 0 : fields.length)) {
4218
- return null;
4219
- }
4220
- if (!tags) {
4221
- tags = [];
4222
- }
4223
- if (!entity) {
4224
- entity = {};
4225
- }
4226
- for (let i = 0; i < fields.length; i++) {
4227
- const field = fields[i];
4228
- let value;
4229
- switch (field.type) {
4230
- case EValueType.Gradient:
4231
- value = GetGradientValue(field.value, entity);
4232
- break;
4233
- case EValueType.Color:
4234
- case EValueType.Input:
4235
- value = GetInputValue(field.value, entity);
4236
- break;
4237
- case EValueType.Mapping:
4238
- value = GetMappingValue(field.value, entity);
4239
- break;
4240
- }
4241
- if (value != "" && value != null && value != undefined) {
4242
- value = Number(value);
4243
- }
4244
- if (value || value == 0) {
4245
- return value;
4246
- }
4247
- }
4248
- return null;
4344
+ function GetNumber(fields, entity = {}, tags = []) {
4345
+ return Calculate({
4346
+ fields: fields,
4347
+ data: entity,
4348
+ defaultValue: null,
4349
+ tags: tags,
4350
+ type: "number"
4351
+ });
4249
4352
  }
4250
4353
  Calculator.GetNumber = GetNumber;
4251
4354
  /**
@@ -4256,68 +4359,14 @@
4256
4359
  * @param tags
4257
4360
  * @returns
4258
4361
  */
4259
- function GetString(fields, entity, tags) {
4260
- if (!(fields === null || fields === void 0 ? void 0 : fields.length)) {
4261
- return null;
4262
- }
4263
- if (!tags) {
4264
- tags = [];
4265
- }
4266
- if (!entity) {
4267
- entity = {};
4268
- }
4269
- for (let i = 0; i < fields.length; i++) {
4270
- const field = fields[i];
4271
- let value;
4272
- switch (field.type) {
4273
- case EValueType.Gradient:
4274
- {
4275
- const tmp = GetGradientValue(field.value, entity);
4276
- // This avoids null turning into "null".
4277
- if (tmp) {
4278
- value = String(tmp);
4279
- }
4280
- }
4281
- break;
4282
- case EValueType.Color:
4283
- case EValueType.Input:
4284
- {
4285
- const tmp = GetInputValue(field.value, entity);
4286
- // This avoids null turning into "null".
4287
- if (tmp) {
4288
- value = String(tmp);
4289
- }
4290
- }
4291
- break;
4292
- case EValueType.Mapping:
4293
- {
4294
- const tmp = GetMappingValue(field.value, entity);
4295
- // This avoids null turning into "null".
4296
- if (tmp) {
4297
- value = String(tmp);
4298
- }
4299
- }
4300
- break;
4301
- case EValueType.RandomColor:
4302
- // Would be nice to randomize based on an attribute or entity ID instead of pure random.
4303
- var color = exports.Color.RandomColor();
4304
- value = `rgba(${color.red},${color.green},${color.blue},${color.alpha})`;
4305
- break;
4306
- case EValueType.TagColor:
4307
- for (let i = 0; i < tags.length; i++) {
4308
- const tag = tags[i];
4309
- if (tag.Color) {
4310
- value = tag.Color;
4311
- break;
4312
- }
4313
- }
4314
- break;
4315
- }
4316
- if (value) {
4317
- return value;
4318
- }
4319
- }
4320
- return null;
4362
+ function GetString(fields, entity = {}, tags = []) {
4363
+ return Calculate({
4364
+ fields: fields,
4365
+ data: entity,
4366
+ defaultValue: null,
4367
+ tags: tags,
4368
+ type: "string"
4369
+ });
4321
4370
  }
4322
4371
  Calculator.GetString = GetString;
4323
4372
  /**
@@ -4385,9 +4434,11 @@
4385
4434
  * It is intended to be parsed and validated within a value-type context. Eg: GetColor, GetNumber, GetString.
4386
4435
  * @param value
4387
4436
  * @param entity
4437
+ * @param defaultToMin if a value fails to be calculated, should we default to the minimum value?
4438
+ * Default is true for backwards compatibility.
4388
4439
  * @returns
4389
4440
  */
4390
- function GetGradientValue(value, entity) {
4441
+ function GetGradientValue(value, entity, defaultToMin) {
4391
4442
  const min = +value.points[0].position;
4392
4443
  const max = +value.points[value.points.length - 1].position;
4393
4444
  const attrPaths = parseLegacyPath(value.field);
@@ -14139,7 +14190,7 @@
14139
14190
  })(exports.DataSource || (exports.DataSource = {}));
14140
14191
 
14141
14192
  // This is updated with the package.json version on build.
14142
- const VERSION = "4.9.9";
14193
+ const VERSION = "5.0.0";
14143
14194
 
14144
14195
  exports.VERSION = VERSION;
14145
14196
  exports.AbstractApi = AbstractApi;