form0-core 0.1.12 → 0.1.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "form0-core",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/"
6
6
  },
@@ -87,8 +87,11 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
87
87
  default_operator: 'contains',
88
88
  allowed_operators: [
89
89
  'contains',
90
+ 'not_contains',
90
91
  'eq',
91
92
  'neq',
93
+ 'in',
94
+ 'not_in',
92
95
  'starts_with',
93
96
  'ends_with',
94
97
  'is_blank',
@@ -109,6 +112,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
109
112
  'neq',
110
113
  'gt',
111
114
  'lt',
115
+ 'in',
116
+ 'not_in',
112
117
  'is_blank',
113
118
  'is_not_blank',
114
119
  ],
@@ -127,6 +132,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
127
132
  'neq',
128
133
  'gt',
129
134
  'lt',
135
+ 'in',
136
+ 'not_in',
130
137
  'is_blank',
131
138
  'is_not_blank',
132
139
  ],
@@ -145,6 +152,8 @@ const QUERY_SEMANTICS_BY_FIELD_TYPE = {
145
152
  'neq',
146
153
  'gt',
147
154
  'lt',
155
+ 'in',
156
+ 'not_in',
148
157
  'is_blank',
149
158
  'is_not_blank',
150
159
  ],
@@ -202,6 +211,8 @@ const getCalculatedFieldSemantics = (field) => {
202
211
  'neq',
203
212
  'gt',
204
213
  'lt',
214
+ 'in',
215
+ 'not_in',
205
216
  'is_blank',
206
217
  'is_not_blank',
207
218
  ],
@@ -223,6 +234,8 @@ const getCalculatedFieldSemantics = (field) => {
223
234
  'neq',
224
235
  'gt',
225
236
  'lt',
237
+ 'in',
238
+ 'not_in',
226
239
  'is_blank',
227
240
  'is_not_blank',
228
241
  ],
@@ -244,6 +257,8 @@ const getCalculatedFieldSemantics = (field) => {
244
257
  'neq',
245
258
  'gt',
246
259
  'lt',
260
+ 'in',
261
+ 'not_in',
247
262
  'is_blank',
248
263
  'is_not_blank',
249
264
  ],
@@ -258,8 +273,11 @@ const getCalculatedFieldSemantics = (field) => {
258
273
  default_operator: 'contains',
259
274
  allowed_operators: [
260
275
  'contains',
276
+ 'not_contains',
261
277
  'eq',
262
278
  'neq',
279
+ 'in',
280
+ 'not_in',
263
281
  'starts_with',
264
282
  'ends_with',
265
283
  'is_blank',
@@ -293,33 +311,179 @@ const toChoiceValueList = (field) => {
293
311
  return field.choices.filter((choice) => isRecord(choice));
294
312
  };
295
313
 
296
- const toSingleChoiceLabel = (field, rawValue) => {
297
- const choices = toChoiceValueList(field);
298
- if (choices.length === 0) {
299
- return rawValue;
314
+ const isChoicePrimitive = (value) =>
315
+ typeof value === 'string' ||
316
+ typeof value === 'number' ||
317
+ typeof value === 'boolean';
318
+
319
+ const normalizeChoiceEntryValue = (entry) => {
320
+ if (isChoicePrimitive(entry)) {
321
+ return entry;
322
+ }
323
+
324
+ if (!isRecord(entry)) {
325
+ return undefined;
326
+ }
327
+
328
+ if (isChoicePrimitive(entry.value)) {
329
+ return entry.value;
300
330
  }
301
331
 
302
- const matched = choices.find(
303
- (choice) => Object.prototype.hasOwnProperty.call(choice, 'value') && choice.value === rawValue,
332
+ if (isChoicePrimitive(entry.label)) {
333
+ return entry.label;
334
+ }
335
+
336
+ return undefined;
337
+ };
338
+
339
+ const normalizeChoiceEntryDisplayValue = (entry) => {
340
+ if (isChoicePrimitive(entry)) {
341
+ return entry;
342
+ }
343
+
344
+ if (!isRecord(entry)) {
345
+ return undefined;
346
+ }
347
+
348
+ if (isChoicePrimitive(entry.label)) {
349
+ return entry.label;
350
+ }
351
+
352
+ if (isChoicePrimitive(entry.value)) {
353
+ return entry.value;
354
+ }
355
+
356
+ return undefined;
357
+ };
358
+
359
+ const normalizeChoiceEntryLabel = (field, entry) => {
360
+ const normalizedValue = normalizeChoiceEntryValue(entry);
361
+ if (typeof normalizedValue === 'undefined') {
362
+ return undefined;
363
+ }
364
+
365
+ const matched = toChoiceValueList(field).find(
366
+ (choice) =>
367
+ Object.prototype.hasOwnProperty.call(choice, 'value') &&
368
+ choice.value === normalizedValue,
304
369
  );
305
- if (!matched) {
306
- return rawValue;
370
+ if (matched) {
371
+ return toTrimmedString(matched.label) ?? normalizedValue;
372
+ }
373
+
374
+ if (isRecord(entry) && isChoicePrimitive(entry.label)) {
375
+ return entry.label;
307
376
  }
308
377
 
309
- return toTrimmedString(matched.label) ?? rawValue;
378
+ return normalizedValue;
310
379
  };
311
380
 
312
- const toMultiChoiceLabels = (field, rawValue) => {
313
- if (!Array.isArray(rawValue)) {
381
+ const toSingleChoiceSelectionValues = (rawValue) => {
382
+ if (isRecord(rawValue)) {
383
+ const choiceValues = Array.isArray(rawValue.choice)
384
+ ? rawValue.choice
385
+ .map((entry) => normalizeChoiceEntryValue(entry))
386
+ .filter((entry) => typeof entry !== 'undefined')
387
+ : [];
388
+ const otherValues = Array.isArray(rawValue.other)
389
+ ? rawValue.other
390
+ .map((entry) => normalizeChoiceEntryValue(entry))
391
+ .filter((entry) => typeof entry !== 'undefined')
392
+ : [];
393
+
394
+ return [...choiceValues, ...otherValues];
395
+ }
396
+
397
+ const normalized = normalizeChoiceEntryValue(rawValue);
398
+ return typeof normalized === 'undefined' ? [] : [normalized];
399
+ };
400
+
401
+ const toSingleChoiceDisplayValues = (field, rawValue) => {
402
+ if (isRecord(rawValue)) {
403
+ const choiceLabels = Array.isArray(rawValue.choice)
404
+ ? rawValue.choice
405
+ .map((entry) => normalizeChoiceEntryLabel(field, entry))
406
+ .filter((entry) => typeof entry !== 'undefined')
407
+ : [];
408
+ const otherLabels = Array.isArray(rawValue.other)
409
+ ? rawValue.other
410
+ .map((entry) => normalizeChoiceEntryDisplayValue(entry))
411
+ .filter((entry) => typeof entry !== 'undefined')
412
+ : [];
413
+
414
+ return [...choiceLabels, ...otherLabels];
415
+ }
416
+
417
+ const normalized = normalizeChoiceEntryLabel(field, rawValue);
418
+ return typeof normalized === 'undefined' ? [] : [normalized];
419
+ };
420
+
421
+ const toMultiChoiceSelectionValues = (rawValue) => {
422
+ if (isRecord(rawValue)) {
423
+ const selectedValues = Array.isArray(rawValue.choices)
424
+ ? rawValue.choices
425
+ .map((entry) => normalizeChoiceEntryValue(entry))
426
+ .filter((entry) => typeof entry !== 'undefined')
427
+ : [];
428
+ const otherValues = Array.isArray(rawValue.other)
429
+ ? rawValue.other
430
+ .map((entry) => normalizeChoiceEntryValue(entry))
431
+ .filter((entry) => typeof entry !== 'undefined')
432
+ : [];
433
+
434
+ return [...selectedValues, ...otherValues];
435
+ }
436
+
437
+ if (Array.isArray(rawValue)) {
438
+ return rawValue
439
+ .map((entry) => normalizeChoiceEntryValue(entry))
440
+ .filter((entry) => typeof entry !== 'undefined');
441
+ }
442
+
443
+ return [];
444
+ };
445
+
446
+ const toMultiChoiceDisplayValues = (field, rawValue) => {
447
+ if (isRecord(rawValue)) {
448
+ const selectedLabels = Array.isArray(rawValue.choices)
449
+ ? rawValue.choices
450
+ .map((entry) => normalizeChoiceEntryLabel(field, entry))
451
+ .filter((entry) => typeof entry !== 'undefined')
452
+ : [];
453
+ const otherLabels = Array.isArray(rawValue.other)
454
+ ? rawValue.other
455
+ .map((entry) => normalizeChoiceEntryDisplayValue(entry))
456
+ .filter((entry) => typeof entry !== 'undefined')
457
+ : [];
458
+
459
+ return [...selectedLabels, ...otherLabels];
460
+ }
461
+
462
+ if (Array.isArray(rawValue)) {
463
+ return rawValue
464
+ .map((entry) => normalizeChoiceEntryLabel(field, entry))
465
+ .filter((entry) => typeof entry !== 'undefined');
466
+ }
467
+
468
+ return [];
469
+ };
470
+
471
+ const toSingleChoiceLabel = (field, rawValue) => {
472
+ const labels = toSingleChoiceDisplayValues(field, rawValue);
473
+ if (labels.length === 0) {
314
474
  return rawValue;
315
475
  }
316
476
 
317
- const choices = toChoiceValueList(field);
318
- if (choices.length === 0) {
477
+ return labels.length === 1 ? labels[0] : labels;
478
+ };
479
+
480
+ const toMultiChoiceLabels = (field, rawValue) => {
481
+ const labels = toMultiChoiceDisplayValues(field, rawValue);
482
+ if (labels.length === 0) {
319
483
  return rawValue;
320
484
  }
321
485
 
322
- return rawValue.map((entry) => toSingleChoiceLabel(field, entry));
486
+ return labels;
323
487
  };
324
488
 
325
489
  const toDisplayValue = (field, rawValue) => {
@@ -497,7 +661,14 @@ const readFirstAliasValue = (value, aliases) => {
497
661
  return undefined;
498
662
  };
499
663
 
500
- const normalizeScalarValue = (value) => {
664
+ const normalizeScalarValue = (field, value) => {
665
+ if (
666
+ field?.field_type === 'SingleChoiceField' ||
667
+ field?.field_type === 'BooleanField'
668
+ ) {
669
+ return toSingleChoiceSelectionValues(value)[0];
670
+ }
671
+
501
672
  if (Array.isArray(value)) {
502
673
  return undefined;
503
674
  }
@@ -505,7 +676,11 @@ const normalizeScalarValue = (value) => {
505
676
  return value;
506
677
  };
507
678
 
508
- const normalizeTermValues = (value) => {
679
+ const normalizeTermValues = (field, value) => {
680
+ if (field?.field_type === 'MultiChoiceField') {
681
+ return toMultiChoiceSelectionValues(value);
682
+ }
683
+
509
684
  if (!Array.isArray(value)) {
510
685
  return [];
511
686
  }
@@ -539,7 +714,7 @@ export function projectDatasetRowValues(descriptor, rowValues) {
539
714
  displayValues[field.field_id] = toDisplayValue(field, rawValue);
540
715
 
541
716
  if (field.query_kind === 'scalar') {
542
- const scalarValue = normalizeScalarValue(rawValue);
717
+ const scalarValue = normalizeScalarValue(field, rawValue);
543
718
  if (typeof scalarValue !== 'undefined') {
544
719
  scalarValues[field.field_id] = scalarValue;
545
720
  }
@@ -547,7 +722,7 @@ export function projectDatasetRowValues(descriptor, rowValues) {
547
722
  }
548
723
 
549
724
  if (field.query_kind === 'terms') {
550
- const terms = normalizeTermValues(rawValue);
725
+ const terms = normalizeTermValues(field, rawValue);
551
726
  if (terms.length > 0) {
552
727
  termValues[field.field_id] = terms;
553
728
  }