const BAG_ENDPOINT =
"https://inmeterrijnmond-bag.hallo-a97.workers.dev";
export default {
async fetch(request, env) {
// Alleen jouw website mag deze koppeling gebruiken
const ALLOWED_ORIGINS = [
"https://www.inmeterrijnmond.nl",
"https://inmeterrijnmond.nl"
];
const origin = request.headers.get("Origin") || "";
function corsHeaders() {
return {
"Access-Control-Allow-Origin":
ALLOWED_ORIGINS.includes(origin)
? origin
: "https://www.inmeterrijnmond.nl",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"Vary": "Origin"
};
}
function json(data, status = 200) {
return new Response(
JSON.stringify(data),
{
status: status,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Cache-Control": "no-store",
...corsHeaders()
}
}
);
}
// CORS
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: corsHeaders()
});
}
// Alleen GET
if (request.method !== "GET") {
return json(
{
error: "Alleen GET-verzoeken zijn toegestaan."
},
405
);
}
// Controleer website
if (
origin &&
!ALLOWED_ORIGINS.includes(origin)
) {
return json(
{
error: "Deze website heeft geen toegang tot deze koppeling."
},
403
);
}
try {
// ============================
// INVOER
// ============================
const requestUrl = new URL(request.url);
const postcode = (
requestUrl.searchParams.get("postcode") || ""
)
.toUpperCase()
.replace(/\s+/g, "");
const huisnummer = (
requestUrl.searchParams.get("huisnummer") || ""
).trim();
const toevoeging = (
requestUrl.searchParams.get("toevoeging") || ""
)
.trim()
.toUpperCase()
.replace(/\s+/g, "");
// ============================
// VALIDATIE
// ============================
if (
!/^[1-9][0-9]{3}[A-Z]{2}$/.test(postcode)
) {
return json(
{
error:
"Vul een geldige Nederlandse postcode in."
},
400
);
}
if (
!/^[0-9]+$/.test(huisnummer)
) {
return json(
{
error:
"Vul een geldig huisnummer in."
},
400
);
}
// ============================
// BAG API URL
// ============================
const bagUrl = new URL(
"https://api.bag.kadaster.nl/lvbag/individuelebevragingen/v2/adressenuitgebreid"
);
bagUrl.searchParams.set(
"postcode",
postcode
);
bagUrl.searchParams.set(
"huisnummer",
huisnummer
);
bagUrl.searchParams.set(
"exacteMatch",
"false"
);
// ============================
// BAG API AANROEPEN
// ============================
const bagResponse = await fetch(
bagUrl.toString(),
{
method: "GET",
headers: {
"X-Api-Key":
env.BAG_API_KEY,
"Accept":
"application/hal+json",
"Accept-Crs":
"epsg:28992"
}
}
);
// ============================
// FOUTEN BAG API
// ============================
if (
bagResponse.status === 401 ||
bagResponse.status === 403
) {
return json(
{
error:
"De BAG API-key wordt niet geaccepteerd. Controleer BAG_API_KEY in Cloudflare."
},
502
);
}
if (bagResponse.status === 429) {
return json(
{
error:
"De BAG API wordt momenteel te vaak bevraagd. Probeer het later opnieuw."
},
429
);
}
if (!bagResponse.ok) {
const foutTekst =
await bagResponse.text();
console.log(
"BAG fout:",
bagResponse.status,
foutTekst
);
return json(
{
error:
"De BAG kon het adres niet controleren."
},
502
);
}
// ============================
// ANTWOORD BAG
// ============================
const bagData =
await bagResponse.json();
const adressen =
bagData?._embedded?.adressen || [];
if (!adressen.length) {
return json(
{
error:
"Geen adres gevonden met deze postcode en dit huisnummer."
},
404
);
}
// ============================
// JUISTE ADRES SELECTEREN
// ============================
let gevondenAdres = null;
if (toevoeging) {
gevondenAdres =
adressen.find(function(adres) {
const huisletter =
String(
adres.huisletter || ""
)
.toUpperCase()
.replace(/\s+/g, "");
const nummerToevoeging =
String(
adres.huisnummertoevoeging || ""
)
.toUpperCase()
.replace(/\s+/g, "");
const gecombineerd =
huisletter +
nummerToevoeging;
return (
huisletter === toevoeging ||
nummerToevoeging === toevoeging ||
gecombineerd === toevoeging
);
});
if (!gevondenAdres) {
return json(
{
error:
"De opgegeven huisletter of toevoeging is niet gevonden."
},
404
);
}
}
// Geen toevoeging ingevuld
if (!gevondenAdres) {
if (adressen.length === 1) {
gevondenAdres =
adressen[0];
} else {
// Proberen het hoofdadres zonder toevoeging te vinden
const zonderToevoeging =
adressen.filter(function(adres) {
return (
!adres.huisletter &&
!adres.huisnummertoevoeging
);
});
if (
zonderToevoeging.length === 1
) {
gevondenAdres =
zonderToevoeging[0];
} else {
return json(
{
error:
"Er zijn meerdere adressen op dit huisnummer. Vul ook de huisletter of toevoeging in."
},
409
);
}
}
}
// ============================
// OPPERVLAKTE
// ============================
const oppervlakte =
Number(
gevondenAdres.oppervlakte
);
if (
!Number.isFinite(oppervlakte) ||
oppervlakte <= 0
) {
return json(
{
error:
"Voor dit adres is geen geldige gebruiksoppervlakte beschikbaar."
},
404
);
}
// ============================
// ADRES NETJES OPBOUWEN
// ============================
let volledigAdres = "";
if (gevondenAdres.adresregel5) {
volledigAdres =
gevondenAdres.adresregel5;
} else {
volledigAdres =
(gevondenAdres.openbareRuimteNaam || "") +
" " +
(gevondenAdres.huisnummer || huisnummer);
if (
gevondenAdres.huisletter
) {
volledigAdres +=
gevondenAdres.huisletter;
}
if (
gevondenAdres.huisnummertoevoeging
) {
volledigAdres +=
"-" +
gevondenAdres.huisnummertoevoeging;
}
}
if (gevondenAdres.adresregel6) {
volledigAdres +=
", " +
gevondenAdres.adresregel6;
} else {
volledigAdres +=
", " +
(gevondenAdres.postcode || postcode) +
" " +
(gevondenAdres.woonplaatsNaam || "");
}
// ============================
// RESULTAAT NAAR JOUWWEB
// ============================
return json(
{
success: true,
adres:
volledigAdres.trim(),
oppervlakte:
oppervlakte,
bagId:
gevondenAdres
.adresseerbaarObjectIdentificatie ||
null
},
200
);
} catch (error) {
console.error(
"Worker fout:",
error
);
return json(
{
error:
"Er ging iets mis bij het ophalen van de BAG-gegevens."
},
500
);
}
}
};