Constraints and Scoped Names
bino supports constraints that let you conditionally include documents and inline layout children based on the target ReportArtefact’s labels, spec, or the current execution mode.
This enables scenarios like mode-specific pages (preview-only debug views), environment-specific data sources, artefact-specific layouts, or conditional components within a page.
How constraints work
Section titled “How constraints work”When building or previewing a specific ReportArtefact, bino evaluates the metadata.constraints on:
- Every non-artefact document (DataSource, DataSet, LayoutPage, Asset, etc.)
- Inline children of
LayoutPageandLayoutCard(nested components)
A document or inline child is included only if all its constraints evaluate to true. Items without constraints are always included.
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: debugPage
constraints:
- mode==preview
spec:
# This page is only included when running `bino preview`
children:
- kind: Text
spec:
value: "Debug information - only visible in preview mode"Constraint syntax
Section titled “Constraint syntax”Constraints can be written in two equivalent formats. Both are fully supported and maintained.
String format (concise)
Section titled “String format (concise)”Quick and readable for simple constraints:
metadata:
constraints:
- mode==preview
- labels.env==prod
- spec.format in [pdf,png]Each constraint is a string with the format: <field> <operator> <value>
Structured format (IDE-friendly)
Section titled “Structured format (IDE-friendly)”Better IDE support with autocomplete and validation:
metadata:
constraints:
- field: mode
operator: "=="
value: preview
- field: labels.env
operator: in
value: [dev, staging, prod]Mixed format
Section titled “Mixed format”You can mix both formats in the same document:
metadata:
constraints:
- mode==preview # String format (quick)
- field: spec.output.format # Structured format (IDE autocomplete)
operator: in
value: [pdf, png]Both formats have identical evaluation behavior and performance.
Field reference
Section titled “Field reference”The left side (or field property) determines what is being checked:
| Field Path | Description | Example Values |
|---|---|---|
mode | Current execution mode | build, preview, serve |
artefactKind | Type of artefact being built | report, screenshot, document, livereport |
labels.<key> | Artefact’s metadata.labels.<key> | Any string value |
spec.<field> | Artefact’s spec.<field> | Format, orientation, etc. |
Operators
Section titled “Operators”| Operator | Description | Value Type | String Example | Structured Example |
|---|---|---|---|---|
== | Equals | string, bool | labels.env==prod | {field: "labels.env", operator: "==", value: "prod"} |
!= | Not equals | string, bool | mode!=preview | {field: "mode", operator: "!=", value: "preview"} |
in | Value in array | array | labels.env in [dev,prod] | {field: "labels.env", operator: "in", value: ["dev", "prod"]} |
not-in | Value not in array | array | mode not-in [serve] | {field: "mode", operator: "not-in", value: ["serve"]} |
Value types
Section titled “Value types”- String: For
==and!=operators - Boolean: Use
trueorfalse(in string format, write them without quotes) - Array: For
inandnot-inoperators (in string format:[value1,value2])
Constraint context
Section titled “Constraint context”Constraints are evaluated against the target ReportArtefact:
mode: The current execution mode:build,preview, orservelabels: The artefact’smetadata.labelsmapspec: The artefact’sspecfields (e.g.,format,orientation,language)
Execution modes
Section titled “Execution modes”| Mode | Description | Command |
|---|---|---|
build | Building artefacts for production output (PDF/HTML) | bino build |
preview | Live preview during development with hot reload | bino preview |
serve | Production serving via LiveReportArtefact | bino serve |
Artefact kinds
Section titled “Artefact kinds”| Kind | Description | Artefact Type |
|---|---|---|
report | Standard data-driven PDF reports | ReportArtefact |
screenshot | Component screenshots for testing | ScreenshotArtefact |
document | Markdown-based documents | DocumentArtefact |
livereport | Interactive web reports with routes | LiveReportArtefact |
Example artefact with labels
Section titled “Example artefact with labels”apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
name: weeklyReport
labels:
env: prod
region: europe
spec:
title: Weekly Sales Report
filename: weekly-report.pdf
format: a4Documents can now reference these labels and spec fields:
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: sales_data
constraints:
- labels.env==prod
spec:
type: postgres_query
# ... production database connectionMultiple constraints
Section titled “Multiple constraints”When multiple constraints are specified, all must match for the document to be included.
metadata:
name: europeOnlyPage
constraints:
- labels.region==europe
- mode==buildThis page is included only when:
- The artefact has
labels.region: europe, AND - The command is
bino build(not preview)
Common patterns
Section titled “Common patterns”Preview-only content
Section titled “Preview-only content”Show debug information or work-in-progress pages only during development:
# String format
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: dataDebugPage
constraints:
- mode==preview
spec:
children:
- kind: Table
spec:
dataset: raw_dataOr using structured format:
# Structured format
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: dataDebugPage
constraints:
- field: mode
operator: "=="
value: preview
spec:
children:
- kind: Table
spec:
dataset: raw_dataEnvironment-specific data sources
Section titled “Environment-specific data sources”Use different data sources for development vs production:
# Development mock data
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: sales
constraints:
- labels.env==dev
spec:
type: inline
content: |
[{"region": "Test", "amount": 100}]
---
# Production database
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: sales
constraints:
- labels.env==prod
spec:
type: postgres_query
connection:
host: prod-db.example.com
# ...Multiple environments with in operator
Section titled “Multiple environments with in operator”Match multiple environments at once:
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: staging_data
constraints:
- labels.env in [dev,staging,qa] # Matches any non-production environment
spec:
type: postgres_query
connection:
host: staging-db.example.comOr using structured format:
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: staging_data
constraints:
- field: labels.env
operator: in
value: [dev, staging, qa]
spec:
type: postgres_query
connection:
host: staging-db.example.comExclude specific modes with not-in
Section titled “Exclude specific modes with not-in”Include a document in all modes except specific ones:
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: mainPage
constraints:
- mode not-in [serve] # Included in build and preview, but not serve
spec:
# ...Artefact kind filtering
Section titled “Artefact kind filtering”Include components only for specific artefact types:
# Include this data source only in ReportArtefacts (not DocumentArtefacts)
apiVersion: bino.bi/v1alpha1
kind: DataSource
metadata:
name: complex_dashboard_data
constraints:
- artefactKind==report
spec:
type: postgres_query
# ... complex query for dashboardOr exclude from specific artefact types:
# Include everywhere except ScreenshotArtefacts
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: fullPage
constraints:
- artefactKind not-in [screenshot]
spec:
# Full page layoutFormat-specific layouts
Section titled “Format-specific layouts”Create different layouts for different output formats:
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: summaryPage
constraints:
- spec.format==a4
spec:
pageFormat: a4
# A4-optimized layout
---
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: summaryPage
constraints:
- spec.format==xga
spec:
pageFormat: xga
# Screen-optimized layoutOr using in for multiple formats:
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: printPage
constraints:
- spec.format in [a4,letter,legal] # Any print format
spec:
# Print-optimized layoutInline child constraints
Section titled “Inline child constraints”Constraints also work on inline children of LayoutPage and LayoutCard. This allows you to conditionally include or exclude specific components within a layout:
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: dashboardPage
spec:
pageLayout: split-vertical
children:
# This card only appears in build mode
- kind: LayoutCard
metadata:
name: productionCard
constraints:
- mode==build
spec:
cardLayout: full
children:
- kind: Table
spec:
dataset: production_data
# This card only appears in preview mode
- kind: LayoutCard
metadata:
name: debugCard
constraints:
- mode==preview
spec:
cardLayout: full
children:
- kind: Text
spec:
value: "Debug view - not included in final PDF"
# This table always appears (no constraints)
- kind: Table
spec:
dataset: summary_dataInline child constraints support the same syntax as document-level constraints, including structured format:
children:
- kind: ChartStructure
metadata:
name: europeChart
constraints:
- field: labels.region
operator: in
value: [europe, emea]
spec:
dataset: regional_dataChoosing a format
Section titled “Choosing a format”| Use Case | Recommended Format | Why |
|---|---|---|
| Simple equality check | String | More concise: labels.env==prod |
Multiple values (in operator) | Either | Both work well; structured has clearer array syntax |
| Want IDE autocomplete | Structured | JSON Schema provides field/operator suggestions |
| Quick prototyping | String | Faster to type |
| Team prefers YAML validation | Structured | Better schema enforcement |
| Mixed team (devs + analysts) | Both | Let each choose their preference |
Name scoping
Section titled “Name scoping”With constraints, metadata.name uniqueness is per artefact after filtering, not global.
This means:
- The same name can appear multiple times in your configuration
- After applying constraints for a specific artefact, each kind must have unique names
- Different artefacts can include different documents with the same name (if constraints prevent both from matching the same artefact)
Example: Same name, different artefacts
Section titled “Example: Same name, different artefacts”# Both documents have the same name
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: mainPage
constraints:
- labels.variant==simple
spec:
# Simple layout
---
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
name: mainPage
constraints:
- labels.variant==detailed
spec:
# Detailed layoutWith two artefacts:
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
name: simpleReport
labels:
variant: simple
spec:
# Uses the first mainPage
---
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
name: detailedReport
labels:
variant: detailed
spec:
# Uses the second mainPageConflict example
Section titled “Conflict example”If constraints allow two documents with the same name and kind to match a single artefact, bino fails with an error:
artefact "weeklyReport": duplicate LayoutPage name "mainPage" - defined in report.yaml #3 and report.yaml #7 (after applying constraints)Error handling
Section titled “Error handling”Constraints are validated at build/preview/serve time. Errors are reported immediately with helpful hints:
Invalid syntax
Section titled “Invalid syntax”constraint error in DataSet "sales_ds": missing operator
constraint: labels.env prod
hint: use '==', '!=', 'in', or 'not-in' to compare values, e.g., 'mode==preview'Missing label
Section titled “Missing label”constraint error in LayoutPage "europeOnlyPage": label "region" not defined on artefact
constraint: labels.region==europe
hint: add 'labels.region' to the ReportArtefact's metadataUnknown spec field
Section titled “Unknown spec field”constraint error in DataSource "sales": spec field "unknown" not found
constraint: spec.unknown==value
hint: check that the spec field exists on the ReportArtefactInvalid array format (string format)
Section titled “Invalid array format (string format)”constraint error in LayoutPage "page1": expected array format [value1,value2,...], got "pdf"
constraint: spec.format in pdf
hint: use array syntax like [value1,value2] for 'in' and 'not-in' operatorsLimitations
Section titled “Limitations”ReportArtefactdocuments cannot have constraints (they define the context, not consume it)- Only top-level and nested
specfields are accessible; arrays are not traversable - All constraints in a list must pass (AND logic); OR logic requires multiple documents
Best practices
Section titled “Best practices”- Use labels for logical groupings: Define labels like
env,region, orvarianton artefacts rather than relying solely on spec fields - Keep constraints simple: Complex filtering logic is hard to debug; prefer clear, single-purpose constraints
- Use
infor multiple values: Instead of multiple documents, uselabels.env in [dev,staging]to match multiple values - Document your constraints: Add comments explaining why a constraint exists, especially for non-obvious cases
- Test with preview first: Use
bino previewto verify constraint behavior before building - Avoid duplicate names when possible: Even though scoped names are supported, unique names reduce confusion
- Choose format consistently: Pick string or structured format for your project and use it consistently