@limetech/lime-crm-building-blocks 1.100.1 → 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 (131) hide show
  1. package/CHANGELOG.md +14 -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 +22 -426
  5. package/dist/cjs/limebb-lime-query-filter-builder_3.cjs.entry.js +86 -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 +51 -0
  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 +5 -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.css +2 -5
  25. package/dist/collection/components/lime-query-builder/lime-query-builder.js +20 -20
  26. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.css +91 -0
  27. package/dist/collection/components/lime-query-builder/lime-query-response-format-builder.js +355 -0
  28. package/dist/collection/components/lime-query-builder/lime-query-validation.js +154 -7
  29. package/dist/collection/components/lime-query-builder/limetype-field/limetype-field.js +1 -1
  30. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.css +72 -0
  31. package/dist/collection/components/lime-query-builder/order-by/order-by-editor.js +252 -0
  32. package/dist/collection/components/lime-query-builder/order-by/order-by-item.css +45 -0
  33. package/dist/collection/components/lime-query-builder/order-by/order-by-item.js +173 -0
  34. package/dist/collection/components/lime-query-builder/{response-format-editor.css → response-format/response-format-editor.css} +1 -1
  35. package/dist/collection/components/lime-query-builder/{response-format-editor.js → response-format/response-format-editor.js} +5 -5
  36. package/dist/collection/components/lime-query-builder/response-format/response-format-helpers.js +92 -0
  37. package/dist/collection/components/lime-query-builder/{response-format-item.css → response-format/response-format-item.css} +1 -1
  38. package/dist/collection/components/lime-query-builder/{response-format-item.js → response-format/response-format-item.js} +6 -6
  39. package/dist/collection/components/limeobject/file-viewer/live-docs-info.js +2 -2
  40. package/dist/collection/components/locale-picker/locale-picker.js +1 -1
  41. package/dist/collection/components/notification-list/notification-item/notification-item.js +1 -1
  42. package/dist/collection/components/percentage-visualizer/percentage-visualizer.js +2 -2
  43. package/dist/collection/components/summary-popover/summary-popover.js +3 -3
  44. package/dist/collection/components/text-editor/mention-group-counter.js +2 -2
  45. package/dist/collection/components/text-editor/text-editor.js +1 -1
  46. package/dist/collection/components/trend-indicator/trend-indicator.js +1 -1
  47. package/dist/components/lime-query-filter-comparison.js +1 -1
  48. package/dist/components/lime-query-filter-expression.js +2 -2
  49. package/dist/components/lime-query-validation.js +555 -0
  50. package/dist/components/lime-query-value-input.js +1 -1
  51. package/dist/components/limebb-lime-query-builder.js +53 -444
  52. package/dist/components/limebb-lime-query-order-by-editor.d.ts +11 -0
  53. package/dist/components/limebb-lime-query-order-by-editor.js +6 -0
  54. package/dist/components/limebb-lime-query-order-by-item.d.ts +11 -0
  55. package/dist/components/limebb-lime-query-order-by-item.js +6 -0
  56. package/dist/components/limebb-lime-query-response-format-builder.d.ts +11 -0
  57. package/dist/components/limebb-lime-query-response-format-builder.js +283 -0
  58. package/dist/components/limebb-lime-query-response-format-editor.d.ts +11 -0
  59. package/dist/components/{limebb-response-format-editor.js → limebb-lime-query-response-format-editor.js} +2 -2
  60. package/dist/components/limebb-lime-query-response-format-item.d.ts +11 -0
  61. package/dist/components/{limebb-response-format-item.js → limebb-lime-query-response-format-item.js} +2 -2
  62. package/dist/components/limebb-locale-picker.js +1 -1
  63. package/dist/components/limebb-mention-group-counter.js +2 -2
  64. package/dist/components/limebb-percentage-visualizer.js +2 -2
  65. package/dist/components/limebb-text-editor.js +1 -1
  66. package/dist/components/limebb-trend-indicator.js +1 -1
  67. package/dist/components/limetype-field.js +1 -1
  68. package/dist/components/live-docs-info.js +2 -2
  69. package/dist/components/notification-item.js +1 -1
  70. package/dist/components/order-by-editor.js +123 -0
  71. package/dist/components/order-by-item.js +73 -0
  72. package/dist/components/property-selector.js +1 -1
  73. package/dist/components/response-format-editor.js +11 -11
  74. package/dist/components/response-format-item.js +9 -9
  75. package/dist/components/summary-popover.js +3 -3
  76. package/dist/esm/lime-crm-building-blocks.js +1 -1
  77. package/dist/esm/lime-query-validation-573223a5.js +555 -0
  78. package/dist/esm/limebb-lime-query-builder.entry.js +22 -426
  79. package/dist/esm/limebb-lime-query-filter-builder_3.entry.js +86 -243
  80. package/dist/esm/limebb-lime-query-filter-comparison_2.entry.js +1 -1
  81. package/dist/esm/limebb-lime-query-filter-group_3.entry.js +3 -3
  82. package/dist/esm/limebb-lime-query-order-by-item.entry.js +47 -0
  83. package/dist/esm/limebb-lime-query-response-format-builder.entry.js +238 -0
  84. package/dist/esm/limebb-lime-query-response-format-editor_2.entry.js +317 -0
  85. package/dist/esm/limebb-live-docs-info.entry.js +2 -2
  86. package/dist/esm/limebb-locale-picker.entry.js +1 -1
  87. package/dist/esm/limebb-mention-group-counter.entry.js +2 -2
  88. package/dist/esm/limebb-navigation-button_2.entry.js +3 -3
  89. package/dist/esm/limebb-notification-item.entry.js +1 -1
  90. package/dist/esm/limebb-percentage-visualizer.entry.js +2 -2
  91. package/dist/esm/limebb-property-selector.entry.js +1 -1
  92. package/dist/esm/limebb-text-editor.entry.js +1 -1
  93. package/dist/esm/limebb-trend-indicator.entry.js +1 -1
  94. package/dist/esm/loader.js +1 -1
  95. package/dist/esm/{property-resolution-fde2375e.js → property-resolution-c21a1369.js} +1 -1
  96. package/dist/lime-crm-building-blocks/lime-crm-building-blocks.esm.js +1 -1
  97. package/dist/lime-crm-building-blocks/{p-79b8b09b.entry.js → p-0de79b7f.entry.js} +1 -1
  98. package/dist/lime-crm-building-blocks/{p-1034b4a5.entry.js → p-0f7135ff.entry.js} +1 -1
  99. package/dist/lime-crm-building-blocks/{p-6aa216ec.entry.js → p-186e9f1a.entry.js} +1 -1
  100. package/dist/lime-crm-building-blocks/p-289ce8b9.entry.js +1 -0
  101. package/dist/lime-crm-building-blocks/p-3351395b.entry.js +1 -0
  102. package/dist/lime-crm-building-blocks/p-33e6d0ec.entry.js +1 -0
  103. package/dist/lime-crm-building-blocks/{p-8581245a.entry.js → p-3d1be1c9.entry.js} +1 -1
  104. package/dist/lime-crm-building-blocks/{p-b57dafef.entry.js → p-577d8909.entry.js} +1 -1
  105. package/dist/lime-crm-building-blocks/{p-89a6c396.entry.js → p-6579412e.entry.js} +1 -1
  106. package/dist/lime-crm-building-blocks/{p-8fb2e192.entry.js → p-6f6fed59.entry.js} +1 -1
  107. package/dist/lime-crm-building-blocks/{p-58782467.entry.js → p-7e5528f6.entry.js} +1 -1
  108. package/dist/lime-crm-building-blocks/{p-2048ac67.entry.js → p-a9ac501f.entry.js} +1 -1
  109. package/dist/lime-crm-building-blocks/{p-f79e354b.entry.js → p-abfc7815.entry.js} +1 -1
  110. package/dist/lime-crm-building-blocks/{p-e0ab1554.js → p-b748c770.js} +1 -1
  111. package/dist/lime-crm-building-blocks/p-be845252.entry.js +1 -0
  112. package/dist/lime-crm-building-blocks/p-cb338753.entry.js +1 -0
  113. package/dist/lime-crm-building-blocks/{p-76d81eee.entry.js → p-d0721b22.entry.js} +1 -1
  114. package/dist/lime-crm-building-blocks/p-fa2da6bc.js +1 -0
  115. package/dist/types/components/lime-query-builder/lime-query-builder.d.ts +9 -6
  116. package/dist/types/components/lime-query-builder/lime-query-response-format-builder.d.ts +102 -0
  117. package/dist/types/components/lime-query-builder/lime-query-validation.d.ts +13 -0
  118. package/dist/types/components/lime-query-builder/order-by/order-by-editor.d.ts +58 -0
  119. package/dist/types/components/lime-query-builder/order-by/order-by-item.d.ts +37 -0
  120. package/dist/types/components/lime-query-builder/{response-format-editor.d.ts → response-format/response-format-editor.d.ts} +2 -2
  121. package/dist/types/components/lime-query-builder/response-format/response-format-helpers.d.ts +42 -0
  122. package/dist/types/components/lime-query-builder/{response-format-item.d.ts → response-format/response-format-item.d.ts} +2 -2
  123. package/dist/types/components.d.ts +667 -279
  124. package/package.json +1 -1
  125. package/dist/cjs/limebb-response-format-item.cjs.entry.js +0 -80
  126. package/dist/components/limebb-response-format-editor.d.ts +0 -11
  127. package/dist/components/limebb-response-format-item.d.ts +0 -11
  128. package/dist/esm/limebb-response-format-item.entry.js +0 -76
  129. package/dist/lime-crm-building-blocks/p-244ee55b.entry.js +0 -1
  130. package/dist/lime-crm-building-blocks/p-323c49bc.entry.js +0 -1
  131. package/dist/lime-crm-building-blocks/p-f22b66f6.entry.js +0 -1
@@ -4,413 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-ff255a0d.js');
6
6
  const index_esm = require('./index.esm-d785eb6e.js');
7
- const propertyResolution = require('./property-resolution-fb42a46b.js');
7
+ const limeQueryValidation = require('./lime-query-validation-6be10fa7.js');
8
+ require('./property-resolution-fb42a46b.js');
8
9
 
9
- /**
10
- * Dynamic filter values and placeholders that are valid in Lime Query
11
- */
12
- const VALID_DYNAMIC_VALUES = new Set([
13
- // Temporal
14
- '$yesterday',
15
- '$now',
16
- '$today',
17
- '$tomorrow',
18
- // Ranges
19
- '$this_week',
20
- '$this_month',
21
- '$this_quarter',
22
- '$this_year',
23
- ]);
24
- /**
25
- * Pattern for relative date functions: $previous_day(x), $next_month(x), etc.
26
- */
27
- const RELATIVE_DATE_PATTERN = /^\$(previous|next)_(day|week|month|quarter|year)\(\d+\)$/;
28
- /**
29
- * Pattern for user context variables: $me, $me.office.name, etc.
30
- */
31
- const USER_CONTEXT_PATTERN = /^\$me(\.\w+)*$/;
32
- /**
33
- * Check if a value is a valid dynamic value or placeholder
34
- * @param value
35
- */
36
- function isValidDynamicValue(value) {
37
- if (typeof value !== 'string') {
38
- return false;
39
- }
40
- return (VALID_DYNAMIC_VALUES.has(value) ||
41
- RELATIVE_DATE_PATTERN.test(value) ||
42
- USER_CONTEXT_PATTERN.test(value));
43
- }
44
- /**
45
- * Validate a placeholder value
46
- * @param value The value to check (might be a placeholder)
47
- * @param activeLimetype The limetype of the active object
48
- * @param limetypes Record of all available limetypes
49
- * @returns Validation result with error message if invalid
50
- */
51
- function validatePlaceholder(value, activeLimetype, limetypes) {
52
- // Check if it's a valid dynamic value ($today, $me, etc.)
53
- if (isValidDynamicValue(value)) {
54
- return { valid: true };
55
- }
56
- // Not a placeholder, no validation needed
57
- if (typeof value !== 'string' || !value.startsWith('%activeObject%')) {
58
- return { valid: true };
59
- }
60
- // Placeholder used but no active limetype specified
61
- // This is always valid - activeLimetype is optional and only used for validation
62
- if (!activeLimetype) {
63
- return { valid: true };
64
- }
65
- // Extract property path from placeholder
66
- const propertyPath = value.replace(/^%activeObject%\.?/, '');
67
- // %activeObject% without property path is valid (references the ID)
68
- if (!propertyPath) {
69
- return { valid: true };
70
- }
71
- // Validate the property path exists on the active limetype
72
- try {
73
- const property = propertyResolution.getPropertyFromPath(limetypes, activeLimetype, propertyPath);
74
- if (!property) {
75
- return {
76
- valid: false,
77
- error: `Property path '${propertyPath}' does not exist on limetype '${activeLimetype}'`,
78
- };
79
- }
80
- // Path validation is already done by getPropertyFromPath
81
- // If we can traverse the path successfully, it means all intermediate
82
- // properties are valid single relations (belongsTo/hasOne).
83
- // hasMany relations cannot be traversed in paths.
84
- return { valid: true };
85
- }
86
- catch (error) {
87
- return {
88
- valid: false,
89
- error: `Invalid placeholder path: ${error.message}`,
90
- };
91
- }
92
- }
93
- /**
94
- * Validate a response format against limetype schemas
95
- * Throws errors for invalid property references
96
- * Returns GUI limitations for features not yet supported in GUI
97
- * @param responseFormat
98
- * @param limetypes Record of all available limetypes
99
- * @param limetype The root limetype for this query
100
- * @param guiModeEnabled Whether GUI mode is enabled
101
- * @returns GUI limitations found (if any)
102
- */
103
- function validateResponseFormat(responseFormat, limetypes, limetype, guiModeEnabled = true) {
104
- const guiLimitations = [];
105
- // Check for GUI-unsupported features
106
- if (guiModeEnabled && responseFormat.aggregates) {
107
- guiLimitations.push('responseFormat.aggregates is not yet supported in GUI mode');
108
- }
109
- // Validate object properties (throws on invalid properties)
110
- if (responseFormat.object) {
111
- const objectLimitations = validatePropertySelection(responseFormat.object, limetypes, limetype, guiModeEnabled);
112
- guiLimitations.push(...objectLimitations);
113
- }
114
- return guiLimitations;
115
- }
116
- /**
117
- * Extract non-metadata keys from a property value object
118
- * Filters out _alias and all # properties (which are treated as comments)
119
- * @param propValue Property value object
120
- * @param propName Property name (for error messages)
121
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
122
- * @returns Object with non-metadata keys and any GUI limitations found
123
- */
124
- function extractNonMetadataKeys(propValue, propName, guiModeEnabled = true) {
125
- const keys = Object.keys(propValue);
126
- const guiLimitations = [];
127
- // Check for # properties other than #description (GUI limitation)
128
- if (guiModeEnabled) {
129
- const unsupportedHashProps = keys.filter((k) => k.startsWith('#') && k !== '#description');
130
- if (unsupportedHashProps.length > 0) {
131
- guiLimitations.push(`Property '${propName}' contains # properties not supported in GUI: ${unsupportedHashProps.join(', ')}`);
132
- }
133
- }
134
- // Filter out _alias and all # properties (they are metadata/comments)
135
- const nonMetadataKeys = keys.filter((k) => k !== '_alias' && !k.startsWith('#'));
136
- return { keys: nonMetadataKeys, guiLimitations };
137
- }
138
- /**
139
- * Validate a relation property value
140
- * @param propName Property name
141
- * @param propValue Property value
142
- * @param limetypes Record of all available limetypes
143
- * @param property
144
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
145
- * @returns GUI limitations found (if any)
146
- */
147
- function validateRelationProperty(propName, propValue, limetypes, property, guiModeEnabled = true) {
148
- // null is valid - just return the relation ID
149
- if (propValue === null) {
150
- return [];
151
- }
152
- if (typeof propValue !== 'object') {
153
- throw new TypeError(`Relation property '${propName}' must be null or an object`);
154
- }
155
- const propValueObj = propValue;
156
- const { keys: otherKeys, guiLimitations } = extractNonMetadataKeys(propValueObj, propName, guiModeEnabled);
157
- // If it's just {} or { _alias: "...", "#...": "..." }, that's valid
158
- if (otherKeys.length === 0) {
159
- return guiLimitations;
160
- }
161
- // Otherwise, validate nested properties
162
- const relatedLimetype = property.relation.getLimetype();
163
- if (!relatedLimetype) {
164
- throw new Error(`Could not determine related limetype for property '${propName}'`);
165
- }
166
- // Build a clean PropertySelection without metadata for recursive validation
167
- const cleanSelection = {};
168
- for (const key of otherKeys) {
169
- cleanSelection[key] = propValueObj[key];
170
- }
171
- const nestedLimitations = validatePropertySelection(cleanSelection, limetypes, relatedLimetype.name, guiModeEnabled);
172
- return [...guiLimitations, ...nestedLimitations];
173
- }
174
- /**
175
- * Validate a non-relation property value
176
- * @param propName Property name
177
- * @param propValue Property value
178
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
179
- * @returns GUI limitations found (if any)
180
- */
181
- function validateNonRelationProperty(propName, propValue, guiModeEnabled = true) {
182
- // null is valid
183
- if (propValue === null) {
184
- return [];
185
- }
186
- // Allow empty object {} or object with only metadata (_alias, #...)
187
- if (typeof propValue === 'object') {
188
- const { keys: nonMetadataKeys, guiLimitations } = extractNonMetadataKeys(propValue, propName, guiModeEnabled);
189
- if (nonMetadataKeys.length === 0) {
190
- // {} or { _alias: "...", "#...": "..." } is valid
191
- return guiLimitations;
192
- }
193
- throw new Error(`Non-relation property '${propName}' cannot have nested properties other than _alias or # properties (got: ${nonMetadataKeys.join(', ')})`);
194
- }
195
- throw new Error(`Non-relation property '${propName}' must be null or an object (got ${typeof propValue})`);
196
- }
197
- /**
198
- * Validate a single property entry
199
- * @param propName Property name
200
- * @param propValue Property value
201
- * @param normalizedProperties Normalized properties of the limetype
202
- * @param limetypes Record of all available limetypes
203
- * @param limetype Current limetype name
204
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
205
- * @returns GUI limitations found (if any)
206
- */
207
- function validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype, guiModeEnabled = true) {
208
- // Allow empty string (editing state in GUI)
209
- if (propName === '') {
210
- // Only validate empty property name in GUI mode
211
- if (guiModeEnabled && propValue !== null) {
212
- throw new Error('Empty property name must have null value');
213
- }
214
- return [];
215
- }
216
- // Validate property exists on limetype
217
- const property = normalizedProperties[propName];
218
- if (!property) {
219
- throw new Error(`Property '${propName}' does not exist on limetype '${limetype}'`);
220
- }
221
- // Validate value based on property type
222
- if (property.relation) {
223
- return validateRelationProperty(propName, propValue, limetypes, property, guiModeEnabled);
224
- }
225
- else {
226
- return validateNonRelationProperty(propName, propValue, guiModeEnabled);
227
- }
228
- }
229
- /**
230
- * Validate a property selection object against a limetype schema
231
- * Recursively validates nested property selections for relations
232
- * @param selection
233
- * @param limetypes Record of all available limetypes
234
- * @param limetype The limetype for this level of the selection
235
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
236
- * @returns GUI limitations found (if any)
237
- */
238
- function validatePropertySelection(selection, limetypes, limetype, guiModeEnabled = true) {
239
- const limetypeObj = limetypes[limetype];
240
- if (!limetypeObj) {
241
- throw new Error(`Unknown limetype: ${limetype}`);
242
- }
243
- const normalizedProperties = propertyResolution.getNormalizedProperties(limetypeObj);
244
- const allGuiLimitations = [];
245
- for (const [propName, propValue] of Object.entries(selection)) {
246
- // Skip # properties (comments/metadata that backend accepts via unknown=INCLUDE)
247
- // Note: _alias only appears inside property value objects, not at this level
248
- if (propName.startsWith('#')) {
249
- continue;
250
- }
251
- const limitations = validateSinglePropertyEntry(propName, propValue, normalizedProperties, limetypes, limetype, guiModeEnabled);
252
- allGuiLimitations.push(...limitations);
253
- }
254
- return allGuiLimitations;
255
- }
256
- /**
257
- * Validate a comparison expression (has 'key' property)
258
- * @param filter
259
- * @param activeLimetype
260
- * @param limetypes
261
- */
262
- function validateComparisonExpression(filter, activeLimetype, limetypes) {
263
- // Validate operator
264
- const allValidOperators = Object.values(index_esm.Zt);
265
- if (!allValidOperators.includes(filter.op)) {
266
- throw new Error(`Unsupported filter operator: ${filter.op}`);
267
- }
268
- // Validate placeholder
269
- const result = validatePlaceholder(filter.exp, activeLimetype, limetypes);
270
- if (!result.valid) {
271
- throw new Error(`Invalid placeholder in filter '${filter.key}': ${result.error}`);
272
- }
273
- }
274
- /**
275
- * Validate a group expression (AND/OR/NOT)
276
- * @param filter
277
- * @param activeLimetype
278
- * @param limetypes
279
- * @param guiModeEnabled
280
- */
281
- function validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabled) {
282
- // Validate operator
283
- if (filter.op !== index_esm.Zt.AND &&
284
- filter.op !== index_esm.Zt.OR &&
285
- filter.op !== index_esm.Zt.NOT) {
286
- throw new Error(`Unsupported group operator: ${filter.op}`);
287
- }
288
- // Recursively validate children
289
- if (filter.op === index_esm.Zt.NOT) {
290
- validateFilterPlaceholders(filter.exp, activeLimetype, limetypes, guiModeEnabled);
291
- }
292
- else if (filter.op === index_esm.Zt.AND || filter.op === index_esm.Zt.OR) {
293
- const expressions = filter.exp;
294
- for (const expr of expressions) {
295
- validateFilterPlaceholders(expr, activeLimetype, limetypes, guiModeEnabled);
296
- }
297
- }
298
- }
299
- /**
300
- * Validate placeholders in a filter expression
301
- * @param filter Filter expression to validate
302
- * @param activeLimetype The limetype of the active object
303
- * @param limetypes Record of all available limetypes
304
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
305
- */
306
- function validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEnabled = true) {
307
- if (!filter) {
308
- return;
309
- }
310
- if ('key' in filter) {
311
- validateComparisonExpression(filter, activeLimetype, limetypes);
312
- return;
313
- }
314
- if ('exp' in filter) {
315
- validateGroupExpression(filter, activeLimetype, limetypes, guiModeEnabled);
316
- }
317
- }
318
- /**
319
- * Validate Lime Query filter and collect errors
320
- * @param filter The filter expression or group to validate
321
- * @param activeLimetype Optional active object limetype for placeholder validation
322
- * @param limetypes Record of all available limetypes
323
- * @param guiModeEnabled Whether GUI mode is enabled
324
- * @returns Array of validation error messages
325
- */
326
- function validateLimeQueryFilterInternal(filter, activeLimetype, limetypes, guiModeEnabled) {
327
- const errors = [];
328
- try {
329
- validateFilterPlaceholders(filter, activeLimetype, limetypes, guiModeEnabled);
330
- }
331
- catch (error) {
332
- errors.push(`Invalid filter: ${error.message}`);
333
- }
334
- return errors;
335
- }
336
- /**
337
- * Validate Lime Query response format and collect errors/limitations
338
- * @param responseFormat The response format to validate
339
- * @param limetypes Record of all available limetypes
340
- * @param limetype The limetype for this Lime Query
341
- * @param guiModeEnabled Whether GUI mode is enabled
342
- * @returns Object with validation errors and GUI limitations
343
- */
344
- function validateLimeQueryResponseFormatInternal(responseFormat, limetypes, limetype, guiModeEnabled) {
345
- const errors = [];
346
- const limitations = [];
347
- try {
348
- const formatLimitations = validateResponseFormat(responseFormat, limetypes, limetype, guiModeEnabled);
349
- limitations.push(...formatLimitations);
350
- }
351
- catch (error) {
352
- errors.push(`Invalid responseFormat: ${error.message}`);
353
- }
354
- return { errors, limitations };
355
- }
356
- /**
357
- * Validate a Lime Query
358
- * Returns validation result with separate arrays for validity errors and GUI limitations
359
- * @param limeQuery The Lime Query to validate
360
- * @param limetypes Record of all available limetypes
361
- * @param activeLimetype Optional active object limetype for placeholder validation
362
- * @param guiModeEnabled Whether GUI mode is enabled (affects validation)
363
- * @returns LimeQueryValidationResult with validity status and any errors/limitations
364
- */
365
- function isLimeQuerySupported(limeQuery, limetypes, activeLimetype, guiModeEnabled = true) {
366
- // Handle empty/undefined Lime Query
367
- if (!limeQuery) {
368
- return {
369
- valid: true,
370
- guiSupported: true,
371
- validationErrors: [],
372
- guiLimitations: [],
373
- };
374
- }
375
- const validationErrors = [];
376
- const guiLimitations = [];
377
- // Validate limetype exists
378
- if (limeQuery.limetype && !limetypes[limeQuery.limetype]) {
379
- validationErrors.push(`Unknown limetype: ${limeQuery.limetype}`);
380
- }
381
- // Check for offset without orderBy (Lime Query requirement)
382
- if (limeQuery.offset !== undefined && !limeQuery.orderBy) {
383
- validationErrors.push('offset requires orderBy to be specified');
384
- }
385
- // Check for GUI-unsupported top-level properties
386
- if (guiModeEnabled) {
387
- if (limeQuery.orderBy) {
388
- guiLimitations.push('orderBy is not yet supported in GUI mode');
389
- }
390
- if (limeQuery.offset !== undefined) {
391
- guiLimitations.push('offset is not yet supported in GUI mode');
392
- }
393
- }
394
- // Validate filter
395
- if (limeQuery.filter) {
396
- const filterErrors = validateLimeQueryFilterInternal(limeQuery.filter, activeLimetype, limetypes, guiModeEnabled);
397
- validationErrors.push(...filterErrors);
398
- }
399
- // Validate responseFormat
400
- if (limeQuery.responseFormat) {
401
- const { errors, limitations } = validateLimeQueryResponseFormatInternal(limeQuery.responseFormat, limetypes, limeQuery.limetype, guiModeEnabled);
402
- validationErrors.push(...errors);
403
- guiLimitations.push(...limitations);
404
- }
405
- return {
406
- valid: validationErrors.length === 0,
407
- guiSupported: guiLimitations.length === 0,
408
- validationErrors,
409
- guiLimitations,
410
- };
411
- }
412
-
413
- const limeQueryBuilderCss = ":host(limebb-lime-lime-query-builder){display:block;width:100%}.lime-query-builder{display:flex;flex-direction:column;gap:2rem}.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}.mode-switch limel-helper-text{margin-left:1rem;color:rgb(var(--color-red-default))}.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}.lime-query-builder-label{margin:0;font-size:1.5rem;font-weight:600;color:rgb(var(--contrast-1100))}.limetype-section{display:flex;flex-direction:column}.filter-section,.query-options-section{display:flex;flex-direction:column;gap:1rem}.section-label{margin:0;font-size:1.125rem;font-weight:600;color:rgb(var(--contrast-1000))}.query-options-controls{display:grid;grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));gap:1rem}@media (max-width: 768px){.lime-query-builder{gap:1.5rem}.query-options-controls{grid-template-columns:1fr}}";
10
+ const limeQueryBuilderCss = ":host(limebb-lime-lime-query-builder){display:block;width:100%}.lime-query-builder{display:flex;flex-direction:column;gap:2rem}.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}.mode-switch limel-helper-text{margin-left:1rem;color:rgb(var(--color-red-default))}.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}.lime-query-builder-label{margin:0;font-size:1.5rem;font-weight:600;color:rgb(var(--contrast-1100))}.limetype-section{display:flex;flex-direction:column}.filter-section,.query-options-section{display:flex;flex-direction:column;gap:1rem}.section-label{margin:0;font-size:1.125rem;font-weight:600;color:rgb(var(--contrast-1000))}.query-options-controls{display:flex;flex-direction:column;gap:1rem}@media (max-width: 768px){.lime-query-builder{gap:1.5rem}}";
414
11
  const LimebbLimeQueryBuilderStyle0 = limeQueryBuilderCss;
415
12
 
416
13
  var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
@@ -460,6 +57,11 @@ const LimeQueryBuilder = class {
460
57
  this.limit = value ? Number.parseInt(value, 10) : undefined;
461
58
  this.emitChange();
462
59
  };
60
+ this.handleOrderByChange = (event) => {
61
+ event.stopPropagation();
62
+ this.orderBy = event.detail;
63
+ this.emitChange();
64
+ };
463
65
  this.switchToGui = () => {
464
66
  // Validate JSON before switching
465
67
  try {
@@ -475,6 +77,7 @@ const LimeQueryBuilder = class {
475
77
  this.filter = parsed.filter;
476
78
  this.internalResponseFormat = parsed.responseFormat;
477
79
  this.limit = parsed.limit;
80
+ this.orderBy = parsed.orderBy;
478
81
  this.mode = 'gui';
479
82
  this.change.emit(parsed);
480
83
  }
@@ -516,6 +119,7 @@ const LimeQueryBuilder = class {
516
119
  this.filter = this.value.filter;
517
120
  this.internalResponseFormat = this.value.responseFormat;
518
121
  this.limit = this.value.limit;
122
+ this.orderBy = this.value.orderBy;
519
123
  }
520
124
  // Initialize code value from prop
521
125
  this.updateCodeValue();
@@ -528,7 +132,7 @@ const LimeQueryBuilder = class {
528
132
  render() {
529
133
  const guiSupported = this.checkGuiSupport();
530
134
  const showCodeMode = !this.guiModeEnabled || this.mode === 'code';
531
- return (index.h("div", { key: '0b4d2bb5b4d503a775d8d3215e1e4c74fdb1eceb', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
135
+ return (index.h("div", { key: 'f51ae0459c1c7f482f3a790abb4cc3bd60b83e70', class: "lime-query-builder" }, this.renderLabel(), this.renderModeControls(guiSupported), showCodeMode
532
136
  ? this.renderCodeMode(guiSupported)
533
137
  : this.renderGuiMode()));
534
138
  }
@@ -540,27 +144,16 @@ const LimeQueryBuilder = class {
540
144
  if (!this.limetype) {
541
145
  return;
542
146
  }
543
- // Use internal state, then default to returning just _id
544
- const responseFormat = this.internalResponseFormat || {
545
- object: {
546
- _id: null,
547
- },
548
- };
549
- const limeQuery = {
550
- limetype: this.limetype,
551
- responseFormat: responseFormat,
552
- filter: this.filter,
553
- };
554
- if (this.limit !== undefined && this.limit > 0) {
555
- limeQuery.limit = this.limit;
556
- }
557
- this.change.emit(limeQuery);
147
+ this.change.emit(this.buildLimeQuery());
558
148
  }
559
149
  updateCodeValue() {
560
150
  if (!this.limetype) {
561
151
  this.codeValue = JSON.stringify(this.value || {}, null, 2);
562
152
  return;
563
153
  }
154
+ this.codeValue = JSON.stringify(this.buildLimeQuery(), null, 2);
155
+ }
156
+ buildLimeQuery() {
564
157
  // Use internal state, then default to returning just _id
565
158
  const responseFormat = this.internalResponseFormat || {
566
159
  object: {
@@ -575,7 +168,10 @@ const LimeQueryBuilder = class {
575
168
  if (this.limit !== undefined && this.limit > 0) {
576
169
  limeQuery.limit = this.limit;
577
170
  }
578
- this.codeValue = JSON.stringify(limeQuery, null, 2);
171
+ if (this.orderBy && this.orderBy.length > 0) {
172
+ limeQuery.orderBy = this.orderBy;
173
+ }
174
+ return limeQuery;
579
175
  }
580
176
  checkGuiSupport() {
581
177
  if (!this.limetypes) {
@@ -627,7 +223,7 @@ const LimeQueryBuilder = class {
627
223
  queryToCheck.limit = this.limit;
628
224
  }
629
225
  }
630
- return isLimeQuerySupported(queryToCheck, this.limetypes, this.activeLimetype, this.guiModeEnabled);
226
+ return limeQueryValidation.isLimeQuerySupported(queryToCheck, this.limetypes, this.activeLimetype, this.guiModeEnabled);
631
227
  }
632
228
  renderModeSwitch(support) {
633
229
  const guiDisabled = !support.guiSupported;
@@ -647,7 +243,7 @@ const LimeQueryBuilder = class {
647
243
  if (!this.limetype) {
648
244
  return;
649
245
  }
650
- return (index.h("div", { class: "response-format-section" }, index.h("limebb-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalResponseFormat, onChange: this.handleResponseFormatChange })));
246
+ return (index.h("div", { class: "response-format-section" }, index.h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalResponseFormat, onChange: this.handleResponseFormatChange })));
651
247
  }
652
248
  renderFilterSection() {
653
249
  if (!this.limetype) {
@@ -660,7 +256,7 @@ const LimeQueryBuilder = class {
660
256
  if (!this.limetype) {
661
257
  return;
662
258
  }
663
- return (index.h("div", { class: "query-options-section" }, index.h("h4", { class: "section-label" }, "Query Options"), index.h("div", { class: "query-options-controls" }, index.h("limel-input-field", { label: "Limit", type: "number", value: ((_a = this.limit) === null || _a === void 0 ? void 0 : _a.toString()) || '', placeholder: "No limit", helperText: "Maximum number of results", onChange: this.handleLimitChange }))));
259
+ return (index.h("div", { class: "query-options-section" }, index.h("h4", { class: "section-label" }, "Query Options"), index.h("div", { class: "query-options-controls" }, index.h("limel-input-field", { label: "Limit", type: "number", value: ((_a = this.limit) === null || _a === void 0 ? void 0 : _a.toString()) || '', placeholder: "No limit", helperText: "Maximum number of results", onChange: this.handleLimitChange }), index.h("limebb-lime-query-order-by-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.orderBy, onChange: this.handleOrderByChange }))));
664
260
  }
665
261
  renderGuiMode() {
666
262
  return (index.h("div", { class: "gui-mode" }, this.renderLimetypeSection(), this.renderResponseFormatSection(), this.renderFilterSection(), this.renderQueryOptionsSection()));