@dataloop-ai/components 0.20.27 → 0.20.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataloop-ai/components",
3
- "version": "0.20.27",
3
+ "version": "0.20.28",
4
4
  "exports": {
5
5
  ".": "./index.ts",
6
6
  "./models": "./models.ts",
@@ -445,8 +445,15 @@ export default defineComponent({
445
445
  queryRightSide = queryRightSide.trimStart()
446
446
  } else {
447
447
  // this|situation: replace whatever is there on both sides with the value
448
- if (/^[^']+('[^']?'[^']+)?'[^']+'?$/.test(queryLeftSide)) {
449
- queryLeftSide = queryLeftSide.replace(/'[^']+'?$/, '')
448
+ if (
449
+ /^[^']+((?<!\\)'.*(?<!\\)'[^']+)*(?<!\\)'([^']+\\')*[^']*((?<!\\)')?$/.test(
450
+ queryLeftSide
451
+ )
452
+ ) {
453
+ queryLeftSide = queryLeftSide.replace(
454
+ /(?<!\\)'([^']+\\')*[^']*((?<!\\)')?$/,
455
+ ''
456
+ )
450
457
  } else {
451
458
  queryLeftSide = queryLeftSide.replace(/[^'\s]+$/, '')
452
459
  }
@@ -159,7 +159,7 @@ export default defineComponent({
159
159
  const removeQuotes = (item: any) => {
160
160
  const str = '' + item
161
161
  const match = str.match(/^'(.*)'$/)
162
- return match ? match[1] : str
162
+ return match ? match[1].replace(/\\'/g, "'") : str
163
163
  }
164
164
 
165
165
  const updatePosition = () => {
@@ -88,10 +88,7 @@
88
88
  </div>
89
89
  <template v-else>
90
90
  <span
91
- v-show="
92
- (multiselect && !searchable) ||
93
- (multiselect && searchable && !isExpanded)
94
- "
91
+ v-show="multiselect && (!searchable || !isExpanded)"
95
92
  class="root-container--placeholder"
96
93
  >
97
94
  <template v-if="allFiltersModel">
@@ -102,10 +99,7 @@
102
99
  </template>
103
100
  </span>
104
101
  <span
105
- v-show="
106
- (!multiselect && !searchable) ||
107
- (!multiselect && searchable && !isExpanded)
108
- "
102
+ v-show="!multiselect && (!searchable || !isExpanded)"
109
103
  class="selected-label"
110
104
  >
111
105
  <dl-ellipsis :text="getLabel(selectedOption)" />
@@ -136,7 +136,7 @@ export default defineComponent({
136
136
  '*': 'any'
137
137
  },
138
138
  type: ['dir', 'file'],
139
- test0: ['why wont', 'this work', 123],
139
+ test0: ['why wont', 'this work', 123, '1\' = 12"'],
140
140
  test1: [...numbersArr, 'number'],
141
141
  test2: ['true', 'false']
142
142
  }
@@ -333,10 +333,12 @@ export const useSuggestions = (
333
333
  const mappedTypes: string[] = []
334
334
  for (const type of filteredTypes) {
335
335
  if (typeof type === 'string') {
336
- mappedTypes.push(`'${type}'`)
336
+ mappedTypes.push(enquoteString(type))
337
337
  } else if (typeof type === 'object') {
338
338
  mappedTypes.push(
339
- ...Object.keys(type).map((key) => `'${key}'`)
339
+ ...Object.keys(type).map((key) =>
340
+ enquoteString(key)
341
+ )
340
342
  )
341
343
  } else {
342
344
  mappedTypes.push(type)
@@ -614,10 +616,19 @@ const isValidBoolean = (str: string) => {
614
616
  }
615
617
 
616
618
  const isValidString = (str: string) => {
617
- const match = str.match(/(?<=\")(.*?)(?=\")|(?<=\')(.*?)(?=\')/)
618
- if (!match) return false
619
- const trimmed = str.trim()
620
- return match[0] === trimmed.substring(1, trimmed.length - 1)
619
+ const matchSingleQuotes = str.match(/^\s*(?<!\\)'(.*)(?<!\\)'\s*$/)
620
+ if (matchSingleQuotes) {
621
+ return !/(?<!\\)'/.test(matchSingleQuotes[1])
622
+ }
623
+ const matchDoubleQuotes = str.match(/^\s*(?<!\\)"(.*)(?<!\\)"\s*$/)
624
+ if (matchDoubleQuotes) {
625
+ return !/(?<!\\)"/.test(matchDoubleQuotes[1])
626
+ }
627
+ return false
628
+ }
629
+
630
+ const enquoteString = (str: string) => {
631
+ return `'${str.replace(/'/g, "\\'")}'`
621
632
  }
622
633
 
623
634
  const getOperatorByDataType = (dataType: string) => {
@@ -728,7 +739,9 @@ const getValueMatch = (
728
739
  let serach = s
729
740
 
730
741
  if (typeof str === 'string') {
731
- term = insensitive(str.replace(/["']/gi, ''))
742
+ term = insensitive(
743
+ str.replace(/^["'](.*)["']$/, '$1').replace(/\\'/g, "'")
744
+ )
732
745
  }
733
746
  if (typeof s === 'string') {
734
747
  serach = insensitive(s)
@@ -844,7 +857,9 @@ const getValueSuggestions = (
844
857
  !knownDataTypes.includes(type as string) &&
845
858
  typeof type !== 'object'
846
859
  ) {
847
- suggestion.push(typeof type === 'string' ? `'${type}'` : type)
860
+ suggestion.push(
861
+ typeof type === 'string' ? enquoteString(type) : type
862
+ )
848
863
  }
849
864
  }
850
865
  }
@@ -863,7 +878,7 @@ const getValueSuggestions = (
863
878
  default:
864
879
  if (typeof type === 'object') {
865
880
  // value aliases: key is the alias, value is the actual value
866
- for (const key in type) suggestion.push(`'${key}'`)
881
+ for (const key in type) suggestion.push(enquoteString(key))
867
882
  }
868
883
  break
869
884
  }
@@ -29,6 +29,17 @@ const GeneratePureValue = (value: any) => {
29
29
  if (isFinite(num)) {
30
30
  return num
31
31
  }
32
+
33
+ let unquoted = value.replace(/^[^']*'(.*)'[^']*$/, '$1')
34
+ if (unquoted !== value) {
35
+ return unquoted.replace(/\\'/g, "'")
36
+ }
37
+
38
+ unquoted = value.replace(/^[^"]*"(.*)"[^"]*$/, '$1')
39
+ if (unquoted !== value) {
40
+ return unquoted.replace(/\\"/g, '"')
41
+ }
42
+
32
43
  return value.replaceAll('"', '').replaceAll("'", '')
33
44
  } catch (e) {}
34
45
  }
@@ -48,6 +59,14 @@ const Operators: string[] = [
48
59
  'DOESNT-EXIST'
49
60
  ]
50
61
 
62
+ const SplitFirst = (what: string, by: string): string[] => {
63
+ const result = what.split(by)
64
+ if (result.length > 2) {
65
+ return [result.shift(), result.join(by)]
66
+ }
67
+ return result
68
+ }
69
+
51
70
  /**
52
71
  * Method to convert a DlSmartSearch query string to Mongo based JSON query
53
72
  *
@@ -112,66 +131,67 @@ export const parseSmartQuery = (
112
131
  for (const term of andTerms) {
113
132
  pureValue = null
114
133
 
134
+ const termUpToQuote = term.replace(/^([^'"]+)['"].*$/, '$1')
135
+
115
136
  switch (true) {
116
- case term.includes('>='):
117
- ;[key, value] = term.split('>=').map((x) => x.trim())
137
+ case termUpToQuote.includes('>='):
138
+ ;[key, value] = SplitFirst(term, '>=').map((x) => x.trim())
118
139
  pureValue = GeneratePureValue(value)
119
140
  if (pureValue !== null) {
120
141
  andQuery.push({ [key]: { $gte: pureValue } })
121
142
  }
122
143
  break
123
- case term.includes('<='):
124
- ;[key, value] = term.split('<=').map((x) => x.trim())
144
+ case termUpToQuote.includes('<='):
145
+ ;[key, value] = SplitFirst(term, '<=').map((x) => x.trim())
125
146
  pureValue = GeneratePureValue(value)
126
147
  if (pureValue !== null) {
127
148
  andQuery.push({ [key]: { $lte: pureValue } })
128
149
  }
129
150
  break
130
- case term.includes('>'):
131
- ;[key, value] = term.split('>').map((x) => x.trim())
151
+ case termUpToQuote.includes('>'):
152
+ ;[key, value] = SplitFirst(term, '>').map((x) => x.trim())
132
153
  pureValue = GeneratePureValue(value)
133
154
  if (pureValue !== null) {
134
155
  andQuery.push({ [key]: { $gt: pureValue } })
135
156
  }
136
157
  break
137
- case term.includes('<'):
138
- ;[key, value] = term.split('<').map((x) => x.trim())
158
+ case termUpToQuote.includes('<'):
159
+ ;[key, value] = SplitFirst(term, '<').map((x) => x.trim())
139
160
  pureValue = GeneratePureValue(value)
140
161
  if (pureValue !== null) {
141
162
  andQuery.push({ [key]: { $lt: pureValue } })
142
163
  }
143
164
  break
144
- case term.includes('!='):
145
- ;[key, value] = term.split('!=').map((x) => x.trim())
165
+ case termUpToQuote.includes('!='):
166
+ ;[key, value] = SplitFirst(term, '!=').map((x) => x.trim())
146
167
  pureValue = GeneratePureValue(value)
147
168
  if (pureValue !== null) {
148
169
  andQuery.push({ [key]: { $ne: pureValue } })
149
170
  }
150
171
  break
151
- case term.includes('='):
152
- ;[key, value] = term.split('=').map((x) => x.trim())
172
+ case termUpToQuote.includes('='):
173
+ ;[key, value] = SplitFirst(term, '=').map((x) => x.trim())
153
174
  pureValue = GeneratePureValue(value)
154
175
  if (pureValue !== null) {
155
176
  andQuery.push({ [key]: pureValue })
156
177
  }
157
178
  break
158
- case term.includes('EXISTS'):
179
+ case termUpToQuote.includes('EXISTS'):
159
180
  key = term.split('EXISTS')[0].trim()
160
181
  andQuery.push({ [key]: { $exists: true } })
161
182
  break
162
- case term.includes('DOESNT-EXIST'):
183
+ case termUpToQuote.includes('DOESNT-EXIST'):
163
184
  key = term.split('DOESNT-EXIST')[0].trim()
164
185
  andQuery.push({ [key]: { $exists: false } })
165
186
  break
166
- case term.includes('IN'):
167
- ;[key, value] = term.split('IN').map((x) => x.trim())
187
+ case termUpToQuote.includes('IN'):
188
+ ;[key, value] = SplitFirst(term, 'IN').map((x) => x.trim())
168
189
  if (key.includes('NOT-')) {
169
- ;[key, value] = term
170
- .split('NOT-IN')
171
- .map((x) => x.trim())
172
- queryValue = term
173
- .split('NOT-IN')
174
- .map((x) => x.trim())[1]
190
+ ;[key, value] = SplitFirst(term, 'NOT-IN').map((x) =>
191
+ x.trim()
192
+ )
193
+ // TODO make , inside quotes work
194
+ queryValue = value
175
195
  .split(',')
176
196
  .map((x) => GeneratePureValue(x.trim()))
177
197
  .filter((x) => x)
@@ -181,9 +201,8 @@ export const parseSmartQuery = (
181
201
  andQuery.push({ [key]: { $nin: pureValue } })
182
202
  }
183
203
  } else {
184
- queryValue = term
185
- .split('IN')
186
- .map((x) => x.trim())[1]
204
+ // TODO make , inside quotes work
205
+ queryValue = value
187
206
  .split(',')
188
207
  .map((x) => GeneratePureValue(x.trim()))
189
208
  .filter((x) => x)
@@ -344,7 +363,7 @@ export const stringifySmartQuery = (query: { [key: string]: any }): string => {
344
363
  } else if (isDatePattern(value)) {
345
364
  result += `${key} = (${value})`
346
365
  } else {
347
- result += `${key} = '${value}'`
366
+ result += `${key} = '${value.toString().replace(/'/g, "\\'")}'`
348
367
  }
349
368
  }
350
369
 
@@ -3,7 +3,7 @@ export function splitByQuotes(input: string, split: string) {
3
3
  .replace('sp', split)
4
4
  .replace('o', '[\\(\\{\\[]')
5
5
  .replace('c', '[\\)\\}\\]]')
6
- .replace('t', '[\'"]')
6
+ .replace('t', '(?<!\\\\)[\'"]')
7
7
  .replace('e', '[\\\\]')
8
8
  const r = new RegExp(pattern, 'gi')
9
9
  const stack: string[] = []
@@ -13,11 +13,20 @@ export function splitByQuotes(input: string, split: string) {
13
13
  if ($e) {
14
14
  buffer.push($1, $s || $o || $c || $t)
15
15
  return
16
- } else if ($o) stack.push($o)
17
- else if ($c) stack.pop()
18
- else if ($t) {
19
- if (stack[stack.length - 1] !== $t) stack.push($t)
20
- else stack.pop()
16
+ } else if ($o) {
17
+ if (!stack.includes("'") && !stack.includes('"')) {
18
+ stack.push($o)
19
+ }
20
+ } else if ($c) {
21
+ if (!stack.includes("'") && !stack.includes('"')) {
22
+ stack.pop()
23
+ }
24
+ } else if ($t) {
25
+ const otherQuote = $t === '"' ? "'" : '"'
26
+ if (!stack.includes(otherQuote)) {
27
+ if (stack[stack.length - 1] !== $t) stack.push($t)
28
+ else stack.pop()
29
+ }
21
30
  } else {
22
31
  if ($s ? !stack.length : !$1) {
23
32
  buffer.push($1)