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