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