Documentation Index
Fetch the complete documentation index at: https://docs.law4devs.eu/llms.txt
Use this file to discover all available pages before exploring further.
The Page<T> type
Every list() method returns a Promise<Page<T>>. The Page<T> object has three properties:
interface Page<T> {
data: T[]; // items on the current page
meta: PageMeta; // totals and current position
links: PageLinks; // pre-built URLs for adjacent pages
}
interface PageMeta {
total: number; // total items across all pages
page: number; // current page number (1-based)
perPage: number; // items per page
pages: number; // total number of pages
apiVersion: string; // API version string
}
interface PageLinks {
next: string | null; // URL of the next page, or null on the last page
prev: string | null; // URL of the previous page, or null on the first page
}
Use links.next to detect when there are more pages and increment page manually.
let page = 1;
let total = 0;
while (true) {
const result = await client.frameworks.list({ page, perPage: 10 });
total += result.data.length;
console.log(`Page ${result.meta.page}/${result.meta.pages}: ${result.data.length} items`);
if (!result.links.next) break; // no more pages
page++;
}
console.log(`Fetched ${total} frameworks in total`);
Every resource exposes an iter() method (or iterDeadlines() for compliance) that returns an AsyncGenerator<T>. Pages are fetched lazily — only when the current batch is exhausted.
// Frameworks
for await (const fw of client.frameworks.iter()) {
console.log(fw.slug);
}
// Articles scoped to a framework
for await (const article of client.articles.iter('gdpr')) {
console.log(`Art. ${article.articleNumber}: ${article.title}`);
}
// Compliance deadlines
for await (const deadline of client.compliance.iterDeadlines({ frameworkSlug: 'nis2' })) {
console.log(deadline.description);
}
TypeScript infers the correct item type from the generator signature:
// article is typed as ArticleSummary — no cast needed
for await (const article of client.articles.iter('cra')) {
const tags: Tag[] = article.tags; // fully typed
}
Early exit
Because iter() is a lazy AsyncGenerator, breaking out of the loop stops further fetches immediately.
// Find the first article tagged 'security' — stop as soon as found
let found: ArticleSummary | undefined;
for await (const article of client.articles.iter('nis2')) {
if (article.tags.some(t => t.slug === 'security')) {
found = article;
break; // no further pages are fetched
}
}
if (found) {
console.log(`First security article: Art. ${found.articleNumber}`);
}
Controlling page size
Pass perPage to iter() or list() to tune the number of items fetched per HTTP request. Valid range is 1–100; default is 20.
// Fewer, larger pages — fewer HTTP requests
for await (const req of client.requirements.iter({
frameworkSlug: 'gdpr',
perPage: 100,
})) {
// process requirement
}
For large datasets, a higher perPage value reduces the number of HTTP round-trips. For interactive UIs where you want to display results quickly, a smaller perPage value returns the first items faster.
Collecting all results into an array
async function collectAll<T>(gen: AsyncGenerator<T>): Promise<T[]> {
const items: T[] = [];
for await (const item of gen) {
items.push(item);
}
return items;
}
const allFrameworks = await collectAll(client.frameworks.iter());
console.log(`${allFrameworks.length} total frameworks`);
Collecting all results into memory with a helper like collectAll is convenient but be mindful of response size. For large resources such as requirements or articles across all frameworks, stream and process items one-by-one inside the for await loop instead.