@rayfold/server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +10 -0
- package/README.md +70 -0
- package/args.d.ts +15 -0
- package/args.js +226 -0
- package/args.js.map +1 -0
- package/batch.d.ts +54 -0
- package/batch.js +483 -0
- package/batch.js.map +1 -0
- package/bindings.d.ts +37 -0
- package/bindings.js +284 -0
- package/bindings.js.map +1 -0
- package/capability-scope.d.ts +8 -0
- package/capability-scope.js +19 -0
- package/capability-scope.js.map +1 -0
- package/capability.d.ts +56 -0
- package/capability.js +112 -0
- package/capability.js.map +1 -0
- package/context.d.ts +74 -0
- package/context.js +109 -0
- package/context.js.map +1 -0
- package/core.d.ts +18 -0
- package/core.js +18 -0
- package/core.js.map +1 -0
- package/cost.d.ts +15 -0
- package/cost.js +110 -0
- package/cost.js.map +1 -0
- package/executor.d.ts +89 -0
- package/executor.js +695 -0
- package/executor.js.map +1 -0
- package/guard.d.ts +33 -0
- package/guard.js +65 -0
- package/guard.js.map +1 -0
- package/http.d.ts +33 -0
- package/http.js +379 -0
- package/http.js.map +1 -0
- package/index.d.ts +8 -0
- package/index.js +9 -0
- package/index.js.map +1 -0
- package/instrumentation.d.ts +36 -0
- package/instrumentation.js +2 -0
- package/instrumentation.js.map +1 -0
- package/live.d.ts +37 -0
- package/live.js +240 -0
- package/live.js.map +1 -0
- package/mcp.d.ts +55 -0
- package/mcp.js +314 -0
- package/mcp.js.map +1 -0
- package/openapi.d.ts +11 -0
- package/openapi.js +124 -0
- package/openapi.js.map +1 -0
- package/package.json +53 -0
- package/policy.d.ts +17 -0
- package/policy.js +64 -0
- package/policy.js.map +1 -0
- package/protocol.d.ts +139 -0
- package/protocol.js +98 -0
- package/protocol.js.map +1 -0
- package/server.d.ts +58 -0
- package/server.js +79 -0
- package/server.js.map +1 -0
- package/usage.d.ts +39 -0
- package/usage.js +44 -0
- package/usage.js.map +1 -0
- package/views.d.ts +33 -0
- package/views.js +108 -0
- package/views.js.map +1 -0
- package/wiring.d.ts +16 -0
- package/wiring.js +57 -0
- package/wiring.js.map +1 -0
- package/ws.d.ts +21 -0
- package/ws.js +209 -0
- package/ws.js.map +1 -0
package/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP bridge (spec 10): any Rayfold server is an MCP server.\n * Streamable HTTP, stateless (revision 2026-07-28): POST JSON-RPC to /mcp, JSON response.\n * commands -> tools (plus a `simulate` variant), queries -> tools and resources, schema docs -> descriptions.\n */\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { annotation, baseName, type ArgDef, type FieldDef, type OpDef, type RayfoldSchemaIR, type TypeRef } from \"@rayfold/schema\";\nimport type { RayfoldServer } from \"./server.ts\";\nimport type { Frame } from \"./protocol.ts\";\nimport { hostProblem, mediaType, originProblem, refuse, type OriginOptions } from \"./guard.ts\";\n\nexport const MCP_PROTOCOL_VERSION = \"2026-07-28\";\n\ninterface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: number | string | null;\n method: string;\n params?: Record<string, unknown>;\n}\n\nexport interface McpTool {\n name: string;\n title?: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n outputSchema?: Record<string, unknown>;\n annotations?: { readOnlyHint?: boolean; destructiveHint?: boolean; idempotentHint?: boolean };\n}\n\nexport interface McpResource {\n uri: string;\n name: string;\n description?: string;\n mimeType: string;\n}\n\n/** JSON Schema 2020-12 for a Rayfold type reference. */\nexport function jsonSchemaFor(ir: RayfoldSchemaIR, t: TypeRef, defs: Record<string, unknown>, forInput: boolean): Record<string, unknown> {\n const nullable = (s: Record<string, unknown>): Record<string, unknown> => (t.nullable ? { anyOf: [s, { type: \"null\" }] } : s);\n if (t.kind === \"list\") return nullable({ type: \"array\", items: jsonSchemaFor(ir, t.of, defs, forInput) });\n const def = ir.types[t.name];\n if (!def) return {};\n switch (def.kind) {\n case \"scalar\": {\n const map: Record<string, Record<string, unknown>> = {\n ID: { type: \"string\" },\n String: { type: \"string\" },\n Int: { type: \"integer\" },\n Long: { type: [\"integer\", \"string\"] },\n Float: { type: \"number\" },\n Boolean: { type: \"boolean\" },\n Decimal: { type: \"string\", pattern: \"^-?\\\\d+(\\\\.\\\\d+)?$\" },\n Instant: { type: \"string\", format: \"date-time\" },\n Date: { type: \"string\", format: \"date\" },\n Duration: { type: [\"string\", \"integer\"] },\n Bytes: { type: \"string\", contentEncoding: \"base64url\" },\n JSON: {},\n };\n return nullable(map[t.name] ?? { type: [\"string\", \"number\"] });\n }\n case \"enum\":\n return nullable({ type: \"string\", enum: def.values.map((v) => v.name) });\n case \"union\":\n return nullable({ anyOf: def.members.map((m) => jsonSchemaFor(ir, { kind: \"named\", name: m, nullable: false }, defs, forInput)) });\n default: {\n const key = t.name === \"Page\" && t.args?.[0] ? `Page_${baseName(t.args[0])}` : t.name;\n if (!(key in defs)) {\n defs[key] = {}; // placeholder for recursion\n const fields = def.kind === \"object\" && def.typeParams?.length && t.args ? substituteFields(ir, def.fields, def.typeParams, t.args) : def.fields;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n if (def.kind === \"entity\") properties[\"$type\"] = { const: def.name };\n for (const f of fields) {\n if (forInput && f.args.length) continue;\n const s = withRange(jsonSchemaFor(ir, f.type, defs, forInput), f.annotations, baseName(f.type));\n properties[f.name] = f.description ? { ...s, description: f.description } : s;\n if (!f.type.nullable && f.default === undefined) required.push(f.name);\n }\n const schema: Record<string, unknown> = { type: \"object\", properties, additionalProperties: false };\n if (required.length) schema[\"required\"] = required;\n if (def.description) schema[\"description\"] = def.description;\n defs[key] = schema;\n }\n return nullable({ $ref: `#/$defs/${key}` });\n }\n }\n}\n\nfunction substituteFields(ir: RayfoldSchemaIR, fields: FieldDef[], params: string[], args: TypeRef[]): FieldDef[] {\n void ir;\n const bind = new Map(params.map((p, i) => [p, args[i]!]));\n const sub = (t: TypeRef): TypeRef => {\n if (t.kind === \"list\") return { kind: \"list\", of: sub(t.of), nullable: t.nullable };\n const b = bind.get(t.name);\n return b ? { ...b, nullable: t.nullable || b.nullable } : t;\n };\n return fields.map((f) => ({ ...f, type: sub(f.type) }));\n}\n\n/**\n * @range becomes JSON Schema keywords the validator understands (minimum/maximum on numbers, minLength/maxLength\n * on strings) plus `x-rayfold-range`, which also covers Decimal (a string on the wire).\n */\nexport function withRange(s: Record<string, unknown>, annotations: { name: string; args: Record<string, unknown> }[], typeName: string): Record<string, unknown> {\n const r = annotations.find((a) => a.name === \"range\");\n if (!r) return s;\n const min = typeof r.args[\"min\"] === \"number\" ? r.args[\"min\"] : undefined;\n const max = typeof r.args[\"max\"] === \"number\" ? r.args[\"max\"] : undefined;\n const out: Record<string, unknown> = { ...s, \"x-rayfold-range\": { ...(min !== undefined ? { min } : {}), ...(max !== undefined ? { max } : {}) } };\n const numeric = [\"Int\", \"Long\", \"Float\"].includes(typeName);\n const text = typeName === \"String\";\n if (numeric || text) {\n if (min !== undefined) out[numeric ? \"minimum\" : \"minLength\"] = min;\n if (max !== undefined) out[numeric ? \"maximum\" : \"maxLength\"] = max;\n }\n return out;\n}\n\nfunction argsSchema(ir: RayfoldSchemaIR, args: ArgDef[]): Record<string, unknown> {\n const defs: Record<string, unknown> = {};\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const a of args) {\n const s = withRange(jsonSchemaFor(ir, a.type, defs, true), a.annotations, baseName(a.type));\n properties[a.name] = a.description ? { ...s, description: a.description } : s;\n if (!a.type.nullable && a.default === undefined) required.push(a.name);\n }\n const schema: Record<string, unknown> = { $schema: \"https://json-schema.org/draft/2020-12/schema\", type: \"object\", properties, additionalProperties: false };\n if (required.length) schema[\"required\"] = required;\n if (Object.keys(defs).length) schema[\"$defs\"] = defs;\n return schema;\n}\n\nfunction resultSchema(ir: RayfoldSchemaIR, t: TypeRef): Record<string, unknown> {\n const defs: Record<string, unknown> = {};\n const inner = jsonSchemaFor(ir, t, defs, false);\n const schema: Record<string, unknown> = { $schema: \"https://json-schema.org/draft/2020-12/schema\", type: \"object\", properties: { result: inner }, required: [\"result\"] };\n if (Object.keys(defs).length) schema[\"$defs\"] = defs;\n return schema;\n}\n\nexport function mcpTools(server: RayfoldServer): McpTool[] {\n const ir = server.ir;\n const tools: McpTool[] = [];\n for (const op of Object.values(ir.ops)) {\n if (op.kind === \"stream\") continue;\n const base: McpTool = { name: op.name, inputSchema: argsSchema(ir, op.args), outputSchema: resultSchema(ir, op.returns) };\n const desc = [op.description, op.throws.length ? `May fail with: ${op.throws.join(\", \")}.` : \"\", op.kind === \"query\" ? \"Read-only.\" : \"Changes state; idempotent per call key.\"].filter(Boolean).join(\" \");\n if (desc) base.description = desc;\n base.annotations = op.kind === \"query\" ? { readOnlyHint: true, idempotentHint: true } : { readOnlyHint: false, destructiveHint: true, idempotentHint: true };\n tools.push(base);\n // A dry-run tool is offered only where the command declares @simulate: the runtime cannot stop a resolver that ignores ctx.simulate.\n if (op.kind === \"command\" && op.annotations.some((a) => a.name === \"simulate\")) {\n tools.push({\n ...base,\n name: `${op.name}.simulate`,\n description: `Dry run of ${op.name}: returns the would-be result and effects without committing.`,\n annotations: { readOnlyHint: true, idempotentHint: true },\n });\n }\n }\n return tools;\n}\n\nexport function mcpResources(server: RayfoldServer): McpResource[] {\n const out: McpResource[] = [{ uri: \"rayfold://schema\", name: \"Rayfold schema (IR)\", description: \"The full schema as JSON IR\", mimeType: \"application/json\" }];\n for (const op of Object.values(server.ir.ops)) {\n if (op.kind !== \"query\" || op.args.some((a) => !a.type.nullable && a.default === undefined)) continue;\n const r: McpResource = { uri: `rayfold://query/${op.name}`, name: op.name, mimeType: \"application/json\" };\n if (op.description) r.description = op.description;\n out.push(r);\n }\n return out;\n}\n\nasync function callTool(server: RayfoldServer, name: string, args: Record<string, unknown>, viewer: unknown): Promise<Record<string, unknown>> {\n const simulate = name.endsWith(\".simulate\");\n const opName = simulate ? name.slice(0, -\".simulate\".length) : name;\n const op = server.ir.ops[opName];\n if (!op || op.kind === \"stream\") return { isError: true, content: [{ type: \"text\", text: `Unknown tool ${name}` }] };\n const req: import(\"./protocol.ts\").RequestOp = { id: 1, op: opName, args };\n if (op.kind === \"command\") {\n const optedOut = op.annotations.some((a) => a.name === \"idempotent\" && a.args[\"value\"] === false);\n if (!optedOut) req.key = `mcp-${hashKey(JSON.stringify(args))}`;\n if (simulate) req.simulate = true;\n }\n const frames = await server.collect({ ops: [req], meta: { client: \"mcp\" } }, { viewer });\n const data = foldForMcp(frames);\n if (\"error\" in data) {\n const e = data.error;\n return { isError: true, content: [{ type: \"text\", text: `${e.code}${e.type ? ` ${e.type}` : \"\"}: ${e.message}` }], structuredContent: { error: e } };\n }\n const structured: Record<string, unknown> = { result: data.result };\n if (data.patch) structured[\"effects\"] = data.patch;\n return { content: [{ type: \"text\", text: JSON.stringify(structured.result, null, 2) }], structuredContent: structured, resultType: \"complete\" };\n}\n\nfunction foldForMcp(frames: Frame[]): { result: unknown; patch?: unknown } | { error: { code: string; type?: string; message: string; data?: unknown } } {\n let result: unknown;\n let patch: unknown;\n for (const f of frames) {\n if (\"error\" in f) return { error: f.error };\n if (\"ok\" in f) {\n result = f.ok;\n patch = f.patch;\n } else if (\"data\" in f && !(\"at\" in f)) result = f.data;\n else if (\"at\" in f && result && typeof result === \"object\") {\n const target = f.at === \"\" ? result : getPath(result, f.at.split(\".\"));\n if (target && typeof target === \"object\") Object.assign(target as object, f.data as object);\n }\n }\n return patch !== undefined ? { result, patch } : { result };\n}\n\nfunction getPath(v: unknown, path: string[]): unknown {\n let cur = v;\n for (const p of path) {\n if (cur === null || cur === undefined || typeof cur !== \"object\") return undefined;\n cur = Array.isArray(cur) ? cur[Number(p)] : (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nfunction hashKey(s: string): string {\n let h = 2166136261;\n for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619);\n return (h >>> 0).toString(16).padStart(8, \"0\") + s.length.toString(16).padStart(8, \"0\");\n}\n\n/** Handle one JSON-RPC request (stateless). */\nexport async function handleMcp(server: RayfoldServer, req: JsonRpcRequest, viewer: unknown): Promise<Record<string, unknown> | null> {\n const reply = (result: unknown) => ({ jsonrpc: \"2.0\", id: req.id ?? null, result });\n const fail = (code: number, message: string) => ({ jsonrpc: \"2.0\", id: req.id ?? null, error: { code, message } });\n const p = req.params ?? {};\n switch (req.method) {\n case \"initialize\":\n return reply({ protocolVersion: MCP_PROTOCOL_VERSION, capabilities: { tools: { listChanged: false }, resources: { subscribe: false, listChanged: false } }, serverInfo: { name: \"rayfold\", version: \"0.1\", schemaHash: server.hash } });\n case \"server/discover\":\n return reply({ protocolVersion: MCP_PROTOCOL_VERSION, capabilities: { tools: {}, resources: {} }, serverInfo: { name: \"rayfold\", version: \"0.1\", schemaHash: server.hash } });\n case \"ping\":\n return reply({});\n case \"notifications/initialized\":\n return null;\n case \"tools/list\":\n return reply({ tools: mcpTools(server), ttlMs: 300_000, cacheScope: \"public\" });\n case \"tools/call\": {\n const name = p[\"name\"];\n if (typeof name !== \"string\") return fail(-32602, \"name is required\");\n return reply(await callTool(server, name, (p[\"arguments\"] as Record<string, unknown>) ?? {}, viewer));\n }\n case \"resources/list\":\n return reply({ resources: mcpResources(server), ttlMs: 300_000, cacheScope: \"public\" });\n case \"resources/read\": {\n const uri = p[\"uri\"];\n if (typeof uri !== \"string\") return fail(-32602, \"uri is required\");\n if (uri === \"rayfold://schema\") return reply({ contents: [{ uri, mimeType: \"application/json\", text: JSON.stringify(server.ir) }] });\n const m = /^rayfold:\\/\\/query\\/([A-Za-z_][A-Za-z0-9_]*)(\\?(.*))?$/.exec(uri);\n if (!m) return fail(-32602, `Unknown resource ${uri}`);\n const args: Record<string, unknown> = {};\n for (const [k, v] of new URLSearchParams(m[3] ?? \"\")) args[k] = v;\n const r = await callTool(server, m[1]!, args, viewer);\n if (r[\"isError\"]) return fail(-32000, (r[\"content\"] as Array<{ text: string }>)[0]?.text ?? \"error\");\n return reply({ contents: [{ uri, mimeType: \"application/json\", text: JSON.stringify((r[\"structuredContent\"] as { result: unknown }).result) }] });\n }\n case \"prompts/list\":\n return reply({ prompts: [] });\n default:\n return fail(-32601, `Method not found: ${req.method}`);\n }\n}\n\nexport interface McpHttpOptions extends OriginOptions {\n path?: string;\n viewer?: (req: IncomingMessage) => unknown | Promise<unknown>;\n}\n\n/** Streamable HTTP endpoint: POST JSON-RPC, JSON reply. */\nexport function createMcpHandler(server: RayfoldServer, opts: McpHttpOptions = {}): (req: IncomingMessage, res: ServerResponse) => Promise<boolean> {\n const path = opts.path ?? \"/mcp\";\n return async (req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n if (url.pathname !== path) return false;\n if (req.method !== \"POST\") {\n res.writeHead(405, { Allow: \"POST\", \"X-Content-Type-Options\": \"nosniff\" }).end();\n return true;\n }\n // The MCP transport requires Origin validation: without it any web page could drive a local or intranet server.\n const refused = hostProblem(req, opts) ?? originProblem(req, opts);\n if (refused) {\n refuse(res, 403, \"permission_denied\", refused);\n return true;\n }\n if (mediaType(req) !== \"application/json\") {\n refuse(res, 415, \"invalid_argument\", `Content-Type ${mediaType(req) || \"(none)\"} is not accepted; send application/json`, \"unsupported_media_type\");\n return true;\n }\n res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n const chunks: Buffer[] = [];\n for await (const c of req) chunks.push(c as Buffer);\n let body: JsonRpcRequest | JsonRpcRequest[];\n try {\n body = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" }).end(JSON.stringify({ jsonrpc: \"2.0\", id: null, error: { code: -32700, message: \"Parse error\" } }));\n return true;\n }\n const viewer = opts.viewer ? await opts.viewer(req) : null;\n const headerMethod = req.headers[\"mcp-method\"];\n const first = Array.isArray(body) ? body[0] : body;\n if (typeof headerMethod === \"string\" && first && headerMethod !== first.method) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" }).end(JSON.stringify({ jsonrpc: \"2.0\", id: first.id ?? null, error: { code: -32020, message: \"HeaderMismatch\" } }));\n return true;\n }\n const results = await Promise.all((Array.isArray(body) ? body : [body]).map((r) => handleMcp(server, r, viewer)));\n const out = Array.isArray(body) ? results.filter(Boolean) : results[0];\n res.setHeader(\"MCP-Protocol-Version\", MCP_PROTOCOL_VERSION);\n if (out === null || out === undefined) {\n res.writeHead(202).end();\n return true;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" }).end(JSON.stringify(out));\n return true;\n };\n}\n\nexport { annotation as _annotation };\n"]}
|
package/openapi.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI 3.2 generated from the schema and its HTTP bindings. The document is derived from the same IR that
|
|
3
|
+
* the runtime enforces, so the published contract and the validation rules cannot drift apart.
|
|
4
|
+
* 3.2 is required for the QUERY operation.
|
|
5
|
+
*/
|
|
6
|
+
import { type RayfoldSchemaIR } from "@rayfold/schema";
|
|
7
|
+
export declare function openApiFor(ir: RayfoldSchemaIR, opts?: {
|
|
8
|
+
title?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
}): Record<string, unknown>;
|
package/openapi.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI 3.2 generated from the schema and its HTTP bindings. The document is derived from the same IR that
|
|
3
|
+
* the runtime enforces, so the published contract and the validation rules cannot drift apart.
|
|
4
|
+
* 3.2 is required for the QUERY operation.
|
|
5
|
+
*/
|
|
6
|
+
import { annotation, baseName } from "@rayfold/schema";
|
|
7
|
+
import { bindingsOf } from "./bindings.js";
|
|
8
|
+
import { jsonSchemaFor, withRange } from "./mcp.js";
|
|
9
|
+
export function openApiFor(ir, opts = {}) {
|
|
10
|
+
const defs = {};
|
|
11
|
+
const schema = (t, input) => jsonSchemaFor(ir, t, defs, input);
|
|
12
|
+
const paths = {};
|
|
13
|
+
for (const b of bindingsOf(ir)) {
|
|
14
|
+
const op = b.op;
|
|
15
|
+
const p = (opts.prefix ?? "") + b.path;
|
|
16
|
+
const parameters = b.params.map((name) => param(ir, op, name, "path", true, defs));
|
|
17
|
+
if (b.method === "GET") {
|
|
18
|
+
for (const a of op.args)
|
|
19
|
+
if (!b.params.includes(a.name))
|
|
20
|
+
parameters.push(param(ir, op, a.name, "query", !a.type.nullable && a.default === undefined, defs));
|
|
21
|
+
parameters.push({ name: "shape", in: "query", required: false, description: "Rayfold shape text or sha256: shape id; default view when absent", schema: { type: "string" } });
|
|
22
|
+
}
|
|
23
|
+
const versioned = returnsVersionedEntity(ir, op);
|
|
24
|
+
if (op.kind === "command" && b.method === "POST") {
|
|
25
|
+
const optOut = annotation(op, "idempotent")?.args["value"] === false;
|
|
26
|
+
parameters.push({ name: "Idempotency-Key", in: "header", required: !optOut, description: "Replays the original response on retry", schema: { type: "string", minLength: 16, maxLength: 128 } });
|
|
27
|
+
}
|
|
28
|
+
// The binding honours If-Match on every method, so every versioned command offers it (and lists 412).
|
|
29
|
+
if (op.kind === "command" && versioned) {
|
|
30
|
+
parameters.push({ name: "If-Match", in: "header", required: false, description: "Entity version from a previous response; 412 with the current entity when stale", schema: { type: "string" } });
|
|
31
|
+
}
|
|
32
|
+
const operation = { operationId: op.name, parameters };
|
|
33
|
+
if (op.description)
|
|
34
|
+
operation["summary"] = op.description;
|
|
35
|
+
if (b.body) {
|
|
36
|
+
const bodySchema = b.body === "*" ? argsObject(ir, op.args.filter((a) => !b.params.includes(a.name)), defs) : schema(op.args.find((a) => a.name === b.body).type, true);
|
|
37
|
+
const types = b.method === "PATCH" ? ["application/merge-patch+json", "application/json"] : ["application/json"];
|
|
38
|
+
const bodyArgs = b.body === "*" ? op.args.filter((a) => !b.params.includes(a.name)) : op.args.filter((a) => a.name === b.body);
|
|
39
|
+
const required = bodyArgs.some((a) => !a.type.nullable && a.default === undefined);
|
|
40
|
+
operation["requestBody"] = { required, content: Object.fromEntries(types.map((t) => [t, { schema: bodySchema }])) };
|
|
41
|
+
}
|
|
42
|
+
const ok = { description: "Result in the requested shape (default view when no shape is given)", content: { "application/json": { schema: schema(op.returns, false) } } };
|
|
43
|
+
const responses = {};
|
|
44
|
+
responses[b.method === "POST" && b.location ? "201" : "200"] = ok;
|
|
45
|
+
if (op.kind === "query")
|
|
46
|
+
responses["304"] = { description: "Not modified (ETag revalidation)" };
|
|
47
|
+
responses["400"] = problemRef("Invalid argument, including schema constraints such as @range");
|
|
48
|
+
if (hasPolicy(op) || typeHasPolicy(ir, op.returns)) {
|
|
49
|
+
responses["401"] = problemRef("Sign-in required by a policy");
|
|
50
|
+
responses["403"] = problemRef("Denied by a policy");
|
|
51
|
+
}
|
|
52
|
+
if (op.kind === "command" && versioned)
|
|
53
|
+
responses["412"] = problemRef("VersionConflict: data.current carries the entity as stored");
|
|
54
|
+
if (op.throws.length) {
|
|
55
|
+
responses["422"] = { description: `Declared domain errors: ${op.throws.join(", ")}`, content: { "application/problem+json": { schema: { oneOf: op.throws.map((t) => domainProblem(t, schema({ kind: "named", name: t, nullable: false }, false))) } } } };
|
|
56
|
+
}
|
|
57
|
+
operation["responses"] = responses;
|
|
58
|
+
(paths[p] ??= {})[b.method.toLowerCase()] = operation;
|
|
59
|
+
}
|
|
60
|
+
const components = JSON.parse(JSON.stringify({ schemas: { ...defs, Problem: PROBLEM } }).replace(/"#\/\$defs\//g, '"#/components/schemas/'));
|
|
61
|
+
const doc = { openapi: "3.2.0", info: { title: opts.title ?? "Rayfold API", version: opts.version ?? "0.1" }, paths, components };
|
|
62
|
+
return JSON.parse(JSON.stringify(doc).replace(/"#\/\$defs\//g, '"#/components/schemas/'));
|
|
63
|
+
}
|
|
64
|
+
const PROBLEM = {
|
|
65
|
+
type: "object",
|
|
66
|
+
description: "RFC 9457 problem details; Rayfold errors keep code, type and data",
|
|
67
|
+
properties: { type: { type: "string" }, title: { type: "string" }, status: { type: "integer" }, detail: { type: "string" }, code: { type: "string" }, path: { type: "string" }, data: {} },
|
|
68
|
+
required: ["type", "title", "status", "code"],
|
|
69
|
+
};
|
|
70
|
+
function problemRef(description) {
|
|
71
|
+
return { description, content: { "application/problem+json": { schema: { $ref: "#/components/schemas/Problem" } } } };
|
|
72
|
+
}
|
|
73
|
+
function domainProblem(type, dataSchema) {
|
|
74
|
+
return { allOf: [{ $ref: "#/components/schemas/Problem" }, { properties: { title: { const: type }, data: dataSchema } }] };
|
|
75
|
+
}
|
|
76
|
+
function param(ir, op, name, where, required, defs) {
|
|
77
|
+
const a = op.args.find((x) => x.name === name);
|
|
78
|
+
const s = a ? jsonSchemaFor(ir, a.type, defs, true) : { type: "string" };
|
|
79
|
+
const out = { name, in: where, required: where === "path" ? true : required, schema: a ? withRange(s, a.annotations, baseName(a.type)) : s };
|
|
80
|
+
if (a?.description)
|
|
81
|
+
out["description"] = a.description;
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function argsObject(ir, args, defs) {
|
|
85
|
+
const properties = {};
|
|
86
|
+
const required = [];
|
|
87
|
+
for (const a of args) {
|
|
88
|
+
properties[a.name] = withRange(jsonSchemaFor(ir, a.type, defs, true), a.annotations, baseName(a.type));
|
|
89
|
+
if (!a.type.nullable && a.default === undefined)
|
|
90
|
+
required.push(a.name);
|
|
91
|
+
}
|
|
92
|
+
return required.length ? { type: "object", properties, required } : { type: "object", properties };
|
|
93
|
+
}
|
|
94
|
+
function hasPolicy(op) {
|
|
95
|
+
return op.annotations.some((a) => a.name === "allow" || a.name === "deny");
|
|
96
|
+
}
|
|
97
|
+
/** A policy on any type the result can reach (list elements, Page<T>, nested fields), or on one of their fields, can refuse a caller. */
|
|
98
|
+
function typeHasPolicy(ir, t, seen = new Set()) {
|
|
99
|
+
if (t.kind === "list")
|
|
100
|
+
return typeHasPolicy(ir, t.of, seen);
|
|
101
|
+
if (t.args?.some((a) => typeHasPolicy(ir, a, seen)))
|
|
102
|
+
return true;
|
|
103
|
+
if (seen.has(t.name))
|
|
104
|
+
return false;
|
|
105
|
+
seen.add(t.name);
|
|
106
|
+
const def = ir.types[t.name];
|
|
107
|
+
if (!def)
|
|
108
|
+
return false;
|
|
109
|
+
if (guarded(def.annotations))
|
|
110
|
+
return true;
|
|
111
|
+
if (def.kind === "union")
|
|
112
|
+
return def.members.some((m) => typeHasPolicy(ir, { kind: "named", name: m, nullable: false }, seen));
|
|
113
|
+
return "fields" in def && def.fields.some((f) => guarded(f.annotations) || typeHasPolicy(ir, f.type, seen));
|
|
114
|
+
}
|
|
115
|
+
function guarded(annotations) {
|
|
116
|
+
return annotations.some((a) => a.name === "allow" || a.name === "deny");
|
|
117
|
+
}
|
|
118
|
+
function returnsVersionedEntity(ir, op) {
|
|
119
|
+
if (op.returns.kind !== "named")
|
|
120
|
+
return false;
|
|
121
|
+
const def = ir.types[op.returns.name];
|
|
122
|
+
return !!def && def.kind === "entity" && def.fields.some((f) => annotation(f, "version"));
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=openapi.js.map
|
package/openapi.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OpenAPI 3.2 generated from the schema and its HTTP bindings. The document is derived from the same IR that\n * the runtime enforces, so the published contract and the validation rules cannot drift apart.\n * 3.2 is required for the QUERY operation.\n */\nimport { annotation, baseName, type Annotation, type ArgDef, type OpDef, type RayfoldSchemaIR, type TypeRef } from \"@rayfold/schema\";\nimport { bindingsOf } from \"./bindings.ts\";\nimport { jsonSchemaFor, withRange } from \"./mcp.ts\";\n\nexport function openApiFor(ir: RayfoldSchemaIR, opts: { title?: string; version?: string; prefix?: string } = {}): Record<string, unknown> {\n const defs: Record<string, unknown> = {};\n const schema = (t: TypeRef, input: boolean) => jsonSchemaFor(ir, t, defs, input);\n const paths: Record<string, Record<string, unknown>> = {};\n\n for (const b of bindingsOf(ir)) {\n const op = b.op;\n const p = (opts.prefix ?? \"\") + b.path;\n const parameters: unknown[] = b.params.map((name) => param(ir, op, name, \"path\", true, defs));\n if (b.method === \"GET\") {\n for (const a of op.args) if (!b.params.includes(a.name)) parameters.push(param(ir, op, a.name, \"query\", !a.type.nullable && a.default === undefined, defs));\n parameters.push({ name: \"shape\", in: \"query\", required: false, description: \"Rayfold shape text or sha256: shape id; default view when absent\", schema: { type: \"string\" } });\n }\n const versioned = returnsVersionedEntity(ir, op);\n if (op.kind === \"command\" && b.method === \"POST\") {\n const optOut = annotation(op, \"idempotent\")?.args[\"value\"] === false;\n parameters.push({ name: \"Idempotency-Key\", in: \"header\", required: !optOut, description: \"Replays the original response on retry\", schema: { type: \"string\", minLength: 16, maxLength: 128 } });\n }\n // The binding honours If-Match on every method, so every versioned command offers it (and lists 412).\n if (op.kind === \"command\" && versioned) {\n parameters.push({ name: \"If-Match\", in: \"header\", required: false, description: \"Entity version from a previous response; 412 with the current entity when stale\", schema: { type: \"string\" } });\n }\n const operation: Record<string, unknown> = { operationId: op.name, parameters };\n if (op.description) operation[\"summary\"] = op.description;\n if (b.body) {\n const bodySchema = b.body === \"*\" ? argsObject(ir, op.args.filter((a) => !b.params.includes(a.name)), defs) : schema(op.args.find((a) => a.name === b.body)!.type, true);\n const types = b.method === \"PATCH\" ? [\"application/merge-patch+json\", \"application/json\"] : [\"application/json\"];\n const bodyArgs = b.body === \"*\" ? op.args.filter((a) => !b.params.includes(a.name)) : op.args.filter((a) => a.name === b.body);\n const required = bodyArgs.some((a) => !a.type.nullable && a.default === undefined);\n operation[\"requestBody\"] = { required, content: Object.fromEntries(types.map((t) => [t, { schema: bodySchema }])) };\n }\n const ok = { description: \"Result in the requested shape (default view when no shape is given)\", content: { \"application/json\": { schema: schema(op.returns, false) } } };\n const responses: Record<string, unknown> = {};\n responses[b.method === \"POST\" && b.location ? \"201\" : \"200\"] = ok;\n if (op.kind === \"query\") responses[\"304\"] = { description: \"Not modified (ETag revalidation)\" };\n responses[\"400\"] = problemRef(\"Invalid argument, including schema constraints such as @range\");\n if (hasPolicy(op) || typeHasPolicy(ir, op.returns)) {\n responses[\"401\"] = problemRef(\"Sign-in required by a policy\");\n responses[\"403\"] = problemRef(\"Denied by a policy\");\n }\n if (op.kind === \"command\" && versioned) responses[\"412\"] = problemRef(\"VersionConflict: data.current carries the entity as stored\");\n if (op.throws.length) {\n responses[\"422\"] = { description: `Declared domain errors: ${op.throws.join(\", \")}`, content: { \"application/problem+json\": { schema: { oneOf: op.throws.map((t) => domainProblem(t, schema({ kind: \"named\", name: t, nullable: false }, false))) } } } };\n }\n operation[\"responses\"] = responses;\n (paths[p] ??= {})[b.method.toLowerCase()] = operation;\n }\n\n const components = JSON.parse(JSON.stringify({ schemas: { ...defs, Problem: PROBLEM } }).replace(/\"#\\/\\$defs\\//g, '\"#/components/schemas/'));\n const doc = { openapi: \"3.2.0\", info: { title: opts.title ?? \"Rayfold API\", version: opts.version ?? \"0.1\" }, paths, components };\n return JSON.parse(JSON.stringify(doc).replace(/\"#\\/\\$defs\\//g, '\"#/components/schemas/'));\n}\n\nconst PROBLEM = {\n type: \"object\",\n description: \"RFC 9457 problem details; Rayfold errors keep code, type and data\",\n properties: { type: { type: \"string\" }, title: { type: \"string\" }, status: { type: \"integer\" }, detail: { type: \"string\" }, code: { type: \"string\" }, path: { type: \"string\" }, data: {} },\n required: [\"type\", \"title\", \"status\", \"code\"],\n};\n\nfunction problemRef(description: string): unknown {\n return { description, content: { \"application/problem+json\": { schema: { $ref: \"#/components/schemas/Problem\" } } } };\n}\n\nfunction domainProblem(type: string, dataSchema: unknown): unknown {\n return { allOf: [{ $ref: \"#/components/schemas/Problem\" }, { properties: { title: { const: type }, data: dataSchema } }] };\n}\n\nfunction param(ir: RayfoldSchemaIR, op: OpDef, name: string, where: \"path\" | \"query\", required: boolean, defs: Record<string, unknown>): unknown {\n const a = op.args.find((x) => x.name === name);\n const s = a ? jsonSchemaFor(ir, a.type, defs, true) : { type: \"string\" };\n const out: Record<string, unknown> = { name, in: where, required: where === \"path\" ? true : required, schema: a ? withRange(s, a.annotations, baseName(a.type)) : s };\n if (a?.description) out[\"description\"] = a.description;\n return out;\n}\n\nfunction argsObject(ir: RayfoldSchemaIR, args: ArgDef[], defs: Record<string, unknown>): unknown {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const a of args) {\n properties[a.name] = withRange(jsonSchemaFor(ir, a.type, defs, true), a.annotations, baseName(a.type));\n if (!a.type.nullable && a.default === undefined) required.push(a.name);\n }\n return required.length ? { type: \"object\", properties, required } : { type: \"object\", properties };\n}\n\nfunction hasPolicy(op: OpDef): boolean {\n return op.annotations.some((a) => a.name === \"allow\" || a.name === \"deny\");\n}\n\n/** A policy on any type the result can reach (list elements, Page<T>, nested fields), or on one of their fields, can refuse a caller. */\nfunction typeHasPolicy(ir: RayfoldSchemaIR, t: TypeRef, seen = new Set<string>()): boolean {\n if (t.kind === \"list\") return typeHasPolicy(ir, t.of, seen);\n if (t.args?.some((a) => typeHasPolicy(ir, a, seen))) return true;\n if (seen.has(t.name)) return false;\n seen.add(t.name);\n const def = ir.types[t.name];\n if (!def) return false;\n if (guarded(def.annotations)) return true;\n if (def.kind === \"union\") return def.members.some((m) => typeHasPolicy(ir, { kind: \"named\", name: m, nullable: false }, seen));\n return \"fields\" in def && def.fields.some((f) => guarded(f.annotations) || typeHasPolicy(ir, f.type, seen));\n}\n\nfunction guarded(annotations: Annotation[]): boolean {\n return annotations.some((a) => a.name === \"allow\" || a.name === \"deny\");\n}\n\nfunction returnsVersionedEntity(ir: RayfoldSchemaIR, op: OpDef): boolean {\n if (op.returns.kind !== \"named\") return false;\n const def = ir.types[op.returns.name];\n return !!def && def.kind === \"entity\" && def.fields.some((f) => annotation(f, \"version\"));\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rayfold/server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Rayfold server for Node.js: batches with pipelining, schema policies, HTTP caching, live queries, WebSocket, MCP and REST bindings.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"rayfold",
|
|
7
|
+
"api",
|
|
8
|
+
"protocol",
|
|
9
|
+
"server",
|
|
10
|
+
"http",
|
|
11
|
+
"rest",
|
|
12
|
+
"mcp",
|
|
13
|
+
"live-queries",
|
|
14
|
+
"graphql-alternative"
|
|
15
|
+
],
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
|
+
"homepage": "https://eddyboutros.github.io/rayfold/",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/eddyboutros/rayfold/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/eddyboutros/rayfold.git",
|
|
24
|
+
"directory": "packages/server"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22"
|
|
29
|
+
},
|
|
30
|
+
"main": "./index.js",
|
|
31
|
+
"types": "./index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./index.d.ts",
|
|
35
|
+
"default": "./index.js"
|
|
36
|
+
},
|
|
37
|
+
"./core": {
|
|
38
|
+
"types": "./core.d.ts",
|
|
39
|
+
"default": "./core.js"
|
|
40
|
+
},
|
|
41
|
+
"./protocol": {
|
|
42
|
+
"types": "./protocol.d.ts",
|
|
43
|
+
"default": "./protocol.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@rayfold/schema": "^0.1.0",
|
|
48
|
+
"@rayfold/rb": "^0.1.0"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
}
|
|
53
|
+
}
|
package/policy.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Policy evaluation. Spec: spec/06-auth.md. */
|
|
2
|
+
import { type Annotation, type Expr, type ExprEnv } from "@rayfold/schema";
|
|
3
|
+
import { RayfoldError } from "./protocol.js";
|
|
4
|
+
export type PolicyMode = "read" | "write";
|
|
5
|
+
interface Policies {
|
|
6
|
+
allow?: Expr;
|
|
7
|
+
deny?: Expr;
|
|
8
|
+
}
|
|
9
|
+
export declare function policiesOf(annotations: Annotation[], mode: PolicyMode): Policies;
|
|
10
|
+
export declare function hasPolicy(annotations: Annotation[], mode: PolicyMode): boolean;
|
|
11
|
+
export type Decision = "allow" | "deny" | "unauthenticated";
|
|
12
|
+
/** Absent allow = allowed; deny evaluated after allow. Viewer-dependent denial with no viewer = unauthenticated. */
|
|
13
|
+
export declare function decide(annotations: Annotation[], mode: PolicyMode, env: ExprEnv): Decision;
|
|
14
|
+
export declare function decisionError(d: Exclude<Decision, "allow">, what: string): RayfoldError;
|
|
15
|
+
/** The read policy of a type if it can be pushed down to a loader as a filter (spec 06 §4). */
|
|
16
|
+
export declare function pushableFilter(annotations: Annotation[]): Expr | undefined;
|
|
17
|
+
export {};
|
package/policy.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Policy evaluation. Spec: spec/06-auth.md. */
|
|
2
|
+
import { evalExpr, isPushable, referencesViewer } from "@rayfold/schema";
|
|
3
|
+
import { RayfoldError } from "./protocol.js";
|
|
4
|
+
const cache = new WeakMap();
|
|
5
|
+
export function policiesOf(annotations, mode) {
|
|
6
|
+
let entry = cache.get(annotations);
|
|
7
|
+
if (!entry) {
|
|
8
|
+
entry = { read: extract(annotations, "read"), write: extract(annotations, "write") };
|
|
9
|
+
cache.set(annotations, entry);
|
|
10
|
+
}
|
|
11
|
+
return entry[mode];
|
|
12
|
+
}
|
|
13
|
+
function extract(annotations, mode) {
|
|
14
|
+
const out = {};
|
|
15
|
+
for (const a of annotations) {
|
|
16
|
+
if (a.name !== "allow" && a.name !== "deny")
|
|
17
|
+
continue;
|
|
18
|
+
const v = a.args[mode];
|
|
19
|
+
if (v && typeof v === "object" && "$expr" in v)
|
|
20
|
+
out[a.name] = v.$expr;
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
export function hasPolicy(annotations, mode) {
|
|
25
|
+
const p = policiesOf(annotations, mode);
|
|
26
|
+
return p.allow !== undefined || p.deny !== undefined;
|
|
27
|
+
}
|
|
28
|
+
/** Absent allow = allowed; deny evaluated after allow. Viewer-dependent denial with no viewer = unauthenticated. */
|
|
29
|
+
export function decide(annotations, mode, env) {
|
|
30
|
+
const p = policiesOf(annotations, mode);
|
|
31
|
+
if (p.allow === undefined && p.deny === undefined)
|
|
32
|
+
return "allow";
|
|
33
|
+
const denied = (e) => (env.viewer === null || env.viewer === undefined) && referencesViewer(e) ? "unauthenticated" : "deny";
|
|
34
|
+
// An expression that cannot be evaluated (say, ordering a string against a boolean) fails closed: it never allows
|
|
35
|
+
// and always denies.
|
|
36
|
+
const holds = (e) => {
|
|
37
|
+
try {
|
|
38
|
+
return evalExpr(e, env) === true;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return "error";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
if (p.allow !== undefined && holds(p.allow) !== true)
|
|
45
|
+
return denied(p.allow);
|
|
46
|
+
if (p.deny !== undefined && holds(p.deny) !== false)
|
|
47
|
+
return denied(p.deny);
|
|
48
|
+
return "allow";
|
|
49
|
+
}
|
|
50
|
+
export function decisionError(d, what) {
|
|
51
|
+
return d === "unauthenticated"
|
|
52
|
+
? new RayfoldError("unauthenticated", `Sign in to access ${what}`)
|
|
53
|
+
: new RayfoldError("permission_denied", `Not allowed to access ${what}`);
|
|
54
|
+
}
|
|
55
|
+
/** The read policy of a type if it can be pushed down to a loader as a filter (spec 06 §4). */
|
|
56
|
+
export function pushableFilter(annotations) {
|
|
57
|
+
const p = policiesOf(annotations, "read");
|
|
58
|
+
if (p.deny !== undefined)
|
|
59
|
+
return undefined; // deny needs post-filter semantics
|
|
60
|
+
if (p.allow !== undefined && isPushable(p.allow))
|
|
61
|
+
return p.allow;
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=policy.js.map
|
package/policy.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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","sourcesContent":["/** Policy evaluation. Spec: spec/06-auth.md. */\nimport { evalExpr, isPushable, referencesViewer, type Annotation, type Expr, type ExprEnv } from \"@rayfold/schema\";\nimport { RayfoldError } from \"./protocol.ts\";\n\nexport type PolicyMode = \"read\" | \"write\";\n\ninterface Policies {\n allow?: Expr;\n deny?: Expr;\n}\n\nconst cache = new WeakMap<Annotation[], Record<PolicyMode, Policies>>();\n\nexport function policiesOf(annotations: Annotation[], mode: PolicyMode): Policies {\n let entry = cache.get(annotations);\n if (!entry) {\n entry = { read: extract(annotations, \"read\"), write: extract(annotations, \"write\") };\n cache.set(annotations, entry);\n }\n return entry[mode];\n}\n\nfunction extract(annotations: Annotation[], mode: PolicyMode): Policies {\n const out: Policies = {};\n for (const a of annotations) {\n if (a.name !== \"allow\" && a.name !== \"deny\") continue;\n const v = a.args[mode];\n if (v && typeof v === \"object\" && \"$expr\" in v) out[a.name] = (v as { $expr: Expr }).$expr;\n }\n return out;\n}\n\nexport function hasPolicy(annotations: Annotation[], mode: PolicyMode): boolean {\n const p = policiesOf(annotations, mode);\n return p.allow !== undefined || p.deny !== undefined;\n}\n\nexport type Decision = \"allow\" | \"deny\" | \"unauthenticated\";\n\n/** Absent allow = allowed; deny evaluated after allow. Viewer-dependent denial with no viewer = unauthenticated. */\nexport function decide(annotations: Annotation[], mode: PolicyMode, env: ExprEnv): Decision {\n const p = policiesOf(annotations, mode);\n if (p.allow === undefined && p.deny === undefined) return \"allow\";\n const denied = (e: Expr) => (env.viewer === null || env.viewer === undefined) && referencesViewer(e) ? \"unauthenticated\" : \"deny\";\n // An expression that cannot be evaluated (say, ordering a string against a boolean) fails closed: it never allows\n // and always denies.\n const holds = (e: Expr): boolean | \"error\" => {\n try {\n return evalExpr(e, env) === true;\n } catch {\n return \"error\";\n }\n };\n if (p.allow !== undefined && holds(p.allow) !== true) return denied(p.allow);\n if (p.deny !== undefined && holds(p.deny) !== false) return denied(p.deny);\n return \"allow\";\n}\n\nexport function decisionError(d: Exclude<Decision, \"allow\">, what: string): RayfoldError {\n return d === \"unauthenticated\"\n ? new RayfoldError(\"unauthenticated\", `Sign in to access ${what}`)\n : new RayfoldError(\"permission_denied\", `Not allowed to access ${what}`);\n}\n\n/** The read policy of a type if it can be pushed down to a loader as a filter (spec 06 §4). */\nexport function pushableFilter(annotations: Annotation[]): Expr | undefined {\n const p = policiesOf(annotations, \"read\");\n if (p.deny !== undefined) return undefined; // deny needs post-filter semantics\n if (p.allow !== undefined && isPushable(p.allow)) return p.allow;\n return undefined;\n}\n"]}
|
package/protocol.d.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** Wire-level request/frame types. Spec: spec/03, spec/04, spec/05. */
|
|
2
|
+
import type { JsonValue } from "@rayfold/schema";
|
|
3
|
+
export interface RequestOp {
|
|
4
|
+
id: number;
|
|
5
|
+
op: string;
|
|
6
|
+
args?: Record<string, unknown>;
|
|
7
|
+
shape?: string;
|
|
8
|
+
vars?: Record<string, JsonValue>;
|
|
9
|
+
key?: string;
|
|
10
|
+
live?: boolean;
|
|
11
|
+
deadline?: number;
|
|
12
|
+
simulate?: boolean;
|
|
13
|
+
/** Omit `$type` where the schema makes it redundant and omit `meta` unless it carries `replay`. Requires a schema-aware client. */
|
|
14
|
+
compact?: boolean;
|
|
15
|
+
/** Conditional write: the version the client last saw of the entity this command targets (spec 03 section 4a). */
|
|
16
|
+
ifVersion?: string | number;
|
|
17
|
+
}
|
|
18
|
+
export interface RequestMeta {
|
|
19
|
+
client?: string;
|
|
20
|
+
deadline?: number;
|
|
21
|
+
/** W3C trace context (spec 04 section 4); the HTTP transport copies it from the headers of the same names. */
|
|
22
|
+
traceparent?: string;
|
|
23
|
+
tracestate?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface RequestEnvelope {
|
|
26
|
+
rayfold?: string;
|
|
27
|
+
ops: RequestOp[];
|
|
28
|
+
meta?: RequestMeta;
|
|
29
|
+
}
|
|
30
|
+
export declare const PROTOCOL_CODES: readonly ["canceled", "unknown", "invalid_argument", "deadline_exceeded", "not_found", "already_exists", "permission_denied", "resource_exhausted", "failed_precondition", "aborted", "out_of_range", "unimplemented", "internal", "unavailable", "data_loss", "unauthenticated"];
|
|
31
|
+
export type ProtocolCode = (typeof PROTOCOL_CODES)[number];
|
|
32
|
+
export type ErrorCode = ProtocolCode | "domain";
|
|
33
|
+
export interface WireError {
|
|
34
|
+
code: ErrorCode;
|
|
35
|
+
type?: string;
|
|
36
|
+
message: string;
|
|
37
|
+
data?: unknown;
|
|
38
|
+
path?: string;
|
|
39
|
+
retryable?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export type PatchOp = {
|
|
42
|
+
set: string;
|
|
43
|
+
value: Record<string, unknown>;
|
|
44
|
+
} | {
|
|
45
|
+
del: string;
|
|
46
|
+
} | {
|
|
47
|
+
inv: string[];
|
|
48
|
+
} | {
|
|
49
|
+
invOp: string[];
|
|
50
|
+
}
|
|
51
|
+
/** Result-scoped (spec 04 section 2b): merge these fields into the plain object at this result path. */
|
|
52
|
+
| {
|
|
53
|
+
at: string;
|
|
54
|
+
value: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
/** Result-scoped: remove these old positions, then insert these elements at these new positions. */
|
|
57
|
+
| {
|
|
58
|
+
list: string;
|
|
59
|
+
del?: number[];
|
|
60
|
+
ins?: Array<{
|
|
61
|
+
at: number;
|
|
62
|
+
value: unknown;
|
|
63
|
+
}>;
|
|
64
|
+
};
|
|
65
|
+
export interface FrameMeta {
|
|
66
|
+
cost?: number;
|
|
67
|
+
cache?: "hit" | "miss" | "stale";
|
|
68
|
+
ms?: number;
|
|
69
|
+
replay?: boolean;
|
|
70
|
+
cursor?: string;
|
|
71
|
+
[k: string]: unknown;
|
|
72
|
+
}
|
|
73
|
+
export type Frame = {
|
|
74
|
+
id: number;
|
|
75
|
+
data: unknown;
|
|
76
|
+
meta?: FrameMeta;
|
|
77
|
+
errors?: WireError[];
|
|
78
|
+
fin?: boolean;
|
|
79
|
+
} | {
|
|
80
|
+
id: number;
|
|
81
|
+
ok: unknown;
|
|
82
|
+
patch?: PatchOp[];
|
|
83
|
+
meta?: FrameMeta;
|
|
84
|
+
errors?: WireError[];
|
|
85
|
+
fin: true;
|
|
86
|
+
} | {
|
|
87
|
+
id: number;
|
|
88
|
+
item: unknown;
|
|
89
|
+
meta?: FrameMeta;
|
|
90
|
+
} | {
|
|
91
|
+
id: number;
|
|
92
|
+
patch: PatchOp[];
|
|
93
|
+
meta?: FrameMeta;
|
|
94
|
+
} | {
|
|
95
|
+
id: number;
|
|
96
|
+
at: string;
|
|
97
|
+
data: unknown;
|
|
98
|
+
errors?: WireError[];
|
|
99
|
+
} | {
|
|
100
|
+
id: number;
|
|
101
|
+
error: WireError;
|
|
102
|
+
fin: true;
|
|
103
|
+
} | {
|
|
104
|
+
id: number;
|
|
105
|
+
fin: true;
|
|
106
|
+
} | {
|
|
107
|
+
error: WireError;
|
|
108
|
+
fin: true;
|
|
109
|
+
};
|
|
110
|
+
export declare const HTTP_STATUS: Record<ErrorCode, number>;
|
|
111
|
+
/** Thrown by resolvers / runtime; converted to a WireError at the frame boundary. */
|
|
112
|
+
export declare class RayfoldError extends Error {
|
|
113
|
+
readonly code: ErrorCode;
|
|
114
|
+
readonly type: string | undefined;
|
|
115
|
+
readonly data: unknown;
|
|
116
|
+
readonly path: string | undefined;
|
|
117
|
+
readonly retryable: boolean;
|
|
118
|
+
constructor(code: ErrorCode, message: string, opts?: {
|
|
119
|
+
type?: string | undefined;
|
|
120
|
+
data?: unknown;
|
|
121
|
+
path?: string | undefined;
|
|
122
|
+
retryable?: boolean | undefined;
|
|
123
|
+
});
|
|
124
|
+
toWire(): WireError;
|
|
125
|
+
withPath(path: string): RayfoldError;
|
|
126
|
+
static domain(type: string, data: unknown, message?: string): RayfoldError;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Raised through `ctx.checkVersion` when a conditional command's `ifVersion` does not match.
|
|
130
|
+
* The executor projects `current` through the op's shape so the client can repair its cache without a GET.
|
|
131
|
+
*/
|
|
132
|
+
export declare class VersionConflict extends RayfoldError {
|
|
133
|
+
readonly key: string;
|
|
134
|
+
readonly expected: string | number;
|
|
135
|
+
readonly actual: unknown;
|
|
136
|
+
readonly current: unknown;
|
|
137
|
+
constructor(key: string, expected: string | number, actual: unknown, current: unknown);
|
|
138
|
+
}
|
|
139
|
+
export declare function toWireError(e: unknown): WireError;
|