@fin.cx/opendata 1.2.0 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/opendata',
6
- version: '1.2.0',
6
+ version: '1.4.4',
7
7
  description: 'A TypeScript library for accessing, managing, and updating open business data, focused on German companies and integrating with MongoDB.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDBJQUEwSTtDQUN4SixDQUFBIn0=
@@ -1,8 +1,12 @@
1
1
  import * as plugins from './plugins.js';
2
2
  export declare class BusinessRecord extends plugins.smartdata.SmartDataDbDoc<BusinessRecord, BusinessRecord> {
3
+ static getByGermanParsedRegistration: (parsedGermanRegistrationArg: BusinessRecord["data"]["germanParsedRegistration"]) => Promise<BusinessRecord>;
3
4
  id: string;
4
5
  data: {
5
6
  name?: string;
7
+ startDate?: string;
8
+ endDate?: string;
9
+ status?: 'active' | 'liquidating' | 'closed';
6
10
  address?: string;
7
11
  postalCode?: string;
8
12
  city?: string;
@@ -12,9 +16,13 @@ export declare class BusinessRecord extends plugins.smartdata.SmartDataDbDoc<Bus
12
16
  email?: string;
13
17
  website?: string;
14
18
  businessType?: string;
15
- registrationNumber?: string;
16
- registrationCourt?: string;
17
- legalForm?: string;
19
+ registrationId?: string;
20
+ germanParsedRegistration?: {
21
+ court?: string;
22
+ type?: 'HRA' | 'HRB' | 'GnR' | 'PR' | 'VR' | 'GsR';
23
+ number?: string;
24
+ };
25
+ legalForm?: 'GmbH' | 'GmbH & Co. KG' | 'AG' | 'LLC' | 'LLP' | 'GmbH & Co. KGaA' | 'GmbH & Co. KGaA, LLC';
18
26
  managingDirectors?: string[];
19
27
  boardOfDirectors?: string[];
20
28
  supervisoryBoard?: string[];
@@ -23,4 +31,8 @@ export declare class BusinessRecord extends plugins.smartdata.SmartDataDbDoc<Bus
23
31
  purpose?: string;
24
32
  lastUpdate?: string;
25
33
  };
34
+ /**
35
+ * validates the record against the Handelregister.
36
+ */
37
+ validate(): Promise<void>;
26
38
  }
@@ -7,12 +7,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
+ var BusinessRecord_1;
10
11
  import * as plugins from './plugins.js';
11
12
  let BusinessRecord = class BusinessRecord extends plugins.smartdata.SmartDataDbDoc {
12
13
  constructor() {
13
14
  super(...arguments);
14
15
  this.data = {};
15
16
  }
17
+ static { BusinessRecord_1 = this; }
18
+ // STATIC
19
+ static { this.getByGermanParsedRegistration = async (parsedGermanRegistrationArg) => {
20
+ const businessRecords = await BusinessRecord_1.getInstance({
21
+ data: {
22
+ germanParsedRegistration: parsedGermanRegistrationArg,
23
+ }
24
+ });
25
+ return businessRecords;
26
+ }; }
27
+ /**
28
+ * validates the record against the Handelregister.
29
+ */
30
+ async validate() {
31
+ if (!this.data.name)
32
+ throw new Error('Name is required.');
33
+ }
16
34
  };
17
35
  __decorate([
18
36
  plugins.smartdata.unI(),
@@ -22,8 +40,8 @@ __decorate([
22
40
  plugins.smartdata.svDb(),
23
41
  __metadata("design:type", Object)
24
42
  ], BusinessRecord.prototype, "data", void 0);
25
- BusinessRecord = __decorate([
43
+ BusinessRecord = BusinessRecord_1 = __decorate([
26
44
  plugins.smartdata.Manager()
27
45
  ], BusinessRecord);
28
46
  export { BusinessRecord };
29
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5idXNpbmVzc3JlY29yZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuYnVzaW5lc3NyZWNvcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFHakMsSUFBTSxjQUFjLEdBQXBCLE1BQU0sY0FBZSxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsY0FBOEM7SUFBN0Y7O1FBTUwsU0FBSSxHQXFCQSxFQUFFLENBQUM7SUFDVCxDQUFDO0NBQUEsQ0FBQTtBQXpCQztJQURDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFOzswQ0FDYjtBQUdYO0lBREMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUU7OzRDQXNCbEI7QUEzQkksY0FBYztJQUQxQixPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRTtHQUNmLGNBQWMsQ0E0QjFCIn0=
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5idXNpbmVzc3JlY29yZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuYnVzaW5lc3NyZWNvcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR2pDLElBQU0sY0FBYyxHQUFwQixNQUFNLGNBQWUsU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLGNBR3JEO0lBSE07O1FBb0JMLFNBQUksR0FtQ0EsRUFBRSxDQUFDO0lBUVQsQ0FBQzs7SUEzREMsU0FBUzthQUNLLGtDQUE2QixHQUFHLEtBQUssRUFBRSwyQkFBK0UsRUFBRSxFQUFFO1FBQ3RJLE1BQU0sZUFBZSxHQUFHLE1BQU0sZ0JBQWMsQ0FBQyxXQUFXLENBQUM7WUFDdkQsSUFBSSxFQUFFO2dCQUNKLHdCQUF3QixFQUFFLDJCQUEyQjthQUN0RDtTQUNGLENBQUMsQ0FBQztRQUNILE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUMsQUFQMEMsQ0FPekM7SUE2Q0Y7O09BRUc7SUFDSSxLQUFLLENBQUMsUUFBUTtRQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzVELENBQUM7O0FBN0NEO0lBREMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7OzBDQUNiO0FBR1g7SUFEQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTs7NENBb0NsQjtBQXZESSxjQUFjO0lBRDFCLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFO0dBQ2YsY0FBYyxDQStEMUIifQ==
@@ -1,3 +1,4 @@
1
+ import type { BusinessRecord } from './classes.businessrecord.js';
1
2
  import type { OpenData } from './classes.main.opendata.js';
2
3
  import * as plugins from './plugins.js';
3
4
  /**
@@ -5,12 +6,126 @@ import * as plugins from './plugins.js';
5
6
  */
6
7
  export declare class HandelsRegister {
7
8
  private openDataRef;
9
+ private asyncExecutionStack;
10
+ private uniqueDowloadFolder;
8
11
  smartbrowserInstance: plugins.smartbrowser.SmartBrowser;
9
12
  constructor(openDataRef: OpenData);
10
13
  start(): Promise<void>;
11
14
  stop(): Promise<void>;
12
15
  /**
13
- * Search for a company by name
16
+ * Creates a new page and configures it to allow file downloads
17
+ * to a predefined path.
14
18
  */
15
- getDataForCompany(companyNameArg: string): Promise<any[]>;
19
+ getNewPage: () => Promise<plugins.smartbrowser.smartpuppeteer.puppeteer.Page>;
20
+ private navigateToPage;
21
+ private waitForResults;
22
+ private clickFindButton;
23
+ private downloadFile;
24
+ /**
25
+ * Helper method to parse the German registration string
26
+ */
27
+ private parseGermanRegistration;
28
+ /**
29
+ * Search for a company by name and return basic info
30
+ */
31
+ searchCompany(companyNameArg: string, resultsLimitArg?: number): Promise<{
32
+ name?: string;
33
+ startDate?: string;
34
+ endDate?: string;
35
+ status?: "active" | "liquidating" | "closed";
36
+ address?: string;
37
+ postalCode?: string;
38
+ city?: string;
39
+ country?: string;
40
+ phone?: string;
41
+ fax?: string;
42
+ email?: string;
43
+ website?: string;
44
+ businessType?: string;
45
+ registrationId?: string;
46
+ germanParsedRegistration?: {
47
+ court?: string;
48
+ type?: "HRA" | "HRB" | "GnR" | "PR" | "VR" | "GsR";
49
+ number?: string;
50
+ };
51
+ legalForm?: "GmbH" | "GmbH & Co. KG" | "AG" | "LLC" | "LLP" | "GmbH & Co. KGaA" | "GmbH & Co. KGaA, LLC";
52
+ managingDirectors?: string[];
53
+ boardOfDirectors?: string[];
54
+ supervisoryBoard?: string[];
55
+ foundingDate?: string;
56
+ capital?: string;
57
+ purpose?: string;
58
+ lastUpdate?: string;
59
+ }[]>;
60
+ /**
61
+ * Search for a specific company (known register type/number/court),
62
+ * then click on an element that triggers a file download.
63
+ */
64
+ getSpecificCompany(companyArg: BusinessRecord['data']['germanParsedRegistration']): Promise<{
65
+ businessRecords: {
66
+ name?: string;
67
+ startDate?: string;
68
+ endDate?: string;
69
+ status?: "active" | "liquidating" | "closed";
70
+ address?: string;
71
+ postalCode?: string;
72
+ city?: string;
73
+ country?: string;
74
+ phone?: string;
75
+ fax?: string;
76
+ email?: string;
77
+ website?: string;
78
+ businessType?: string;
79
+ registrationId?: string;
80
+ germanParsedRegistration?: {
81
+ court?: string;
82
+ type?: "HRA" | "HRB" | "GnR" | "PR" | "VR" | "GsR";
83
+ number?: string;
84
+ };
85
+ legalForm?: "GmbH" | "GmbH & Co. KG" | "AG" | "LLC" | "LLP" | "GmbH & Co. KGaA" | "GmbH & Co. KGaA, LLC";
86
+ managingDirectors?: string[];
87
+ boardOfDirectors?: string[];
88
+ supervisoryBoard?: string[];
89
+ foundingDate?: string;
90
+ capital?: string;
91
+ purpose?: string;
92
+ lastUpdate?: string;
93
+ }[];
94
+ files: plugins.smartfile.SmartFile[];
95
+ }>;
96
+ /**
97
+ * get specific company by full name
98
+ */
99
+ getSpecificCompanyByName(companyNameArg: string): Promise<{
100
+ businessRecords: {
101
+ name?: string;
102
+ startDate?: string;
103
+ endDate?: string;
104
+ status?: "active" | "liquidating" | "closed";
105
+ address?: string;
106
+ postalCode?: string;
107
+ city?: string;
108
+ country?: string;
109
+ phone?: string;
110
+ fax?: string;
111
+ email?: string;
112
+ website?: string;
113
+ businessType?: string;
114
+ registrationId?: string;
115
+ germanParsedRegistration?: {
116
+ court?: string;
117
+ type?: "HRA" | "HRB" | "GnR" | "PR" | "VR" | "GsR";
118
+ number?: string;
119
+ };
120
+ legalForm?: "GmbH" | "GmbH & Co. KG" | "AG" | "LLC" | "LLP" | "GmbH & Co. KGaA" | "GmbH & Co. KGaA, LLC";
121
+ managingDirectors?: string[];
122
+ boardOfDirectors?: string[];
123
+ supervisoryBoard?: string[];
124
+ foundingDate?: string;
125
+ capital?: string;
126
+ purpose?: string;
127
+ lastUpdate?: string;
128
+ }[];
129
+ files: plugins.smartfile.SmartFile[];
130
+ }>;
16
131
  }
@@ -1,111 +1,288 @@
1
1
  import * as plugins from './plugins.js';
2
+ import * as paths from './paths.js';
2
3
  /**
3
4
  * the HandlesRegister exposed as a class
4
5
  */
5
6
  export class HandelsRegister {
6
7
  constructor(openDataRef) {
8
+ this.asyncExecutionStack = new plugins.lik.AsyncExecutionStack();
9
+ this.uniqueDowloadFolder = plugins.path.join(paths.downloadDir, plugins.smartunique.uniSimple());
10
+ // Puppeteer wrapper instance
7
11
  this.smartbrowserInstance = new plugins.smartbrowser.SmartBrowser();
12
+ /**
13
+ * Creates a new page and configures it to allow file downloads
14
+ * to a predefined path.
15
+ */
16
+ this.getNewPage = async () => {
17
+ const page = await this.smartbrowserInstance.headlessBrowser.newPage();
18
+ // 1) Create a DevTools session for this page
19
+ const cdpSession = await page.target().createCDPSession();
20
+ // 2) Allow file downloads and set the download path
21
+ await cdpSession.send('Page.setDownloadBehavior', {
22
+ behavior: 'allow',
23
+ downloadPath: this.uniqueDowloadFolder, // <-- Change this to your desired absolute path
24
+ });
25
+ // Optionally set viewport and go to page
26
+ await page.setViewport({ width: 1920, height: 1080 });
27
+ await page.goto('https://www.handelsregister.de/');
28
+ return page;
29
+ };
30
+ this.navigateToPage = async (pageArg, pageNameArg) => {
31
+ try {
32
+ await pageArg.evaluate((pageNameArg2) => {
33
+ const elements = Array.from(document.querySelectorAll('.ui-menuitem-text > span'));
34
+ const targetElement = elements.find((el) => el.textContent?.trim() === pageNameArg2);
35
+ if (targetElement) {
36
+ targetElement.click();
37
+ }
38
+ }, pageNameArg);
39
+ console.log(`Navigated to the ${pageNameArg} page successfully.`);
40
+ }
41
+ catch (error) {
42
+ console.error(`Failed to navigate to the ${pageNameArg} page:`, error);
43
+ }
44
+ };
45
+ this.waitForResults = async (pageArg) => {
46
+ await pageArg
47
+ .waitForSelector('#ergebnissForm\\:selectedSuchErgebnisFormTable_data', {
48
+ timeout: 30000,
49
+ })
50
+ .catch(async (err) => {
51
+ await pageArg.screenshot({ path: paths.downloadDir + '/error.png' });
52
+ throw err;
53
+ });
54
+ const businessRecords = await pageArg.evaluate(() => {
55
+ const rows = document.querySelectorAll('#ergebnissForm\\:selectedSuchErgebnisFormTable_data > tr');
56
+ const records = [];
57
+ rows.forEach((row) => {
58
+ const nameElement = row.querySelector('td.ui-panelgrid-cell span.marginLeft20');
59
+ const cityElement = row.querySelector('td.ui-panelgrid-cell.sitzSuchErgebnisse span');
60
+ const statusElement = row.querySelector('td.ui-panelgrid-cell span.verticalText');
61
+ const registrationCourtElement = row.querySelector('td.ui-panelgrid-cell.fontTableNameSize');
62
+ const name = nameElement?.textContent?.trim();
63
+ const city = cityElement?.textContent?.trim();
64
+ const status = statusElement?.textContent?.trim();
65
+ const registrationId = registrationCourtElement?.textContent?.trim();
66
+ // Push parsed data into records array
67
+ records.push({
68
+ name,
69
+ city,
70
+ registrationId,
71
+ businessType: status,
72
+ });
73
+ });
74
+ return records;
75
+ });
76
+ return businessRecords;
77
+ };
78
+ this.clickFindButton = async (pageArg, resultsLimitArg = 100) => {
79
+ try {
80
+ // Wait for the button with the text "Find" to appear
81
+ await pageArg.waitForSelector('span.ui-button-text.ui-c', { timeout: 5000 });
82
+ // adjust to 100 results per page
83
+ await pageArg.select('#form\\:ergebnisseProSeite_input', `${resultsLimitArg}`);
84
+ // Locate and click the button using its text
85
+ await pageArg.evaluate(() => {
86
+ const buttons = Array.from(document.querySelectorAll('span.ui-button-text.ui-c'));
87
+ const targetButton = buttons.find((button) => button.textContent?.trim() === 'Find');
88
+ if (targetButton) {
89
+ const parentButton = targetButton.closest('button') || targetButton;
90
+ parentButton.click();
91
+ }
92
+ });
93
+ console.log('Find button clicked successfully!');
94
+ }
95
+ catch (error) {
96
+ console.error('Failed to find or click the "Find" button:', error);
97
+ }
98
+ };
8
99
  this.openDataRef = openDataRef;
9
100
  }
10
101
  async start() {
102
+ // Start the browser
103
+ await plugins.smartfile.fs.ensureDir(this.uniqueDowloadFolder);
11
104
  await this.smartbrowserInstance.start();
12
105
  }
13
106
  async stop() {
107
+ // Stop the browser
108
+ await plugins.smartfile.fs.remove(this.uniqueDowloadFolder);
14
109
  await this.smartbrowserInstance.stop();
15
110
  }
16
- /**
17
- * Search for a company by name
18
- */
19
- async getDataForCompany(companyNameArg) {
20
- const page = await this.smartbrowserInstance.headlessBrowser.newPage();
21
- await page.setViewport({ width: 1920, height: 1080 });
22
- await page.goto('https://www.handelsregister.de/');
23
- await page.evaluate(() => {
24
- const elements = Array.from(document.querySelectorAll('.ui-menuitem-text > span'));
25
- const targetElement = elements.find((el) => el.textContent?.trim() === 'Normal search');
26
- if (targetElement) {
27
- targetElement.click();
111
+ async downloadFile(pageArg, typeArg) {
112
+ // Trigger the file download by clicking on the relevant link
113
+ await pageArg.evaluate((typeArg2) => {
114
+ // Locate the table body
115
+ const tableBody = document.querySelector('#ergebnissForm\\:selectedSuchErgebnisFormTable_data');
116
+ if (!tableBody) {
117
+ throw new Error('Table body not found');
28
118
  }
29
- });
30
- try {
31
- // Wait for the textarea to appear
32
- await page.waitForSelector('#form\\:schlagwoerter', { timeout: 5000 });
33
- // Enter text into the textarea using page.evaluate
34
- const inputText = companyNameArg;
35
- await page.evaluate((text) => {
36
- const textarea = document.querySelector('#form\\:schlagwoerter');
37
- if (textarea) {
38
- textarea.value = text; // Set the value
39
- // Trigger the change event manually if required
40
- const event = new Event('change', { bubbles: true });
41
- textarea.dispatchEvent(event);
42
- }
43
- }, inputText);
44
- console.log('Text entered successfully!');
45
- }
46
- catch (error) {
47
- console.error('Failed to find or enter text into the textarea:', error);
48
- }
49
- try {
50
- // Wait for the radio button's label to appear
51
- await page.waitForSelector('label[for="form:schlagwortOptionen:0"]', { timeout: 5000 });
52
- // Click the label to select the radio button
53
- await page.evaluate(() => {
54
- const label = document.querySelector('label[for="form:schlagwortOptionen:0"]');
55
- if (label) {
56
- label.click();
57
- }
58
- });
59
- console.log('Radio button clicked successfully!');
60
- }
61
- catch (error) {
62
- console.error('Failed to find or click the radio button:', error);
63
- }
64
- try {
65
- // Wait for the button with the text "Find" to appear
66
- await page.waitForSelector('span.ui-button-text.ui-c', { timeout: 5000 });
67
- // Locate and click the button using its text
68
- await page.evaluate(() => {
69
- const buttons = Array.from(document.querySelectorAll('span.ui-button-text.ui-c'));
70
- const targetButton = buttons.find((button) => button.textContent?.trim() === 'Find');
71
- if (targetButton) {
72
- const parentButton = targetButton.closest('button') || targetButton;
73
- parentButton.click();
74
- }
75
- });
76
- console.log('Find button clicked successfully!');
119
+ // Locate the first row
120
+ const firstRow = tableBody.querySelector('tr:nth-child(1)');
121
+ if (!firstRow) {
122
+ throw new Error('First row not found');
123
+ }
124
+ // Locate the last cell in the first row
125
+ const lastCell = firstRow.querySelector('td:last-child');
126
+ if (!lastCell) {
127
+ throw new Error('Last cell not found in the first row');
128
+ }
129
+ // Locate the download links
130
+ const adLink = lastCell.querySelector('a:first-of-type');
131
+ const siLink = lastCell.querySelector('a:last-of-type');
132
+ if (!siLink) {
133
+ throw new Error('SI link not found in the last cell');
134
+ }
135
+ // Simulate a click on the last <a> element
136
+ switch (typeArg2) {
137
+ case 'AD':
138
+ adLink.click();
139
+ break;
140
+ case 'SI':
141
+ siLink.click();
142
+ break;
143
+ default:
144
+ throw new Error('Invalid file type');
145
+ }
146
+ }, typeArg);
147
+ await plugins.smartfile.fs.waitForFileToBeReady(this.uniqueDowloadFolder);
148
+ const files = await plugins.smartfile.fs.fileTreeToObject(this.uniqueDowloadFolder, '**/*');
149
+ const file = files[0];
150
+ // lets clear the folder for the next download
151
+ await plugins.smartfile.fs.ensureEmptyDir(this.uniqueDowloadFolder);
152
+ switch (typeArg) {
153
+ case 'AD':
154
+ await file.rename(`ad.pdf`);
155
+ break;
156
+ case 'SI':
157
+ await file.rename(`si.xml`);
158
+ break;
159
+ break;
77
160
  }
78
- catch (error) {
79
- console.error('Failed to find or click the "Find" button:', error);
161
+ return file;
162
+ }
163
+ /**
164
+ * Helper method to parse the German registration string
165
+ */
166
+ async parseGermanRegistration(input) {
167
+ // e.g. District court Berlin (Charlottenburg) HRB 123456
168
+ const regex = /District court (\p{L}[\p{L}\s-]*?(?:\s*\([\p{L}\s-]+\))?)\s+(HRA|HRB|GnR|VR|PR|GsR)\s+(\d+)/u;
169
+ const match = input.match(regex);
170
+ if (match) {
171
+ return {
172
+ court: match[1],
173
+ type: match[2], // Adjust if needed
174
+ number: match[3],
175
+ };
80
176
  }
81
- await page.waitForSelector('#ergebnissForm\\:selectedSuchErgebnisFormTable_data', {
82
- timeout: 10000,
83
- });
84
- const businessRecords = await page.evaluate(() => {
85
- const rows = document.querySelectorAll('#ergebnissForm\\:selectedSuchErgebnisFormTable_data > tr');
86
- const records = [];
87
- rows.forEach((row) => {
88
- const nameElement = row.querySelector('td.ui-panelgrid-cell span.marginLeft20');
89
- const cityElement = row.querySelector('td.ui-panelgrid-cell.sitzSuchErgebnisse span');
90
- const statusElement = row.querySelector('td.ui-panelgrid-cell span.verticalText');
91
- const registrationCourtElement = row.querySelector('td.ui-panelgrid-cell.fontTableNameSize');
92
- const name = nameElement?.textContent?.trim();
93
- const city = cityElement?.textContent?.trim();
94
- const status = statusElement?.textContent?.trim();
95
- const registrationCourt = registrationCourtElement?.textContent?.trim();
96
- // Push parsed data into records array
97
- records.push({
98
- name,
99
- city,
100
- registrationCourt,
101
- businessType: status,
177
+ }
178
+ /**
179
+ * Search for a company by name and return basic info
180
+ */
181
+ async searchCompany(companyNameArg, resultsLimitArg = 100) {
182
+ return this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
183
+ const page = await this.getNewPage();
184
+ await this.navigateToPage(page, 'Normal search');
185
+ try {
186
+ // Wait for the textarea to appear
187
+ await page.waitForSelector('#form\\:schlagwoerter', { timeout: 5000 });
188
+ // Enter text into the textarea
189
+ const inputText = companyNameArg;
190
+ await page.evaluate((text) => {
191
+ const textarea = document.querySelector('#form\\:schlagwoerter');
192
+ if (textarea) {
193
+ textarea.value = text; // Set the value
194
+ // Trigger the change event manually if required
195
+ const event = new Event('change', { bubbles: true });
196
+ textarea.dispatchEvent(event);
197
+ }
198
+ }, inputText);
199
+ console.log('Text entered successfully!');
200
+ }
201
+ catch (error) {
202
+ console.error('Failed to find or enter text into the textarea:', error);
203
+ }
204
+ try {
205
+ // Wait for the radio button's label to appear
206
+ await page.waitForSelector('label[for="form:schlagwortOptionen:0"]', { timeout: 5000 });
207
+ // Click the label to select the radio button
208
+ await page.evaluate(() => {
209
+ const label = document.querySelector('label[for="form:schlagwortOptionen:0"]');
210
+ if (label) {
211
+ label.click();
212
+ }
102
213
  });
103
- });
104
- return records;
105
- });
106
- await page.close();
107
- // Finally, we return an object, which triggers a JSON file download
108
- return businessRecords;
214
+ console.log('Radio button clicked successfully!');
215
+ }
216
+ catch (error) {
217
+ console.error('Failed to find or click the radio button:', error);
218
+ }
219
+ await this.clickFindButton(page, resultsLimitArg);
220
+ const businessRecords = await this.waitForResults(page);
221
+ // Parse out the registration info
222
+ for (const record of businessRecords) {
223
+ if (record.registrationId) {
224
+ record.germanParsedRegistration = await this.parseGermanRegistration(record.registrationId);
225
+ }
226
+ }
227
+ await page.close();
228
+ return businessRecords;
229
+ }, 60000);
230
+ }
231
+ /**
232
+ * Search for a specific company (known register type/number/court),
233
+ * then click on an element that triggers a file download.
234
+ */
235
+ async getSpecificCompany(companyArg) {
236
+ return this.asyncExecutionStack.getExclusiveExecutionSlot(async () => {
237
+ const page = await this.getNewPage();
238
+ await this.navigateToPage(page, 'Normal search');
239
+ await page.waitForSelector('#form\\:schlagwoerter', { timeout: 5000 });
240
+ // 1) Type of Register (e.g. HRB, HRA, etc.)
241
+ await page.waitForSelector('#form\\:registerArt_label');
242
+ await page.click('#form\\:registerArt_label');
243
+ await page.waitForSelector('#form\\:registerArt_items');
244
+ await page.evaluate((type) => {
245
+ const options = Array.from(document.querySelectorAll('#form\\:registerArt_items li'));
246
+ const targetOption = options.find((option) => option.textContent?.trim() === type);
247
+ targetOption?.click();
248
+ }, companyArg.type);
249
+ // 2) Register number
250
+ await page.waitForSelector('#form\\:registerNummer');
251
+ await page.type('#form\\:registerNummer', companyArg.number);
252
+ // 3) Register court
253
+ await page.waitForSelector('#form\\:registergericht_label');
254
+ await page.click('#form\\:registergericht_label');
255
+ await page.waitForSelector('#form\\:registergericht_items');
256
+ await page.evaluate((court) => {
257
+ const options = Array.from(document.querySelectorAll('#form\\:registergericht_items li'));
258
+ const targetOption = options.find((option) => option.textContent?.trim() === court);
259
+ targetOption?.click();
260
+ }, companyArg.court);
261
+ // Click 'Find'
262
+ await this.clickFindButton(page);
263
+ // Optionally grab the results, just for logging
264
+ const businessRecords = await this.waitForResults(page);
265
+ console.log(businessRecords);
266
+ const files = [];
267
+ // download files
268
+ files.push(await this.downloadFile(page, 'SI'));
269
+ files.push(await this.downloadFile(page, 'AD'));
270
+ // At this point, the file should have been downloaded automatically
271
+ // to the path specified by `Page.setDownloadBehavior`
272
+ await page.close();
273
+ return {
274
+ businessRecords,
275
+ files,
276
+ };
277
+ }, 60000);
278
+ }
279
+ /**
280
+ * get specific company by full name
281
+ */
282
+ async getSpecificCompanyByName(companyNameArg) {
283
+ const businessRecords = await this.searchCompany(companyNameArg, 1);
284
+ const result = this.getSpecificCompany(businessRecords[0].germanParsedRegistration);
285
+ return result;
109
286
  }
110
287
  }
111
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5oYW5kZWxzcmVnaXN0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmhhbmRlbHNyZWdpc3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4Qzs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBSzFCLFlBQVksV0FBcUI7UUFGMUIseUJBQW9CLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBR3BFLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0lBQ2pDLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNoQixNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsY0FBc0I7UUFDbkQsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZFLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUN2QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUM7WUFDbkYsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxD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
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5oYW5kZWxzcmVnaXN0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmhhbmRlbHNyZWdpc3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUVwQzs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBUTFCLFlBQVksV0FBcUI7UUFOekIsd0JBQW1CLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDNUQsd0JBQW1CLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFFcEcsNkJBQTZCO1FBQ3RCLHlCQUFvQixHQUFHLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQWtCdEU7OztXQUdHO1FBQ0ksZUFBVSxHQUFHLEtBQUssSUFBSSxFQUFFO1lBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUV2RSw2Q0FBNkM7WUFDN0MsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUUxRCxvREFBb0Q7WUFDcEQsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFO2dCQUNoRCxRQUFRLEVBQUUsT0FBTztnQkFDakIsWUFBWSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxnREFBZ0Q7YUFDekYsQ0FBQyxDQUFDO1lBRUgseUNBQXlDO1lBQ3pDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUs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