lancer-shared 1.2.192 → 1.2.194

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.
@@ -11136,6 +11136,7 @@ const jobFiltersSchema = z.object({
11136
11136
  excludes: z.string().nullable(),
11137
11137
  })
11138
11138
  .nullable(),
11139
+ searchQuery: z.string().nullable(),
11139
11140
  isFeatured: z.enum(['all', 'true', 'false']).nullable(),
11140
11141
  regions: z.array(regionEnum).nullable(),
11141
11142
  categories: z
@@ -13107,6 +13108,7 @@ const campaignSchema = z.object({
13107
13108
  // automatedSuitability: z.boolean().nullable(),
13108
13109
  boostingEnabled: z.boolean().nullable().default(false),
13109
13110
  maximumBoost: z.number().nullable().default(30),
13111
+ minBoost: z.number().nullable().default(1),
13110
13112
  boostDownToNthPlace: z.number().min(1).max(4).nullable(),
13111
13113
  connectsAbovePrevious: z.number().min(1).nullable(),
13112
13114
  insufficeintBoostConnectsAction: insufficeintBoostConnectsActionEnum,
@@ -13406,6 +13408,354 @@ const campaignInsightsSchema = z.object({
13406
13408
  suitabilityRange90to100: z.number(),
13407
13409
  });
13408
13410
 
13411
+ // Clean, validated schema using Zod
13412
+ const SearchFieldsSchema = z.object({
13413
+ allWords: z.string().default(''),
13414
+ anyWords: z.string().default(''),
13415
+ noneWords: z.string().default(''),
13416
+ exactPhrase: z.string().default(''),
13417
+ titleSearch: z.string().default(''),
13418
+ skillsSearch: z.string().default(''),
13419
+ });
13420
+ class SearchQueryBuilder {
13421
+ /**
13422
+ * Build a search query from structured fields
13423
+ * Properly handles quoted phrases in all fields
13424
+ */
13425
+ static buildQuery(fields) {
13426
+ const validatedFields = SearchFieldsSchema.parse(fields);
13427
+ const parts = [];
13428
+ // All words (AND logic) - supports phrases
13429
+ if (validatedFields.allWords.trim()) {
13430
+ const terms = this.splitTerms(validatedFields.allWords);
13431
+ if (terms.length === 1) {
13432
+ parts.push(terms[0]);
13433
+ }
13434
+ else if (terms.length > 1) {
13435
+ parts.push(`(${terms.join(' AND ')})`);
13436
+ }
13437
+ }
13438
+ // Any words (OR logic) - supports phrases
13439
+ if (validatedFields.anyWords.trim()) {
13440
+ const terms = this.splitTerms(validatedFields.anyWords);
13441
+ if (terms.length === 1) {
13442
+ parts.push(terms[0]);
13443
+ }
13444
+ else if (terms.length > 1) {
13445
+ parts.push(`(${terms.join(' OR ')})`);
13446
+ }
13447
+ }
13448
+ // Excluded words (NOT logic) - supports phrases
13449
+ if (validatedFields.noneWords.trim()) {
13450
+ const terms = this.splitTerms(validatedFields.noneWords);
13451
+ const notParts = terms.map((term) => `NOT ${term}`);
13452
+ parts.push(...notParts);
13453
+ }
13454
+ // Exact phrase - single phrase only
13455
+ if (validatedFields.exactPhrase.trim()) {
13456
+ parts.push(`"${validatedFields.exactPhrase.trim()}"`);
13457
+ }
13458
+ // Field-specific searches - now support phrases too
13459
+ if (validatedFields.titleSearch.trim()) {
13460
+ const titleTerms = this.splitTerms(validatedFields.titleSearch);
13461
+ if (titleTerms.length === 1) {
13462
+ // Single term or phrase
13463
+ const term = titleTerms[0];
13464
+ const isQuoted = term.startsWith('"') && term.endsWith('"');
13465
+ parts.push(isQuoted ? `title:${term}` : `title:"${term}"`);
13466
+ }
13467
+ else {
13468
+ // Multiple terms - each gets title: prefix
13469
+ const titleParts = titleTerms.map((term) => {
13470
+ const isQuoted = term.startsWith('"') && term.endsWith('"');
13471
+ return isQuoted ? `title:${term}` : `title:"${term}"`;
13472
+ });
13473
+ parts.push(`(${titleParts.join(' AND ')})`);
13474
+ }
13475
+ }
13476
+ if (validatedFields.skillsSearch.trim()) {
13477
+ const skillsTerms = this.splitTerms(validatedFields.skillsSearch);
13478
+ if (skillsTerms.length === 1) {
13479
+ const term = skillsTerms[0];
13480
+ const isQuoted = term.startsWith('"') && term.endsWith('"');
13481
+ parts.push(isQuoted ? `skills:${term}` : `skills:"${term}"`);
13482
+ }
13483
+ else {
13484
+ const skillsParts = skillsTerms.map((term) => {
13485
+ const isQuoted = term.startsWith('"') && term.endsWith('"');
13486
+ return isQuoted ? `skills:${term}` : `skills:"${term}"`;
13487
+ });
13488
+ parts.push(`(${skillsParts.join(' AND ')})`);
13489
+ }
13490
+ }
13491
+ return parts.join(' AND ').trim() || '*';
13492
+ }
13493
+ /**
13494
+ * Get human-readable description of search criteria
13495
+ */
13496
+ static describe(fields) {
13497
+ const validatedFields = SearchFieldsSchema.parse(fields);
13498
+ const descriptions = [];
13499
+ if (validatedFields.allWords)
13500
+ descriptions.push(`All words: ${validatedFields.allWords}`);
13501
+ if (validatedFields.anyWords)
13502
+ descriptions.push(`Any words: ${validatedFields.anyWords}`);
13503
+ if (validatedFields.noneWords)
13504
+ descriptions.push(`Excluding: ${validatedFields.noneWords}`);
13505
+ if (validatedFields.exactPhrase)
13506
+ descriptions.push(`Exact phrase: "${validatedFields.exactPhrase}"`);
13507
+ if (validatedFields.titleSearch)
13508
+ descriptions.push(`In title: ${validatedFields.titleSearch}`);
13509
+ if (validatedFields.skillsSearch)
13510
+ descriptions.push(`Skills: ${validatedFields.skillsSearch}`);
13511
+ return descriptions.length > 0 ? descriptions.join(' • ') : 'All results';
13512
+ }
13513
+ /**
13514
+ * Validate search fields
13515
+ */
13516
+ static validate(fields) {
13517
+ const result = SearchFieldsSchema.safeParse(fields);
13518
+ if (result.success) {
13519
+ return { valid: true, data: result.data };
13520
+ }
13521
+ return {
13522
+ valid: false,
13523
+ errors: result.error.errors.map((err) => `${err.path.join('.')}: ${err.message}`),
13524
+ };
13525
+ }
13526
+ /**
13527
+ * Test/demo method to show phrase handling
13528
+ * Remove this in production
13529
+ */
13530
+ static examples() {
13531
+ const testFields = {
13532
+ allWords: 'react "senior developer" javascript',
13533
+ anyWords: 'frontend "full stack" backend',
13534
+ noneWords: 'junior "entry level"',
13535
+ exactPhrase: 'tech lead',
13536
+ titleSearch: 'software engineer',
13537
+ skillsSearch: 'node.js',
13538
+ };
13539
+ console.log('Query:', this.buildQuery(testFields));
13540
+ console.log('Description:', this.describe(testFields));
13541
+ // Should produce:
13542
+ // 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"
13543
+ }
13544
+ /**
13545
+ * Parse a query string back into SearchFields structure
13546
+ * Fixed to handle grouped NOT expressions correctly
13547
+ */
13548
+ static parseQuery(query) {
13549
+ const result = {
13550
+ allWords: '',
13551
+ anyWords: '',
13552
+ noneWords: '',
13553
+ exactPhrase: '',
13554
+ titleSearch: '',
13555
+ skillsSearch: '',
13556
+ };
13557
+ if (!query || query.trim() === '*') {
13558
+ return result;
13559
+ }
13560
+ let remainingQuery = query.trim();
13561
+ // 1. Extract field-specific searches first
13562
+ const fieldPatterns = [
13563
+ { field: 'titleSearch', pattern: /title:("([^"]+)"|([^\s)]+))/g },
13564
+ { field: 'skillsSearch', pattern: /skills:("([^"]+)"|([^\s)]+))/g },
13565
+ ];
13566
+ for (const { field, pattern } of fieldPatterns) {
13567
+ const matches = [...remainingQuery.matchAll(pattern)];
13568
+ if (matches.length > 0) {
13569
+ const terms = matches.map((match) => {
13570
+ if (match[2]) {
13571
+ return `"${match[2]}"`;
13572
+ }
13573
+ return match[3];
13574
+ });
13575
+ result[field] = terms.join(' ');
13576
+ remainingQuery = remainingQuery.replace(pattern, '').trim();
13577
+ }
13578
+ }
13579
+ // 2. Extract grouped field searches like title:(term1 AND term2)
13580
+ const groupedFieldPattern = /(title|skills):\(([^)]+)\)/g;
13581
+ let groupMatch;
13582
+ while ((groupMatch = groupedFieldPattern.exec(remainingQuery)) !== null) {
13583
+ const fieldName = groupMatch[1] === 'title' ? 'titleSearch' : 'skillsSearch';
13584
+ const groupContent = groupMatch[2];
13585
+ const terms = this.extractTermsFromGroup(groupContent, groupMatch[1]);
13586
+ result[fieldName] = terms.join(' ');
13587
+ remainingQuery = remainingQuery.replace(groupMatch[0], '').trim();
13588
+ }
13589
+ // 3. **NEW** - Extract grouped NOT expressions FIRST: NOT (term1 OR term2 OR ...)
13590
+ const groupedNotPattern = /NOT\s+\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
13591
+ const groupedNotMatches = [...remainingQuery.matchAll(groupedNotPattern)];
13592
+ if (groupedNotMatches.length > 0) {
13593
+ const noneTerms = this.extractTermsFromORGroup(groupedNotMatches[0][1]);
13594
+ result.noneWords = noneTerms.join(' ');
13595
+ remainingQuery = remainingQuery
13596
+ .replace(groupedNotMatches[0][0], '')
13597
+ .trim();
13598
+ }
13599
+ // 4. Extract individual NOT terms (only if no grouped NOT was found)
13600
+ if (!result.noneWords) {
13601
+ const notPattern = /NOT\s+("([^"]+)"|([^\s)]+))/g;
13602
+ const notMatches = [...remainingQuery.matchAll(notPattern)];
13603
+ if (notMatches.length > 0) {
13604
+ const noneTerms = notMatches.map((match) => {
13605
+ if (match[2]) {
13606
+ return `"${match[2]}"`;
13607
+ }
13608
+ return match[3];
13609
+ });
13610
+ result.noneWords = noneTerms.join(' ');
13611
+ remainingQuery = remainingQuery.replace(notPattern, '').trim();
13612
+ }
13613
+ }
13614
+ // 5. Process grouped expressions - Clean up connectors first
13615
+ remainingQuery = this.cleanupConnectors(remainingQuery);
13616
+ // Extract OR groups (anyWords) - PROCESS FIRST
13617
+ const orGroupPattern = /\(([^)]+(?:\s+OR\s+[^)]+)+)\)/g;
13618
+ const orMatches = [...remainingQuery.matchAll(orGroupPattern)];
13619
+ if (orMatches.length > 0) {
13620
+ const orTerms = this.extractTermsFromORGroup(orMatches[0][1]);
13621
+ result.anyWords = orTerms.join(' ');
13622
+ remainingQuery = remainingQuery.replace(orMatches[0][0], '').trim();
13623
+ }
13624
+ // Extract AND groups (allWords) - PROCESS SECOND
13625
+ const andGroupPattern = /\(([^)]+(?:\s+AND\s+[^)]+)+)\)/g;
13626
+ const andMatches = [...remainingQuery.matchAll(andGroupPattern)];
13627
+ if (andMatches.length > 0) {
13628
+ const andTerms = this.extractTermsFromANDGroup(andMatches[0][1]);
13629
+ result.allWords = andTerms.join(' ');
13630
+ remainingQuery = remainingQuery.replace(andMatches[0][0], '').trim();
13631
+ }
13632
+ // 6. Extract standalone quoted phrases (exactPhrase) - ONLY after all groups processed
13633
+ const standaloneQuotePattern = /(?:^|\s)("([^"]+)")(?=\s|$)/g;
13634
+ const quoteMatches = [...remainingQuery.matchAll(standaloneQuotePattern)];
13635
+ if (quoteMatches.length > 0) {
13636
+ result.exactPhrase = quoteMatches[0][2];
13637
+ remainingQuery = remainingQuery.replace(quoteMatches[0][1], '').trim();
13638
+ }
13639
+ // 7. Handle remaining simple terms as allWords
13640
+ if (remainingQuery) {
13641
+ const remainingTerms = this.splitTermsWithQuotes(remainingQuery);
13642
+ if (remainingTerms.length > 0) {
13643
+ result.allWords = result.allWords
13644
+ ? `${result.allWords} ${remainingTerms.join(' ')}`.trim()
13645
+ : remainingTerms.join(' ');
13646
+ }
13647
+ }
13648
+ return result;
13649
+ }
13650
+ /**
13651
+ * Extract terms from grouped field content, preserving quotes
13652
+ */
13653
+ static extractTermsFromGroup(content, fieldPrefix) {
13654
+ // Remove field prefixes but preserve quotes
13655
+ let cleanContent = content;
13656
+ const fieldPattern = new RegExp(`${fieldPrefix}:("([^"]+)"|([^\\s]+))`, 'g');
13657
+ const terms = [];
13658
+ let match;
13659
+ while ((match = fieldPattern.exec(content)) !== null) {
13660
+ if (match[2]) {
13661
+ // Quoted content
13662
+ terms.push(`"${match[2]}"`);
13663
+ }
13664
+ else if (match[3]) {
13665
+ // Unquoted content
13666
+ terms.push(match[3]);
13667
+ }
13668
+ }
13669
+ return terms.length > 0
13670
+ ? terms
13671
+ : [
13672
+ cleanContent
13673
+ .replace(/(title|skills):/g, '')
13674
+ .replace(/\s+AND\s+/g, ' ')
13675
+ .trim(),
13676
+ ];
13677
+ }
13678
+ /**
13679
+ * Extract terms from OR group, preserving quotes and removing OR separators
13680
+ */
13681
+ static extractTermsFromORGroup(content) {
13682
+ return content
13683
+ .split(/\s+OR\s+/)
13684
+ .map((term) => term.trim())
13685
+ .filter(Boolean);
13686
+ }
13687
+ /**
13688
+ * Extract terms from AND group, preserving quotes
13689
+ */
13690
+ static extractTermsFromANDGroup(content) {
13691
+ return content
13692
+ .split(/\s+AND\s+/)
13693
+ .map((term) => term.trim())
13694
+ .filter(Boolean);
13695
+ }
13696
+ /**
13697
+ * Split simple terms while preserving quoted phrases
13698
+ */
13699
+ static splitTermsWithQuotes(input) {
13700
+ const terms = [];
13701
+ const regex = /"([^"]+)"|(\S+)/g;
13702
+ let match;
13703
+ while ((match = regex.exec(input)) !== null) {
13704
+ if (match[1]) {
13705
+ // Quoted phrase - preserve quotes
13706
+ terms.push(`"${match[1]}"`);
13707
+ }
13708
+ else if (match[2] && !['AND', 'OR', 'NOT'].includes(match[2])) {
13709
+ // Regular word (not a connector)
13710
+ terms.push(match[2]);
13711
+ }
13712
+ }
13713
+ return terms;
13714
+ }
13715
+ /**
13716
+ * Clean up AND/OR connectors while preserving quotes
13717
+ */
13718
+ static cleanupConnectors(query) {
13719
+ return query
13720
+ .replace(/\s+AND\s+/g, ' ')
13721
+ .replace(/\s+/g, ' ')
13722
+ .trim();
13723
+ }
13724
+ /**
13725
+ * Test the roundtrip conversion (buildQuery -> parseQuery)
13726
+ */
13727
+ static testRoundtrip(fields) {
13728
+ const query = this.buildQuery(fields);
13729
+ const parsed = this.parseQuery(query);
13730
+ const matches = JSON.stringify(fields) === JSON.stringify(parsed);
13731
+ return {
13732
+ original: fields,
13733
+ query,
13734
+ parsed,
13735
+ matches,
13736
+ };
13737
+ }
13738
+ /**
13739
+ * Simple term splitting that handles quoted phrases
13740
+ */
13741
+ static splitTerms(input) {
13742
+ const terms = [];
13743
+ const regex = /"([^"]+)"|(\S+)/g;
13744
+ let match;
13745
+ while ((match = regex.exec(input)) !== null) {
13746
+ if (match[1]) {
13747
+ // Quoted phrase
13748
+ terms.push(`"${match[1]}"`);
13749
+ }
13750
+ else if (match[2]) {
13751
+ // Regular word
13752
+ terms.push(match[2]);
13753
+ }
13754
+ }
13755
+ return terms;
13756
+ }
13757
+ }
13758
+
13409
13759
  const fallbackEnum = z.enum(['noBoostBid', 'ignore']);
13410
13760
  const boostFormSchema = z.object({
13411
13761
  minPlace: z.number().int().min(1).max(4), // Don't boost below this place
@@ -13416,144 +13766,14 @@ const boostFormSchema = z.object({
13416
13766
  const nodeEnums = z.enum([
13417
13767
  'clientAvgHourlyRateNode',
13418
13768
  'bidNode',
13769
+ 'suitabilityNode',
13419
13770
  'clientHireRateNode',
13420
13771
  'clientSizeNode',
13421
13772
  'boostNode',
13422
13773
  'clientSpentNode',
13423
13774
  'clientRatingNode',
13424
- 'startNode',
13425
- 'budgetNode',
13426
- 'paymentTypeNode',
13427
13775
  ]);
13428
13776
 
13429
- const rangesOverlap$5 = (range1, range2) => {
13430
- return range1.min < range2.max && range2.min < range1.max;
13431
- };
13432
- // Payment type options (excluding 'Unspecified')
13433
- const budgetPaymentTypeEnum = z.enum(['Hourly', 'Fixed-price']);
13434
- const createBudgetFormSchema = (existingHourlyRateRanges, existingFixedBudgetRanges) => z
13435
- .object({
13436
- paymentTypes: z
13437
- .array(budgetPaymentTypeEnum)
13438
- .min(1, 'Please select at least one payment type'),
13439
- hourlyRateMin: z
13440
- .number()
13441
- .min(0, 'Minimum hourly rate must be non-negative')
13442
- .optional(),
13443
- hourlyRateMax: z
13444
- .number()
13445
- .min(0, 'Maximum hourly rate must be non-negative')
13446
- .optional(),
13447
- fixedBudgetMin: z
13448
- .number()
13449
- .min(0, 'Minimum fixed budget must be non-negative')
13450
- .optional(),
13451
- fixedBudgetMax: z
13452
- .number()
13453
- .min(0, 'Maximum fixed budget must be non-negative')
13454
- .optional(),
13455
- action: nodeEnums,
13456
- })
13457
- // Validate hourly rate fields are provided when Hourly is selected
13458
- .refine((data) => {
13459
- if (data.paymentTypes.includes('Hourly')) {
13460
- return (data.hourlyRateMin !== undefined && data.hourlyRateMax !== undefined);
13461
- }
13462
- return true;
13463
- }, {
13464
- message: 'Hourly rate min and max are required when Hourly payment type is selected',
13465
- path: ['hourlyRateMin'],
13466
- })
13467
- // Validate fixed budget fields are provided when Fixed-price is selected
13468
- .refine((data) => {
13469
- if (data.paymentTypes.includes('Fixed-price')) {
13470
- return (data.fixedBudgetMin !== undefined &&
13471
- data.fixedBudgetMax !== undefined);
13472
- }
13473
- return true;
13474
- }, {
13475
- message: 'Fixed budget min and max are required when Fixed-price payment type is selected',
13476
- path: ['fixedBudgetMin'],
13477
- })
13478
- // Validate hourly rate range when provided AND hourly payment type is selected
13479
- .refine((data) => {
13480
- if (data.paymentTypes.includes('Hourly') &&
13481
- data.hourlyRateMin !== undefined &&
13482
- data.hourlyRateMax !== undefined) {
13483
- return data.hourlyRateMin < data.hourlyRateMax;
13484
- }
13485
- return true;
13486
- }, {
13487
- message: 'Minimum hourly rate must be less than maximum',
13488
- path: ['hourlyRateMin'],
13489
- })
13490
- .refine((data) => {
13491
- if (data.paymentTypes.includes('Hourly') &&
13492
- data.hourlyRateMin !== undefined &&
13493
- data.hourlyRateMax !== undefined) {
13494
- return data.hourlyRateMax > data.hourlyRateMin;
13495
- }
13496
- return true;
13497
- }, {
13498
- message: 'Maximum hourly rate must be greater than minimum',
13499
- path: ['hourlyRateMax'],
13500
- })
13501
- // Validate fixed budget range when provided AND fixed payment type is selected
13502
- .refine((data) => {
13503
- if (data.paymentTypes.includes('Fixed-price') &&
13504
- data.fixedBudgetMin !== undefined &&
13505
- data.fixedBudgetMax !== undefined) {
13506
- return data.fixedBudgetMin < data.fixedBudgetMax;
13507
- }
13508
- return true;
13509
- }, {
13510
- message: 'Minimum fixed budget must be less than maximum',
13511
- path: ['fixedBudgetMin'],
13512
- })
13513
- .refine((data) => {
13514
- if (data.paymentTypes.includes('Fixed-price') &&
13515
- data.fixedBudgetMin !== undefined &&
13516
- data.fixedBudgetMax !== undefined) {
13517
- return data.fixedBudgetMax > data.fixedBudgetMin;
13518
- }
13519
- return true;
13520
- }, {
13521
- message: 'Maximum fixed budget must be greater than minimum',
13522
- path: ['fixedBudgetMax'],
13523
- })
13524
- // Check for hourly rate range overlaps when provided
13525
- .refine((data) => {
13526
- if (data.hourlyRateMin !== undefined &&
13527
- data.hourlyRateMax !== undefined) {
13528
- const newHourlyRateRange = {
13529
- min: data.hourlyRateMin,
13530
- max: data.hourlyRateMax,
13531
- };
13532
- return !existingHourlyRateRanges.some((existingRange) => rangesOverlap$5(newHourlyRateRange, existingRange));
13533
- }
13534
- return true;
13535
- }, {
13536
- message: 'Hourly rate range overlaps with existing hourly rate range',
13537
- path: ['hourlyRateMin'],
13538
- })
13539
- // Check for fixed budget range overlaps when provided
13540
- .refine((data) => {
13541
- if (data.fixedBudgetMin !== undefined &&
13542
- data.fixedBudgetMax !== undefined) {
13543
- const newFixedBudgetRange = {
13544
- min: data.fixedBudgetMin,
13545
- max: data.fixedBudgetMax,
13546
- };
13547
- return !existingFixedBudgetRanges.some((existingRange) => rangesOverlap$5(newFixedBudgetRange, existingRange));
13548
- }
13549
- return true;
13550
- }, {
13551
- message: 'Fixed budget range overlaps with existing fixed budget range',
13552
- path: ['fixedBudgetMin'],
13553
- });
13554
- // Default schema for backwards compatibility
13555
- const addBudgetNodeFormSchema = createBudgetFormSchema([], []);
13556
-
13557
13777
  const sizeOverlap = (size1, size2) => {
13558
13778
  if (size1 === size2) {
13559
13779
  return true;
@@ -13654,27 +13874,6 @@ const createHourlyRateFormSchema = (existingRanges) => z
13654
13874
  // Keep the original schema for backwards compatibility if needed
13655
13875
  const addFromHourlyRateNodeFormSchema = createHourlyRateFormSchema([]);
13656
13876
 
13657
- const limitedPaymentTypeEnum = paymentTypeEnum.exclude(['Unspecified']);
13658
- const paymentTypeOverlap = (paymentType1, paymentType2) => {
13659
- if (paymentType1 === paymentType2) {
13660
- return true;
13661
- }
13662
- return false;
13663
- };
13664
- const createPaymentTypeFormSchema = (existingPaymentTypes) => z
13665
- .object({
13666
- paymentTypes: z.array(limitedPaymentTypeEnum).min(1),
13667
- action: nodeEnums,
13668
- })
13669
- .refine((data) => {
13670
- const newPaymentTypes = data.paymentTypes;
13671
- return !existingPaymentTypes.some((existingPaymentType) => newPaymentTypes.some((newPaymentType) => paymentTypeOverlap(newPaymentType, existingPaymentType)));
13672
- }, {
13673
- message: 'Payment type overlaps with existing payment type',
13674
- path: ['paymentTypes'],
13675
- });
13676
- const addFromPaymentTypeNodeFormSchema = createPaymentTypeFormSchema([]);
13677
-
13678
13877
  const rangesOverlap$1 = (range1, range2) => {
13679
13878
  return range1.from < range2.to && range2.from < range1.to;
13680
13879
  };
@@ -13701,10 +13900,6 @@ const createClientRatingFormSchema = (existingRanges) => z
13701
13900
  });
13702
13901
  const addFromClientRatingNodeFormSchema = createClientRatingFormSchema([]);
13703
13902
 
13704
- const addFromStartNodeFormSchema = z.object({
13705
- action: nodeEnums,
13706
- });
13707
-
13708
13903
  const rangesOverlap = (range1, range2) => {
13709
13904
  return range1.from < range2.to && range2.from < range1.to;
13710
13905
  };
@@ -13740,6 +13935,7 @@ const bidPayloadProposalDataSchema = z.object({
13740
13935
  boostingEnabled: z.boolean(),
13741
13936
  specialisedProfileOptions: z.array(z.string()),
13742
13937
  maximumBoost: z.number().nullable(),
13938
+ minimumBoost: z.number().nullable(),
13743
13939
  boostDownToNthPlace: z.number().min(1).max(4).nullable(),
13744
13940
  connectsAbovePrevious: z.number().min(1).nullable(),
13745
13941
  insufficeintBoostConnectsAction: insufficeintBoostConnectsActionEnum,
@@ -23526,6 +23722,8 @@ exports.PuppeteerConnectionErrorException = PuppeteerConnectionErrorException;
23526
23722
  exports.QuestionPairNotMatchingException = QuestionPairNotMatchingException;
23527
23723
  exports.ROUTES = ROUTES;
23528
23724
  exports.ScraperAccountProxyNotFoundException = ScraperAccountProxyNotFoundException;
23725
+ exports.SearchFieldsSchema = SearchFieldsSchema;
23726
+ exports.SearchQueryBuilder = SearchQueryBuilder;
23529
23727
  exports.SelectAgencyException = SelectAgencyException;
23530
23728
  exports.SelectContractorException = SelectContractorException;
23531
23729
  exports.SelectorNotFoundError = SelectorNotFoundError;
@@ -23537,14 +23735,11 @@ exports.acceptUpworkInvitationSchema = acceptUpworkInvitationSchema;
23537
23735
  exports.accountStatusDisplayMap = accountStatusDisplayMap;
23538
23736
  exports.accountStatusOrder = accountStatusOrder;
23539
23737
  exports.accountStatusSchema = accountStatusSchema;
23540
- exports.addBudgetNodeFormSchema = addBudgetNodeFormSchema;
23541
23738
  exports.addFromClientHireRateNodeFormSchema = addFromClientHireRateNodeFormSchema;
23542
23739
  exports.addFromClientRatingNodeFormSchema = addFromClientRatingNodeFormSchema;
23543
23740
  exports.addFromClientSizeNodeFormSchema = addFromClientSizeNodeFormSchema;
23544
23741
  exports.addFromClientSpentNodeFormSchema = addFromClientSpentNodeFormSchema;
23545
23742
  exports.addFromHourlyRateNodeFormSchema = addFromHourlyRateNodeFormSchema;
23546
- exports.addFromPaymentTypeNodeFormSchema = addFromPaymentTypeNodeFormSchema;
23547
- exports.addFromStartNodeFormSchema = addFromStartNodeFormSchema;
23548
23743
  exports.addFromSuitabilityNodeFormSchema = addFromSuitabilityNodeFormSchema;
23549
23744
  exports.agencyBidPayloadSchema = agencyBidPayloadSchema;
23550
23745
  exports.agencyBidProposalDataSchema = agencyBidProposalDataSchema;
@@ -23579,7 +23774,6 @@ exports.biddingRejectedWithFeedbackEventMetadata = biddingRejectedWithFeedbackEv
23579
23774
  exports.booleanSchema = booleanSchema;
23580
23775
  exports.boostAboveMaxConnectsException = boostAboveMaxConnectsException;
23581
23776
  exports.boostFormSchema = boostFormSchema;
23582
- exports.budgetPaymentTypeEnum = budgetPaymentTypeEnum;
23583
23777
  exports.buildRoute = buildRoute;
23584
23778
  exports.campaignAIMetricsSchema = campaignAIMetricsSchema;
23585
23779
  exports.campaignActivityCreateSchema = campaignActivityCreateSchema;
@@ -23612,7 +23806,6 @@ exports.convertToUtc = convertToUtc;
23612
23806
  exports.countryMapping = countryMapping;
23613
23807
  exports.coverLetterTemplateSchema = coverLetterTemplateSchema;
23614
23808
  exports.createBidderAccountSchema = createBidderAccountSchema;
23615
- exports.createBudgetFormSchema = createBudgetFormSchema;
23616
23809
  exports.createCampaignSchema = createCampaignSchema;
23617
23810
  exports.createChatbotSchema = createChatbotSchema;
23618
23811
  exports.createClientHireRateFormSchema = createClientHireRateFormSchema;
@@ -23623,7 +23816,6 @@ exports.createCoverLetterTemplateSchema = createCoverLetterTemplateSchema;
23623
23816
  exports.createHourlyRateFormSchema = createHourlyRateFormSchema;
23624
23817
  exports.createOrganizationProfileSchema = createOrganizationProfileSchema;
23625
23818
  exports.createOrganizationSchema = createOrganizationSchema;
23626
- exports.createPaymentTypeFormSchema = createPaymentTypeFormSchema;
23627
23819
  exports.createScraperAccountSchema = createScraperAccountSchema;
23628
23820
  exports.createSuitabilityFormSchema = createSuitabilityFormSchema;
23629
23821
  exports.dailyUsageSchema = dailyUsageSchema;
@@ -23715,7 +23907,6 @@ exports.leadSchema = leadSchema;
23715
23907
  exports.leadStatusActivitySchema = leadStatusActivitySchema;
23716
23908
  exports.leadStatusEnum = leadStatusEnum;
23717
23909
  exports.leadStatusEventMetadata = leadStatusEventMetadata;
23718
- exports.limitedPaymentTypeEnum = limitedPaymentTypeEnum;
23719
23910
  exports.limitsSchema = limitsSchema;
23720
23911
  exports.logEventSchema = logEventSchema;
23721
23912
  exports.loginFailedException = loginFailedException;