UNPKG

eggi-ai-db-schema

Version:

Type-safe database schema and ORM client for Eggi.AI with direct RDS connection

127 lines 5.36 kB
"use strict"; /** * LinkedIn Identifier Utilities for RDS Schema Package * * Determines identifier types and proper storage mapping for social accounts */ Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidAcoIdentifierError = void 0; exports.validateAcoIdentifier = validateAcoIdentifier; exports.getLinkedInIdentifierMapping = getLinkedInIdentifierMapping; exports.buildSocialAccountValues = buildSocialAccountValues; /** * Validation error for invalid ACoA identifiers */ class InvalidAcoIdentifierError extends Error { constructor(identifier, reason) { super(`Invalid ACoA identifier "${identifier}": ${reason}`); this.name = "InvalidAcoIdentifierError"; } } exports.InvalidAcoIdentifierError = InvalidAcoIdentifierError; /** * Validates that an ACoA identifier meets all requirements: * - Starts with "ACoA" * - Is exactly 39 characters long * - Contains only valid characters (alphanumeric + underscores, hyphens) */ function validateAcoIdentifier(identifier) { if (!identifier) { throw new InvalidAcoIdentifierError(identifier, "identifier cannot be empty or null"); } const trimmed = identifier.trim(); if (!trimmed.startsWith("ACoA")) { throw new InvalidAcoIdentifierError(identifier, "must start with 'ACoA'"); } if (trimmed.length !== 39) { throw new InvalidAcoIdentifierError(identifier, `must be exactly 39 characters long, got ${trimmed.length} characters`); } // Optional: Validate character set (LinkedIn identifiers typically use alphanumeric + some special chars) const validPattern = /^ACoA[A-Za-z0-9_-]+$/; if (!validPattern.test(trimmed)) { throw new InvalidAcoIdentifierError(identifier, "contains invalid characters (only alphanumeric, underscore, and hyphen allowed after 'ACoA')"); } } /** * Determine how to store LinkedIn identifiers based on their format */ function getLinkedInIdentifierMapping(identifier) { const trimmed = identifier.trim(); // ACoA* identifiers → internal_identifier_regular if (trimmed.startsWith("ACoA")) { return { identifierType: "aco_regular", storeInRegular: true, storeInInternal: false, storeInPublic: false, }; } // ACwA* identifiers → internal_identifier (updated to be more specific) if (trimmed.startsWith("ACwA")) { return { identifierType: "aco_sales_navigator", storeInRegular: false, storeInInternal: true, storeInPublic: false, }; } // AEMA* identifiers → internal_identifier if (trimmed.startsWith("AEMA")) { return { identifierType: "aco_recruiter", storeInRegular: false, storeInInternal: true, storeInPublic: false, }; } // Everything else (public identifiers, URLs, etc.) → public_identifier return { identifierType: "public_identifier", storeInRegular: false, storeInInternal: false, storeInPublic: true, }; } /** * Helper function to build social account values with proper identifier mapping * CRITICAL: Handles complementary identifiers correctly - stores BOTH request and response identifiers */ function buildSocialAccountValues(requestIdentifier, profileData) { const values = {}; // Step 1: Handle request identifier (what user passed in the API call) // This ALWAYS gets stored first and should NEVER be overwritten const requestMapping = getLinkedInIdentifierMapping(requestIdentifier); if (requestMapping.storeInRegular) { // Validate ACoA identifier before storing validateAcoIdentifier(requestIdentifier); values.internalIdentifierRegular = requestIdentifier; } else if (requestMapping.storeInInternal) { values.internalIdentifier = requestIdentifier; } else if (requestMapping.storeInPublic) { values.publicIdentifier = requestIdentifier; } // Step 2: Handle Unipile response provider_id (complementary identifier) // Only store if it's different from request and goes to a DIFFERENT field if (profileData.provider_id && profileData.provider_id !== requestIdentifier) { const providerMapping = getLinkedInIdentifierMapping(profileData.provider_id); // Store provider_id ONLY if it goes to a different field than the request identifier if (providerMapping.storeInRegular && !values.internalIdentifierRegular) { // Validate ACoA identifier before storing validateAcoIdentifier(profileData.provider_id); values.internalIdentifierRegular = profileData.provider_id; } else if (providerMapping.storeInInternal && !values.internalIdentifier) { values.internalIdentifier = profileData.provider_id; } // Note: We don't store provider_id in publicIdentifier as it should be a LinkedIn internal ID } // Step 3: Always store public_identifier from Unipile response (overwrites request if needed) // Public identifier is always from the response, not the request if (profileData.public_identifier) { values.publicIdentifier = profileData.public_identifier; } return values; } //# sourceMappingURL=linkedin-identifier-utils.js.map