Mizan IR: cut over to KDL, delete OpenAPI envelope
Replaces the transitional OpenAPI 3.0 + `x-mizan-*` extensions
substrate with the canonical Mizan IR as KDL, per docs/AFI_ARCHITECTURE.md:
"KDL is the contract; everything else (REST envelopes, OpenAPI
documents, framework idioms) is sediment around it."
End-to-end cutover. No transitional path left on main.
Forward direction:
cores/mizan-python/src/mizan_core/ir.py
build_ir() walks mizan_core.registry, introspects Pydantic
models directly (no JSON-Schema indirection), and emits the
Mizan IR document. The KDL grammar is locked in this file's
module docstring.
Backends emit KDL:
backends/mizan-fastapi/src/mizan_fastapi/ir.py
`python -m mizan_fastapi.ir <module>` — CLI entry point.
backends/mizan-django/.../management/commands/export_mizan_ir.py
`manage.py export_mizan_ir` — Django mgmt command.
Codegen consumes KDL:
protocol/mizan-codegen/Cargo.toml: + kdl = "6"
protocol/mizan-codegen/src/ir.rs: NamedType { Struct/List/Enum/Alias }
+ TypeShape { Primitive/Ref/List/Optional/Enum/Union } sum types,
replacing the JsonSchema sprawl. KDL parser walks the
`kdl::KdlDocument` tree into typed Rust structs.
protocol/mizan-codegen/src/fetch.rs: subprocess command switches
to the new IR-export entry points.
All emit modules (stage1 / react / python / rust / vue / svelte /
channels) port their type-walkers from JsonSchema to the new
sum types — case analysis collapses substantially.
Substrate-honesty wins beyond the moat closure:
- `int | bool` multi-arm unions land as `TypeShape::Union` (was
silently coerced to "string" before).
- `<CamelName>Output = list[T]` returns emit as named alias
types instead of struct-shaped wrappers, so consumer code
`.map()` works directly on the type.
- Pydantic field defaults flow through to `default` properties
in KDL, then back to non-optional shape in every target.
Deleted:
- backends/mizan-fastapi/src/mizan_fastapi/{cli,schema}.py
- backends/mizan-django/.../export_mizan_schema.py
- openapi-bearing half of mizan/export/__init__.py (edge
manifest generator preserved — separate concern).
- tests/afi/schema_normalizer.py
- tests/fixtures/{afi_schema.json, channels_schema.json}
- tests/fixtures/js_* baseline directories.
Verification:
- 20 mizan-codegen unit tests green (IR deserialization,
byte-equivalence parity across stage1/rust/python/react/vue/svelte
against fresh KDL-driven baselines, channels structural).
- tests/rust/run_wire_parity.py: 12/12 probes green driving
the binary end-to-end through KDL.
- Blazr studio-ui typechecks against the regenerated React client.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,7 @@ fn fixture_config() -> Config {
|
||||
#[test]
|
||||
fn channels_target_emits_expected_files() {
|
||||
let raw = std::fs::read_to_string(
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/channels_schema.json"),
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/channels_ir.kdl"),
|
||||
).unwrap();
|
||||
let ir = parse_ir_from_str(&raw).unwrap();
|
||||
|
||||
@@ -72,7 +72,7 @@ fn channels_target_emits_expected_files() {
|
||||
fn channels_target_emits_nothing_when_empty() {
|
||||
// AFI fixture has no channels — target should produce zero files.
|
||||
let raw = std::fs::read_to_string(
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_schema.json"),
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_ir.kdl"),
|
||||
).unwrap();
|
||||
let ir = parse_ir_from_str(&raw).unwrap();
|
||||
let files = ChannelsTarget.emit(&ir, &fixture_config());
|
||||
|
||||
187
protocol/mizan-codegen/tests/fixtures/afi_ir.kdl
vendored
Normal file
187
protocol/mizan-codegen/tests/fixtures/afi_ir.kdl
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
type "OrderOutput" {
|
||||
struct {
|
||||
field "id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "total" {
|
||||
primitive "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "echoInput" {
|
||||
struct {
|
||||
field "text" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "echoOutput" {
|
||||
struct {
|
||||
field "message" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "findUserInput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "findUserOutput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "name" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "renameUserInput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "name" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "renameUserOutput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "name" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "updateProfileInput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "name" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "updateProfileOutput" {
|
||||
struct {
|
||||
field "ok" {
|
||||
primitive "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "userOrdersInput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "userOrdersOutput" {
|
||||
alias {
|
||||
list {
|
||||
ref "OrderOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "userProfileInput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "userProfileOutput" {
|
||||
struct {
|
||||
field "user_id" {
|
||||
primitive "integer"
|
||||
}
|
||||
field "name" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
type "whoamiOutput" {
|
||||
struct {
|
||||
field "email" {
|
||||
primitive "string"
|
||||
}
|
||||
field "authenticated" {
|
||||
primitive "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function "echo" {
|
||||
camel "echo"
|
||||
has-input #true
|
||||
input "echoInput"
|
||||
output "echoOutput"
|
||||
transport "http"
|
||||
}
|
||||
function "whoami" {
|
||||
camel "whoami"
|
||||
has-input #false
|
||||
output "whoamiOutput"
|
||||
transport "http"
|
||||
}
|
||||
function "user_profile" {
|
||||
camel "userProfile"
|
||||
has-input #true
|
||||
input "userProfileInput"
|
||||
output "userProfileOutput"
|
||||
transport "http"
|
||||
context "user"
|
||||
}
|
||||
function "user_orders" {
|
||||
camel "userOrders"
|
||||
has-input #true
|
||||
input "userOrdersInput"
|
||||
output "userOrdersOutput"
|
||||
transport "http"
|
||||
context "user"
|
||||
}
|
||||
function "update_profile" {
|
||||
camel "updateProfile"
|
||||
has-input #true
|
||||
input "updateProfileInput"
|
||||
output "updateProfileOutput"
|
||||
transport "http"
|
||||
affects "user"
|
||||
}
|
||||
function "find_user" {
|
||||
camel "findUser"
|
||||
has-input #true
|
||||
input "findUserInput"
|
||||
output "findUserOutput"
|
||||
output-nullable #true
|
||||
transport "http"
|
||||
}
|
||||
function "rename_user" {
|
||||
camel "renameUser"
|
||||
has-input #true
|
||||
input "renameUserInput"
|
||||
output "renameUserOutput"
|
||||
transport "http"
|
||||
merge "user"
|
||||
}
|
||||
|
||||
context "user" {
|
||||
function "user_profile"
|
||||
function "user_orders"
|
||||
param "user_id" {
|
||||
type "integer"
|
||||
required #true
|
||||
shared-by "user_profile"
|
||||
shared-by "user_orders"
|
||||
}
|
||||
}
|
||||
@@ -1,685 +0,0 @@
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "mizan Server Functions",
|
||||
"description": "Auto-generated schema for mizan server functions",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/mizan/echo": {
|
||||
"post": {
|
||||
"summary": "Echoes the input back.",
|
||||
"operationId": "echo",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/echoInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/echoOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/whoami": {
|
||||
"post": {
|
||||
"summary": "Returns the current user identity.",
|
||||
"operationId": "whoami",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/whoamiOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/user_profile": {
|
||||
"post": {
|
||||
"summary": "One half of the user context.",
|
||||
"operationId": "userProfile",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/userProfileInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/userProfileOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": "user"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/user_orders": {
|
||||
"post": {
|
||||
"summary": "Other half of the user context \u2014 same param, proves param elevation.",
|
||||
"operationId": "userOrders",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/userOrdersInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/userOrdersOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": "user"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/update_profile": {
|
||||
"post": {
|
||||
"summary": "Mutation declaring affects on the user context.",
|
||||
"operationId": "updateProfile",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/updateProfileInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/updateProfileOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/find_user": {
|
||||
"post": {
|
||||
"summary": "Optional return \u2014 exercises Pydantic `T | None` schema introspection.",
|
||||
"operationId": "findUser",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/findUserInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/findUserOutput"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Response Finduser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mizan/rename_user": {
|
||||
"post": {
|
||||
"summary": "Merge target \u2014 kernel splices return value into the user context.",
|
||||
"operationId": "renameUser",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/renameUserInput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/renameUserOutput"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan": {
|
||||
"transport": "http",
|
||||
"isContext": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"HTTPValidationError": {
|
||||
"properties": {
|
||||
"detail": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Detail"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"title": "HTTPValidationError"
|
||||
},
|
||||
"OrderOutput": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"title": "Id"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"title": "Total"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"user_id",
|
||||
"total"
|
||||
],
|
||||
"title": "OrderOutput"
|
||||
},
|
||||
"ValidationError": {
|
||||
"properties": {
|
||||
"loc": {
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "integer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Location"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string",
|
||||
"title": "Message"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"title": "Error Type"
|
||||
},
|
||||
"input": {
|
||||
"title": "Input"
|
||||
},
|
||||
"ctx": {
|
||||
"type": "object",
|
||||
"title": "Context"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"loc",
|
||||
"msg",
|
||||
"type"
|
||||
],
|
||||
"title": "ValidationError"
|
||||
},
|
||||
"echoInput": {
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"title": "Text"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"text"
|
||||
],
|
||||
"title": "echoInput"
|
||||
},
|
||||
"echoOutput": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"title": "Message"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"title": "echoOutput"
|
||||
},
|
||||
"findUserInput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id"
|
||||
],
|
||||
"title": "findUserInput"
|
||||
},
|
||||
"findUserOutput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id",
|
||||
"name"
|
||||
],
|
||||
"title": "findUserOutput"
|
||||
},
|
||||
"renameUserInput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id",
|
||||
"name"
|
||||
],
|
||||
"title": "renameUserInput"
|
||||
},
|
||||
"renameUserOutput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id",
|
||||
"name"
|
||||
],
|
||||
"title": "renameUserOutput"
|
||||
},
|
||||
"updateProfileInput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id",
|
||||
"name"
|
||||
],
|
||||
"title": "updateProfileInput"
|
||||
},
|
||||
"updateProfileOutput": {
|
||||
"properties": {
|
||||
"ok": {
|
||||
"type": "boolean",
|
||||
"title": "Ok"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ok"
|
||||
],
|
||||
"title": "updateProfileOutput"
|
||||
},
|
||||
"userOrdersInput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id"
|
||||
],
|
||||
"title": "userOrdersInput"
|
||||
},
|
||||
"userOrdersOutput": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/OrderOutput"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "userOrdersOutput"
|
||||
},
|
||||
"userProfileInput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id"
|
||||
],
|
||||
"title": "userProfileInput"
|
||||
},
|
||||
"userProfileOutput": {
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"title": "User Id"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"user_id",
|
||||
"name"
|
||||
],
|
||||
"title": "userProfileOutput"
|
||||
},
|
||||
"whoamiOutput": {
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"title": "Email"
|
||||
},
|
||||
"authenticated": {
|
||||
"type": "boolean",
|
||||
"title": "Authenticated"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"email",
|
||||
"authenticated"
|
||||
],
|
||||
"title": "whoamiOutput"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-mizan-functions": [
|
||||
{
|
||||
"name": "echo",
|
||||
"camelName": "echo",
|
||||
"hasInput": true,
|
||||
"inputType": "echoInput",
|
||||
"outputType": "echoOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": false,
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null
|
||||
},
|
||||
{
|
||||
"name": "whoami",
|
||||
"camelName": "whoami",
|
||||
"hasInput": false,
|
||||
"inputType": null,
|
||||
"outputType": "whoamiOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": false,
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null
|
||||
},
|
||||
{
|
||||
"name": "user_profile",
|
||||
"camelName": "userProfile",
|
||||
"hasInput": true,
|
||||
"inputType": "userProfileInput",
|
||||
"outputType": "userProfileOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": "user",
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null
|
||||
},
|
||||
{
|
||||
"name": "user_orders",
|
||||
"camelName": "userOrders",
|
||||
"hasInput": true,
|
||||
"inputType": "userOrdersInput",
|
||||
"outputType": "userOrdersOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": "user",
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null
|
||||
},
|
||||
{
|
||||
"name": "update_profile",
|
||||
"camelName": "updateProfile",
|
||||
"hasInput": true,
|
||||
"inputType": "updateProfileInput",
|
||||
"outputType": "updateProfileOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": false,
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null,
|
||||
"affects": [
|
||||
{
|
||||
"type": "context",
|
||||
"name": "user"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "find_user",
|
||||
"camelName": "findUser",
|
||||
"hasInput": true,
|
||||
"inputType": "findUserInput",
|
||||
"outputType": "findUserOutput",
|
||||
"outputNullable": true,
|
||||
"transport": "http",
|
||||
"isContext": false,
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null
|
||||
},
|
||||
{
|
||||
"name": "rename_user",
|
||||
"camelName": "renameUser",
|
||||
"hasInput": true,
|
||||
"inputType": "renameUserInput",
|
||||
"outputType": "renameUserOutput",
|
||||
"outputNullable": false,
|
||||
"transport": "http",
|
||||
"isContext": false,
|
||||
"isForm": false,
|
||||
"formName": null,
|
||||
"formRole": null,
|
||||
"merge": [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
],
|
||||
"x-mizan-contexts": {
|
||||
"user": {
|
||||
"functions": [
|
||||
"user_profile",
|
||||
"user_orders"
|
||||
],
|
||||
"params": {
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"sharedBy": [
|
||||
"user_profile",
|
||||
"user_orders"
|
||||
],
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,21 +6,11 @@ from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
class HTTPValidationError(BaseModel):
|
||||
detail: list[ValidationError] | None = None
|
||||
|
||||
class OrderOutput(BaseModel):
|
||||
id: int
|
||||
user_id: int
|
||||
total: int
|
||||
|
||||
class ValidationError(BaseModel):
|
||||
loc: list[Any]
|
||||
msg: str
|
||||
r#type: str
|
||||
input: Any | None = None
|
||||
ctx: dict[str, Any] | None = None
|
||||
|
||||
class EchoInput(BaseModel):
|
||||
text: str
|
||||
|
||||
14
protocol/mizan-codegen/tests/fixtures/baselines/react/index.ts
vendored
Normal file
14
protocol/mizan-codegen/tests/fixtures/baselines/react/index.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export * from './types'
|
||||
|
||||
export { fetchUserContext, type UserContextData, type UserContextParams } from './contexts/user'
|
||||
|
||||
export { callEcho } from './functions/echo'
|
||||
export { callWhoami } from './functions/whoami'
|
||||
export { callUpdateProfile } from './mutations/updateProfile'
|
||||
export { callFindUser } from './functions/findUser'
|
||||
export { callRenameUser } from './functions/renameUser'
|
||||
|
||||
// Stage 2 framework adapter
|
||||
export * from './react'
|
||||
64
protocol/mizan-codegen/tests/fixtures/baselines/react/types.ts
vendored
Normal file
64
protocol/mizan-codegen/tests/fixtures/baselines/react/types.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export interface OrderOutput {
|
||||
id: number
|
||||
user_id: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface echoInput {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface echoOutput {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface findUserInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface findUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileOutput {
|
||||
ok: boolean
|
||||
}
|
||||
|
||||
export interface userOrdersInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export type userOrdersOutput = OrderOutput[]
|
||||
|
||||
export interface userProfileInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface userProfileOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface whoamiOutput {
|
||||
email: string
|
||||
authenticated: boolean
|
||||
}
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HTTPValidationError {
|
||||
pub detail: Option<Vec<ValidationError>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OrderOutput {
|
||||
pub id: i64,
|
||||
@@ -16,16 +11,6 @@ pub struct OrderOutput {
|
||||
pub total: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ValidationError {
|
||||
pub loc: Vec<serde_json::Value>,
|
||||
pub msg: String,
|
||||
#[serde(rename = "type")]
|
||||
pub r#type: String,
|
||||
pub input: Option<serde_json::Value>,
|
||||
pub ctx: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct EchoInput {
|
||||
pub text: String,
|
||||
@@ -75,9 +60,7 @@ pub struct UserOrdersInput {
|
||||
pub user_id: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct UserOrdersOutput(pub Vec<OrderOutput>);
|
||||
pub type UserOrdersOutput = Vec<OrderOutput>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UserProfileInput {
|
||||
18
protocol/mizan-codegen/tests/fixtures/baselines/stage1/contexts/user.ts
vendored
Normal file
18
protocol/mizan-codegen/tests/fixtures/baselines/stage1/contexts/user.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanFetch } from '@mizan/base'
|
||||
|
||||
import type { userProfileOutput, userOrdersOutput } from '../types'
|
||||
|
||||
export interface UserContextData {
|
||||
user_profile: userProfileOutput
|
||||
user_orders: userOrdersOutput
|
||||
}
|
||||
|
||||
export interface UserContextParams {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export function fetchUserContext(params: UserContextParams): Promise<UserContextData> {
|
||||
return mizanFetch('user', params)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/echo.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/echo.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { echoInput, echoOutput } from '../types'
|
||||
|
||||
export function callEcho(args: echoInput): Promise<echoOutput> {
|
||||
return mizanCall('echo', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/findUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/findUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { findUserInput, findUserOutput } from '../types'
|
||||
|
||||
export function callFindUser(args: findUserInput): Promise<findUserOutput> {
|
||||
return mizanCall('find_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/renameUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/renameUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { renameUserInput, renameUserOutput } from '../types'
|
||||
|
||||
export function callRenameUser(args: renameUserInput): Promise<renameUserOutput> {
|
||||
return mizanCall('rename_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/whoami.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/functions/whoami.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { whoamiOutput } from '../types'
|
||||
|
||||
export function callWhoami(): Promise<whoamiOutput> {
|
||||
return mizanCall('whoami', {})
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/mutations/updateProfile.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/stage1/mutations/updateProfile.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { updateProfileInput, updateProfileOutput } from '../types'
|
||||
|
||||
export function callUpdateProfile(args: updateProfileInput): Promise<updateProfileOutput> {
|
||||
return mizanCall('update_profile', args)
|
||||
}
|
||||
64
protocol/mizan-codegen/tests/fixtures/baselines/stage1/types.ts
vendored
Normal file
64
protocol/mizan-codegen/tests/fixtures/baselines/stage1/types.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export interface OrderOutput {
|
||||
id: number
|
||||
user_id: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface echoInput {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface echoOutput {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface findUserInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface findUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileOutput {
|
||||
ok: boolean
|
||||
}
|
||||
|
||||
export interface userOrdersInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export type userOrdersOutput = OrderOutput[]
|
||||
|
||||
export interface userProfileInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface userProfileOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface whoamiOutput {
|
||||
email: string
|
||||
authenticated: boolean
|
||||
}
|
||||
|
||||
18
protocol/mizan-codegen/tests/fixtures/baselines/svelte/contexts/user.ts
vendored
Normal file
18
protocol/mizan-codegen/tests/fixtures/baselines/svelte/contexts/user.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanFetch } from '@mizan/base'
|
||||
|
||||
import type { userProfileOutput, userOrdersOutput } from '../types'
|
||||
|
||||
export interface UserContextData {
|
||||
user_profile: userProfileOutput
|
||||
user_orders: userOrdersOutput
|
||||
}
|
||||
|
||||
export interface UserContextParams {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export function fetchUserContext(params: UserContextParams): Promise<UserContextData> {
|
||||
return mizanFetch('user', params)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/echo.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/echo.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { echoInput, echoOutput } from '../types'
|
||||
|
||||
export function callEcho(args: echoInput): Promise<echoOutput> {
|
||||
return mizanCall('echo', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/findUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/findUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { findUserInput, findUserOutput } from '../types'
|
||||
|
||||
export function callFindUser(args: findUserInput): Promise<findUserOutput> {
|
||||
return mizanCall('find_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/renameUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/renameUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { renameUserInput, renameUserOutput } from '../types'
|
||||
|
||||
export function callRenameUser(args: renameUserInput): Promise<renameUserOutput> {
|
||||
return mizanCall('rename_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/whoami.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/functions/whoami.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { whoamiOutput } from '../types'
|
||||
|
||||
export function callWhoami(): Promise<whoamiOutput> {
|
||||
return mizanCall('whoami', {})
|
||||
}
|
||||
14
protocol/mizan-codegen/tests/fixtures/baselines/svelte/index.ts
vendored
Normal file
14
protocol/mizan-codegen/tests/fixtures/baselines/svelte/index.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export * from './types'
|
||||
|
||||
export { fetchUserContext, type UserContextData, type UserContextParams } from './contexts/user'
|
||||
|
||||
export { callEcho } from './functions/echo'
|
||||
export { callWhoami } from './functions/whoami'
|
||||
export { callUpdateProfile } from './mutations/updateProfile'
|
||||
export { callFindUser } from './functions/findUser'
|
||||
export { callRenameUser } from './functions/renameUser'
|
||||
|
||||
// Stage 2 framework adapter
|
||||
export * from './svelte'
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/mutations/updateProfile.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/svelte/mutations/updateProfile.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { updateProfileInput, updateProfileOutput } from '../types'
|
||||
|
||||
export function callUpdateProfile(args: updateProfileInput): Promise<updateProfileOutput> {
|
||||
return mizanCall('update_profile', args)
|
||||
}
|
||||
64
protocol/mizan-codegen/tests/fixtures/baselines/svelte/types.ts
vendored
Normal file
64
protocol/mizan-codegen/tests/fixtures/baselines/svelte/types.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export interface OrderOutput {
|
||||
id: number
|
||||
user_id: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface echoInput {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface echoOutput {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface findUserInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface findUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileOutput {
|
||||
ok: boolean
|
||||
}
|
||||
|
||||
export interface userOrdersInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export type userOrdersOutput = OrderOutput[]
|
||||
|
||||
export interface userProfileInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface userProfileOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface whoamiOutput {
|
||||
email: string
|
||||
authenticated: boolean
|
||||
}
|
||||
|
||||
18
protocol/mizan-codegen/tests/fixtures/baselines/vue/contexts/user.ts
vendored
Normal file
18
protocol/mizan-codegen/tests/fixtures/baselines/vue/contexts/user.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanFetch } from '@mizan/base'
|
||||
|
||||
import type { userProfileOutput, userOrdersOutput } from '../types'
|
||||
|
||||
export interface UserContextData {
|
||||
user_profile: userProfileOutput
|
||||
user_orders: userOrdersOutput
|
||||
}
|
||||
|
||||
export interface UserContextParams {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export function fetchUserContext(params: UserContextParams): Promise<UserContextData> {
|
||||
return mizanFetch('user', params)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/echo.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/echo.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { echoInput, echoOutput } from '../types'
|
||||
|
||||
export function callEcho(args: echoInput): Promise<echoOutput> {
|
||||
return mizanCall('echo', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/findUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/findUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { findUserInput, findUserOutput } from '../types'
|
||||
|
||||
export function callFindUser(args: findUserInput): Promise<findUserOutput> {
|
||||
return mizanCall('find_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/renameUser.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/renameUser.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { renameUserInput, renameUserOutput } from '../types'
|
||||
|
||||
export function callRenameUser(args: renameUserInput): Promise<renameUserOutput> {
|
||||
return mizanCall('rename_user', args)
|
||||
}
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/whoami.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/functions/whoami.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { whoamiOutput } from '../types'
|
||||
|
||||
export function callWhoami(): Promise<whoamiOutput> {
|
||||
return mizanCall('whoami', {})
|
||||
}
|
||||
14
protocol/mizan-codegen/tests/fixtures/baselines/vue/index.ts
vendored
Normal file
14
protocol/mizan-codegen/tests/fixtures/baselines/vue/index.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export * from './types'
|
||||
|
||||
export { fetchUserContext, type UserContextData, type UserContextParams } from './contexts/user'
|
||||
|
||||
export { callEcho } from './functions/echo'
|
||||
export { callWhoami } from './functions/whoami'
|
||||
export { callUpdateProfile } from './mutations/updateProfile'
|
||||
export { callFindUser } from './functions/findUser'
|
||||
export { callRenameUser } from './functions/renameUser'
|
||||
|
||||
// Stage 2 framework adapter
|
||||
export * from './vue'
|
||||
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/mutations/updateProfile.ts
vendored
Normal file
9
protocol/mizan-codegen/tests/fixtures/baselines/vue/mutations/updateProfile.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
import { mizanCall } from '@mizan/base'
|
||||
|
||||
import type { updateProfileInput, updateProfileOutput } from '../types'
|
||||
|
||||
export function callUpdateProfile(args: updateProfileInput): Promise<updateProfileOutput> {
|
||||
return mizanCall('update_profile', args)
|
||||
}
|
||||
64
protocol/mizan-codegen/tests/fixtures/baselines/vue/types.ts
vendored
Normal file
64
protocol/mizan-codegen/tests/fixtures/baselines/vue/types.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by mizan — do not edit
|
||||
|
||||
export interface OrderOutput {
|
||||
id: number
|
||||
user_id: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface echoInput {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface echoOutput {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface findUserInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface findUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface renameUserOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileInput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface updateProfileOutput {
|
||||
ok: boolean
|
||||
}
|
||||
|
||||
export interface userOrdersInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export type userOrdersOutput = OrderOutput[]
|
||||
|
||||
export interface userProfileInput {
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export interface userProfileOutput {
|
||||
user_id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface whoamiOutput {
|
||||
email: string
|
||||
authenticated: boolean
|
||||
}
|
||||
|
||||
46
protocol/mizan-codegen/tests/fixtures/channels_ir.kdl
vendored
Normal file
46
protocol/mizan-codegen/tests/fixtures/channels_ir.kdl
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
type "ChatChannelParams" {
|
||||
struct {
|
||||
field "room_id" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type "ChatReactMessage" {
|
||||
struct {
|
||||
field "text" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type "ChatDjangoMessage" {
|
||||
struct {
|
||||
field "text" {
|
||||
primitive "string"
|
||||
}
|
||||
field "from_user" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type "NotificationsDjangoMessage" {
|
||||
struct {
|
||||
field "body" {
|
||||
primitive "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channel "chat" {
|
||||
pascal-name "Chat"
|
||||
params "ChatChannelParams"
|
||||
react-message "ChatReactMessage"
|
||||
django-message "ChatDjangoMessage"
|
||||
}
|
||||
|
||||
channel "notifications" {
|
||||
pascal-name "Notifications"
|
||||
django-message "NotificationsDjangoMessage"
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"x-mizan-channels": [
|
||||
{
|
||||
"name": "chat",
|
||||
"pascalName": "Chat",
|
||||
"hasParams": true,
|
||||
"hasReactMessage": true,
|
||||
"hasDjangoMessage": true,
|
||||
"paramsType": "ChatChannelParams",
|
||||
"reactMessageType": "ChatReactMessage",
|
||||
"djangoMessageType": "ChatDjangoMessage"
|
||||
},
|
||||
{
|
||||
"name": "notifications",
|
||||
"pascalName": "Notifications",
|
||||
"hasParams": false,
|
||||
"hasReactMessage": false,
|
||||
"hasDjangoMessage": true,
|
||||
"djangoMessageType": "NotificationsDjangoMessage"
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"schemas": {
|
||||
"ChatChannelParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"room_id": { "type": "string" }
|
||||
},
|
||||
"required": ["room_id"]
|
||||
},
|
||||
"ChatReactMessage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": { "type": "string" }
|
||||
},
|
||||
"required": ["text"]
|
||||
},
|
||||
"ChatDjangoMessage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": { "type": "string" },
|
||||
"from_user": { "type": "string" }
|
||||
},
|
||||
"required": ["text", "from_user"]
|
||||
},
|
||||
"NotificationsDjangoMessage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"body": { "type": "string" }
|
||||
},
|
||||
"required": ["body"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
//! IR deserialization tests against the AFI fixture schema.
|
||||
//! IR deserialization tests against the AFI fixture (KDL).
|
||||
//!
|
||||
//! The fixture is captured from the FastAPI backend's `build_schema()`
|
||||
//! The fixture is captured from `cores/mizan-python/src/mizan_core/ir.py::build_ir()`
|
||||
//! against `tests/afi/fixture.py`. Each test exercises a different facet
|
||||
//! of the IR — function set, per-function field decoding, context-param
|
||||
//! elevation, and components.schemas presence — to confirm the typed
|
||||
//! Rust structs match the JSON shape the backends emit.
|
||||
//! elevation, and named-type presence — to confirm the typed Rust structs
|
||||
//! match the KDL shape the backend emits.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use mizan_codegen::fetch::parse_ir_from_str;
|
||||
use mizan_codegen::ir::{AffectKind, IsContext, Transport};
|
||||
use mizan_codegen::ir::{AffectKind, IsContext, NamedType, Primitive, Transport};
|
||||
|
||||
|
||||
fn load_fixture() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/afi_schema.json");
|
||||
.join("tests/fixtures/afi_ir.kdl");
|
||||
let raw = std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("read {}: {e}", path.display()));
|
||||
parse_ir_from_str(&raw).unwrap_or_else(|e| panic!("parse IR: {e}"))
|
||||
@@ -26,7 +26,6 @@ fn afi_fixture_deserializes_function_set() {
|
||||
let ir = load_fixture();
|
||||
let names: Vec<&str> = ir.functions.iter().map(|f| f.name.as_str()).collect();
|
||||
|
||||
// Seven fixture functions per tests/afi/fixture.py.
|
||||
assert_eq!(ir.functions.len(), 7, "expected 7 functions, got {}: {names:?}", ir.functions.len());
|
||||
|
||||
for expected in [
|
||||
@@ -67,6 +66,10 @@ fn afi_fixture_function_field_decode() {
|
||||
assert_eq!(update_profile.affects.len(), 1);
|
||||
assert_eq!(update_profile.affects[0].kind, AffectKind::Context);
|
||||
assert_eq!(update_profile.affects[0].name, "user");
|
||||
|
||||
// Mutation with `merge="user"`.
|
||||
let rename_user = ir.functions.iter().find(|f| f.name == "rename_user").unwrap();
|
||||
assert_eq!(rename_user.merge, vec!["user".to_string()]);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +80,7 @@ fn afi_fixture_context_param_elevation() {
|
||||
|
||||
// Both context functions share `user_id` as a required param.
|
||||
let user_id = user.params.get("user_id").expect("user_id param");
|
||||
assert_eq!(user_id.ty, "integer");
|
||||
assert_eq!(user_id.ty, Primitive::Integer);
|
||||
assert!(user_id.required, "user_id is required (declared by every fn in the group)");
|
||||
assert!(user_id.shared_by.contains(&"user_profile".to_string()));
|
||||
assert!(user_id.shared_by.contains(&"user_orders".to_string()));
|
||||
@@ -85,19 +88,26 @@ fn afi_fixture_context_param_elevation() {
|
||||
|
||||
|
||||
#[test]
|
||||
fn afi_fixture_components_schemas_present() {
|
||||
fn afi_fixture_named_types_present() {
|
||||
let ir = load_fixture();
|
||||
// Each fixture function pairs with an *Input/Output schema in components.
|
||||
// Every IR function references its <camelName>Input / <camelName>Output
|
||||
// type by name; the IR's `type` section must declare each as a named
|
||||
// type (struct, alias to a list, etc.).
|
||||
for expected in [
|
||||
"echoInput", "echoOutput",
|
||||
"whoamiOutput",
|
||||
"userProfileInput", "userProfileOutput",
|
||||
"userOrdersInput",
|
||||
"updateProfileInput", "updateProfileOutput",
|
||||
"findUserInput", "findUserOutput",
|
||||
"renameUserInput", "renameUserOutput",
|
||||
] {
|
||||
assert!(
|
||||
ir.components.schemas.contains_key(expected),
|
||||
"missing schema {expected:?}",
|
||||
);
|
||||
let ty = ir.types.get(expected)
|
||||
.unwrap_or_else(|| panic!("missing type {expected:?}"));
|
||||
// Each named type is one of the four KDL shapes — sanity-check
|
||||
// we round-tripped a non-trivial declaration.
|
||||
match ty {
|
||||
NamedType::Struct(_) | NamedType::List(_) | NamedType::Enum(_) | NamedType::Alias(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use mizan_codegen::fetch::parse_ir_from_str;
|
||||
|
||||
|
||||
fn load_ir() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_schema.json");
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_ir.kdl");
|
||||
parse_ir_from_str(&std::fs::read_to_string(&path).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ fn fixture_config() -> Config {
|
||||
|
||||
fn read_baseline(rel: &str) -> String {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/js_python")
|
||||
.join("tests/fixtures/baselines/python")
|
||||
.join(rel);
|
||||
std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("read baseline {}: {e}", path.display()))
|
||||
|
||||
@@ -9,7 +9,7 @@ use mizan_codegen::fetch::parse_ir_from_str;
|
||||
|
||||
|
||||
fn load_ir() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_schema.json");
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_ir.kdl");
|
||||
parse_ir_from_str(&std::fs::read_to_string(&path).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ fn react_target_byte_match() {
|
||||
let actual = &files[0].content;
|
||||
|
||||
let expected_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/js_react/react.tsx");
|
||||
.join("tests/fixtures/baselines/react/react.tsx");
|
||||
let expected = std::fs::read_to_string(&expected_path).unwrap();
|
||||
|
||||
if *actual != expected {
|
||||
|
||||
@@ -14,7 +14,7 @@ use mizan_codegen::fetch::parse_ir_from_str;
|
||||
|
||||
fn load_ir() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/afi_schema.json");
|
||||
.join("tests/fixtures/afi_ir.kdl");
|
||||
parse_ir_from_str(&std::fs::read_to_string(&path).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ fn fixture_config() -> Config {
|
||||
|
||||
fn read_baseline(rel: &str) -> String {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/js_rust")
|
||||
.join("tests/fixtures/baselines/rust")
|
||||
.join(rel);
|
||||
std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("read baseline {}: {e}", path.display()))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Byte-equivalence tests for the deterministic Stage 1 files (contexts,
|
||||
//! mutations, functions, index). Baseline output captured from the JS
|
||||
//! codegen at `protocol/mizan-generate/generator/lib/stage1.mjs` against
|
||||
//! the AFI fixture schema (`tests/fixtures/afi_schema.json`).
|
||||
//! the AFI fixture schema (`tests/fixtures/afi_ir.kdl`).
|
||||
//!
|
||||
//! `types.ts` is NOT byte-checked here — the JS codegen routes type
|
||||
//! emission through openapi-typescript while the Rust substrate emits
|
||||
@@ -19,7 +19,7 @@ use mizan_codegen::fetch::parse_ir_from_str;
|
||||
|
||||
fn load_ir() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/afi_schema.json");
|
||||
.join("tests/fixtures/afi_ir.kdl");
|
||||
let raw = std::fs::read_to_string(&path).unwrap();
|
||||
parse_ir_from_str(&raw).unwrap()
|
||||
}
|
||||
@@ -44,7 +44,7 @@ fn emit_index(files: &[EmittedFile]) -> BTreeMap<PathBuf, &str> {
|
||||
|
||||
fn read_baseline(rel: &str) -> String {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("tests/fixtures/js_stage1")
|
||||
.join("tests/fixtures/baselines/stage1")
|
||||
.join(rel);
|
||||
std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("read baseline {}: {e}", path.display()))
|
||||
|
||||
@@ -10,7 +10,7 @@ use mizan_codegen::fetch::parse_ir_from_str;
|
||||
|
||||
|
||||
fn load_ir() -> mizan_codegen::ir::MizanIR {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_schema.json");
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/afi_ir.kdl");
|
||||
parse_ir_from_str(&std::fs::read_to_string(&path).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ fn vue_target_byte_match() {
|
||||
let ir = load_ir();
|
||||
let files = VueAdapter.emit(&ir, &fixture_config("vue"));
|
||||
assert_eq!(files.len(), 1);
|
||||
assert_byte_equal(&files[0].content, "tests/fixtures/js_vue/vue.ts", "vue.ts");
|
||||
assert_byte_equal(&files[0].content, "tests/fixtures/baselines/vue/vue.ts", "vue.ts");
|
||||
}
|
||||
|
||||
|
||||
@@ -62,5 +62,5 @@ fn svelte_target_byte_match() {
|
||||
let ir = load_ir();
|
||||
let files = SvelteAdapter.emit(&ir, &fixture_config("svelte"));
|
||||
assert_eq!(files.len(), 1);
|
||||
assert_byte_equal(&files[0].content, "tests/fixtures/js_svelte/svelte.ts", "svelte.ts");
|
||||
assert_byte_equal(&files[0].content, "tests/fixtures/baselines/svelte/svelte.ts", "svelte.ts");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user