import { config } from '../config.js';
export interface BrregCompany {
organisasjonsnummer: string;
navn: string;
organisasjonsform: { kode: string; beskrivelse: string };
registreringsdatoEnhetsregisteret?: string;
registrertIMvaregisteret?: boolean;
naeringskode1?: { kode: string; beskrivelse: string };
naeringskode2?: { kode: string; beskrivelse: string };
naeringskode3?: { kode: string; beskrivelse: string };
antallAnsatte?: number;
harRegistrertAntallAnsatte?: boolean;
stiftelsesdato?: string;
hjemmeside?: string;
telefon?: string;
sisteInnsendteAarsregnskap?: string;
forretningsadresse?: {
land: string;
landkode: string;
postnummer?: string;
poststed?: string;
adresse?: string[];
kommune?: string;
kommunenummer?: string;
};
postadresse?: {
land: string;
landkode: string;
postnummer?: string;
poststed?: string;
adresse?: string[];
kommune?: string;
kommunenummer?: string;
};
registrertIForetaksregisteret?: boolean;
registrertIStiftelsesregisteret?: boolean;
registrertIFrivillighetsregisteret?: boolean;
konkurs?: boolean;
underAvvikling?: boolean;
underTvangsavviklingEllerTvangsopplosning?: boolean;
_links?: any;
}
export interface BrregSearchResponse {
_embedded?: { enheter: BrregCompany[] };
_links: any;
page: {
size: number;
totalElements: number;
totalPages: number;
number: number;
};
}
export class BrregClient {
private baseUrl = config.brreg.baseUrl;
private username = config.brreg.username;
private requestDelay = config.brreg.rateLimitDelay;
private async sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
private async fetch(endpoint: string): Promise<any> {
await this.sleep(this.requestDelay);
const url = `${this.baseUrl}${endpoint}`;
console.error(`Fetching from Brønnøysund: ${url}`);
const response = await fetch(url, {
headers: {
'Accept': 'application/json',
'User-Agent': `CompanyIQ/${this.username}`
}
});
if (!response.ok) {
throw new Error(`Brønnøysund API error: ${response.status}`);
}
return await response.json();
}
async getCompany(orgNr: string): Promise<BrregCompany | null> {
try {
return await this.fetch(`/enheter/${orgNr}`);
} catch (error) {
console.error('Error fetching company:', error);
return null;
}
}
async searchCompanies(query: string, limit: number = 20): Promise<BrregCompany[]> {
try {
const data: BrregSearchResponse = await this.fetch(
`/enheter?navn=${encodeURIComponent(query)}&size=${limit}`
);
return data._embedded?.enheter || [];
} catch (error) {
console.error('Error searching companies:', error);
return [];
}
}
async searchByNACE(naceCode: string, limit: number = 100, excludeBankrupt: boolean = true): Promise<BrregCompany[]> {
try {
let url = `/enheter?naeringskode=${naceCode}&size=${limit}`;
if (excludeBankrupt) {
url += '&konkurs=false';
}
const data: BrregSearchResponse = await this.fetch(url);
return data._embedded?.enheter || [];
} catch (error) {
console.error('Error searching by NACE:', error);
return [];
}
}
async searchBankruptCompanies(naceCode?: string, limit: number = 100): Promise<BrregCompany[]> {
try {
let url = `/enheter?konkurs=true&size=${limit}`;
if (naceCode) {
url += `&naeringskode=${naceCode}`;
}
const data: BrregSearchResponse = await this.fetch(url);
return data._embedded?.enheter || [];
} catch (error) {
console.error('Error searching bankrupt companies:', error);
return [];
}
}
async getSubunits(parentOrgNr: string): Promise<any[]> {
try {
const data = await this.fetch(`/underenheter?overordnetEnhet=${parentOrgNr}&size=100`);
return data._embedded?.underenheter || [];
} catch (error) {
console.error('Error fetching subunits:', error);
return [];
}
}
async getRoles(orgNr: string): Promise<any[]> {
try {
// Note: Roles endpoint may require authentication
const data = await this.fetch(`/enheter/${orgNr}/roller`);
return data.rollegrupper || [];
} catch (error) {
console.error('Error fetching roles (may require auth):', error);
return [];
}
}
}