mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 14:31:07 +02:00
adding test fixtures so that we can run tests 'offline'
This commit is contained in:
@@ -19,4 +19,4 @@ jobs:
|
||||
cache: 'yarn'
|
||||
|
||||
- run: yarn install
|
||||
- run: yarn testGH
|
||||
- run: yarn test:offline
|
||||
|
||||
@@ -188,10 +188,25 @@ You should now be able to access _Fredy_ from your browser. Check your Terminal
|
||||
|
||||
### Run Tests
|
||||
|
||||
## "Online" tests
|
||||
These tests are directly executed against the actual providers.
|
||||
``` bash
|
||||
yarn run test
|
||||
```
|
||||
|
||||
## "Offline" tests
|
||||
These tests are using the test fixtures instead of the actual providers. Much faster and "good enough" to test the core functionality.
|
||||
``` bash
|
||||
yarn run test:offline
|
||||
```
|
||||
|
||||
## Download new fixtures
|
||||
If you have to refresh the fixtures (every once in a while needed because the providers change their code), run this command:
|
||||
``` bash
|
||||
yarn run download-fixtures
|
||||
```
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 📐 Architecture
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @returns {number|null}
|
||||
*/
|
||||
export const extractNumber = (str) => {
|
||||
if (str == null) return null;
|
||||
if (str == null) return 0;
|
||||
if (typeof str === 'number') return str;
|
||||
const cleaned = str.replace(/\./g, '').replace(',', '.');
|
||||
const num = parseFloat(cleaned);
|
||||
|
||||
+9
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fredy",
|
||||
"version": "20.3.2",
|
||||
"version": "20.3.3",
|
||||
"description": "[F]ind [R]eal [E]states [d]amn eas[y].",
|
||||
"scripts": {
|
||||
"prepare": "husky",
|
||||
@@ -11,8 +11,9 @@
|
||||
"build:frontend": "vite build",
|
||||
"format": "prettier --write \"**/*.js\"",
|
||||
"format:check": "prettier --check \"**/*.js\"",
|
||||
"test": "vitest run",
|
||||
"testGH": "vitest run --config vitest.gh.config.js",
|
||||
"test": "x-var TEST_MODE=live vitest run",
|
||||
"test:offline": "x-var TEST_MODE=offline vitest run",
|
||||
"test:download-fixtures": "node tools/testFixtures/downloadFixtures.js",
|
||||
"lint": "eslint .",
|
||||
"mcp:stdio": "node lib/mcp/stdio.js",
|
||||
"lint:fix": "yarn lint --fix",
|
||||
@@ -61,9 +62,9 @@
|
||||
"Firefox ESR"
|
||||
],
|
||||
"dependencies": {
|
||||
"@douyinfe/semi-icons": "^2.95.0",
|
||||
"@douyinfe/semi-ui": "2.95.0",
|
||||
"@douyinfe/semi-ui-19": "^2.95.0",
|
||||
"@douyinfe/semi-icons": "^2.95.1",
|
||||
"@douyinfe/semi-ui": "2.95.1",
|
||||
"@douyinfe/semi-ui-19": "^2.95.1",
|
||||
"@mapbox/mapbox-gl-draw": "^1.5.1",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@sendgrid/mail": "8.1.6",
|
||||
@@ -84,7 +85,7 @@
|
||||
"nodemailer": "^8.0.5",
|
||||
"p-throttle": "^8.1.0",
|
||||
"package-up": "^5.0.0",
|
||||
"puppeteer": "^24.41.0",
|
||||
"puppeteer": "^24.42.0",
|
||||
"puppeteer-extra": "^3.3.6",
|
||||
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
||||
"query-string": "9.3.1",
|
||||
@@ -94,7 +95,7 @@
|
||||
"react-range-slider-input": "^3.3.5",
|
||||
"react-router": "7.14.1",
|
||||
"react-router-dom": "7.14.1",
|
||||
"resend": "^6.12.0",
|
||||
"resend": "^6.12.2",
|
||||
"restana": "5.2.0",
|
||||
"semver": "^7.7.4",
|
||||
"serve-static": "2.2.1",
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2026 by Christian Kellner.
|
||||
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
||||
*/
|
||||
|
||||
import { readFile } from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const FIXTURES_DIR = path.join(__dirname, 'testFixtures');
|
||||
|
||||
const testProviderConfig = JSON.parse(
|
||||
await readFile(new URL('./provider/testProvider.json', import.meta.url), 'utf-8'),
|
||||
);
|
||||
|
||||
// hostname → providerName, built from testProvider.json
|
||||
const hostnameToProvider = {};
|
||||
// providerName → list page pathname (for distinguishing list vs detail URLs)
|
||||
const providerListPath = {};
|
||||
|
||||
for (const [name, cfg] of Object.entries(testProviderConfig)) {
|
||||
if (!cfg.url) continue;
|
||||
try {
|
||||
const parsed = new URL(cfg.url);
|
||||
hostnameToProvider[parsed.hostname] = name;
|
||||
providerListPath[name] = parsed.pathname;
|
||||
} catch {
|
||||
// skip malformed URLs
|
||||
}
|
||||
}
|
||||
|
||||
async function tryReadFile(filepath) {
|
||||
try {
|
||||
return await readFile(filepath, 'utf-8');
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns fixture HTML for the given URL by mapping hostname → provider name,
|
||||
* then distinguishing list vs detail pages by comparing the URL path against
|
||||
* the configured list URL path from testProvider.json.
|
||||
*/
|
||||
export async function readFixture(url) {
|
||||
let hostname, pathname;
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
hostname = parsed.hostname;
|
||||
pathname = parsed.pathname;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
const providerName = hostnameToProvider[hostname];
|
||||
if (!providerName) return null;
|
||||
|
||||
if (providerListPath[providerName] === pathname) {
|
||||
return tryReadFile(path.join(FIXTURES_DIR, `${providerName}.html`));
|
||||
}
|
||||
|
||||
// Detail page: prefer dedicated detail fixture, fall back to list fixture
|
||||
const detailHtml = await tryReadFile(path.join(FIXTURES_DIR, `${providerName}_detail.html`));
|
||||
if (detailHtml) return detailHtml;
|
||||
return tryReadFile(path.join(FIXTURES_DIR, `${providerName}.html`));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fetch replacement that intercepts immoscout mobile API calls and
|
||||
* serves pre-downloaded JSON fixtures. Throws for any other URL to prevent
|
||||
* accidental live network traffic in offline mode.
|
||||
*/
|
||||
export function buildFetchMock() {
|
||||
let listData = null;
|
||||
let detailData = null;
|
||||
|
||||
return async (url) => {
|
||||
const urlStr = String(url);
|
||||
|
||||
if (urlStr.includes('api.mobile.immobilienscout24.de/search/list')) {
|
||||
if (!listData) {
|
||||
const raw = await tryReadFile(path.join(FIXTURES_DIR, 'immoscout_list.json'));
|
||||
listData = raw ? JSON.parse(raw) : { resultListItems: [] };
|
||||
}
|
||||
return { ok: true, status: 200, json: () => Promise.resolve(listData) };
|
||||
}
|
||||
|
||||
if (urlStr.includes('api.mobile.immobilienscout24.de/expose/')) {
|
||||
if (!detailData) {
|
||||
const raw = await tryReadFile(path.join(FIXTURES_DIR, 'immoscout_detail.json'));
|
||||
detailData = raw ? JSON.parse(raw) : { sections: [], contact: {} };
|
||||
}
|
||||
return { ok: true, status: 200, json: () => Promise.resolve(detailData) };
|
||||
}
|
||||
|
||||
throw new Error(`Network request blocked in offline mode: ${urlStr}`);
|
||||
};
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,998 @@
|
||||
{
|
||||
"totalResults": 1505,
|
||||
"pageSize": 20,
|
||||
"pageNumber": 1,
|
||||
"numberOfPages": 76,
|
||||
"numberOfListings": 1505,
|
||||
"resultListItems": [
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165994740&publicationState=live",
|
||||
"id": "165994740",
|
||||
"title": "Tolle 3-Zimmer-Wohnung im Erdgeschoss mit Sonnenterrasse und schicker Einbauküche im Neubauquartier!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/5bb2b09d-75a4-4276-b285-fac7d19ec2f4-1997026927.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/5bb2b09d-75a4-4276-b285-fac7d19ec2f4-1997026927.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/5bb2b09d-75a4-4276-b285-fac7d19ec2f4-1997026927.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.740 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "82 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "3 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165994703&publicationState=live",
|
||||
"id": "165994703",
|
||||
"title": "Neubauquartier Deiker Höfe: Attraktive Dachgeschosswohnung mit Einbauküche und Sonnenloggia!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/8183b9a1-a928-491c-b6ea-6f3a5ff8162f-1997026335.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/8183b9a1-a928-491c-b6ea-6f3a5ff8162f-1997026335.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/8183b9a1-a928-491c-b6ea-6f3a5ff8162f-1997026335.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.790 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "78 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "3 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=166561801&publicationState=live",
|
||||
"id": "166561801",
|
||||
"title": "Gut geschnittene 2-Zimmer-Wohnung mit Einbauküche und Loggia im Neubauquartier Deiker Höfe!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/44e0e5f9-d5d8-48e5-9e42-3274cbc05556-2007039892.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/44e0e5f9-d5d8-48e5-9e42-3274cbc05556-2007039892.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/44e0e5f9-d5d8-48e5-9e42-3274cbc05556-2007039892.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.320 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "59 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165975759&publicationState=live",
|
||||
"id": "165975759",
|
||||
"title": "Exklusive 4-Zimmer-Wohnung in den Deiker Höfen mit Einbauküche, Südloggia und Dachterrasse!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/756e9426-c1f8-4756-98b1-2bdc6028f07a-1996650985.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/756e9426-c1f8-4756-98b1-2bdc6028f07a-1996650985.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/756e9426-c1f8-4756-98b1-2bdc6028f07a-1996650985.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.150 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "98 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "4 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165975741&publicationState=live",
|
||||
"id": "165975741",
|
||||
"title": "Exklusive 5-Zimmer-Wohnung mit Einbauküche im 1. Obergeschoss des Neubauquartiers Deiker Höfe!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/eb298253-08a4-48eb-baa6-4ad19ed72df3-1996650699.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/eb298253-08a4-48eb-baa6-4ad19ed72df3-1996650699.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/eb298253-08a4-48eb-baa6-4ad19ed72df3-1996650699.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.360 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "113 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "5 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165975624&publicationState=live",
|
||||
"id": "165975624",
|
||||
"title": "Exklusive 2-Zimmer-Wohnung im Erdgeschoss mit Einbauküche im Neubauquartier Deiker Höfe!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/6fafe087-d314-4727-bc7a-0bf7aed4c73a-1996648745.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/6fafe087-d314-4727-bc7a-0bf7aed4c73a-1996648745.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/6fafe087-d314-4727-bc7a-0bf7aed4c73a-1996648745.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.520 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "71 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165975598&publicationState=live",
|
||||
"id": "165975598",
|
||||
"title": "Tolle 3-Zimmer-Wohnung mit Einbauküche und großer Süd-Terrasse im Neubauquartier Deiker Höfe!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/29e6e279-21ed-4630-8229-2d455d60c5ac-1996648285.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/29e6e279-21ed-4630-8229-2d455d60c5ac-1996648285.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/29e6e279-21ed-4630-8229-2d455d60c5ac-1996648285.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.320 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "58 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165975460&publicationState=live",
|
||||
"id": "165975460",
|
||||
"title": "Gut geschnittene 2-Zimmer-Wohnung mit Einbauküche im exklusiven Neubauquartier Deiker Höfe!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/b93d4825-7e8a-4e0f-824e-cd1a7e6bf35e-1996645907.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/b93d4825-7e8a-4e0f-824e-cd1a7e6bf35e-1996645907.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/b93d4825-7e8a-4e0f-824e-cd1a7e6bf35e-1996645907.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.210 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "51 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165199718&publicationState=live",
|
||||
"id": "165199718",
|
||||
"title": "Neubauquartier Deiker Höfe: Attraktive 4-Zimmer-Wohnung mit Einbauküche und Balkon",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/dac3d681-8027-4d3a-8c4b-3d89be4ed223-1985561565.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/dac3d681-8027-4d3a-8c4b-3d89be4ed223-1985561565.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/dac3d681-8027-4d3a-8c4b-3d89be4ed223-1985561565.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 3 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.190 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "102 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "4 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=167016936&publicationState=live",
|
||||
"id": "167016936",
|
||||
"title": "Erstbezug: Einladende Dachgeschosswohnung mit Einbauküche und Westbalkon!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/bdfc5d22-dd7c-4fa3-ad6e-1339ad1083f9-2014969185.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/bdfc5d22-dd7c-4fa3-ad6e-1339ad1083f9-2014969185.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/bdfc5d22-dd7c-4fa3-ad6e-1339ad1083f9-2014969185.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 3 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.360 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "113 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "5 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165199377&publicationState=live",
|
||||
"id": "165199377",
|
||||
"title": "Großzügige Neubauwohnung mit 4 Zimmern im Erdgeschoss inklusive Einbauküche und einladender Terrasse",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/2c6d2272-d28e-477d-8ee2-63a05263244a-1985562301.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/2c6d2272-d28e-477d-8ee2-63a05263244a-1985562301.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/2c6d2272-d28e-477d-8ee2-63a05263244a-1985562301.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 3 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.230 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "105 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "4 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165146621&publicationState=live",
|
||||
"id": "165146621",
|
||||
"title": "Großzügige 3-Zimmer-Wohnung im Erdgeschoss mit Südterrasse und Einbauküche im Neubauquartier!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/6059fc5f-2f9d-43b9-9e6c-9f82c715e8c7-1985563642.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/6059fc5f-2f9d-43b9-9e6c-9f82c715e8c7-1985563642.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/6059fc5f-2f9d-43b9-9e6c-9f82c715e8c7-1985563642.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 3 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.870 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "89 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "3 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=164094597&publicationState=live",
|
||||
"id": "164094597",
|
||||
"title": "Großzügige 2-Zimmer-Wohnung mit Einbauküche im exklusiven Neubauquartier Deiker Höfe",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/a3a0c67d-be45-423e-9a5b-8489e0123303-1967561926.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/a3a0c67d-be45-423e-9a5b-8489e0123303-1967561926.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/a3a0c67d-be45-423e-9a5b-8489e0123303-1967561926.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 5 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.660 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "79 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=167016134&publicationState=live",
|
||||
"id": "167016134",
|
||||
"title": "Ansprechende Neubauwohnung mit Einbauküche, 4 Schlafzimmern und Bad en Suite!",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/b3e15ecd-0449-4d44-a69e-39c5081b4b82-2014962686.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/b3e15ecd-0449-4d44-a69e-39c5081b4b82-2014962686.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/b3e15ecd-0449-4d44-a69e-39c5081b4b82-2014962686.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Am Hain 53, 40468 Düsseldorf - Stockum, Stockum",
|
||||
"lat": 51.26249,
|
||||
"lon": 6.76223
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 10 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "2.990 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "150 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "5 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/d7337319-0132-41a6-8ac2-ba3619087b0f.PNG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#CEC5C0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=162614366&publicationState=live",
|
||||
"id": "162614366",
|
||||
"title": "Vollmöbliertes Studio-Apartment mit EBK und eigenem Keller | verfügbar ab sofort!",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/03667818-85ab-4eb4-8f15-c1a48dfd5f68-2016315143.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/03667818-85ab-4eb4-8f15-c1a48dfd5f68-2016315143.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/03667818-85ab-4eb4-8f15-c1a48dfd5f68-2016315143.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Moltkestraße 31, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.23962,
|
||||
"lon": 6.78686
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor einem Tag",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.120 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "36,91 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "1 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165687913&publicationState=live",
|
||||
"id": "165687913",
|
||||
"title": "Große 3-Zimmer-Wohnung mit Balkon und Einbauküche | ab sofort verfügbar!",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/c69b8e8c-3f32-409f-8efa-a412577b1076-1991704632.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/c69b8e8c-3f32-409f-8efa-a412577b1076-1991704632.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/c69b8e8c-3f32-409f-8efa-a412577b1076-1991704632.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Moltkestraße 25b, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.24016,
|
||||
"lon": 6.78547
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.655 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "90 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "3 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165687647&publicationState=live",
|
||||
"id": "165687647",
|
||||
"title": "Geräumige 2-Zimmer-Wohnung mit Einbauküche und eigener Terrasse | verfügbar ab sofort!",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/55287aea-d6d7-40b4-8aa2-45b63b253457-1991699878.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/55287aea-d6d7-40b4-8aa2-45b63b253457-1991699878.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/55287aea-d6d7-40b4-8aa2-45b63b253457-1991699878.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Moltkestraße 21c, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.24016,
|
||||
"lon": 6.78547
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.555 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "90 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165687226&publicationState=live",
|
||||
"id": "165687226",
|
||||
"title": "Neubau-Erstbezug | Große 2-Zimmer-Wohnung mit Terrasse und Einbauküche",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/04e3316f-169f-46a5-9ffd-97be14dc0aa4-1991692049.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/04e3316f-169f-46a5-9ffd-97be14dc0aa4-1991692049.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/04e3316f-169f-46a5-9ffd-97be14dc0aa4-1991692049.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Moltkestraße 25b, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.24016,
|
||||
"lon": 6.78547
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.450 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "78 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "2 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=165686635&publicationState=live",
|
||||
"id": "165686635",
|
||||
"title": "Geräumige 1-Zimmer-Wohnung mit Einbauküche zum Erstbezug | kurzfristig verfügbar",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/e9e2e984-2606-493a-b3fa-623a336943b5-2012822475.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/e9e2e984-2606-493a-b3fa-623a336943b5-2012822475.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/e9e2e984-2606-493a-b3fa-623a336943b5-2012822475.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Moltkestraße 31, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.23962,
|
||||
"lon": 6.78686
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 2 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.065 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "53 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "1 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "EXPOSE_RESULT",
|
||||
"item": {
|
||||
"reportUrl": "https://angebot-melden.immobilienscout24.de/report?realEstateId=162272460&publicationState=live",
|
||||
"id": "162272460",
|
||||
"title": "Große 1-Zimmer-Wohnung mit EBK und eigenem Keller | verfügbar ab sofort!",
|
||||
"energyEfficiencyClass": "B",
|
||||
"pictures": [
|
||||
{
|
||||
"urlScaleAndCrop": "https://pictures.immobilienscout24.de/listings/0fbfbfab-b6f1-477b-be10-b1ae72208f92-2012822634.jpg/ORIG/legacy_thumbnail/%WIDTH%x%HEIGHT%/format/webp/quality/80"
|
||||
}
|
||||
],
|
||||
"titlePicture": {
|
||||
"preview": "https://pictures.immobilienscout24.de/listings/0fbfbfab-b6f1-477b-be10-b1ae72208f92-2012822634.jpg/ORIG/resize/800x600>/format/webp/quality/20",
|
||||
"full": "https://pictures.immobilienscout24.de/listings/0fbfbfab-b6f1-477b-be10-b1ae72208f92-2012822634.jpg/ORIG/resize/800x600>/format/webp/quality/80"
|
||||
},
|
||||
"address": {
|
||||
"line": "Gneisenaustraße 66, 40477 Düsseldorf, Pempelfort",
|
||||
"lat": 51.23982,
|
||||
"lon": 6.78523
|
||||
},
|
||||
"isProject": false,
|
||||
"isPrivate": false,
|
||||
"listingType": "XL",
|
||||
"published": "vor 6 Monaten",
|
||||
"isNewObject": false,
|
||||
"liveVideoTourAvailable": false,
|
||||
"listOnlyOnIs24": false,
|
||||
"attributes": [
|
||||
{
|
||||
"label": "",
|
||||
"value": "1.110 €"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "55 m²"
|
||||
},
|
||||
{
|
||||
"label": "",
|
||||
"value": "1 Zi."
|
||||
}
|
||||
],
|
||||
"realEstateType": "apartmentrent",
|
||||
"realtor": {
|
||||
"logoUrlScale": "https://pictures.immobilienscout24.de/usercontent/ad89c012-9213-4b7a-b78d-a6e69fc88d64.JPG/ORIG/resize/%WIDTH%x%HEIGHT%%3E/format/webp/quality/80",
|
||||
"showcasePlacementColor": "#8AA1A5"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"shapes": [],
|
||||
"reporting": {},
|
||||
"quickFilterStatistics": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,23 @@ vi.mock('../lib/services/storage/jobStorage.js', () => ({
|
||||
}));
|
||||
vi.mock('../lib/notification/notify.js', () => ({ send }));
|
||||
|
||||
vi.mock('../lib/services/extractor/puppeteerExtractor.js', async (importOriginal) => {
|
||||
if (process.env.TEST_MODE !== 'offline') {
|
||||
return importOriginal();
|
||||
}
|
||||
const { readFixture } = await import('./offlineFixtures.js');
|
||||
return {
|
||||
default: (url) => readFixture(url),
|
||||
launchBrowser: async () => ({ close: async () => {}, __fredy_removeUserDataDir: false }),
|
||||
closeBrowser: async () => {},
|
||||
};
|
||||
});
|
||||
|
||||
if (process.env.TEST_MODE === 'offline') {
|
||||
const { buildFetchMock } = await import('./offlineFixtures.js');
|
||||
vi.stubGlobal('fetch', buildFetchMock());
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<typeof import('../lib/FredyPipelineExecutioner.js').default>}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2026 by Christian Kellner.
|
||||
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
||||
*/
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { readFile, writeFile, mkdir } from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import * as cheerio from 'cheerio';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT = path.join(__dirname, '../..');
|
||||
const FIXTURES_DIR = path.join(ROOT, 'test', 'testFixtures');
|
||||
const TEST_PROVIDER_PATH = path.join(ROOT, 'test', 'provider', 'testProvider.json');
|
||||
|
||||
/**
|
||||
* Extracts the first listing link from HTML using the provider's link crawl selector.
|
||||
* Selector format: "css-selector@attribute | transform | ..."
|
||||
*/
|
||||
function extractFirstLink(html, linkSelectorExpr, baseUrl) {
|
||||
if (!linkSelectorExpr) return null;
|
||||
|
||||
const selectorPart = linkSelectorExpr.split('|')[0].trim();
|
||||
let cssSelector = selectorPart;
|
||||
let attribute = null;
|
||||
|
||||
const atMatch = selectorPart.match(/^(.+?)@(\w+)$/);
|
||||
if (atMatch) {
|
||||
cssSelector = atMatch[1].trim();
|
||||
attribute = atMatch[2];
|
||||
}
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
const el = $(cssSelector).first();
|
||||
const value = attribute ? el.attr(attribute) : el.text().trim();
|
||||
|
||||
if (!value) return null;
|
||||
if (value.startsWith('http')) return value;
|
||||
if (value.startsWith('/')) return new URL(value, baseUrl).href;
|
||||
return null;
|
||||
}
|
||||
|
||||
async function downloadImmoscoutFixtures(mobileApiUrl) {
|
||||
console.log('\nDownloading immoscout...');
|
||||
|
||||
const listResponse = await fetch(mobileApiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'User-Agent': 'ImmoScout_27.12_26.2_._',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ supportedResultListTypes: [], userData: {} }),
|
||||
});
|
||||
|
||||
if (!listResponse.ok) {
|
||||
console.warn(` Failed to download immoscout list: ${listResponse.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const listData = await listResponse.json();
|
||||
await writeFile(path.join(FIXTURES_DIR, 'immoscout_list.json'), JSON.stringify(listData, null, 2), 'utf-8');
|
||||
console.log(' Saved immoscout_list.json');
|
||||
|
||||
const exposes = (listData.resultListItems || []).filter((item) => item.type === 'EXPOSE_RESULT');
|
||||
if (exposes.length === 0) {
|
||||
console.warn(' No expose results found – skipping detail fixture');
|
||||
return;
|
||||
}
|
||||
|
||||
const exposeId = exposes[0].item?.id;
|
||||
if (!exposeId) return;
|
||||
|
||||
console.log(` Downloading immoscout detail (expose ${exposeId})...`);
|
||||
const detailResponse = await fetch(`https://api.mobile.immobilienscout24.de/expose/${exposeId}`, {
|
||||
headers: {
|
||||
'User-Agent': 'ImmoScout_27.3_26.0_._',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!detailResponse.ok) {
|
||||
console.warn(` Failed to download immoscout detail: ${detailResponse.statusText}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const detailData = await detailResponse.json();
|
||||
await writeFile(path.join(FIXTURES_DIR, 'immoscout_detail.json'), JSON.stringify(detailData, null, 2), 'utf-8');
|
||||
console.log(' Saved immoscout_detail.json');
|
||||
}
|
||||
|
||||
async function downloadHtmlProvider(name, providerConfig, launchBrowser, closeBrowser, puppeteerExtractor) {
|
||||
console.log(`\nDownloading ${name}...`);
|
||||
|
||||
const browser = await launchBrowser(providerConfig.url, {});
|
||||
try {
|
||||
const html = await puppeteerExtractor(providerConfig.url, providerConfig.waitForSelector, { browser });
|
||||
|
||||
if (!html) {
|
||||
console.warn(` Failed to download ${name}`);
|
||||
return;
|
||||
}
|
||||
|
||||
await writeFile(path.join(FIXTURES_DIR, `${name}.html`), html, 'utf-8');
|
||||
console.log(` Saved ${name}.html`);
|
||||
|
||||
const needsDetailFixture = typeof providerConfig.fetchDetails === 'function' && providerConfig.crawlFields?.link;
|
||||
|
||||
if (needsDetailFixture) {
|
||||
const detailUrl = extractFirstLink(html, providerConfig.crawlFields.link, providerConfig.url);
|
||||
if (!detailUrl) {
|
||||
console.warn(` Could not find detail URL in ${name} list page`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(` Downloading ${name} detail...`);
|
||||
const detailHtml = await puppeteerExtractor(detailUrl, null, { browser });
|
||||
if (detailHtml) {
|
||||
await writeFile(path.join(FIXTURES_DIR, `${name}_detail.html`), detailHtml, 'utf-8');
|
||||
console.log(` Saved ${name}_detail.html`);
|
||||
} else {
|
||||
console.warn(` Failed to download ${name} detail`);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
await closeBrowser(browser);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await mkdir(FIXTURES_DIR, { recursive: true });
|
||||
|
||||
const testProviderConfig = JSON.parse(await readFile(TEST_PROVIDER_PATH, 'utf-8'));
|
||||
|
||||
const {
|
||||
launchBrowser,
|
||||
closeBrowser,
|
||||
default: puppeteerExtractor,
|
||||
} = await import('../../lib/services/extractor/puppeteerExtractor.js');
|
||||
|
||||
for (const [name, cfg] of Object.entries(testProviderConfig)) {
|
||||
const provider = await import(`../../lib/provider/${name}.js`);
|
||||
provider.init(cfg, [], []);
|
||||
|
||||
if (name === 'immoscout') {
|
||||
await downloadImmoscoutFixtures(provider.config.url);
|
||||
} else {
|
||||
await downloadHtmlProvider(name, provider.config, launchBrowser, closeBrowser, puppeteerExtractor);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\nAll fixtures downloaded.');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('Error downloading fixtures:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -890,34 +890,34 @@
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@douyinfe/semi-animation-react@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-react/-/semi-animation-react-2.95.0.tgz#89f9f97a0448ca571744ea844e69555574dc0658"
|
||||
integrity sha512-tTyMbICbnqY7aPmrM0WwQ8L0JI2mk2QTCJpHoDK6z5deZBg0IMbozZC302oP8f2O1473/W+HKS43t2p5JaezPQ==
|
||||
"@douyinfe/semi-animation-react@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-react/-/semi-animation-react-2.95.1.tgz#1dcdef37c9cf0656f06a350972658ed1b7a21498"
|
||||
integrity sha512-KMoForxRQe0VIHa1+G1+o/mIJPLrXXjb81YDNoUV32+95ErlnWWTto4z72w34CGrCow1uTLqG9r/ib4/iqifVA==
|
||||
dependencies:
|
||||
"@douyinfe/semi-animation" "2.95.0"
|
||||
"@douyinfe/semi-animation-styled" "2.95.0"
|
||||
"@douyinfe/semi-animation" "2.95.1"
|
||||
"@douyinfe/semi-animation-styled" "2.95.1"
|
||||
classnames "^2.2.6"
|
||||
|
||||
"@douyinfe/semi-animation-styled@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.95.0.tgz#7b7d626f4b2a08d2f88977bec834ca92188384e2"
|
||||
integrity sha512-9vuLU5LPW+U5o7msN6S2ihIydF2zToXNabmYC7FHLCTXXGjJTc7eoNy3wAElNETZaFR85kpnKV6gs1tiOiRqtQ==
|
||||
"@douyinfe/semi-animation-styled@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.95.1.tgz#7e5d39a5106e80cb19bf8546b23834e73564f5a1"
|
||||
integrity sha512-e39OzzZ+74RDvdVuHrXexELZ/whix2XoHub3wHEoDqqtyA9PCi3krLKYrs9wx3E4nEtYpWXEdEAlwpHMUJBNDQ==
|
||||
|
||||
"@douyinfe/semi-animation@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation/-/semi-animation-2.95.0.tgz#012d2368ad9a04712eca15c68f1123d15ed70c4d"
|
||||
integrity sha512-iqhVg8PPD8oEMBBhXJVKik4YubLt+zC2RuWfAq3UMZe04ZDF6nGkgfBYBMIWK4a+1W1KWQWiGuiPusmgBndwhA==
|
||||
"@douyinfe/semi-animation@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation/-/semi-animation-2.95.1.tgz#5ce11db1188e8130a64e54068b61d717318b00cd"
|
||||
integrity sha512-XRotwrBA0ds+Ce6V+3MiSmhhaANW+Z7fIvgxQu0a09JYqPRbxcqhtm9ia9861JpJ0+YJ/hRcU2LeMWAdwoPE7g==
|
||||
dependencies:
|
||||
bezier-easing "^2.1.0"
|
||||
|
||||
"@douyinfe/semi-foundation@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-foundation/-/semi-foundation-2.95.0.tgz#6cc86cb4daf5b00be6aa301c8870e1170c16a003"
|
||||
integrity sha512-McSkhWw9Qlc1wDtZLY4oDynVcVoUHN1in/iqhf/iTL+nM+sDVSWHZ6nufesuBUHTTFesEK34yZxSo9Fh/lU3LA==
|
||||
"@douyinfe/semi-foundation@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-foundation/-/semi-foundation-2.95.1.tgz#8275c15c0c3a199a3d3941d08251a36efbc968b6"
|
||||
integrity sha512-wxFgRkasfvbE1JvKt8tTUPGOC3PxuAYOOKiOCZ+9yqVFOTqWPuJOORDXPN0C3UjVr6E0ZGY/tayz9GgNKG4YpQ==
|
||||
dependencies:
|
||||
"@douyinfe/semi-animation" "2.95.0"
|
||||
"@douyinfe/semi-json-viewer-core" "2.95.0"
|
||||
"@douyinfe/semi-animation" "2.95.1"
|
||||
"@douyinfe/semi-json-viewer-core" "2.95.1"
|
||||
"@mdx-js/mdx" "^3.0.1"
|
||||
async-validator "^3.5.0"
|
||||
classnames "^2.2.6"
|
||||
@@ -931,44 +931,44 @@
|
||||
remark-gfm "^4.0.0"
|
||||
scroll-into-view-if-needed "^2.2.24"
|
||||
|
||||
"@douyinfe/semi-icons@2.95.0", "@douyinfe/semi-icons@^2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.95.0.tgz#a5b937f42b3fa6deb210c879f73b3df76bc9c203"
|
||||
integrity sha512-JVKOQ7WHjbOjHXW+isydR6yWgoHaG8FN8c5r0JvVZwONUc45DutfNiK/MyuZ1JW/QzEznYAjJ0yAKze6xSEE3A==
|
||||
"@douyinfe/semi-icons@2.95.1", "@douyinfe/semi-icons@^2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.95.1.tgz#067380c0a169cb300dbb98ec41072a26c227add6"
|
||||
integrity sha512-gX4afcDaKvoosbL8zRgnJs831FNabBgnMKLAxNz6ddHp244WGBXbnlCrtrRda3GjQ3AK2WIc1Wj9npGVeqAq7w==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
|
||||
"@douyinfe/semi-illustrations@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-illustrations/-/semi-illustrations-2.95.0.tgz#7e7030269c60b26fd7e0f107db6c8576b5f423be"
|
||||
integrity sha512-ynHZHwmeb7QiNe6aMonsNBufZDCRsSRYSpEuIs1uP1dvY8l4koZxxlCu6f8tMOGGiAjRV8kCNTrszVb2XxsqhA==
|
||||
"@douyinfe/semi-illustrations@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-illustrations/-/semi-illustrations-2.95.1.tgz#42980ffa992bb4aea05d0073c3e4f0a63650cc4c"
|
||||
integrity sha512-j7/72ICRxhMUh7l77Xy4Xda8P2KH5QMQZ8wzBubrQ57aEDn0RLE+vXStrZzhItaeYSF5NnXnHCAFN2mVxkK7Nw==
|
||||
|
||||
"@douyinfe/semi-json-viewer-core@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.95.0.tgz#3a94659cc5a51cedb208b27ed06a9e04a98dfe7f"
|
||||
integrity sha512-U62wmLoeK1b30Ds7rPiU0SU/GVBmTN/gpO9abwUEDkRsqVDf7EmWWM+mJCHgxErkiHX7vDY9bwFVr26VKWOB5Q==
|
||||
"@douyinfe/semi-json-viewer-core@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.95.1.tgz#73d0f43aa067438b58055d1d533a6f4298f69671"
|
||||
integrity sha512-wZskJB55YQdIVwYtElUYWNb4XrinQe7nRUHwOFzYwvciqhJ1tAWR4r+JnwGiNIavXTBIuL51vr4JkNevhLJGBQ==
|
||||
dependencies:
|
||||
jsonc-parser "^3.3.1"
|
||||
|
||||
"@douyinfe/semi-theme-default@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-theme-default/-/semi-theme-default-2.95.0.tgz#7c03ae2e10a801a752d0292cfd560f6f810f6493"
|
||||
integrity sha512-bJvUI0gL1XEsw3aIWTHcZ9dBRoZRY8cxUMHLfNg7v2ypuYEyKbHuklrkIBWoLKGIijJUkZO3Qb38sGqLp9Gi0g==
|
||||
"@douyinfe/semi-theme-default@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-theme-default/-/semi-theme-default-2.95.1.tgz#bcf90a2e5654f117045263a53a9c6864915ca8c3"
|
||||
integrity sha512-clzisILc+n6jR3fSexS14fnsyqGDi+v/UzIM3lNMb9Bdh5SKuTGp+qZNmbhSFNM/amigQAsPWzhC4OgUXSncVA==
|
||||
|
||||
"@douyinfe/semi-ui-19@^2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui-19/-/semi-ui-19-2.95.0.tgz#196ac67e35db609af0bf3b5bfce0fd716a8712fd"
|
||||
integrity sha512-pLkYHx6GzzGRDHm2J+PNgOf9wDOhUuQk2jJtMtHuuDLpziU74T/bPMxPsG01So2/mKghuCWAcwAxC21QoLiT1g==
|
||||
"@douyinfe/semi-ui-19@^2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui-19/-/semi-ui-19-2.95.1.tgz#7b9d2e63af1b885573786489200320013f34ddcc"
|
||||
integrity sha512-/DAa78GsS8g8RUHqAa2oI+f6k0KjKjhzGGnb5QjK9tJEncYYe7dmNtsHnXV4FiIW5aMiPv9QVtD6WySy3SkzSg==
|
||||
dependencies:
|
||||
"@dnd-kit/core" "^6.0.8"
|
||||
"@dnd-kit/sortable" "^7.0.2"
|
||||
"@dnd-kit/utilities" "^3.2.1"
|
||||
"@douyinfe/semi-animation" "2.95.0"
|
||||
"@douyinfe/semi-animation-react" "2.95.0"
|
||||
"@douyinfe/semi-foundation" "2.95.0"
|
||||
"@douyinfe/semi-icons" "2.95.0"
|
||||
"@douyinfe/semi-illustrations" "2.95.0"
|
||||
"@douyinfe/semi-theme-default" "2.95.0"
|
||||
"@douyinfe/semi-animation" "2.95.1"
|
||||
"@douyinfe/semi-animation-react" "2.95.1"
|
||||
"@douyinfe/semi-foundation" "2.95.1"
|
||||
"@douyinfe/semi-icons" "2.95.1"
|
||||
"@douyinfe/semi-illustrations" "2.95.1"
|
||||
"@douyinfe/semi-theme-default" "2.95.1"
|
||||
"@tiptap/core" "^3.10.7"
|
||||
"@tiptap/extension-document" "^3.10.7"
|
||||
"@tiptap/extension-hard-break" "^3.10.7"
|
||||
@@ -997,20 +997,20 @@
|
||||
scroll-into-view-if-needed "^2.2.24"
|
||||
utility-types "^3.10.0"
|
||||
|
||||
"@douyinfe/semi-ui@2.95.0":
|
||||
version "2.95.0"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.95.0.tgz#cd83d54c8a65e39aeeb21a9bf191e81ad46a2b25"
|
||||
integrity sha512-lGHvaYA71HhU+kTX7dJk/L0WbAIXR2hK18F+pqxomYz1w0qcCMnCWwkKpoqlj0KrhlS4mFqHfDASuxBbBMwtyQ==
|
||||
"@douyinfe/semi-ui@2.95.1":
|
||||
version "2.95.1"
|
||||
resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.95.1.tgz#50e651461a2b66d018d3a7b2b3df2195edceef68"
|
||||
integrity sha512-GHtYFWM597B5/Esn5RlLhQYyAfAuxxxYL7FsgDxJu8wUWRc4xnL21oYH03FCIevuHndHqw8h86FawGvHUZrL5Q==
|
||||
dependencies:
|
||||
"@dnd-kit/core" "^6.0.8"
|
||||
"@dnd-kit/sortable" "^7.0.2"
|
||||
"@dnd-kit/utilities" "^3.2.1"
|
||||
"@douyinfe/semi-animation" "2.95.0"
|
||||
"@douyinfe/semi-animation-react" "2.95.0"
|
||||
"@douyinfe/semi-foundation" "2.95.0"
|
||||
"@douyinfe/semi-icons" "2.95.0"
|
||||
"@douyinfe/semi-illustrations" "2.95.0"
|
||||
"@douyinfe/semi-theme-default" "2.95.0"
|
||||
"@douyinfe/semi-animation" "2.95.1"
|
||||
"@douyinfe/semi-animation-react" "2.95.1"
|
||||
"@douyinfe/semi-foundation" "2.95.1"
|
||||
"@douyinfe/semi-icons" "2.95.1"
|
||||
"@douyinfe/semi-illustrations" "2.95.1"
|
||||
"@douyinfe/semi-theme-default" "2.95.1"
|
||||
"@tiptap/core" "^3.10.7"
|
||||
"@tiptap/extension-document" "^3.10.7"
|
||||
"@tiptap/extension-hard-break" "^3.10.7"
|
||||
@@ -6470,10 +6470,10 @@ punycode@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
puppeteer-core@24.41.0:
|
||||
version "24.41.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.41.0.tgz#e1c5030a8720e67a6a2530340ab08a3238b843d5"
|
||||
integrity sha512-rLIUri7E/NQ3APSEYCCozaSJx0u8Tu9wxO6BJwnvXmIgILSK3L0TombaVh3izp1njAGrO6H2ru0hcIrLF+gWLw==
|
||||
puppeteer-core@24.42.0:
|
||||
version "24.42.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.42.0.tgz#85c1f6c73e6225be0d50fc6a4f2914690280e8cf"
|
||||
integrity sha512-T4zXokk/izH01fYPhyyev1A4piWiOKrYq7CUFpdoYQxmOnXoV6YjUabmfIjCYkNspSoAXIxRid3Tw+Vg0fthYg==
|
||||
dependencies:
|
||||
"@puppeteer/browsers" "2.13.0"
|
||||
chromium-bidi "14.0.0"
|
||||
@@ -6530,16 +6530,16 @@ puppeteer-extra@^3.3.6:
|
||||
debug "^4.1.1"
|
||||
deepmerge "^4.2.2"
|
||||
|
||||
puppeteer@^24.41.0:
|
||||
version "24.41.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.41.0.tgz#fdfcc343e16a87f31578206cf9a1ff10bb33c129"
|
||||
integrity sha512-W6Fk0J3TPjjtwjXOyR/qf+YaL0H/Uq8HIgHcXG4mNM/IgbKMCH/HPyK0Fi2qbTU/QpSl9bCte2yBpGHKejTpIw==
|
||||
puppeteer@^24.42.0:
|
||||
version "24.42.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.42.0.tgz#2efe442c240ea44c05138a12a98aa0fdba1a6b83"
|
||||
integrity sha512-94MoPfFp2eY3eYIMdINkez4IOP5TMHntlZbVx06fHlQTtiQiYgaY0L2Zzfod8PVUkPqP7m3Qlre2v8YS8cudPA==
|
||||
dependencies:
|
||||
"@puppeteer/browsers" "2.13.0"
|
||||
chromium-bidi "14.0.0"
|
||||
cosmiconfig "^9.0.0"
|
||||
devtools-protocol "0.0.1595872"
|
||||
puppeteer-core "24.41.0"
|
||||
puppeteer-core "24.42.0"
|
||||
typed-query-selector "^2.12.1"
|
||||
|
||||
qs@^6.14.0:
|
||||
@@ -6863,10 +6863,10 @@ require-from-string@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
resend@^6.12.0:
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/resend/-/resend-6.12.0.tgz#99e6f33a53e757b538b9b663cf2a936943db2688"
|
||||
integrity sha512-CaxEvX1z+/MGbgnhsM/bvmkbnZd1v1sEXELAjBNSDBQNMaB7MgqOyrBgI27CYikEgdaDnBrXghAXYWTBs/h5Bw==
|
||||
resend@^6.12.2:
|
||||
version "6.12.2"
|
||||
resolved "https://registry.yarnpkg.com/resend/-/resend-6.12.2.tgz#4b9eb2e129c9369e25e19c8abd12913968e8c647"
|
||||
integrity sha512-xwgmU4b0OqoabJsIoK/x0Whk0Fcs3bpbK4i/DEWPiE5hYJHyHl0TbB6QbI3gIr+bLdLUJ1GYm/fe41aVFuHXgw==
|
||||
dependencies:
|
||||
postal-mime "2.7.4"
|
||||
svix "1.90.0"
|
||||
|
||||
Reference in New Issue
Block a user