Semantic metadata inference engine + template compiler for generating architecture artifacts from typed domain configs.
- semantic metadata DSL
- normalized manifest compiler
- inference engine
- template-driven code generator
You define facts about your domain.
Codepurify infers:
- query capabilities
- mutation semantics
- relation groups
- workflows
- validation groups
- reusable template contexts
Templates decide final architecture output.
Configs define facts
↓
Inference engine derives semantics
↓
Normalized context is generated
↓
Handlebars templates render outputCodepurify does not hardcode:
- NestJS
- TypeORM
- FastAPI
- GraphQL
- React
- REST
- DTO patterns
- folder structures
All architecture styles are implemented through templates.
- Strongly typed TypeScript configs
- Semantic metadata inference
- Handlebars-based generation
- Framework agnostic
- Runtime metadata compilation
- Query/mutation capability inference
- Typed enum transitions/workflows
- Semantic validation rule AST
- Relation graph inference
- JSON-safe normalized manifests
- Extensible template ecosystem
Generate:
- DTOs
- ORM entities
- repositories
- GraphQL schemas
- Zod schemas
- Pydantic models
- React forms
- OpenAPI specs
- validation layers
- constants
- metadata registries
- query builders
- admin panels
- SDKs
from a single semantic source of truth.
npm install @codepurify/coreimport { EntityConfigBase, stringField, enumField, query, mutation, transition } from '@codepurify/core';
export default class UserEntityConfig extends EntityConfigBase {
key = 'user';
fields = this.defineFields({
email: stringField({
length: 255,
query: query().select().defaultSelect().search().sort().build(),
mutation: mutation().apiWritable().build(),
}),
status: enumField(['active', 'suspended', 'deleted'] as const, {
default: 'active',
}),
});
transitions = [
transition({
field: () => this.fields.status,
initial: this.fields.status.values.active,
terminal: [this.fields.status.values.deleted],
transitions: {
[this.fields.status.values.active]: [this.fields.status.values.suspended, this.fields.status.values.deleted],
[this.fields.status.values.suspended]: [this.fields.status.values.active, this.fields.status.values.deleted],
[this.fields.status.values.deleted]: [],
},
}),
];
templates = ['dto.create', 'dto.update', 'typeorm.entity', 'schema.zod'] as const;
}Codepurify automatically infers semantic groups from metadata.
You never manually define groups.
For example:
query().select().defaultSelect().search().build();automatically contributes the field into:
entity.fields.query.select
entity.fields.query.default_select
entity.fields.query.searchLikewise:
mutation().apiWritable().immutableAfterCreate().build();automatically contributes the field into:
entity.fields.mutation.api_create
entity.fields.mutation.immutable_after_createCodepurify uses Handlebars for rendering generated artifacts.
Templates receive a normalized semantic context.
export class CreateUserDto {
email!: string;
status!: UserStatus;
}All exposed template variables are normalized to snake_case.
Example context:
{
"entity": {
"key": "user",
"pascal_case_key": "User",
"fields": {
"all": [],
"strings": [],
"enums": [],
"query": {
"select": [],
"default_select": [],
"search": [],
"sort": []
},
"mutation": {
"api_create": [],
"api_update": [],
"immutable": [],
"generated": []
}
},
"relations": {
"all": []
},
"checks": {
"all": []
},
"indexes": {
"all": []
}
}
}Semantic query capabilities are defined fluently.
query().select().defaultSelect().sort().search().build();Mutation semantics describe API/system behavior.
mutation().apiWritable().immutableAfterCreate().build();Supported semantics include:
- api writable
- system writable
- readonly
- immutable
- immutable after create
- generated
- computed
- persisted
Relations are fully typed semantic metadata.
relationField(this, AppEntityConfig, {
relation: {
kind: 'one_to_many',
remote_field: () => new AppEntityConfig().fields.ownerId,
cascade: true,
},
query: {
select: true,
},
});Checks are represented as semantic ASTs.
No raw SQL.
checks = [
{
name: 'email_not_empty',
rule: field(() => this.fields.email).notEmpty(),
},
];Transitions are defined independently from enum fields.
transition({
field: () => this.fields.status,
initial: this.fields.status.values.active,
terminal: [this.fields.status.values.deleted],
transitions: {
active: ['suspended', 'deleted'],
suspended: ['active', 'deleted'],
deleted: [],
},
});TypeScript Configs
↓
Runtime Metadata Extraction
↓
Semantic Inference Engine
↓
Normalized Manifest
↓
Handlebars Template Compilation
↓
Generated Source Code- infer semantic groups automatically
- remain architecture agnostic
- support multiple output ecosystems
- expose normalized template context
- prioritize metadata semantics over implementation details
- hardcode framework architecture
- assume NestJS patterns
- assume ORM implementations
- force a specific folder structure
- expose raw database concerns directly
Codepurify aims to become a universal semantic metadata compiler capable of generating:
- backend architectures
- frontend forms
- APIs
- SDKs
- validation layers
- schemas
- admin systems
- documentation
- infrastructure metadata
from a single semantic domain definition.
@codepurify/core
@codepurify/compiler
@codepurify/runtime
@codepurify/templates
@codepurify/typeorm
@codepurify/graphql
@codepurify/zod
@codepurify/react-form
@codepurify/openapi
@codepurify/fastapiMIT