Files
zeekay 999e2153b3 Type every wire: bytes, forms, streams, sockets, redirects, unions
A typed op could only take one JSON value and answer one, so uploads,
signed webhooks, form posts, YAML and merge-patch bodies, PDFs, SSE,
WebSockets, OAuth redirects and upstream relays stayed untyped routes
with no schema, tool, command or SDK method. Each is now a typed op and
its REST wire is unchanged.

Requests: a zip.Body field takes the body and Content-Type exactly as
sent; an In implementing Parser decodes itself; form: fields and
*zip.File parts bind url-encoded and multipart forms; cookie: binds a
request cookie as an in: cookie parameter. Consumes names the media.

Answers: zip.Body (bytes, filename, its own status and headers, a
Reader streams chunked), Verbatim[T] (a relay documented as T), Sse[T]
(events with keep-alive), Socket[M] (an upgrade after the contract
runs; 426 without one, 501 over ZAP), Redirect, CookieCoder, Produces,
and unions: a type whose OneOf method's results are the alternatives,
with Or[A,B] as the stock one filing each under the status it states.

Projections follow from the manifest: the document publishes binary
media, form schemas, x-events, x-socket with 101, 3xx with Location
and oneOf; MCP takes bytes as base64 and returns bytes, text or
collected events as tool content, listing a socket op in _meta as no
tool; the CLI reads --body @file|-, --field name=@file and --out,
prints events as they arrive and bridges a socket to stdin and stdout.
tools/list is ProjectMCP over the manifest, the projection MCPTools
already was.

Prose reaches promoted fields (filed under the declaring struct), a
type defined over another struct, and the type arguments of zip's
kinds and OneOf results; an instantiated generic is published under
its name followed by its argument names instead of an illegal
component key. The unused reflect-only document and tool builders go.
2026-10-09 09:42:00 -07:00

42 lines
1.0 KiB
Go

// Package defined answers with a type defined over another struct, whose
// fields are the other's and whose prose is written there.
package defined
import (
"context"
"github.com/zap-proto/zip"
"github.com/zap-proto/zip/internal/zipdoc/testdata/defined/court"
)
// Filing is one filing.
type Filing struct {
// Name is the filing's title.
Name string `json:"name"`
}
// legalFiling is a Filing as this package answers it.
type legalFiling Filing
// docket is a court record as this package answers it.
type docket court.Record
// In names a filing.
type In struct {
// ID addresses the filing.
ID string `json:"id" url:"id"`
}
// Get returns one filing.
func Get(ctx context.Context, in *In) (*legalFiling, error) { return &legalFiling{}, nil }
// Docket returns the filing's court record.
func Docket(ctx context.Context, in *In) (*docket, error) { return &docket{}, nil }
// Register declares the ops.
func Register(app *zip.App) {
app.Get("/v1/filings/:id", Get)
app.Get("/v1/filings/:id/docket", Docket)
}