@limetech/lime-crm-building-blocks 1.101.0 → 1.102.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.
Files changed (113) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/lime-crm-building-blocks.cjs.js +1 -1
  3. package/dist/cjs/lime-query-validation-6be10fa7.js +558 -0
  4. package/dist/cjs/limebb-lime-query-builder.cjs.entry.js +4 -514
  5. package/dist/cjs/{limebb-lime-query-filter-builder_4.cjs.entry.js → limebb-lime-query-filter-builder_3.cjs.entry.js} +1 -243
  6. package/dist/cjs/limebb-lime-query-filter-comparison_2.cjs.entry.js +1 -1
  7. package/dist/cjs/limebb-lime-query-filter-group_3.cjs.entry.js +2 -2
  8. package/dist/cjs/limebb-lime-query-order-by-item.cjs.entry.js +2 -2
  9. package/dist/cjs/limebb-lime-query-response-format-builder.cjs.entry.js +242 -0
  10. package/dist/cjs/limebb-lime-query-response-format-editor_2.cjs.entry.js +322 -0
  11. package/dist/cjs/limebb-live-docs-info.cjs.entry.js +2 -2
  12. package/dist/cjs/limebb-locale-picker.cjs.entry.js +1 -1
  13. package/dist/cjs/limebb-mention-group-counter.cjs.entry.js +2 -2
  14. package/dist/cjs/limebb-navigation-button_2.cjs.entry.js +3 -3
  15. package/dist/cjs/limebb-notification-item.cjs.entry.js +1 -1
  16. package/dist/cjs/limebb-percentage-visualizer.cjs.entry.js +2 -2
  17. package/dist/cjs/limebb-text-editor.cjs.entry.js +1 -1
  18. package/dist/cjs/limebb-trend-indicator.cjs.entry.js +1 -1
  19. package/dist/cjs/loader.cjs.js +1 -1
  20. package/dist/collection/collection-manifest.json +3 -2
  21. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-comparison.js +1 -1
  22. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-group.js +1 -1
  23. package/dist/collection/components/lime-query-builder/expressions/lime-query-filter-not.js +1 -1
  24. package/dist/collection/components/lime-query-builder/lime-query-builder.js +1 -1
  25. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.css +91 -0
  26. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +355 -0
  27. package/dist/collection/components/lime-query-builder/lime-query-validation.js +40 -0
  28. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
  29. package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +2 -2
  30. package/dist/collection/components/lime-query-builder/{response-format-editor.css → response-format/response-format-editor.css} +1 -1
  31. package/dist/collection/components/lime-query-builder/{response-format-editor.js → response-format/response-format-editor.js} +5 -5
  32. package/dist/collection/components/lime-query-builder/response-format/response-format-helpers.js +92 -0
  33. package/dist/collection/components/lime-query-builder/{response-format-item.css → response-format/response-format-item.css} +1 -1
  34. package/dist/collection/components/lime-query-builder/{response-format-item.js → response-format/response-format-item.js} +6 -6
  35. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  36. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  37. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  38. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  39. package/dist/collection/components/summary-popover/summary-popover.js +3 -3
  40. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  41. package/dist/collection/components/text-editor/text-editor.js +1 -1
  42. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  43. package/dist/components/lime-query-filter-comparison.js +1 -1
  44. package/dist/components/lime-query-filter-expression.js +2 -2
  45. package/dist/components/lime-query-validation.js +555 -0
  46. package/dist/components/limebb-lime-query-builder.js +14 -524
  47. package/dist/components/limebb-lime-query-response-format-builder.d.ts +11 -0
  48. package/dist/components/limebb-lime-query-response-format-builder.js +283 -0
  49. package/dist/components/limebb-lime-query-response-format-editor.d.ts +11 -0
  50. package/dist/components/{limebb-response-format-editor.js → limebb-lime-query-response-format-editor.js} +2 -2
  51. package/dist/components/limebb-lime-query-response-format-item.d.ts +11 -0
  52. package/dist/components/{limebb-response-format-item.js → limebb-lime-query-response-format-item.js} +2 -2
  53. package/dist/components/limebb-locale-picker.js +1 -1
  54. package/dist/components/limebb-mention-group-counter.js +2 -2
  55. package/dist/components/limebb-percentage-visualizer.js +2 -2
  56. package/dist/components/limebb-text-editor.js +1 -1
  57. package/dist/components/limebb-trend-indicator.js +1 -1
  58. package/dist/components/limetype-field.js +1 -1
  59. package/dist/components/live-docs-info.js +2 -2
  60. package/dist/components/notification-item.js +1 -1
  61. package/dist/components/order-by-item.js +2 -2
  62. package/dist/components/response-format-editor.js +11 -11
  63. package/dist/components/response-format-item.js +9 -9
  64. package/dist/components/summary-popover.js +3 -3
  65. package/dist/esm/lime-crm-building-blocks.js +1 -1
  66. package/dist/esm/lime-query-validation-573223a5.js +555 -0
  67. package/dist/esm/limebb-lime-query-builder.entry.js +4 -514
  68. package/dist/esm/{limebb-lime-query-filter-builder_4.entry.js → limebb-lime-query-filter-builder_3.entry.js} +2 -243
  69. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +1 -1
  70. package/dist/esm/limebb-lime-query-filter-group_3.entry.js +2 -2
  71. package/dist/esm/limebb-lime-query-order-by-item.entry.js +2 -2
  72. package/dist/esm/limebb-lime-query-response-format-builder.entry.js +238 -0
  73. package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +317 -0
  74. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  75. package/dist/esm/limebb-locale-picker.entry.js +1 -1
  76. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  77. package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
  78. package/dist/esm/limebb-notification-item.entry.js +1 -1
  79. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  80. package/dist/esm/limebb-text-editor.entry.js +1 -1
  81. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  82. package/dist/esm/loader.js +1 -1
  83. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  84. package/dist/lime-crm-building-blocks/{p-5cf4898d.entry.js → p-0de79b7f.entry.js} +1 -1
  85. package/dist/lime-crm-building-blocks/{p-8c2fb1c9.entry.js → p-0f7135ff.entry.js} +1 -1
  86. package/dist/lime-crm-building-blocks/{p-6aa216ec.entry.js → p-186e9f1a.entry.js} +1 -1
  87. package/dist/lime-crm-building-blocks/p-289ce8b9.entry.js +1 -0
  88. package/dist/lime-crm-building-blocks/p-3351395b.entry.js +1 -0
  89. package/dist/lime-crm-building-blocks/p-33e6d0ec.entry.js +1 -0
  90. package/dist/lime-crm-building-blocks/{p-a1ee8990.entry.js → p-3d1be1c9.entry.js} +1 -1
  91. package/dist/lime-crm-building-blocks/{p-92dfc5f8.entry.js → p-577d8909.entry.js} +1 -1
  92. package/dist/lime-crm-building-blocks/{p-ccf34631.entry.js → p-6579412e.entry.js} +1 -1
  93. package/dist/lime-crm-building-blocks/{p-d84874dc.entry.js → p-6f6fed59.entry.js} +1 -1
  94. package/dist/lime-crm-building-blocks/{p-0cd036ed.entry.js → p-7e5528f6.entry.js} +1 -1
  95. package/dist/lime-crm-building-blocks/{p-8601eab5.entry.js → p-a9ac501f.entry.js} +1 -1
  96. package/dist/lime-crm-building-blocks/p-be845252.entry.js +1 -0
  97. package/dist/lime-crm-building-blocks/{p-2725671e.entry.js → p-cb338753.entry.js} +1 -1
  98. package/dist/lime-crm-building-blocks/{p-425eaba2.entry.js → p-d0721b22.entry.js} +1 -1
  99. package/dist/lime-crm-building-blocks/p-fa2da6bc.js +1 -0
  100. package/dist/types/components/lime-query-builder/lime-query-response-format-builder.d.ts +102 -0
  101. package/dist/types/components/lime-query-builder/lime-query-validation.d.ts +13 -0
  102. package/dist/types/components/lime-query-builder/{response-format-editor.d.ts → response-format/response-format-editor.d.ts} +2 -2
  103. package/dist/types/components/lime-query-builder/response-format/response-format-helpers.d.ts +42 -0
  104. package/dist/types/components/lime-query-builder/{response-format-item.d.ts → response-format/response-format-item.d.ts} +2 -2
  105. package/dist/types/components.d.ts +394 -222
  106. package/package.json +1 -1
  107. package/dist/cjs/limebb-response-format-item.cjs.entry.js +0 -80
  108. package/dist/components/limebb-response-format-editor.d.ts +0 -11
  109. package/dist/components/limebb-response-format-item.d.ts +0 -11
  110. package/dist/esm/limebb-response-format-item.entry.js +0 -76
  111. package/dist/lime-crm-building-blocks/p-244ee55b.entry.js +0 -1
  112. package/dist/lime-crm-building-blocks/p-67c174d0.entry.js +0 -1
  113. package/dist/lime-crm-building-blocks/p-f9efca1d.entry.js +0 -1
@@ -308,7 +308,7 @@ const LimetypeField = class {
308
308
  value: '',
309
309
  };
310
310
  options.unshift(emptyOption);
311
- return (index.h("limel-select", { key: 'fd9522c5df730f65a5ac57140bca6c05c5acd63d', label: this.label, options: options, value: selectedOption, required: this.required, helperText: this.helperText, invalid: invalid, disabled: this.disabled || this.readonly, onChange: this.handleChange }));
311
+ return (index.h("limel-select", { key: 'ee9fdc46424c9e6dc5897260cb16bcbedd43413a', label: this.label, options: options, value: selectedOption, required: this.required, helperText: this.helperText, invalid: invalid, disabled: this.disabled || this.readonly, onChange: this.handleChange }));
312
312
  }
313
313
  componentWillRender() {
314
314
  this.updatePropertyFields(this.value || '');
@@ -346,248 +346,6 @@ const limeTypeToOption = (limetype$1) => ({
346
346
  icon: limetype.getIcon(limetype$1),
347
347
  });
348
348
 
349
- /**
350
- * Process a single property value and add to items array
351
- * @param items Array to add items to
352
- * @param fullPath Full property path
353
- * @param value Property value to process
354
- */
355
- function processPropertyValue(items, fullPath, value) {
356
- if (value === null) {
357
- items.push({ path: fullPath });
358
- return;
359
- }
360
- // Cast to record for checking
361
- const valueObj = value;
362
- const keys = Object.keys(valueObj);
363
- const hasAlias = '_alias' in valueObj;
364
- const hasDescription = '#description' in valueObj;
365
- const otherKeys = keys.filter((k) => k !== '_alias' && k !== '#description');
366
- // If it's {} or only has metadata (_alias, #description), treat as simple property
367
- if (otherKeys.length === 0) {
368
- const aliasValue = valueObj._alias;
369
- const descriptionValue = valueObj['#description'];
370
- if (aliasValue || descriptionValue) {
371
- items.push({
372
- path: fullPath,
373
- alias: aliasValue,
374
- description: descriptionValue,
375
- });
376
- }
377
- else {
378
- items.push({ path: fullPath });
379
- }
380
- return;
381
- }
382
- // If has metadata + other properties, we need to handle both
383
- // Add the nested properties (metadata is preserved in conversion back)
384
- if (hasAlias || hasDescription) {
385
- // Build a PropertySelection without the metadata for recursion
386
- const nestedSelection = {};
387
- for (const key of otherKeys) {
388
- nestedSelection[key] = valueObj[key];
389
- }
390
- items.push(...propertySelectionToItems(nestedSelection, fullPath));
391
- return;
392
- }
393
- // Nested property selection without metadata
394
- items.push(...propertySelectionToItems(value, fullPath));
395
- }
396
- /**
397
- * Convert a nested PropertySelection to a flat list of property items
398
- * @param selection The nested PropertySelection object
399
- * @param prefix Current path prefix (used for recursion)
400
- * @returns Flat array of PropertySelectionItem objects
401
- */
402
- function propertySelectionToItems(selection, prefix = '') {
403
- if (!selection) {
404
- return [];
405
- }
406
- const items = [];
407
- for (const [key, value] of Object.entries(selection)) {
408
- const fullPath = prefix ? `${prefix}.${key}` : key;
409
- if (typeof value === 'object') {
410
- // NOTE: We want to send null values to the processPropertyValue
411
- // function but we don't need a special check for null, since
412
- // `typeof null === 'object'`
413
- processPropertyValue(items, fullPath, value);
414
- }
415
- }
416
- return items;
417
- }
418
- /**
419
- * Set the final property value (with or without alias/description)
420
- * @param current Current PropertySelection object
421
- * @param part Property name/key
422
- * @param item Property selection item with path and optional alias/description
423
- */
424
- function setPropertyValue(current, part, item) {
425
- // Check if there's already a nested PropertySelection with properties
426
- const existing = current[part];
427
- if (existing &&
428
- typeof existing === 'object' &&
429
- !('_alias' in existing) &&
430
- !('#description' in existing)) {
431
- // There's already a nested PropertySelection object with properties
432
- // Don't overwrite it - preserve the nested selections
433
- return;
434
- }
435
- // Build metadata object, stripping empty values
436
- const metadata = {};
437
- if (item.alias && item.alias.trim() !== '') {
438
- metadata._alias = item.alias;
439
- }
440
- if (item.description && item.description.trim() !== '') {
441
- metadata['#description'] = item.description;
442
- }
443
- // If we have metadata, use it; otherwise use null
444
- if (Object.keys(metadata).length > 0) {
445
- current[part] = metadata;
446
- }
447
- else {
448
- current[part] = null;
449
- }
450
- }
451
- /**
452
- * Ensure a nested object exists and return it
453
- * Preserves any existing _alias and #description when converting to nested object
454
- * @param current Current PropertySelection object
455
- * @param part Property name/key
456
- * @returns The nested PropertySelection object
457
- */
458
- function ensureNestedObject(current, part) {
459
- const existing = current[part];
460
- // If doesn't exist or is null, create empty object
461
- if (!existing) {
462
- current[part] = {};
463
- return current[part];
464
- }
465
- // If it's already a PropertySelection object, check for metadata
466
- if (typeof existing === 'object') {
467
- const existingObj = existing;
468
- // If it has metadata but no other properties, preserve the metadata
469
- const keys = Object.keys(existingObj);
470
- const hasMetadata = '_alias' in existingObj || '#description' in existingObj;
471
- const otherKeys = keys.filter((k) => k !== '_alias' && k !== '#description');
472
- if (hasMetadata && otherKeys.length === 0) {
473
- // Convert { _alias: "...", "#description": "..." } to { _alias: "...", "#description": "...", ...nested }
474
- // Keep the existing object and return it (caller will add nested props)
475
- return existingObj;
476
- }
477
- // Already has nested properties, return as is
478
- return existingObj;
479
- }
480
- // Shouldn't reach here, but fallback to creating new object
481
- current[part] = {};
482
- return current[part];
483
- }
484
- /**
485
- * Convert a flat list of property items to a nested PropertySelection structure
486
- * @param items Array of PropertySelectionItem objects
487
- * @returns Nested PropertySelection object
488
- */
489
- function itemsToPropertySelection(items) {
490
- const result = {};
491
- for (const item of items) {
492
- const parts = item.path.split('.');
493
- let current = result;
494
- for (let i = 0; i < parts.length; i++) {
495
- const part = parts[i];
496
- const isLast = i === parts.length - 1;
497
- if (isLast) {
498
- setPropertyValue(current, part, item);
499
- }
500
- else {
501
- current = ensureNestedObject(current, part);
502
- }
503
- }
504
- }
505
- return result;
506
- }
507
-
508
- const responseFormatEditorCss = ":host(limebb-response-format-editor){display:block;width:100%}.response-format-editor{display:flex;flex-direction:column;gap:1rem;padding:1rem}.header{display:flex;justify-content:space-between;align-items:center;gap:1rem}.header h4{margin:0;font-size:1rem;font-weight:600;color:rgb(var(--contrast-1000))}.property-list{display:flex;flex-direction:column;gap:1rem;padding:0.5rem;border:1px solid rgb(var(--contrast-300));border-radius:0.25rem;background-color:rgb(var(--contrast-50));min-height:4rem}.property-item{padding:0.5rem;border-radius:0.25rem;transition:background-color 0.2s}.property-item:hover{background-color:rgb(var(--contrast-100))}.actions{display:flex;justify-content:flex-start}.summary{display:flex;justify-content:space-between;align-items:center;padding-top:0.5rem;border-top:1px solid rgb(var(--contrast-300))}.summary .count{font-size:0.875rem;font-weight:500;color:rgb(var(--contrast-900))}.empty-state{padding:2rem;text-align:center;color:rgb(var(--contrast-700));font-style:italic}.empty-state p{margin:0}";
509
- const LimebbResponseFormatEditorStyle0 = responseFormatEditorCss;
510
-
511
- const ResponseFormatEditor = class {
512
- constructor(hostRef) {
513
- index.registerInstance(this, hostRef);
514
- this.change = index.createEvent(this, "change", 7);
515
- /**
516
- * Optional label
517
- */
518
- this.label = 'Select Properties to Return';
519
- this.items = [{ path: '_id' }];
520
- this.handleItemChange = (index) => (event) => {
521
- event.stopPropagation();
522
- const newItems = [...this.items];
523
- if (event.detail === null) {
524
- // Remove item
525
- newItems.splice(index, 1);
526
- }
527
- else {
528
- // Update item
529
- newItems[index] = event.detail;
530
- }
531
- // Ensure we always have at least _id
532
- if (newItems.length === 0) {
533
- newItems.push({ path: '_id' });
534
- }
535
- this.items = newItems;
536
- this.emitChange();
537
- };
538
- this.handleAddProperty = () => {
539
- this.items = [...this.items, { path: '' }];
540
- this.emitChange();
541
- };
542
- }
543
- componentWillLoad() {
544
- var _a;
545
- if ((_a = this.value) === null || _a === void 0 ? void 0 : _a.object) {
546
- const converted = propertySelectionToItems(this.value.object);
547
- if (converted.length > 0) {
548
- this.items = converted;
549
- }
550
- }
551
- }
552
- componentWillUpdate() {
553
- var _a;
554
- if ((_a = this.value) === null || _a === void 0 ? void 0 : _a.object) {
555
- const currentItems = propertySelectionToItems(this.value.object);
556
- // Check if items have changed
557
- const itemsChanged = currentItems.length !== this.items.length ||
558
- !currentItems.every((item, index) => {
559
- const current = this.items[index];
560
- return (current &&
561
- item.path === current.path &&
562
- item.alias === current.alias &&
563
- item.description === current.description);
564
- });
565
- if (itemsChanged) {
566
- this.items =
567
- currentItems.length > 0 ? currentItems : [{ path: '_id' }];
568
- }
569
- }
570
- }
571
- render() {
572
- if (!this.limetype) {
573
- return (index.h("div", { class: "empty-state" }, index.h("p", null, "Select a limetype to choose properties")));
574
- }
575
- return (index.h("div", { class: "response-format-editor" }, index.h("div", { class: "header" }, index.h("h4", null, this.label)), index.h("div", { class: "property-list" }, this.items.map((item, index) => this.renderItem(item, index))), index.h("div", { class: "actions" }, index.h("limel-button", { label: "Add Property", icon: "plus_math", onClick: this.handleAddProperty })), index.h("div", { class: "summary" }, index.h("span", { class: "count" }, this.items.length, ' ', this.items.length === 1 ? 'property' : 'properties', ' ', "selected"))));
576
- }
577
- renderItem(item, index$1) {
578
- return (index.h("limebb-response-format-item", { key: `${item.path}-${index$1}`, class: "property-item", platform: this.platform, context: this.context, limetype: this.limetype, item: item, onItemChange: this.handleItemChange(index$1) }));
579
- }
580
- emitChange() {
581
- const propertySelection = itemsToPropertySelection(this.items);
582
- const responseFormat = {
583
- object: propertySelection,
584
- };
585
- this.change.emit(responseFormat);
586
- }
587
- };
588
- ResponseFormatEditor.style = LimebbResponseFormatEditorStyle0;
589
-
590
349
  exports.limebb_lime_query_filter_builder = LimeQueryFilterBuilderComponent;
591
350
  exports.limebb_lime_query_order_by_editor = OrderByEditor;
592
351
  exports.limebb_limetype_field = LimetypeField;
593
- exports.limebb_response_format_editor = ResponseFormatEditor;
@@ -82,7 +82,7 @@ const LimeQueryFilterComparisonComponent = class {
82
82
  };
83
83
  }
84
84
  render() {
85
- return (index.h("div", { key: 'a077c982ced9840beec3e574cd3e2e336cff6071', class: "expression" }, this.label && index.h("limel-header", { key: 'fbcb5cf515aac2c8e68d29947c7560684f30822c', heading: this.label }), index.h("div", { key: 'ffea426ea1295ae11aaa3c910f835acbeed24cd9', class: "expression-container" }, this.renderPropertySelector(), this.renderOperator(), this.renderValueInput(), index.h("limel-icon-button", { key: '20064f9fe42a4dfa71b2e1e2d393d50bbe20e2cb', class: "remove", icon: "trash", label: "Remove condition", onClick: this.removeExpression }))));
85
+ return (index.h("div", { key: '41fc60ed4ce76de8bbed05ee8cc658a188347cbd', class: "expression" }, this.label && index.h("limel-header", { key: '95cb9b556e2e0f2c8f3fd8ebe3909c402a844fe3', heading: this.label }), index.h("div", { key: 'feac7dcf059a0a20ad499d1549fa45d775d6bec8', class: "expression-container" }, this.renderPropertySelector(), this.renderOperator(), this.renderValueInput(), index.h("limel-icon-button", { key: '0fee01518c1c4a29c347a47ce1ce7856b32dfa8f', class: "remove", icon: "trash", label: "Remove condition", onClick: this.removeExpression }))));
86
86
  }
87
87
  renderPropertySelector() {
88
88
  return (index.h("limebb-property-selector", { platform: this.platform, context: this.context, label: "Property", limetype: this.limetype, value: this.expression.key, required: true, onChange: this.handlePropertyChange }));
@@ -80,7 +80,7 @@ const LimeQueryFilterGroupComponent = class {
80
80
  }
81
81
  render() {
82
82
  const subheading = this.getSubheading();
83
- return (index.h("div", { key: '0ed5a1403d9641926cd6d474910cedf9c7bba89e', class: "expression" }, subheading && (index.h("limel-header", { key: 'ea88a97df09f0fb5a21bf9afb4745256a611c7f8', subheading: subheading, onClick: this.handleToggleOperator, class: "clickable-header" })), index.h("ul", { key: 'cfbcdd539e84f79bf1d778e075cd3317d7409647' }, this.expression.exp.map(this.renderChildExpression), index.h("li", { key: 'ec443459245bf5852920bb4d3e341f2490a7b75b', class: "add-button" }, this.renderAddButton(), this.renderAddGroupButton()))));
83
+ return (index.h("div", { key: '52195908487144bda718eada4e379e7ad3e413a0', class: "expression" }, subheading && (index.h("limel-header", { key: '71f29d49c8d071822a30990eb48fde1af579bec5', subheading: subheading, onClick: this.handleToggleOperator, class: "clickable-header" })), index.h("ul", { key: '39d798c1424755a8cd0c57ca26d3744ba299b7ad' }, this.expression.exp.map(this.renderChildExpression), index.h("li", { key: '0394f3ec7d63e195f184b081cb1a8179f586cedf', class: "add-button" }, this.renderAddButton(), this.renderAddGroupButton()))));
84
84
  }
85
85
  getSubheading() {
86
86
  if (this.expression.exp.length <= 1) {
@@ -137,7 +137,7 @@ const LimeQueryFilterNotComponent = class {
137
137
  };
138
138
  }
139
139
  render() {
140
- return (index.h("div", { key: '9ab4a6b1e99668a0bcee3e3ba8cbbbe5185222e0', class: "expression" }, this.label && index.h("limel-header", { key: '85e997b0f96db306dd7a4433da959a74303aacfa', heading: this.label }), index.h("limebb-lime-query-filter-expression", { key: '14f634e125ee78f2aa70c7537b270a31699ba7c2', platform: this.platform, context: this.context, label: "Not", limetype: this.limetype, activeLimetype: this.activeLimetype, expression: this.expression.exp, onExpressionChange: this.handleExpressionChange })));
140
+ return (index.h("div", { key: '29770b10d0b892750ad2aab3520cec5a82063774', class: "expression" }, this.label && index.h("limel-header", { key: '9e47d14c6cb526c9c31d67e11a5ed5ec665c7f62', heading: this.label }), index.h("limebb-lime-query-filter-expression", { key: '943c1529057aa6cc918dc935f1a5782b149351ae', platform: this.platform, context: this.context, label: "Not", limetype: this.limetype, activeLimetype: this.activeLimetype, expression: this.expression.exp, onExpressionChange: this.handleExpressionChange })));
141
141
  }
142
142
  };
143
143
  LimeQueryFilterNotComponent.style = LimebbLimeQueryFilterNotStyle0;
@@ -41,9 +41,9 @@ const OrderByItemComponent = class {
41
41
  render() {
42
42
  const propertyPath = Object.keys(this.item)[0] || '';
43
43
  const direction = this.item[propertyPath] || 'ASC';
44
- return (index.h("div", { key: 'e0faeb5b370d8aba00a668f0861e8e1cb4eec495', class: "order-by-controls" }, index.h("div", { key: 'd013e829ca193b6ce9cc3756c3700584984f4478', class: "property-path" }, index.h("limebb-property-selector", { key: '11dee28e5de28d0dc6934abdfe613e87a8b8fbed', platform: this.platform, context: this.context, limetype: this.limetype, label: "Property", value: propertyPath, required: true, onChange: this.handlePathChange })), index.h("div", { key: '66aa416b1f9683a15357d609e3685379d8993733', class: "control-buttons" }, index.h("limel-icon-button", { key: '360f271ecd3cf42581ae21617d297c84ee93569e', icon: direction === 'ASC'
44
+ return (index.h("div", { key: '1587617d84be8905a858059ea966b7a9e0d6df78', class: "order-by-controls" }, index.h("div", { key: '8d4f47423c56cad20e91142f82a5726a7325233b', class: "property-path" }, index.h("limebb-property-selector", { key: '42c54528d2d2ee72e5b3f6ca4b31eb7bbcb9b325', platform: this.platform, context: this.context, limetype: this.limetype, label: "Property", value: propertyPath, required: true, onChange: this.handlePathChange })), index.h("div", { key: '1011a34f626c94608a926567e464d380faded349', class: "control-buttons" }, index.h("limel-icon-button", { key: '510a7c333397792a66f3e17a3501f2af96183db9', icon: direction === 'ASC'
45
45
  ? 'sort_ascending'
46
- : 'sort_descending', label: direction === 'ASC' ? 'Ascending' : 'Descending', onClick: this.handleToggleDirection }), index.h("limel-icon-button", { key: '3cbb13bff679a0ca95bb30b7853551b8bc276520', icon: "trash", label: "Remove", onClick: this.handleRemove }))));
46
+ : 'sort_descending', label: direction === 'ASC' ? 'Ascending' : 'Descending', onClick: this.handleToggleDirection }), index.h("limel-icon-button", { key: '5bc160b38c565e30cca03a88d6f2d181284cefdd', icon: "trash", label: "Remove", onClick: this.handleRemove }))));
47
47
  }
48
48
  };
49
49
  OrderByItemComponent.style = LimebbLimeQueryOrderByItemStyle0;
@@ -0,0 +1,242 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-ff255a0d.js');
6
+ const index_esm = require('./index.esm-d785eb6e.js');
7
+ const limeQueryValidation = require('./lime-query-validation-6be10fa7.js');
8
+ require('./property-resolution-fb42a46b.js');
9
+
10
+ /**
11
+ * Helper functions for working with ResponseFormat objects
12
+ *
13
+ * These utilities handle parsing, stringifying, and default values
14
+ * for ResponseFormat in isolation (without full LimeQuery wrapper)
15
+ */
16
+ /**
17
+ * Parse JSON string to ResponseFormat
18
+ *
19
+ * @param json - JSON string to parse
20
+ * @returns Parsed ResponseFormat object
21
+ * @throws Error if JSON is invalid or not a ResponseFormat
22
+ */
23
+ function parseResponseFormat(json) {
24
+ let parsed;
25
+ try {
26
+ parsed = JSON.parse(json);
27
+ }
28
+ catch (error) {
29
+ throw new Error(`Invalid JSON: ${error.message}`);
30
+ }
31
+ if (parsed === null || typeof parsed !== 'object') {
32
+ throw new Error('Response format must be an object');
33
+ }
34
+ // Validate structure
35
+ const validKeys = new Set(['object', 'aggregates']);
36
+ const keys = Object.keys(parsed);
37
+ // Check for unexpected keys
38
+ const unexpectedKeys = keys.filter((key) => !validKeys.has(key));
39
+ if (unexpectedKeys.length > 0) {
40
+ throw new Error(`Unexpected properties in response format: ${unexpectedKeys.join(', ')}. ` +
41
+ `Only 'object' and 'aggregates' are allowed.`);
42
+ }
43
+ // Must have at least one of object or aggregates
44
+ if (!parsed.object && !parsed.aggregates) {
45
+ throw new Error('Response format must contain at least one of: object, aggregates');
46
+ }
47
+ return parsed;
48
+ }
49
+ /**
50
+ * Stringify ResponseFormat to JSON
51
+ *
52
+ * @param format - ResponseFormat object to stringify
53
+ * @returns Pretty-printed JSON string
54
+ */
55
+ function stringifyResponseFormat(format) {
56
+ return JSON.stringify(format, null, 2);
57
+ }
58
+ /**
59
+ * Get default ResponseFormat (just _id)
60
+ *
61
+ * @returns Default ResponseFormat with only _id selected
62
+ */
63
+ function getDefaultResponseFormat() {
64
+ return {
65
+ object: {
66
+ _id: null,
67
+ },
68
+ };
69
+ }
70
+
71
+ const limeQueryResponseFormatBuilderCss = ":host(limebb-lime-query-response-format-builder){display:block;width:100%}.response-format-builder{display:flex;flex-direction:column;gap:1.5rem}.builder-label{margin:0;font-size:1.25rem;font-weight:600;color:rgb(var(--contrast-1100))}.mode-controls{display:flex;align-items:center;gap:0.5rem;padding:0.5rem}.mode-switch{display:flex;align-items:center;gap:0.5rem}.mode-switch limel-button{min-width:5rem}.gui-mode,.code-mode{display:block}.code-editor-container{--code-editor-max-height:70vh;display:flex;flex-direction:column;gap:1rem}.code-editor-container .validation-errors{padding:0.75rem 1rem;color:rgb(var(--color-red-default));background-color:rgb(var(--color-red-lighter));border-left:0.25rem solid rgb(var(--color-red-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .validation-errors strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .validation-errors ul{margin:0;padding-left:1.5rem}.code-editor-container .validation-errors li{margin:0.25rem 0}.code-editor-container .gui-limitations{padding:0.75rem 1rem;color:rgb(var(--color-blue-dark));background-color:rgb(var(--color-blue-lighter));border-left:0.25rem solid rgb(var(--color-blue-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .gui-limitations strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .gui-limitations ul{margin:0;padding-left:1.5rem}.code-editor-container .gui-limitations li{margin:0.25rem 0}@media (max-width: 768px){.response-format-builder{gap:1rem}}";
72
+ const LimebbLimeQueryResponseFormatBuilderStyle0 = limeQueryResponseFormatBuilderCss;
73
+
74
+ var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
75
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
76
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
77
+ r = Reflect.decorate(decorators, target, key, desc);
78
+ else
79
+ for (var i = decorators.length - 1; i >= 0; i--)
80
+ if (d = decorators[i])
81
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
82
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
83
+ };
84
+ const LimeQueryResponseFormatBuilder = class {
85
+ constructor(hostRef) {
86
+ index.registerInstance(this, hostRef);
87
+ this.change = index.createEvent(this, "change", 7);
88
+ /**
89
+ * Optional label for the builder
90
+ */
91
+ this.label = 'Response Format';
92
+ this.mode = 'gui';
93
+ this.codeValue = '';
94
+ /**
95
+ * Switch from code mode to GUI mode
96
+ */
97
+ this.switchToGui = () => {
98
+ // Validate JSON before switching
99
+ try {
100
+ const parsed = parseResponseFormat(this.codeValue);
101
+ // Check if it's supported in GUI
102
+ const support = limeQueryValidation.validateResponseFormatOnly(parsed, this.limetypes, this.limetype, this.guiModeEnabled);
103
+ if (!support.guiSupported) {
104
+ // Don't switch if GUI can't render this response format
105
+ return;
106
+ }
107
+ // Update internal state from parsed value
108
+ this.internalValue = parsed;
109
+ this.mode = 'gui';
110
+ this.change.emit(parsed);
111
+ }
112
+ catch (_a) {
113
+ // Don't switch if JSON is invalid (linter will show the error)
114
+ }
115
+ };
116
+ /**
117
+ * Switch from GUI mode to code mode
118
+ */
119
+ this.switchToCode = () => {
120
+ this.updateCodeValue();
121
+ this.mode = 'code';
122
+ };
123
+ /**
124
+ * Handle code editor changes
125
+ * @param event
126
+ */
127
+ this.handleCodeChange = (event) => {
128
+ event.stopPropagation();
129
+ this.codeValue = event.detail;
130
+ // Try to parse and emit if valid
131
+ try {
132
+ const parsed = parseResponseFormat(this.codeValue);
133
+ this.internalValue = parsed;
134
+ this.change.emit(parsed);
135
+ }
136
+ catch (_a) {
137
+ // Invalid JSON - don't emit change
138
+ // Validation errors will be shown by checkGuiSupport()
139
+ }
140
+ };
141
+ /**
142
+ * Handle GUI mode changes
143
+ * @param event
144
+ */
145
+ this.handleGuiChange = (event) => {
146
+ event.stopPropagation();
147
+ this.internalValue = event.detail;
148
+ this.updateCodeValue();
149
+ this.change.emit(event.detail);
150
+ };
151
+ }
152
+ /**
153
+ * Check if GUI mode is enabled via feature flag
154
+ */
155
+ get guiModeEnabled() {
156
+ var _a, _b, _c;
157
+ return ((_c = (_b = (_a = this.platform) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled) === null || _b === void 0 ? void 0 : _b.call(_a, 'useLimeQueryBuilderGuiMode')) !== null && _c !== void 0 ? _c : false);
158
+ }
159
+ componentWillLoad() {
160
+ // Initialize internal value
161
+ this.internalValue = this.value || getDefaultResponseFormat();
162
+ // Update code value from internal value
163
+ this.updateCodeValue();
164
+ // Force code mode if GUI is disabled
165
+ if (!this.guiModeEnabled) {
166
+ this.mode = 'code';
167
+ return;
168
+ }
169
+ // Check if GUI mode is supported for current value
170
+ const support = this.checkGuiSupport();
171
+ if (!support.guiSupported) {
172
+ this.mode = 'code';
173
+ }
174
+ }
175
+ componentWillUpdate() {
176
+ // Sync internal value when prop changes externally
177
+ if (this.value && this.mode === 'gui') {
178
+ this.internalValue = this.value;
179
+ }
180
+ }
181
+ render() {
182
+ const guiSupported = this.checkGuiSupport();
183
+ return (index.h("div", { key: '2b5e4ee360d6997a176d24e5a7aa36158461ad4a', class: "response-format-builder" }, this.label && index.h("h3", { key: 'b81f58824e4cf3114efd4d2978c833f7f06f2004', class: "builder-label" }, this.label), this.guiModeEnabled && (index.h("div", { key: '1b2ec0cd39909568732be94707a9dcadaa4a1223', class: "mode-controls" }, this.renderModeSwitch(guiSupported))), !this.guiModeEnabled || this.mode === 'code' ? (index.h("div", { class: "code-mode" }, this.renderCodeEditor(guiSupported))) : (index.h("div", { class: "gui-mode" }, this.renderGuiMode()))));
184
+ }
185
+ renderModeSwitch(support) {
186
+ const guiDisabled = !support.guiSupported;
187
+ return (index.h("div", { class: "mode-switch" }, index.h("limel-button", { label: "GUI", primary: this.mode === 'gui', disabled: guiDisabled, onClick: this.switchToGui }), index.h("limel-button", { label: "Code", primary: this.mode === 'code', onClick: this.switchToCode })));
188
+ }
189
+ renderCodeEditor(support) {
190
+ return (index.h("div", { class: "code-editor-container" }, index.h("limel-code-editor", { value: this.codeValue, language: "json", lineNumbers: true, fold: true, lint: true, onChange: this.handleCodeChange }), !support.valid && support.validationErrors.length > 0 && (index.h("div", { class: "validation-errors" }, index.h("strong", null, "Invalid Response Format:"), index.h("ul", null, support.validationErrors.map((error) => (index.h("li", null, error)))))), this.guiModeEnabled &&
191
+ support.valid &&
192
+ !support.guiSupported &&
193
+ support.guiLimitations.length > 0 && (index.h("div", { class: "gui-limitations" }, index.h("strong", null, "Cannot switch to GUI mode:"), index.h("ul", null, support.guiLimitations.map((limitation) => (index.h("li", null, limitation))))))));
194
+ }
195
+ renderGuiMode() {
196
+ return (index.h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalValue, onChange: this.handleGuiChange }));
197
+ }
198
+ /**
199
+ * Check if current value can be rendered in GUI mode
200
+ */
201
+ checkGuiSupport() {
202
+ if (!this.limetypes) {
203
+ return {
204
+ valid: false,
205
+ guiSupported: false,
206
+ validationErrors: ['Limetypes not loaded'],
207
+ guiLimitations: [],
208
+ };
209
+ }
210
+ // Try to parse code value if in code mode
211
+ let valueToCheck;
212
+ if (this.mode === 'code') {
213
+ try {
214
+ valueToCheck = parseResponseFormat(this.codeValue);
215
+ }
216
+ catch (error) {
217
+ return {
218
+ valid: false,
219
+ guiSupported: false,
220
+ validationErrors: [error.message],
221
+ guiLimitations: [],
222
+ };
223
+ }
224
+ }
225
+ else {
226
+ valueToCheck = this.internalValue;
227
+ }
228
+ return limeQueryValidation.validateResponseFormatOnly(valueToCheck, this.limetypes, this.limetype, this.guiModeEnabled);
229
+ }
230
+ /**
231
+ * Update code value from internal state
232
+ */
233
+ updateCodeValue() {
234
+ this.codeValue = stringifyResponseFormat(this.internalValue);
235
+ }
236
+ };
237
+ __decorate([
238
+ index_esm.Te()
239
+ ], LimeQueryResponseFormatBuilder.prototype, "limetypes", void 0);
240
+ LimeQueryResponseFormatBuilder.style = LimebbLimeQueryResponseFormatBuilderStyle0;
241
+
242
+ exports.limebb_lime_query_response_format_builder = LimeQueryResponseFormatBuilder;