fix: create company workflow (use psl for domain suffix) (#19289)
Fixes edge case where suffix like `.com.cy` which is TLD for Cyprus would attach person to wrong company <img width="715" height="115" alt="image" src="https://github.com/user-attachments/assets/bbaf7c2c-8365-4655-afda-508fbc04de2a" />
This commit is contained in:
+1
@@ -38,6 +38,7 @@
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"lodash.upperfirst": "^4.3.1",
|
||||
"nodemailer": "^8.0.4",
|
||||
"psl": "^1.15.0",
|
||||
"sharp": "^0.34.5",
|
||||
"uuid": "^10.0.0",
|
||||
"winston": "^3.14.2"
|
||||
|
||||
+17
@@ -2374,6 +2374,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"psl@npm:^1.15.0":
|
||||
version: 1.15.0
|
||||
resolution: "psl@npm:1.15.0"
|
||||
dependencies:
|
||||
punycode: "npm:^2.3.1"
|
||||
checksum: 10c0/d8d45a99e4ca62ca12ac3c373e63d80d2368d38892daa40cfddaa1eb908be98cd549ac059783ef3a56cfd96d57ae8e2fd9ae53d1378d90d42bc661ff924e102a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"punycode@npm:^2.3.1":
|
||||
version: 2.3.1
|
||||
resolution: "punycode@npm:2.3.1"
|
||||
checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:~6.14.0":
|
||||
version: 6.14.2
|
||||
resolution: "qs@npm:6.14.2"
|
||||
@@ -2511,6 +2527,7 @@ __metadata:
|
||||
lodash.snakecase: "npm:^4.1.1"
|
||||
lodash.upperfirst: "npm:^4.3.1"
|
||||
nodemailer: "npm:^8.0.4"
|
||||
psl: "npm:^1.15.0"
|
||||
sharp: "npm:^0.34.5"
|
||||
uuid: "npm:^10.0.0"
|
||||
winston: "npm:^3.14.2"
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ import { SEED_DEPENDENCIES_DIRNAME } from 'src/engine/core-modules/application/a
|
||||
// To regenerate: use logicFunctionCreateHash from logic-function-create-hash.utils.
|
||||
// package.json: hash(JSON.stringify(JSON.parse(content))). yarn.lock: hash(content).
|
||||
// Both use first 32 chars of SHA512 hex digest.
|
||||
const DEFAULT_PACKAGE_JSON_CHECKSUM = '4cf57bd317cfe8e49c47b0aa76aabb39';
|
||||
const DEFAULT_YARN_LOCK_CHECKSUM = '415a52f896221c813b6bcafad8d93b19';
|
||||
const DEFAULT_PACKAGE_JSON_CHECKSUM = 'cce6edc8bb5046d992b51a3260b19bfe';
|
||||
const DEFAULT_YARN_LOCK_CHECKSUM = 'e290256e22000e0f4b46001b91999d16';
|
||||
|
||||
export type DefaultApplicationPackageFields = {
|
||||
packageJsonChecksum: string;
|
||||
|
||||
+10
-120
@@ -56,53 +56,13 @@ const FIND_MATCHING_COMPANY_BY_DOMAIN_TOOL_INPUT_SCHEMA = {
|
||||
required: ['companies', 'domain'],
|
||||
};
|
||||
|
||||
const EXTRACT_DOMAIN_LOGIC_FUNCTION_SOURCE = `const MULTI_PART_SUFFIXES = new Set([
|
||||
'ac.uk',
|
||||
'co.in',
|
||||
'co.jp',
|
||||
'co.kr',
|
||||
'co.nz',
|
||||
'co.uk',
|
||||
'co.za',
|
||||
'com.ar',
|
||||
'com.au',
|
||||
'com.br',
|
||||
'com.cn',
|
||||
'com.hk',
|
||||
'com.mx',
|
||||
'com.sg',
|
||||
'com.tr',
|
||||
'com.tw',
|
||||
'com.ua',
|
||||
'gov.uk',
|
||||
'ne.jp',
|
||||
'net.au',
|
||||
'org.au',
|
||||
'org.uk',
|
||||
]);
|
||||
|
||||
const getRegistrableDomain = (host) => {
|
||||
const normalizedHost = host.toLowerCase().replace(/^www\\./, '');
|
||||
const parts = normalizedHost.split('.').filter(Boolean);
|
||||
|
||||
if (parts.length <= 2) {
|
||||
return normalizedHost;
|
||||
}
|
||||
|
||||
const lastTwo = parts.slice(-2).join('.');
|
||||
|
||||
if (MULTI_PART_SUFFIXES.has(lastTwo) && parts.length >= 3) {
|
||||
return parts.slice(-3).join('.');
|
||||
}
|
||||
|
||||
return lastTwo;
|
||||
};
|
||||
const EXTRACT_DOMAIN_LOGIC_FUNCTION_SOURCE = `const psl = require('psl');
|
||||
|
||||
export const main = async (params) => {
|
||||
const email =
|
||||
typeof params?.email === 'string' ? params.email.trim().toLowerCase() : '';
|
||||
const domainFromEmail = email.split('@')[1] ?? '';
|
||||
const domain = domainFromEmail ? getRegistrableDomain(domainFromEmail) : '';
|
||||
const host = email.split('@')[1] ?? '';
|
||||
const domain = host ? (psl.get(host) ?? host) : '';
|
||||
|
||||
return {
|
||||
url: domain ? \`https://\${domain}\` : '',
|
||||
@@ -110,30 +70,7 @@ export const main = async (params) => {
|
||||
};
|
||||
};`;
|
||||
|
||||
const IS_PERSONAL_EMAIL_LOGIC_FUNCTION_SOURCE = `const MULTI_PART_SUFFIXES = new Set([
|
||||
'ac.uk',
|
||||
'co.in',
|
||||
'co.jp',
|
||||
'co.kr',
|
||||
'co.nz',
|
||||
'co.uk',
|
||||
'co.za',
|
||||
'com.ar',
|
||||
'com.au',
|
||||
'com.br',
|
||||
'com.cn',
|
||||
'com.hk',
|
||||
'com.mx',
|
||||
'com.sg',
|
||||
'com.tr',
|
||||
'com.tw',
|
||||
'com.ua',
|
||||
'gov.uk',
|
||||
'ne.jp',
|
||||
'net.au',
|
||||
'org.au',
|
||||
'org.uk',
|
||||
]);
|
||||
const IS_PERSONAL_EMAIL_LOGIC_FUNCTION_SOURCE = `const psl = require('psl');
|
||||
|
||||
const PERSONAL_EMAIL_DOMAINS = new Set([
|
||||
'aol.com',
|
||||
@@ -172,23 +109,6 @@ const PERSONAL_EMAIL_DOMAINS = new Set([
|
||||
'gmail.com',
|
||||
]);
|
||||
|
||||
const getRegistrableDomain = (host) => {
|
||||
const normalizedHost = host.toLowerCase().replace(/^www\\./, '');
|
||||
const parts = normalizedHost.split('.').filter(Boolean);
|
||||
|
||||
if (parts.length <= 2) {
|
||||
return normalizedHost;
|
||||
}
|
||||
|
||||
const lastTwo = parts.slice(-2).join('.');
|
||||
|
||||
if (MULTI_PART_SUFFIXES.has(lastTwo) && parts.length >= 3) {
|
||||
return parts.slice(-3).join('.');
|
||||
}
|
||||
|
||||
return lastTwo;
|
||||
};
|
||||
|
||||
export const main = async (params) => {
|
||||
const email =
|
||||
typeof params?.primaryEmail === 'string'
|
||||
@@ -200,7 +120,7 @@ export const main = async (params) => {
|
||||
}
|
||||
|
||||
const host = email.split('@')[1] ?? '';
|
||||
const registrableDomain = host ? getRegistrableDomain(host) : '';
|
||||
const registrableDomain = host ? (psl.get(host) ?? '') : '';
|
||||
|
||||
return {
|
||||
isPersonal:
|
||||
@@ -210,30 +130,7 @@ export const main = async (params) => {
|
||||
};
|
||||
};`;
|
||||
|
||||
const FIND_MATCHING_COMPANY_BY_DOMAIN_LOGIC_FUNCTION_SOURCE = `const MULTI_PART_SUFFIXES = new Set([
|
||||
'ac.uk',
|
||||
'co.in',
|
||||
'co.jp',
|
||||
'co.kr',
|
||||
'co.nz',
|
||||
'co.uk',
|
||||
'co.za',
|
||||
'com.ar',
|
||||
'com.au',
|
||||
'com.br',
|
||||
'com.cn',
|
||||
'com.hk',
|
||||
'com.mx',
|
||||
'com.sg',
|
||||
'com.tr',
|
||||
'com.tw',
|
||||
'com.ua',
|
||||
'gov.uk',
|
||||
'ne.jp',
|
||||
'net.au',
|
||||
'org.au',
|
||||
'org.uk',
|
||||
]);
|
||||
const FIND_MATCHING_COMPANY_BY_DOMAIN_LOGIC_FUNCTION_SOURCE = `const psl = require('psl');
|
||||
|
||||
const normalizeHost = (value) => {
|
||||
if (typeof value !== 'string') {
|
||||
@@ -252,20 +149,13 @@ const normalizeHost = (value) => {
|
||||
};
|
||||
|
||||
const getRegistrableDomain = (value) => {
|
||||
const normalizedHost = normalizeHost(value);
|
||||
const parts = normalizedHost.split('.').filter(Boolean);
|
||||
const host = normalizeHost(value);
|
||||
|
||||
if (parts.length <= 2) {
|
||||
return normalizedHost;
|
||||
if (!host) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const lastTwo = parts.slice(-2).join('.');
|
||||
|
||||
if (MULTI_PART_SUFFIXES.has(lastTwo) && parts.length >= 3) {
|
||||
return parts.slice(-3).join('.');
|
||||
}
|
||||
|
||||
return lastTwo;
|
||||
return psl.get(host) ?? host;
|
||||
};
|
||||
|
||||
export const main = async (params) => {
|
||||
|
||||
Reference in New Issue
Block a user