import {z} from 'zod' export type GetApiCompaniesKyckrIdEnhancedArgs = {showDirectorships?: boolean | undefined, customerReference?: string | undefined, extend?: string | undefined}; export type GetApiCompaniesKyckrIdEnhancedOptions = {baseUrl?: string | undefined, AuthHeader?: string | undefined, fetch?: typeof fetch | undefined}; export const cost = z.object({type: z.enum(["credit", "lite"]).optional(), value: z.number().optional()}); export const activity = z.object({code: z.string().optional(), description: z.string().optional(), classificationScheme: z.enum(["NACE", "NACErev2", "NACErev2.1", "SIC", "SIC07", "NAICS"]).optional(), type: z.enum(["Primary", "Secondary"]).optional()}); export const activityDeclaration = z.object({declaration: z.string().optional(), declarationDescription: z.string().optional(), language: z.string().optional()}); export const address = z.object({identifier: z.string().nullable().optional(), type: z.string().min(1).optional(), fullAddress: z.string().min(1).optional(), rawAddressLines: z.array(z.string()).optional(), buildingName: z.string().optional(), streetNumber: z.string().optional(), streetName: z.string().optional(), city: z.string().min(1).optional(), postcode: z.string().min(1).optional(), municipality: z.string().optional(), region: z.string().min(1).optional(), country: z.string().min(1).optional(), isoCode: z.string().optional(), secondaryPostalCode: z.string().optional()}); export const capitalAmount = z.object({amount: z.number().optional(), currency: z.string().optional(), quantity: z.number().optional()}); export const capitalAttributes = z.object({registeredCapital: capitalAmount.optional(), authorisedCapital: capitalAmount.optional(), paidUpCapital: capitalAmount.optional()}); export const normalizedDate = z.object({original: z.string().optional(), normalized: z.string().optional()}); export const identifier = z.object({value: z.string().optional(), type: z.string().optional()}); export const shareholderCorporationDetails = z.object({type: z.literal("Corporation"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), registrationNumber: z.string().optional(), registrationDate: normalizedDate.optional(), registrationAuthority: z.string().optional(), registeredAddress: address.optional(), otherIdentifiers: z.array(identifier).optional(), englishName: z.string().nullable().optional()}); export const legalEntity = z.object({type: z.enum(["Person", "Corporation", "Other"]), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional()}); export const shareholderPersonDetails = z.object({type: z.literal("Person"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), englishName: z.string().nullable().optional()}); export const shareholding = z.object({percentage: z.string().nullable().optional(), percentageIsRange: z.boolean().optional(), percentageRange: z.string().nullable().optional(), percentageLowerLimit: z.string().nullable().optional(), percentageUpperLimit: z.string().nullable().optional(), count: z.number().optional(), totalNominalValue: z.number().optional(), currency: z.string().optional(), beneficiallyHeld: z.boolean().optional(), shareholders: z.object({corporations: z.array(z.discriminatedUnion("type", [shareholderCorporationDetails, legalEntity])).optional(), individuals: z.array(z.discriminatedUnion("type", [shareholderPersonDetails, legalEntity])).optional()}).optional()}); export const capital = z.object({type: z.string().optional(), description: z.string().optional(), classCode: z.string().optional(), classDescription: z.string().optional(), quantity: z.number().optional(), unitNominalValue: z.number().optional(), totalNominalValue: z.number().optional(), currency: z.string().optional(), capitalAttributes: capitalAttributes.optional(), votingRights: z.string().optional(), shareholdings: z.array(shareholding).optional()}); export const directorship = z.object({companyNumber: z.string().optional(), companyName: z.string().optional(), role: z.string().optional(), startDate: normalizedDate.optional(), endDate: normalizedDate.optional(), isActive: z.boolean().optional()}); export const corporationRepresentative = z.object({type: z.literal("Corporation"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), registrationNumber: z.string().optional(), registrationDate: normalizedDate.optional(), registrationAuthority: z.string().optional(), registeredAddress: address.optional(), otherIdentifiers: z.array(identifier).optional(), englishName: z.string().nullable().optional(), natureOfControl: z.array(z.string()).optional(), startDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), notifiedDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), endDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), role: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), isActive: z.boolean().optional(), directorships: z.array(directorship).optional(), powers: z.array(z.string()).optional()}); export const otherRepresentative = z.object({type: z.literal("Other"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), role: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), startDate: normalizedDate.optional(), endDate: normalizedDate.optional(), isActive: z.boolean().optional(), directorships: z.array(directorship).optional(), powers: z.array(z.string()).optional()}); export const individualRepresentative = z.object({type: z.literal("Person"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), birthdate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), nationality: z.string().optional(), placeOfBirth: address.optional(), placeOfResidence: address.optional(), englishName: z.string().nullable().optional(), role: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), startDate: normalizedDate.optional(), endDate: normalizedDate.optional(), isActive: z.boolean().optional(), directorships: z.array(directorship).optional(), powers: z.array(z.string()).optional()}); export const individualUBO = z.object({type: z.literal("Person"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), birthdate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), nationality: z.string().optional(), placeOfBirth: address.optional(), placeOfResidence: address.optional(), natureOfControl: z.array(z.string()).optional(), startDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), notifiedDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), endDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), kind: z.string().optional()}); export const otherUBO = z.object({type: z.literal("Other"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), natureOfControl: z.array(z.string()).optional(), startDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), notifiedDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), endDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional()}); export const corporationUBO = z.object({type: z.literal("Corporation"), idNumber: z.string().optional(), name: z.string().optional(), address: address.optional(), registrationNumber: z.string().optional(), registrationDate: normalizedDate.optional(), registrationAuthority: z.string().optional(), registeredAddress: address.optional(), otherIdentifiers: z.array(identifier).optional(), natureOfControl: z.array(z.string()).optional(), startDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), notifiedDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), endDate: z.object({original: z.string().optional(), normalized: z.string().optional()}).optional(), kind: z.string().optional()}); export const contactDetails = z.object({email: z.string().optional(), fax: z.string().optional(), telNumber: z.string().optional(), website: z.string().optional()}); export const companyRelationship = z.object({relationship: z.enum(["Subsidiary", "Merged", "Demerged", "Acquired", "Other"]).optional(), company: z.object({kyckrId: z.string().optional(), companyName: z.string().optional(), companyNumber: z.string().optional()}).optional(), effectiveDate: z.string().optional(), description: z.string().optional()}); export const informationSource = z.object({entityName: z.string().optional(), entityType: z.string().optional(), context: z.string().optional(), path: z.string().optional()}); export const addressGroup = z.object({identifier: z.string().optional(), variants: z.array(address).optional(), sources: z.array(informationSource).optional()}); export const addressAdditionalInformation = z.object({addresses: z.array(addressGroup).optional()}); export const shareholdingSummaryClassContribution = z.object({classCode: z.string().nullable().optional(), classDescription: z.string().nullable().optional(), percentage: z.object({exact: z.number().gte(0).lte(100).nullable().optional(), minimum: z.number().gte(0).lte(100).nullable().optional(), maximum: z.number().gte(0).lte(100).nullable().optional(), exclusiveMinimum: z.boolean().optional(), exclusiveMaximum: z.boolean().optional(), original: z.string().nullable().optional()}).nullable().optional(), count: z.number().nullable().optional(), value: z.number().nullable().optional(), jointlyHeld: z.boolean().optional(), sourceName: z.string().nullable().optional()}); export const shareholdingSummaryOwner = z.object({identifier: z.string().optional(), name: z.string().optional(), shareholderType: z.enum(["Person", "Corporation", "Other"]).optional(), idNumber: z.string().nullable().optional(), registrationNumber: z.string().nullable().optional(), matchedBy: z.enum(["IdNumber", "RegistrationNumber", "Name"]).optional(), totalShareCount: z.number().nullable().optional(), shareCountPercentage: z.object({exact: z.number().gte(0).lte(100).nullable().optional(), minimum: z.number().gte(0).lte(100).nullable().optional(), maximum: z.number().gte(0).lte(100).nullable().optional(), exclusiveMinimum: z.boolean().optional(), exclusiveMaximum: z.boolean().optional(), original: z.string().nullable().optional()}).nullable().optional(), valuePercentage: z.object({exact: z.number().gte(0).lte(100).nullable().optional(), minimum: z.number().gte(0).lte(100).nullable().optional(), maximum: z.number().gte(0).lte(100).nullable().optional(), exclusiveMinimum: z.boolean().optional(), exclusiveMaximum: z.boolean().optional(), original: z.string().nullable().optional()}).nullable().optional(), ownershipPercentage: z.number().nullable().optional(), ownershipPercentageBasis: z.enum(["ShareCountExact", "ValueExact", "ShareCountBound", "ValueBound"]).nullable().optional(), hasJointHoldings: z.boolean().optional(), investigationReasons: z.array(z.enum(["JointHolding", "ShareCountUnknown", "ValueUnknown", "BandOnlyPercentage", "ClassWeightUnknown", "NameMatch"])).optional(), requiresInvestigation: z.boolean().optional(), byClass: z.array(shareholdingSummaryClassContribution).optional()}); export const shareholdingSummaryResolution = z.object({threshold: z.union([z.literal(5), z.literal(10), z.literal(15), z.literal(20), z.literal(25)]).optional(), outcome: z.enum(["ResolvedFromProfile", "FurtherResolutionRequired", "Indeterminate"]).optional(), reasons: z.array(z.enum(["NoShareholdingData", "OwnerPercentageUnknown", "NoCorporateShareholders", "CorporateHoldingsAtOrAboveThreshold", "CorporateHoldingsCouldLiftIndividual", "CorporateHoldingsCannotLiftAnyone"])).optional(), corporateHoldingTotal: z.number().optional(), individualsAtOrAboveThreshold: z.array(z.string()).optional(), individualsWithinReach: z.array(z.string()).optional()}); export const shareholdingSummaryAdditionalInformation = z.object({owners: z.array(shareholdingSummaryOwner).optional(), beneficialOwnershipResolution: shareholdingSummaryResolution.optional()}); export const additionalInformation = z.object({addressInformation: addressAdditionalInformation.optional(), shareholdingSummary: shareholdingSummaryAdditionalInformation.optional()}); export const alternativeNames = z.object({name: z.string().optional(), type: z.string().optional()}); export const previousNames = z.object({name: z.string().optional(), startDate: normalizedDate.optional(), endDate: normalizedDate.optional()}); export const registerNotice = z.object({text: z.string(), origin: z.string(), displayRequired: z.boolean().optional()}); export const registerSource = z.object({notices: z.array(registerNotice).optional(), extractedAt: z.string().nullable().optional(), dataAsOfDate: z.string().nullable().optional()}); export const normalizedStatus = z.object({original: z.string().optional(), normalized: z.enum(["Active", "Inactive", "Distressed", "Other"]).optional()}); export const normalizedLegalForm = z.object({original: z.string().optional(), normalized: z.enum(["Private Limited Company", "Public Limited Company", "Limited Partnership", "Limited Liability Partnership", "General Partnership", "Cooperative", "Collective Investment Vehicle", "Association", "Sole Proprietor", "Branch", "Foreign Registered Body", "Government or Public Body", "Foundation", "Trust", "Other"]).optional()}); export const enhancedProfile = z.object({activities: z.array(activity).optional(), activityDeclarations: z.array(activityDeclaration).optional(), addresses: z.array(address).optional(), totalCapital: z.object({totalValue: z.number().optional(), quantity: z.number().optional(), currency: z.string().optional(), type: z.enum(["Fixed", "Variable", "Registered"]).optional()}).optional(), capital: z.array(capital).optional(), representatives: z.object({corporations: z.array(z.discriminatedUnion("type", [corporationRepresentative, otherRepresentative])).optional(), individuals: z.array(z.discriminatedUnion("type", [individualRepresentative, otherRepresentative])).optional()}).optional(), ultimateBeneficialOwners: z.object({individuals: z.array(z.discriminatedUnion("type", [individualUBO, otherUBO])).optional(), corporations: z.array(z.discriminatedUnion("type", [corporationUBO, otherUBO])).optional()}).optional(), contactDetails: contactDetails.optional(), companyRelationships: z.array(companyRelationship).optional(), links: z.object({document: z.string().optional(), data: z.string().optional()}).optional(), registrationType: z.string().optional(), registrationTypeDetails: z.object({originalCode: z.string().optional(), originalDescription: z.string().optional(), normalizedCode: z.string().optional(), normalizedDescription: z.string().optional()}).optional(), additionalInformation: additionalInformation.optional(), identifiers: z.object({primaryRegistrationNumber: z.string().optional(), taxNumber: z.string().optional(), secondaryRegistrationNumber: z.string().optional(), otherIdentifiers: z.array(identifier).optional()}).optional(), companyName: z.string().optional(), tradingName: z.string().optional(), englishName: z.string().optional(), aliases: z.array(alternativeNames).optional(), previousNames: z.array(previousNames).optional(), registrationAuthority: z.string().optional(), source: registerSource.optional(), lastUpdated: z.string().optional(), lastAnnualAccountDate: normalizedDate.optional(), lastAgmDate: normalizedDate.optional(), lastAnnualConfirmationDate: normalizedDate.optional(), nextAnnualConfirmationDate: normalizedDate.optional(), foundationDate: normalizedDate.optional(), registrationDate: normalizedDate.optional(), incorporationDate: normalizedDate.optional(), dissolutionDate: normalizedDate.optional(), status: normalizedStatus.optional(), legalForm: normalizedLegalForm.optional(), incorporationJurisdiction: z.object({original: z.string().optional()}).optional(), registeredAgentName: z.string().optional(), registeredAgentAddress: z.string().optional()}); export const getApiCompaniesKyckrIdEnhancedResponse = z.object({orderId: z.string().optional(), correlationId: z.string().optional(), customerReference: z.string().optional(), timeStamp: z.string().optional(), details: z.string().optional(), cost: cost.optional(), links: z.object({self: z.string().optional()}).optional(), data: enhancedProfile.optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Enhanced Profile * * GET /companies/{kyckrId}/enhanced */ export const getApiCompaniesKyckrIdEnhanced = async (args: GetApiCompaniesKyckrIdEnhancedArgs, options?: GetApiCompaniesKyckrIdEnhancedOptions) => { const {baseUrl = "https://api.kyckr.com/v2", fetch: fetchFn = fetch, AuthHeader} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.showDirectorships != null) query.append("showDirectorships", String(args.showDirectorships)) if (args.customerReference != null) query.append("customerReference", String(args.customerReference)) if (args.extend != null) query.append("extend", String(args.extend)) if (AuthHeader !== undefined) headers.set('authorization', `Bearer ${AuthHeader}`) const url = `${baseUrl.replace(/\/+$/, '')}/companies/${encodeURIComponent(String(args.kyckrId))}/enhanced${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getApiCompaniesKyckrIdEnhancedResponse, await res.json()) };