Build Blueprint Interfaces
The interfaces build command turns your local *.blueprint.json files into typed interfaces for TypeScript or Python. Once generated, the SDK's entitiesOf(...) calls become fully typed — autocomplete, hovers, and compile-time checks for every blueprint property and relation, with no manual generic parameters.
Pair this with
qelos pull blueprintsto keep your local blueprint definitions in sync with your Qelos instance.
Usage
qelos interfaces build [path] [options]Arguments
| Argument | Description | Default |
|---|---|---|
path | Directory containing *.blueprint.json files. | ./blueprints |
Options
| Option | Description | Default |
|---|---|---|
--lang | Output language. Either ts or py. | ts |
--out | Output directory for the generated module. | ./types |
--save | Persist current options into qelos.config.json under interfaces. | — |
What the command does
- Reads every
*.blueprint.jsonfile in the source directory. - Skips files missing an
identifier(with a warning). - Generates a single declaration file:
- TypeScript →
<out>/qelos-blueprints.d.ts - Python →
<out>/qelos_blueprints.py
- TypeScript →
- TypeScript only: locates
tsconfig.jsonin the current directory and adds the generated file to theincludearray (idempotent — re-running won't duplicate the entry).
The TypeScript output also augments @qelos/sdk via declaration merging, so sdk.blueprints.entitiesOf('todo') resolves directly to the matching entity type.
Quick start
# 1. Pull blueprints from your Qelos instance
qelos pull blueprints ./blueprints
# 2. Generate TypeScript interfaces (default)
qelos interfaces build
# => Loaded N blueprint(s) from .../blueprints
# => Generated TypeScript declarations: .../types/qelos-blueprints.d.ts
# => Updated tsconfig.json include with: ./types/qelos-blueprints.d.tsThat's it. The next time you call sdk.blueprints.entitiesOf('todo'), your IDE will know the exact entity shape.
Examples
Generate TypeScript declarations (default)
qelos interfaces buildGiven a blueprints/todo.blueprint.json:
{
"identifier": "todo",
"name": "Todo",
"properties": {
"title": { "type": "string", "required": true },
"completed": { "type": "boolean" },
"status": { "type": "string", "required": true, "enum": ["open", "done"] }
},
"relations": [
{ "key": "project", "target": "project" }
]
}The generated types/qelos-blueprints.d.ts looks like this:
// AUTO-GENERATED — DO NOT EDIT
// Generated by `qelos interfaces build`
// Source: *.blueprint.json files
import type { IBaseBlueprintEntity } from '@qelos/sdk/blueprints-entities';
export interface TodoProperties {
title: string;
completed?: boolean;
status: "open" | "done";
project?: Pick<ProjectEntity, 'identifier'> | string;
}
export interface TodoEntity extends IBaseBlueprintEntity, TodoProperties {}
export interface BlueprintEntitiesRegistry {
"todo": TodoEntity;
}
declare module '@qelos/sdk' {
interface BlueprintEntitiesRegistry {
"todo": TodoEntity;
}
}Now your SDK calls are fully typed:
import QelosSDK from '@qelos/sdk';
const sdk = new QelosSDK({ appUrl: 'https://my-instance.qelos.app' });
// `todos` is automatically typed as QlBlueprintEntities<TodoEntity> —
// no generic parameter required.
const todos = sdk.blueprints.entitiesOf('todo');
const list = await todos.find(); // TodoEntity[]
const item = await todos.create({
title: 'Ship interfaces docs',
status: 'open', // ✓
// status: 'archived', // ✗ TS error: not assignable to "open" | "done"
});
await todos.update(item._id, { completed: true });Generate Python TypedDicts
qelos interfaces build --lang py --out ./typesProduces types/qelos_blueprints.py:
# AUTO-GENERATED — DO NOT EDIT
# Generated by `qelos interfaces build --lang py`
# Source: *.blueprint.json files
import datetime
from typing import Any, Dict, List, Literal, TypedDict, Union
from typing_extensions import NotRequired
class TodoProperties(TypedDict):
title: str
completed: NotRequired[bool]
status: Literal["open", "done"]
project: NotRequired[Union["ProjectEntity", str]]
class TodoEntity(TodoProperties):
_id: str
identifier: strUse the generated TypedDicts with the Python SDK:
from qelos_sdk import QelosSDK
from types.qelos_blueprints import TodoEntity
sdk = QelosSDK(app_url="https://my-instance.qelos.app")
todos: list[TodoEntity] = sdk.blueprints.entities_of("todo").find()Custom blueprint and output paths
qelos interfaces build ./db/blueprints --out ./src/generatedSave defaults for the project
Persist the options you typed into qelos.config.json so the next run doesn't need any flags:
qelos interfaces build --lang ts --out ./src/generated --save{
"interfaces": {
"lang": "ts",
"out": "./src/generated",
"path": "./blueprints"
}
}After saving, just run:
qelos interfaces buildEnd-to-end demo
A full round-trip from a remote Qelos instance to a typed front-end:
# 1. Pull blueprints from your Qelos instance
qelos pull blueprints ./blueprints
# 2. Generate typed declarations
qelos interfaces build
# 3. Use the typed SDK in your app
cat <<'EOF' > app.ts
import QelosSDK from '@qelos/sdk';
const sdk = new QelosSDK({ appUrl: process.env.QELOS_URL! });
async function main() {
// `entitiesOf` returns the right entity type from the registry —
// no manual generic, no casts.
const products = sdk.blueprints.entitiesOf('product');
const top = await products.find({ $limit: 10, $sort: '-created' });
for (const item of top) {
console.log(item.name, item.price);
}
}
main();
EOF
# 4. Type-check it
npx tsc --noEmit app.tsWhen the blueprint definitions change in Qelos, re-run qelos pull blueprints followed by qelos interfaces build (or wire both into your predev / prebuild script).
CI-friendly script
Add a predev / prebuild hook so types stay fresh:
{
"scripts": {
"interfaces": "qelos pull blueprints ./blueprints && qelos interfaces build",
"predev": "npm run interfaces",
"prebuild": "npm run interfaces"
}
}Notes & limitations
- The command does not require a network connection — it only reads local
.blueprint.jsonfiles. Useqelos pull blueprintsfirst if you need to refresh from your Qelos instance. - Files without an
identifierfield are skipped with a warning. - Property names that aren't valid identifiers (TS) or are Python reserved words (Py) are quoted (TS) or skipped (Py) automatically.
- Nested object schemas are walked up to 4 levels deep in TypeScript; deeper structures fall back to
Record<string, any>. - The generated file always overwrites the previous output — never edit it by hand.
tsconfig.jsondiscovery is non-recursive (current directory only). For monorepos, run the command from the package that owns thetsconfig.jsonyou want to extend.
Related
qelos pull blueprints– Sync blueprint definitions from your Qelos instance.qelos blueprints generate– Bootstrap blueprints from an existing MongoDB database.- Blueprints Operations (SDK) – Use
entitiesOfto read and write entities. - Blueprints API – Raw HTTP endpoints behind the SDK.
