inital commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
||||||
1088
package-lock.json
generated
Normal file
1088
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
package.json
Normal file
15
package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"express": "latest",
|
||||||
|
"ikea-availability-checker": "latest"
|
||||||
|
},
|
||||||
|
"name": "IkeaAvailabilityTools",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"description": "Tools for checking availability at IKEA stores",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node ./server.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
89
public/index.html
Normal file
89
public/index.html
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>IKEA Stock Checker</title>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background: #000000ab;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
padding: 1%;
|
||||||
|
}
|
||||||
|
body { font-family: Arial; padding: 20px; }
|
||||||
|
input { padding: 8px; margin: 5px; }
|
||||||
|
button { padding: 10px; }
|
||||||
|
#result { margin-top: 20px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>IKEA Tools</h1>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><h2>Store stock checker</h2></td>
|
||||||
|
<td><h2>Store finder</h2></td>
|
||||||
|
<td><h2>Country stock checker</h2></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<label>Product ID:</label>
|
||||||
|
<input id="product" placeholder="e.g. 30457915"><br>
|
||||||
|
<label>Store ID:</label>
|
||||||
|
<input id="store" placeholder="e.g. 088 (Amsterdam)"><br>
|
||||||
|
<button onclick="checkStock()">Check Stock</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>Country code:</label>
|
||||||
|
<input id="countryCode" placeholder="e.g. nl"><br>
|
||||||
|
<button onclick="GetStores()">Get stores</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<label>Product ID:</label>
|
||||||
|
<input id="product2" placeholder="e.g. 30457915"><br>
|
||||||
|
<label>Country code:</label>
|
||||||
|
<input id="countryCode2" placeholder="e.g. nl"><br>
|
||||||
|
<button onclick="checkCountryStock()">Check Stock</button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div id="result"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function checkStock() {
|
||||||
|
const product = document.getElementById("product").value;
|
||||||
|
const store = document.getElementById("store").value;
|
||||||
|
|
||||||
|
const res = await fetch(`/api/stock?product=${product}&store=${store}`);
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
document.getElementById("result").innerHTML =
|
||||||
|
`<pre>${JSON.stringify(data, null, 2)}</pre>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetStores() {
|
||||||
|
const countryCode = document.getElementById("countryCode").value;
|
||||||
|
|
||||||
|
const res = await fetch(`/api/stores?countryCode=${countryCode}}`);
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
document.getElementById("result").innerHTML =
|
||||||
|
`<pre>${JSON.stringify(data, null, 2)}</pre>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkCountryStock() {
|
||||||
|
const product = document.getElementById("product2").value;
|
||||||
|
const countryCode = document.getElementById("countryCode2").value;
|
||||||
|
|
||||||
|
const res = await fetch(`/api/countrystock?countryCode=${countryCode}&product=${product}`);
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
document.getElementById("result").innerHTML =
|
||||||
|
`<pre>${JSON.stringify(data, null, 2)}</pre>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
139
server.js
Normal file
139
server.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const ikea = require("ikea-availability-checker");
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = 3000;
|
||||||
|
|
||||||
|
app.use(express.static("public"));
|
||||||
|
|
||||||
|
app.get("/api/stock", async (req, res) => {
|
||||||
|
const { store, product } = req.query;
|
||||||
|
|
||||||
|
if (!product || !store) {
|
||||||
|
return res.status(400).json({ error: "Missing product or store parameter" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await ikea.availability(store, product);
|
||||||
|
const Filterdresult = ({
|
||||||
|
productId: result.productId || null,
|
||||||
|
stock: result.stock,
|
||||||
|
probability: result.probability,
|
||||||
|
store: result.store.name,
|
||||||
|
buCode: result.store.buCode,
|
||||||
|
country: result.store.country,
|
||||||
|
});
|
||||||
|
res.json(Filterdresult);
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
error: "Failed to fetch stock",
|
||||||
|
details: err.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/api/countrystock", async (req, res) => {
|
||||||
|
const { countryCode, product } = req.query;
|
||||||
|
|
||||||
|
if (!product || !countryCode) {
|
||||||
|
return res.status(400).json({ error: "Missing product or countryCode parameter" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const stores = ikea.stores.findByCountryCode(countryCode);
|
||||||
|
const result = await ikea.availabilities(stores, [product]);
|
||||||
|
const Filterdresult = result.map(item => ({
|
||||||
|
productId: item.productId || null,
|
||||||
|
stock: item.stock,
|
||||||
|
probability: item.probability,
|
||||||
|
store: item.store.name,
|
||||||
|
buCode: item.store.buCode,
|
||||||
|
country: item.store.country,
|
||||||
|
}));
|
||||||
|
res.json(Filterdresult);
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
error: "Failed to fetch stock",
|
||||||
|
details: err.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/stores", async (req, res) => {
|
||||||
|
const { countryCode } = req.query;
|
||||||
|
|
||||||
|
if (!countryCode) {
|
||||||
|
return res.status(400).json({ error: "Missing product or store parameter" });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await ikea.stores.findByCountryCode(countryCode);
|
||||||
|
|
||||||
|
const Filterdresult = result.map(item => ({
|
||||||
|
buCode: item.buCode || null,
|
||||||
|
name: item.name,
|
||||||
|
country: item.country
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.json(Filterdresult);
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
error: "Failed to fetch stock",
|
||||||
|
details: err.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//For ChangeDetection.io instance
|
||||||
|
app.get("/api/change", async (req, res) => {
|
||||||
|
const { product, store } = req.query;
|
||||||
|
|
||||||
|
if (!product || !store) {
|
||||||
|
return res.status(400).send("Missing product or store");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await ikea.availability(store, product);
|
||||||
|
const quantity = result.stock ?? 0;
|
||||||
|
let inStock;
|
||||||
|
|
||||||
|
if( quantity > 0 ) {
|
||||||
|
inStock = "InStock" ;
|
||||||
|
} else{
|
||||||
|
inStock = "OutOfStock" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(`
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background: #000000ab;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h1>${product}</h1>
|
||||||
|
<p>Status: ${inStock ? "In Stock" : "Out of Stock"}</p>
|
||||||
|
|
||||||
|
<!-- JSON-LD structured data for restock detection -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org/",
|
||||||
|
"@type": "Product",
|
||||||
|
"name": "${product}",
|
||||||
|
"offers": {
|
||||||
|
"@type": "Offer",
|
||||||
|
"priceCurrency": "EUR",
|
||||||
|
"availability": "https://schema.org/${inStock}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`);
|
||||||
|
} catch (err) {
|
||||||
|
res.type("text").send("error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Server running at http://localhost:${PORT}`);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user