@malevichai/nova-ts
v0.1.0
Published
TypeScript types and generator for Nova resources with OGM metadata
Maintainers
Readme
nova-ts
Type-safe Neo4j OGM helpers, resource utilities and automatic schema-driven type generation for Nova API.
Key Features
- Generates complete node and resource TypeScript interfaces directly from your OpenAPI schema
- Powerful filter/request type system with compile-time validation
- Zero-config Nuxt 3 module – point it at your API url and it will autogenerate types on
nuxi devandnuxi build - Lightweight, dependency-free runtime helpers
Nuxt 3 Quick Start
# Install from NPM
npm install @malevichai/nova-tsnuxt.config.ts:
export default defineNuxtConfig({
modules: [
[
'@malevichai/nova-ts',
{
apiUrl: 'https://your/api/schema', // OpenAPI JSON url
outDir: 'types/generated' // where to write nodes.ts / resources.ts / base.ts
}
]
]
})The module fetches the schema, writes the generated types, and registers the folder with Vite so your IDE picks it up instantly.
🚀 Quick Start
Installation
npm install @malevichai/nova-tsBasic Usage
Import filter and request types directly from the package:
import type {
ResourceRequest,
SubresourceRequest,
ResourceFilter,
Match,
Join,
ResourceEdge,
Link,
Resource
} from '@malevichai/nova-ts'
// Generated resource type (from resources.ts)
// Pivot type ▾ Pivot key ▾ Additional mounts ▾
export type TaskResource = Resource<Task, 'task', {
// optional mounts example (uncomment if present in schema)
// assigned_to: { resource: User; edge: Link; array: false; arrayEdges: true }
}>
// If your schema only contains the pivot field, the third generic can stay `{}` as above
// Create type-safe requests
const request: ResourceRequest<TaskResource, 'task'> = {
filter: {
$filter: {
$type: 'match',
$field: 'task.title',
$value: 'Important',
$operation: 'CONTAINS'
}
},
subresources: {
assigned_to: {
filter: {
$type: 'match',
$field: 'name',
$value: 'John'
}
}
}
}🛠️ Generation
Generate Node Types
# Using CLI
npx nova-ts generate schema.json > nodes.ts
# Using npm script
npm run generate schema.json > nodes.ts
# Programmatically
import { generate } from 'nova-ts/generator'
const nodeTypes = await generate('./schema.json')Generate Resource Types
# Programmatically
import { generateResources } from 'nova-ts/resource-generator'
await generateResources('./schema.json', './generated')This generates:
nodes.ts- Base node interfacesresources.ts- Resource interfaces extendingResource<T, K>base.ts- Re-exports from nova-ts
📚 Type System
Core Types
Resource<PivotType, PivotKey, Additional>- Generic resource type (auto-generated)ResourceEdge<S, T>- Edge between resourcesMaterializedResource<R>– runtime-friendly representation using$resource/$edgeswrappersCreateResource<R>/UpdateResource<R>– payload shapes for mutationsLinkResource<R>/UnlinkResource<R>– edge operationsCreate<T>/Update<T>– low-level node helpers
Example
import type { MaterializedResource, CreateResource, UpdateResource } from '@malevichai/nova-ts'
import type { TaskResource } from '@/types/generated/resources'
// Reading existing data
type TaskProxy = MaterializedResource<TaskResource>
// Creating a new task
const newTask: CreateResource<TaskResource> = {
task: { title: 'Write docs' }
}
// Updating a task
const patch: UpdateResource<TaskResource> = {
task: { uid: 'task-123', title: 'Write better docs' }
}Filters
Match- Field equality/comparisonMatchEdge- Edge field matchingJoin- Logical AND/OR operationsExists- Subresource existenceResourceFilter/SubresourceFilter- Composite filters
Requests
ResourceRequest<T, K>- Type-safe resource queriesSubresourceRequest<T, K>- Nested resource queries
🧪 Testing
# Run all tests
npm test
# Quick test
npm run test:quick
# Manual testing
node test/test-usage.js📖 Examples
Schema Requirements
Your OpenAPI schema needs OGM metadata:
Basic Resource Schema
{
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"uid": { "type": "string" },
"name": { "type": "string" }
},
"_malevich_ogm_node": {
"label": "User",
"name": "User"
}
},
"TaskResource": {
"type": "object",
"properties": {
"task": { "$ref": "#/components/schemas/Task" }
},
"_resource": {
"type": "proxy"
}
}
}
}
}Enhanced Resource Schema (Recommended)
For better pivot detection, include explicit metadata:
{
"TaskResource": {
"type": "object",
"properties": {
"task": { "$ref": "#/components/schemas/Task" },
"assigned_to": { "$ref": "#/components/schemas/ResourceEdge_User_Link_" }
},
"_resource": {
"info": {
"name": "TaskResource",
"pivot_key": "task",
"pivot_type": "Task",
"mounts": {
"assigned_to": {
"is_array": false,
"is_foreign": false,
"is_resource": false,
"pivot_type": "User"
}
}
},
"type": "proxy"
}
}
}Enhanced Features:
- ✅ Explicit Pivot Detection - Uses
pivot_keyandpivot_typefrom_resource.info - ✅ Mount Metadata - Understands relationship types and cardinalities
- ✅ Accurate Type Generation - No more guessing pivot fields
- ✅ Backwards Compatible - Falls back to heuristics for basic schemas
Generated Output
// nodes.ts
export interface User {
uid: string
name: string
}
// resources.ts
import type { Resource, ResourceEdge, Link } from '@malevichai/nova-ts'
import type { User, Task } from './nodes'
export interface TaskResource extends Resource<Task, 'task'> {
task: Task
assigned_to?: ResourceEdge<User, Link> | null
}🔧 Development
# Build
npm run build
# Run tests
npm test
# Generate from sample
npm run generate test/sample-schema.jsonContributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run tests:
npm test - Build the project:
npm run build - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin feature/my-feature - Submit a pull request
Publishing
This package uses automated publishing to NPM via GitHub Actions:
Automated Publishing Process
- Create Release: Tag a new version and push it to GitHub
- GitHub Release: Create a GitHub release from the tag
- Automatic Publishing: GitHub Action automatically builds, tests, and publishes to NPM
The package is published to NPM with the scoped name @malevichai/nova-ts.
Release Process
# Tag a new version
git tag v0.0.2
git push origin v0.0.2
# Create GitHub release (triggers publishing)
gh release create v0.0.2 --generate-notesManual Publishing (if needed)
npm run build
npm publish --access publicNote: Tests are currently disabled for publishing to allow deployment while test issues are resolved.
Required Secrets
You need to add NPM_TOKEN as a GitHub repository secret for automated publishing to work.
Available Scripts
npm run build- Build TypeScript to dist/npm test- Run all testsnpm run test:quick- Run quick functionality testnpm run generate- Run CLI generatornpm run prepublishOnly- Pre-publish checks (build + test)
CI/CD
The project includes comprehensive GitHub Actions workflows:
- CI (
ci.yml): Runs tests on Node.js 18, 20, and 22 for every push and PR - Publish (
publish.yml): Publishes to NPM on GitHub release
📝 License
MIT
