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 codepurifyimport {
EntityConfigBase,
stringField,
enumField,
query,
mutation,
transition,
} from "codepurify";
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
@codepurify/compiler
@codepurify/runtime
@codepurify/templates
@codepurify/typeorm
@codepurify/graphql
@codepurify/zod
@codepurify/react-form
@codepurify/openapi
@codepurify/fastapiMIT