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 ↓ Codepurify templates render output
Codepurify 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
- Codepurify-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
import { 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.search
Likewise:
mutation().apiWritable().immutableAfterCreate().build();
automatically contributes the field into:
entity.fields.mutation.api_create entity.fields.mutation.immutable_after_create
Codepurify uses Codepurify for rendering generated artifacts.
Templates receive a normalized semantic context.
export class Create{{entity.pascal_case_key}}Dto {
{{#each entity.fields.mutation.api_create}}
{{snake_case_key}}!:
{{typescript_type}};
{{/each}}
}
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 ↓ Codepurify 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/fastapi
MIT