lancer-shared 1.2.260 → 1.2.261
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 +104 -35
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.esm.js +104 -37
- package/dist/bundle.esm.js.map +1 -1
- package/dist/schemas/agent/index.d.ts +13 -13
- package/dist/schemas/agent/proposal.d.ts +1 -1
- package/dist/schemas/bidder/bid.d.ts +129 -129
- package/dist/schemas/campaign/campaign-analytics.d.ts +17 -17
- package/dist/schemas/campaign/campaign-search.d.ts +3 -5
- package/dist/schemas/campaign/campaign.d.ts +13 -13
- package/dist/schemas/lead/index.d.ts +57 -54
- package/dist/schemas/lead/lead-status.d.ts +4 -4
- package/dist/schemas/logger/log-event.d.ts +4 -4
- package/dist/schemas/organization/index.d.ts +1 -0
- package/dist/schemas/organization/organization-leads.d.ts +23 -0
- package/dist/schemas/scraper/scrape-payload.d.ts +21 -21
- package/package.json +1 -1
package/dist/bundle.cjs.js
CHANGED
|
@@ -6770,12 +6770,12 @@ const leadSchema = upworkJobSchema
|
|
|
6770
6770
|
biddingTaskScheduled: booleanType().nullable(),
|
|
6771
6771
|
scheduledBiddingTime: numberType().nullable(),
|
|
6772
6772
|
inQueue: booleanType().nullable(),
|
|
6773
|
+
biddingDelayInMinutes: numberType().nullable(),
|
|
6773
6774
|
wonAmount: numberType().optional(),
|
|
6774
6775
|
feedbackCheckTaskId: stringType().nullable(),
|
|
6775
6776
|
bidDecision: z.enum(['proceeded', 'rejected']).nullable(),
|
|
6776
6777
|
rejectedFeedback: stringType().nullable(),
|
|
6777
6778
|
applicationId: stringType().nullable(),
|
|
6778
|
-
campaignName: stringType().optional(),
|
|
6779
6779
|
})
|
|
6780
6780
|
.omit({
|
|
6781
6781
|
processed: true,
|
|
@@ -6814,6 +6814,7 @@ const getCampaignLeadsRequestQuerySchema = z.object({
|
|
|
6814
6814
|
limit: z.number().default(20).optional(),
|
|
6815
6815
|
status: getCampaignLeadsStatusEnum.optional(),
|
|
6816
6816
|
campaignId: z.string().optional(),
|
|
6817
|
+
inQueue: z.boolean().optional(),
|
|
6817
6818
|
});
|
|
6818
6819
|
const getCampaignLeadsResponseSchema = z.object({
|
|
6819
6820
|
data: z.array(leadSchema),
|
|
@@ -6998,6 +6999,21 @@ const onboardingProgressSchema = z.object({
|
|
|
6998
6999
|
startCampaign: z.boolean(),
|
|
6999
7000
|
});
|
|
7000
7001
|
|
|
7002
|
+
const getOrganizationLeadsStatusEnum = z.enum([
|
|
7003
|
+
'all',
|
|
7004
|
+
'suitable',
|
|
7005
|
+
'contacted',
|
|
7006
|
+
'viewed',
|
|
7007
|
+
'replied',
|
|
7008
|
+
]);
|
|
7009
|
+
const getOrganizationLeadsRequestQuerySchema = z.object({
|
|
7010
|
+
cursor: z.string().optional(),
|
|
7011
|
+
limit: z.number().default(20).optional(),
|
|
7012
|
+
status: getOrganizationLeadsStatusEnum.optional(),
|
|
7013
|
+
campaignId: z.string().optional(),
|
|
7014
|
+
inQueue: z.boolean().optional(),
|
|
7015
|
+
});
|
|
7016
|
+
|
|
7001
7017
|
const organizationTypeSchema = z.enum(['agency', 'freelancer']);
|
|
7002
7018
|
const organizationTierEnum = z.enum(['free', 'premium']);
|
|
7003
7019
|
const limitsSchema = objectType({
|
|
@@ -7485,7 +7501,8 @@ const SearchFieldsSchema = z.object({
|
|
|
7485
7501
|
anyWords: z.string().default(''),
|
|
7486
7502
|
noneWords: z.string().default(''),
|
|
7487
7503
|
exactPhrase: z.string().default(''),
|
|
7488
|
-
titleSearch: z.string().default(''),
|
|
7504
|
+
titleSearch: z.string().default(''), // AND logic for titles
|
|
7505
|
+
titleAny: z.string().default(''), // OR logic for titles
|
|
7489
7506
|
skillsSearch: z.string().default(''),
|
|
7490
7507
|
});
|
|
7491
7508
|
class SearchQueryBuilder {
|
|
@@ -7526,17 +7543,15 @@ class SearchQueryBuilder {
|
|
|
7526
7543
|
if (validatedFields.exactPhrase.trim()) {
|
|
7527
7544
|
parts.push(`"${validatedFields.exactPhrase.trim()}"`);
|
|
7528
7545
|
}
|
|
7529
|
-
//
|
|
7546
|
+
// Title searches with proper AND/OR logic
|
|
7530
7547
|
if (validatedFields.titleSearch.trim()) {
|
|
7531
7548
|
const titleTerms = this.splitTerms(validatedFields.titleSearch);
|
|
7532
7549
|
if (titleTerms.length === 1) {
|
|
7533
|
-
// Single term or phrase
|
|
7534
7550
|
const term = titleTerms[0];
|
|
7535
7551
|
const isQuoted = term.startsWith('"') && term.endsWith('"');
|
|
7536
7552
|
parts.push(isQuoted ? `title:${term}` : `title:"${term}"`);
|
|
7537
7553
|
}
|
|
7538
7554
|
else {
|
|
7539
|
-
// Multiple terms - each gets title: prefix
|
|
7540
7555
|
const titleParts = titleTerms.map((term) => {
|
|
7541
7556
|
const isQuoted = term.startsWith('"') && term.endsWith('"');
|
|
7542
7557
|
return isQuoted ? `title:${term}` : `title:"${term}"`;
|
|
@@ -7544,6 +7559,21 @@ class SearchQueryBuilder {
|
|
|
7544
7559
|
parts.push(`(${titleParts.join(' AND ')})`);
|
|
7545
7560
|
}
|
|
7546
7561
|
}
|
|
7562
|
+
if (validatedFields.titleAny.trim()) {
|
|
7563
|
+
const titleTerms = this.splitTerms(validatedFields.titleAny);
|
|
7564
|
+
if (titleTerms.length === 1) {
|
|
7565
|
+
const term = titleTerms[0];
|
|
7566
|
+
const isQuoted = term.startsWith('"') && term.endsWith('"');
|
|
7567
|
+
parts.push(isQuoted ? `title:${term}` : `title:"${term}"`);
|
|
7568
|
+
}
|
|
7569
|
+
else {
|
|
7570
|
+
const titleParts = titleTerms.map((term) => {
|
|
7571
|
+
const isQuoted = term.startsWith('"') && term.endsWith('"');
|
|
7572
|
+
return isQuoted ? `title:${term}` : `title:"${term}"`;
|
|
7573
|
+
});
|
|
7574
|
+
parts.push(`(${titleParts.join(' OR ')})`);
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7547
7577
|
if (validatedFields.skillsSearch.trim()) {
|
|
7548
7578
|
const skillsTerms = this.splitTerms(validatedFields.skillsSearch);
|
|
7549
7579
|
if (skillsTerms.length === 1) {
|
|
@@ -7576,7 +7606,9 @@ class SearchQueryBuilder {
|
|
|
7576
7606
|
if (validatedFields.exactPhrase)
|
|
7577
7607
|
descriptions.push(`Exact phrase: "${validatedFields.exactPhrase}"`);
|
|
7578
7608
|
if (validatedFields.titleSearch)
|
|
7579
|
-
descriptions.push(`
|
|
7609
|
+
descriptions.push(`Title (all): ${validatedFields.titleSearch}`);
|
|
7610
|
+
if (validatedFields.titleAny)
|
|
7611
|
+
descriptions.push(`Title (any): ${validatedFields.titleAny}`);
|
|
7580
7612
|
if (validatedFields.skillsSearch)
|
|
7581
7613
|
descriptions.push(`Skills: ${validatedFields.skillsSearch}`);
|
|
7582
7614
|
return descriptions.length > 0 ? descriptions.join(' • ') : 'All results';
|
|
@@ -7594,24 +7626,6 @@ class SearchQueryBuilder {
|
|
|
7594
7626
|
errors: result.error.errors.map((err) => `${err.path.join('.')}: ${err.message}`),
|
|
7595
7627
|
};
|
|
7596
7628
|
}
|
|
7597
|
-
/**
|
|
7598
|
-
* Test/demo method to show phrase handling
|
|
7599
|
-
* Remove this in production
|
|
7600
|
-
*/
|
|
7601
|
-
static examples() {
|
|
7602
|
-
const testFields = {
|
|
7603
|
-
allWords: 'react "senior developer" javascript',
|
|
7604
|
-
anyWords: 'frontend "full stack" backend',
|
|
7605
|
-
noneWords: 'junior "entry level"',
|
|
7606
|
-
exactPhrase: 'tech lead',
|
|
7607
|
-
titleSearch: 'software engineer',
|
|
7608
|
-
skillsSearch: 'node.js',
|
|
7609
|
-
};
|
|
7610
|
-
console.log('Query:', this.buildQuery(testFields));
|
|
7611
|
-
console.log('Description:', this.describe(testFields));
|
|
7612
|
-
// Should produce:
|
|
7613
|
-
// Query: (react AND "senior developer" AND javascript) AND (frontend OR "full stack" OR backend) AND NOT junior AND NOT "entry level" AND "tech lead" AND title:"software engineer" AND skills:"node.js"
|
|
7614
|
-
}
|
|
7615
7629
|
/**
|
|
7616
7630
|
* Parse a query string back into SearchFields structure
|
|
7617
7631
|
* Fixed to handle grouped NOT expressions correctly
|
|
@@ -7623,13 +7637,40 @@ class SearchQueryBuilder {
|
|
|
7623
7637
|
noneWords: '',
|
|
7624
7638
|
exactPhrase: '',
|
|
7625
7639
|
titleSearch: '',
|
|
7640
|
+
titleAny: '',
|
|
7626
7641
|
skillsSearch: '',
|
|
7627
7642
|
};
|
|
7628
7643
|
if (!query || query.trim() === '*') {
|
|
7629
7644
|
return result;
|
|
7630
7645
|
}
|
|
7631
7646
|
let remainingQuery = query.trim();
|
|
7632
|
-
// 1. Extract
|
|
7647
|
+
// 1. FIRST: Extract grouped expressions like (title:"a" OR title:"b") or (title:"a" AND title:"b")
|
|
7648
|
+
const titleGroupPattern = /\((title:"[^"]+"(?:\s+(?:OR|AND)\s+title:"[^"]+")+)\)/g;
|
|
7649
|
+
const titleGroupMatches = [...remainingQuery.matchAll(titleGroupPattern)];
|
|
7650
|
+
for (const match of titleGroupMatches) {
|
|
7651
|
+
const groupContent = match[1]; // e.g., 'title:"developer" OR title:"expert"'
|
|
7652
|
+
if (groupContent.includes(' OR ')) {
|
|
7653
|
+
// Extract terms from OR group for titleAny
|
|
7654
|
+
const terms = groupContent
|
|
7655
|
+
.split(/\s+OR\s+/)
|
|
7656
|
+
.map((term) => term.replace(/^title:"([^"]+)"$/, '"$1"'))
|
|
7657
|
+
.filter(Boolean);
|
|
7658
|
+
result.titleAny = terms.join(' ');
|
|
7659
|
+
}
|
|
7660
|
+
else if (groupContent.includes(' AND ')) {
|
|
7661
|
+
// Extract terms from AND group for titleSearch
|
|
7662
|
+
const terms = groupContent
|
|
7663
|
+
.split(/\s+AND\s+/)
|
|
7664
|
+
.map((term) => term.replace(/^title:"([^"]+)"$/, '"$1"'))
|
|
7665
|
+
.filter(Boolean);
|
|
7666
|
+
result.titleSearch = result.titleSearch
|
|
7667
|
+
? `${result.titleSearch} ${terms.join(' ')}`
|
|
7668
|
+
: terms.join(' ');
|
|
7669
|
+
}
|
|
7670
|
+
// Remove the matched group from remaining query
|
|
7671
|
+
remainingQuery = remainingQuery.replace(match[0], '').trim();
|
|
7672
|
+
}
|
|
7673
|
+
// 2. THEN: Extract individual title: and skills: patterns
|
|
7633
7674
|
const fieldPatterns = [
|
|
7634
7675
|
{ field: 'titleSearch', pattern: /title:("([^"]+)"|([^\s)]+))/g },
|
|
7635
7676
|
{ field: 'skillsSearch', pattern: /skills:("([^"]+)"|([^\s)]+))/g },
|
|
@@ -7643,21 +7684,46 @@ class SearchQueryBuilder {
|
|
|
7643
7684
|
}
|
|
7644
7685
|
return match[3];
|
|
7645
7686
|
});
|
|
7646
|
-
|
|
7687
|
+
if (field === 'titleSearch') {
|
|
7688
|
+
result.titleSearch = result.titleSearch
|
|
7689
|
+
? `${result.titleSearch} ${terms.join(' ')}`
|
|
7690
|
+
: terms.join(' ');
|
|
7691
|
+
}
|
|
7692
|
+
else {
|
|
7693
|
+
result[field] = terms.join(' ');
|
|
7694
|
+
}
|
|
7647
7695
|
remainingQuery = remainingQuery.replace(pattern, '').trim();
|
|
7648
7696
|
}
|
|
7649
7697
|
}
|
|
7650
|
-
//
|
|
7698
|
+
// 3. Handle legacy grouped field searches like title:(term1 AND term2)
|
|
7651
7699
|
const groupedFieldPattern = /(title|skills):\(([^)]+)\)/g;
|
|
7652
7700
|
let groupMatch;
|
|
7653
7701
|
while ((groupMatch = groupedFieldPattern.exec(remainingQuery)) !== null) {
|
|
7654
|
-
const
|
|
7702
|
+
const fieldType = groupMatch[1];
|
|
7655
7703
|
const groupContent = groupMatch[2];
|
|
7656
|
-
|
|
7657
|
-
|
|
7704
|
+
if (fieldType === 'title') {
|
|
7705
|
+
// Check if it's OR logic (titleAny) or AND logic (titleSearch)
|
|
7706
|
+
if (groupContent.includes(' OR ')) {
|
|
7707
|
+
const terms = this.extractTermsFromGroup(groupContent, fieldType);
|
|
7708
|
+
result.titleAny = result.titleAny
|
|
7709
|
+
? `${result.titleAny} ${terms.join(' ')}`
|
|
7710
|
+
: terms.join(' ');
|
|
7711
|
+
}
|
|
7712
|
+
else {
|
|
7713
|
+
const terms = this.extractTermsFromGroup(groupContent, fieldType);
|
|
7714
|
+
result.titleSearch = result.titleSearch
|
|
7715
|
+
? `${result.titleSearch} ${terms.join(' ')}`
|
|
7716
|
+
: terms.join(' ');
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
else {
|
|
7720
|
+
// skills logic remains the same
|
|
7721
|
+
const terms = this.extractTermsFromGroup(groupContent, fieldType);
|
|
7722
|
+
result.skillsSearch = terms.join(' ');
|
|
7723
|
+
}
|
|
7658
7724
|
remainingQuery = remainingQuery.replace(groupMatch[0], '').trim();
|
|
7659
7725
|
}
|
|
7660
|
-
//
|
|
7726
|
+
// 4. Extract grouped NOT expressions: NOT (term1 OR term2 OR ...)
|
|
7661
7727
|
const groupedNotPattern = /NOT\s+\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
|
|
7662
7728
|
const groupedNotMatches = [...remainingQuery.matchAll(groupedNotPattern)];
|
|
7663
7729
|
if (groupedNotMatches.length > 0) {
|
|
@@ -7667,7 +7733,7 @@ class SearchQueryBuilder {
|
|
|
7667
7733
|
.replace(groupedNotMatches[0][0], '')
|
|
7668
7734
|
.trim();
|
|
7669
7735
|
}
|
|
7670
|
-
//
|
|
7736
|
+
// 5. Extract individual NOT terms (only if no grouped NOT was found)
|
|
7671
7737
|
if (!result.noneWords) {
|
|
7672
7738
|
const notPattern = /NOT\s+("([^"]+)"|([^\s)]+))/g;
|
|
7673
7739
|
const notMatches = [...remainingQuery.matchAll(notPattern)];
|
|
@@ -7682,7 +7748,7 @@ class SearchQueryBuilder {
|
|
|
7682
7748
|
remainingQuery = remainingQuery.replace(notPattern, '').trim();
|
|
7683
7749
|
}
|
|
7684
7750
|
}
|
|
7685
|
-
//
|
|
7751
|
+
// 6. Process grouped expressions - DON'T clean up connectors first!
|
|
7686
7752
|
// Extract OR groups (anyWords) - PROCESS FIRST
|
|
7687
7753
|
const orGroupPattern = /\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
|
|
7688
7754
|
const orMatches = [...remainingQuery.matchAll(orGroupPattern)];
|
|
@@ -7701,14 +7767,14 @@ class SearchQueryBuilder {
|
|
|
7701
7767
|
}
|
|
7702
7768
|
// NOW clean up connectors after group processing
|
|
7703
7769
|
remainingQuery = this.cleanupConnectors(remainingQuery);
|
|
7704
|
-
//
|
|
7770
|
+
// 7. Extract standalone quoted phrases (exactPhrase) - ONLY after all groups processed
|
|
7705
7771
|
const standaloneQuotePattern = /(?:^|\s)("([^"]+)")(?=\s|$)/g;
|
|
7706
7772
|
const quoteMatches = [...remainingQuery.matchAll(standaloneQuotePattern)];
|
|
7707
7773
|
if (quoteMatches.length > 0) {
|
|
7708
7774
|
result.exactPhrase = quoteMatches[0][2];
|
|
7709
7775
|
remainingQuery = remainingQuery.replace(quoteMatches[0][1], '').trim();
|
|
7710
7776
|
}
|
|
7711
|
-
//
|
|
7777
|
+
// 8. Handle remaining simple terms as allWords
|
|
7712
7778
|
if (remainingQuery) {
|
|
7713
7779
|
const remainingTerms = this.splitTermsWithQuotes(remainingQuery);
|
|
7714
7780
|
if (remainingTerms.length > 0) {
|
|
@@ -7791,6 +7857,7 @@ class SearchQueryBuilder {
|
|
|
7791
7857
|
return query
|
|
7792
7858
|
.replace(/\s+AND\s+/g, ' ')
|
|
7793
7859
|
.replace(/\s+/g, ' ')
|
|
7860
|
+
.replace(/\(\s*\)/g, '')
|
|
7794
7861
|
.trim();
|
|
7795
7862
|
}
|
|
7796
7863
|
/**
|
|
@@ -24029,6 +24096,8 @@ exports.getCampaignLeadsResponseSchema = getCampaignLeadsResponseSchema;
|
|
|
24029
24096
|
exports.getCampaignLeadsStatusEnum = getCampaignLeadsStatusEnum;
|
|
24030
24097
|
exports.getMultiloginBrowserException = getMultiloginBrowserException;
|
|
24031
24098
|
exports.getNextStatus = getNextStatus;
|
|
24099
|
+
exports.getOrganizationLeadsRequestQuerySchema = getOrganizationLeadsRequestQuerySchema;
|
|
24100
|
+
exports.getOrganizationLeadsStatusEnum = getOrganizationLeadsStatusEnum;
|
|
24032
24101
|
exports.getPreviousStatus = getPreviousStatus;
|
|
24033
24102
|
exports.getRouteWithoutAdminPrefix = getRouteWithoutAdminPrefix;
|
|
24034
24103
|
exports.getSamplesRequestSchema = getSamplesRequestSchema;
|