diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json index 8de712e0b0..08c7391a3f 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json @@ -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" diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock index 405a00797d..483a8dd09e 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock @@ -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" diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts index 96e67762ef..eab98a94c1 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts @@ -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; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflow-code-step-logic-functions.util.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflow-code-step-logic-functions.util.ts index c5ff73b047..4df9974c0b 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflow-code-step-logic-functions.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflow-code-step-logic-functions.util.ts @@ -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) => {