API Reference
piq.from()
Create a query builder from a resolver.
import { piq } from 'piqit'
const query = piq.from(posts) scan(constraints)
Finds items by pattern. This is your cheapest operation—it works at the collection level without reading file contents.
// Find all posts from 2024
piq.from(posts).scan({ year: '2024' })
// Find a specific post
piq.from(posts).scan({ year: '2024', slug: 'hello-world' })
// Find all posts (empty constraints)
piq.from(posts).scan({}) For filesystem resolvers, scan leverages path structure. Constraints match the path parameters defined in your resolver.
filter(constraints)
Narrows results by document-level criteria. Requires reading frontmatter from each item, so use after scan has narrowed the set.
piq.from(posts)
.scan({ year: '2024' })
.filter({ status: 'published' }) Filter parameters match the frontmatter schema. Only items where all filter values match are included.
select(...paths) / select(aliases)
Declares which fields to include in results. Required before exec().
Variadic form
.select('params.slug', 'params.year', 'frontmatter.title', 'body.html')
// Result: { slug: string; year: string; title: string; html: string } Object form (aliasing)
.select({
postSlug: 'params.slug',
postTitle: 'frontmatter.title',
content: 'body.html'
})
// Result: { postSlug: string; postTitle: string; content: string } Wildcards
.select('params.*')
// Result: { slug: string; year: string } (all params fields)
.select('params.*', 'frontmatter.*')
// Result: { slug, year, title, status, tags, ... } Namespaces
For the fileMarkdown resolver:
params— extracted from path patterns (free, from scan)frontmatter— YAML metadata (light I/O)body— parsed content (heavy I/O)
exec()
Executes the query and returns all results as an array.
const results = await piq.from(posts)
.scan({ year: '2024' })
.select('params.slug')
.exec()
// results: Array<{ slug: string }> single()
Returns a builder for single-result queries.
// Returns first result or undefined
const post = await piq.from(posts)
.scan({ year: '2024', slug: 'hello-world' })
.select('params.slug', 'frontmatter.title')
.single()
.exec()
// Throws if no results
const post = await piq.from(posts)
.scan({ year: '2024', slug: 'hello-world' })
.select('params.slug')
.single()
.execOrThrow() stream()
For large result sets, stream results instead of loading all into memory:
for await (const post of piq.from(posts).scan({}).select('params.slug').stream()) {
console.log(post.slug)
}