lancer-shared 1.2.328 → 1.2.330
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/dist/bundle.cjs.js +73 -39
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.esm.js +73 -39
- package/dist/bundle.esm.js.map +1 -1
- package/dist/constants/chat.d.ts +5 -5
- package/dist/schemas/campaign/campaign-search.d.ts +3 -0
- package/dist/schemas/chat/index.d.ts +12 -12
- package/package.json +1 -1
package/dist/bundle.cjs.js
CHANGED
|
@@ -9,41 +9,41 @@ const ROOM_TYPES_MATCHING_EMPTY_EXTENDED_TYPE = new Set([
|
|
|
9
9
|
'proposal',
|
|
10
10
|
]);
|
|
11
11
|
const ROOM_CRM_STATUS_ORDER = [
|
|
12
|
-
'
|
|
12
|
+
'new',
|
|
13
|
+
'qualified',
|
|
13
14
|
'follow_up',
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'closed',
|
|
15
|
+
'won',
|
|
16
|
+
'archived',
|
|
17
17
|
];
|
|
18
18
|
const ROOM_CRM_STATUS_LABELS = {
|
|
19
|
-
|
|
20
|
-
interested: 'Interested',
|
|
19
|
+
new: 'New',
|
|
21
20
|
follow_up: 'Follow Up',
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
qualified: 'Qualified',
|
|
22
|
+
won: 'Won',
|
|
23
|
+
archived: 'Archived',
|
|
24
24
|
};
|
|
25
|
-
const DEFAULT_ROOM_CRM_STATUS = '
|
|
25
|
+
const DEFAULT_ROOM_CRM_STATUS = 'new';
|
|
26
26
|
const ROOM_CRM_STATUS_IDS = {
|
|
27
|
-
|
|
27
|
+
new: 1,
|
|
28
28
|
follow_up: 2,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
qualified: 3,
|
|
30
|
+
won: 4,
|
|
31
|
+
archived: 5,
|
|
32
32
|
};
|
|
33
33
|
const ROOM_CRM_STATUS_BY_ID = {
|
|
34
|
-
1: '
|
|
34
|
+
1: 'new',
|
|
35
35
|
2: 'follow_up',
|
|
36
|
-
3: '
|
|
37
|
-
4: '
|
|
38
|
-
5: '
|
|
36
|
+
3: 'qualified',
|
|
37
|
+
4: 'won',
|
|
38
|
+
5: 'archived',
|
|
39
39
|
};
|
|
40
40
|
// Explicit board order avoids scattered "exclude then append" logic in consumers.
|
|
41
41
|
const ROOM_CRM_KANBAN_STATUS_ORDER = [
|
|
42
|
-
'
|
|
42
|
+
'new',
|
|
43
|
+
'qualified',
|
|
43
44
|
'follow_up',
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'not_interested',
|
|
45
|
+
'won',
|
|
46
|
+
'archived',
|
|
47
47
|
];
|
|
48
48
|
const isRoomCrmStatus = (status) => {
|
|
49
49
|
return ROOM_CRM_STATUS_ORDER.includes(status);
|
|
@@ -53,9 +53,6 @@ const normalizeRoomCrmStatus = (status) => {
|
|
|
53
53
|
return DEFAULT_ROOM_CRM_STATUS;
|
|
54
54
|
}
|
|
55
55
|
const normalizedStatus = status.trim().toLowerCase();
|
|
56
|
-
if (normalizedStatus === 'archived') {
|
|
57
|
-
return 'closed';
|
|
58
|
-
}
|
|
59
56
|
if (isRoomCrmStatus(normalizedStatus)) {
|
|
60
57
|
return normalizedStatus;
|
|
61
58
|
}
|
|
@@ -70,9 +67,6 @@ const normalizeRoomCrmStatuses = (statuses) => {
|
|
|
70
67
|
if (!normalizedStatus) {
|
|
71
68
|
return null;
|
|
72
69
|
}
|
|
73
|
-
if (normalizedStatus === 'archived') {
|
|
74
|
-
return 'closed';
|
|
75
|
-
}
|
|
76
70
|
if (isRoomCrmStatus(normalizedStatus)) {
|
|
77
71
|
return normalizedStatus;
|
|
78
72
|
}
|
|
@@ -7832,6 +7826,7 @@ const SearchFieldsSchema = z.object({
|
|
|
7832
7826
|
exactPhrase: z.string().default(''),
|
|
7833
7827
|
titleSearch: z.string().default(''), // AND logic for titles
|
|
7834
7828
|
titleAny: z.string().default(''), // OR logic for titles
|
|
7829
|
+
titleNoneAny: z.string().default(''), // NOT logic for titles
|
|
7835
7830
|
skillsSearch: z.string().default(''),
|
|
7836
7831
|
});
|
|
7837
7832
|
class SearchQueryBuilder {
|
|
@@ -7903,6 +7898,14 @@ class SearchQueryBuilder {
|
|
|
7903
7898
|
parts.push(`(${titleParts.join(' OR ')})`);
|
|
7904
7899
|
}
|
|
7905
7900
|
}
|
|
7901
|
+
if (validatedFields.titleNoneAny.trim()) {
|
|
7902
|
+
const titleTerms = this.splitTerms(validatedFields.titleNoneAny);
|
|
7903
|
+
const titleNotParts = titleTerms.map((term) => {
|
|
7904
|
+
const isQuoted = term.startsWith('"') && term.endsWith('"');
|
|
7905
|
+
return isQuoted ? `NOT title:${term}` : `NOT title:"${term}"`;
|
|
7906
|
+
});
|
|
7907
|
+
parts.push(...titleNotParts);
|
|
7908
|
+
}
|
|
7906
7909
|
if (validatedFields.skillsSearch.trim()) {
|
|
7907
7910
|
const skillsTerms = this.splitTerms(validatedFields.skillsSearch);
|
|
7908
7911
|
if (skillsTerms.length === 1) {
|
|
@@ -7938,6 +7941,8 @@ class SearchQueryBuilder {
|
|
|
7938
7941
|
descriptions.push(`Title (all): ${validatedFields.titleSearch}`);
|
|
7939
7942
|
if (validatedFields.titleAny)
|
|
7940
7943
|
descriptions.push(`Title (any): ${validatedFields.titleAny}`);
|
|
7944
|
+
if (validatedFields.titleNoneAny)
|
|
7945
|
+
descriptions.push(`Title (excluding any): ${validatedFields.titleNoneAny}`);
|
|
7941
7946
|
if (validatedFields.skillsSearch)
|
|
7942
7947
|
descriptions.push(`Skills: ${validatedFields.skillsSearch}`);
|
|
7943
7948
|
return descriptions.length > 0 ? descriptions.join(' • ') : 'All results';
|
|
@@ -7967,6 +7972,7 @@ class SearchQueryBuilder {
|
|
|
7967
7972
|
exactPhrase: '',
|
|
7968
7973
|
titleSearch: '',
|
|
7969
7974
|
titleAny: '',
|
|
7975
|
+
titleNoneAny: '',
|
|
7970
7976
|
skillsSearch: '',
|
|
7971
7977
|
};
|
|
7972
7978
|
if (!query || query.trim() === '*') {
|
|
@@ -7999,7 +8005,35 @@ class SearchQueryBuilder {
|
|
|
7999
8005
|
// Remove the matched group from remaining query
|
|
8000
8006
|
remainingQuery = remainingQuery.replace(match[0], '').trim();
|
|
8001
8007
|
}
|
|
8002
|
-
// 2. THEN: Extract
|
|
8008
|
+
// 2. THEN: Extract NOT title groups like NOT (title:"a" OR title:"b")
|
|
8009
|
+
const titleNotGroupPattern = /NOT\s+\((title:"[^"]+"(?:\s+OR\s+title:"[^"]+")+?)\)/g;
|
|
8010
|
+
const titleNotGroupMatches = [...remainingQuery.matchAll(titleNotGroupPattern)];
|
|
8011
|
+
for (const match of titleNotGroupMatches) {
|
|
8012
|
+
const terms = match[1]
|
|
8013
|
+
.split(/\s+OR\s+/)
|
|
8014
|
+
.map((term) => term.replace(/^title:"([^"]+)"$/, '"$1"'))
|
|
8015
|
+
.filter(Boolean);
|
|
8016
|
+
result.titleNoneAny = result.titleNoneAny
|
|
8017
|
+
? `${result.titleNoneAny} ${terms.join(' ')}`
|
|
8018
|
+
: terms.join(' ');
|
|
8019
|
+
remainingQuery = remainingQuery.replace(match[0], '').trim();
|
|
8020
|
+
}
|
|
8021
|
+
// 3. Extract individual NOT title: terms before generic title extraction
|
|
8022
|
+
const titleNotPattern = /NOT\s+title:("([^"]+)"|([^\s)]+))/g;
|
|
8023
|
+
const titleNotMatches = [...remainingQuery.matchAll(titleNotPattern)];
|
|
8024
|
+
if (titleNotMatches.length > 0) {
|
|
8025
|
+
const terms = titleNotMatches.map((match) => {
|
|
8026
|
+
if (match[2]) {
|
|
8027
|
+
return `"${match[2]}"`;
|
|
8028
|
+
}
|
|
8029
|
+
return match[3];
|
|
8030
|
+
});
|
|
8031
|
+
result.titleNoneAny = result.titleNoneAny
|
|
8032
|
+
? `${result.titleNoneAny} ${terms.join(' ')}`
|
|
8033
|
+
: terms.join(' ');
|
|
8034
|
+
remainingQuery = remainingQuery.replace(titleNotPattern, '').trim();
|
|
8035
|
+
}
|
|
8036
|
+
// 4. THEN: Extract individual title: and skills: patterns
|
|
8003
8037
|
const fieldPatterns = [
|
|
8004
8038
|
{ field: 'titleSearch', pattern: /title:("([^"]+)"|([^\s)]+))/g },
|
|
8005
8039
|
{ field: 'skillsSearch', pattern: /skills:("([^"]+)"|([^\s)]+))/g },
|
|
@@ -8024,7 +8058,7 @@ class SearchQueryBuilder {
|
|
|
8024
8058
|
remainingQuery = remainingQuery.replace(pattern, '').trim();
|
|
8025
8059
|
}
|
|
8026
8060
|
}
|
|
8027
|
-
//
|
|
8061
|
+
// 5. Handle legacy grouped field searches like title:(term1 AND term2)
|
|
8028
8062
|
const groupedFieldPattern = /(title|skills):\(([^)]+)\)/g;
|
|
8029
8063
|
let groupMatch;
|
|
8030
8064
|
while ((groupMatch = groupedFieldPattern.exec(remainingQuery)) !== null) {
|
|
@@ -8052,7 +8086,7 @@ class SearchQueryBuilder {
|
|
|
8052
8086
|
}
|
|
8053
8087
|
remainingQuery = remainingQuery.replace(groupMatch[0], '').trim();
|
|
8054
8088
|
}
|
|
8055
|
-
//
|
|
8089
|
+
// 6. Extract grouped NOT expressions: NOT (term1 OR term2 OR ...)
|
|
8056
8090
|
const groupedNotPattern = /NOT\s+\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
|
|
8057
8091
|
const groupedNotMatches = [...remainingQuery.matchAll(groupedNotPattern)];
|
|
8058
8092
|
if (groupedNotMatches.length > 0) {
|
|
@@ -8062,9 +8096,9 @@ class SearchQueryBuilder {
|
|
|
8062
8096
|
.replace(groupedNotMatches[0][0], '')
|
|
8063
8097
|
.trim();
|
|
8064
8098
|
}
|
|
8065
|
-
//
|
|
8099
|
+
// 7. Extract individual NOT terms (only if no grouped NOT was found)
|
|
8066
8100
|
if (!result.noneWords) {
|
|
8067
|
-
const notPattern = /NOT\s+("([^"]+)"|([^\s)]+))/g;
|
|
8101
|
+
const notPattern = /NOT\s+(?!title:)("([^"]+)"|([^\s)]+))/g;
|
|
8068
8102
|
const notMatches = [...remainingQuery.matchAll(notPattern)];
|
|
8069
8103
|
if (notMatches.length > 0) {
|
|
8070
8104
|
const noneTerms = notMatches.map((match) => {
|
|
@@ -8077,7 +8111,7 @@ class SearchQueryBuilder {
|
|
|
8077
8111
|
remainingQuery = remainingQuery.replace(notPattern, '').trim();
|
|
8078
8112
|
}
|
|
8079
8113
|
}
|
|
8080
|
-
//
|
|
8114
|
+
// 8. Process grouped expressions - DON'T clean up connectors first!
|
|
8081
8115
|
// Extract OR groups (anyWords) - PROCESS FIRST
|
|
8082
8116
|
const orGroupPattern = /\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
|
|
8083
8117
|
const orMatches = [...remainingQuery.matchAll(orGroupPattern)];
|
|
@@ -8096,14 +8130,14 @@ class SearchQueryBuilder {
|
|
|
8096
8130
|
}
|
|
8097
8131
|
// NOW clean up connectors after group processing
|
|
8098
8132
|
remainingQuery = this.cleanupConnectors(remainingQuery);
|
|
8099
|
-
//
|
|
8133
|
+
// 9. Extract standalone quoted phrases (exactPhrase) - ONLY after all groups processed
|
|
8100
8134
|
const standaloneQuotePattern = /(?:^|\s)("([^"]+)")(?=\s|$)/g;
|
|
8101
8135
|
const quoteMatches = [...remainingQuery.matchAll(standaloneQuotePattern)];
|
|
8102
8136
|
if (quoteMatches.length > 0) {
|
|
8103
8137
|
result.exactPhrase = quoteMatches[0][2];
|
|
8104
8138
|
remainingQuery = remainingQuery.replace(quoteMatches[0][1], '').trim();
|
|
8105
8139
|
}
|
|
8106
|
-
//
|
|
8140
|
+
// 10. Handle remaining simple terms as allWords
|
|
8107
8141
|
if (remainingQuery) {
|
|
8108
8142
|
const remainingTerms = this.splitTermsWithQuotes(remainingQuery);
|
|
8109
8143
|
if (remainingTerms.length > 0) {
|
|
@@ -8845,11 +8879,11 @@ const roomNoteSchema = z.object({
|
|
|
8845
8879
|
updatedAt: z.number(),
|
|
8846
8880
|
});
|
|
8847
8881
|
const roomCrmStatusEnum = z.enum([
|
|
8848
|
-
'
|
|
8849
|
-
'interested',
|
|
8882
|
+
'new',
|
|
8850
8883
|
'follow_up',
|
|
8851
|
-
'
|
|
8852
|
-
'
|
|
8884
|
+
'qualified',
|
|
8885
|
+
'won',
|
|
8886
|
+
'archived',
|
|
8853
8887
|
]);
|
|
8854
8888
|
const roomJobClientHistorySchema = z.object({
|
|
8855
8889
|
jobUrl: z.string().nullable(),
|