feat(types,auth): zod contracts + magic-link session auth
This commit is contained in:
135
packages/types/src/index.ts
Normal file
135
packages/types/src/index.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const ServerStatus = z.enum([
|
||||
'draft',
|
||||
'queued',
|
||||
'generating',
|
||||
'building',
|
||||
'deploying',
|
||||
'live',
|
||||
'failed',
|
||||
'paused',
|
||||
]);
|
||||
export type ServerStatus = z.infer<typeof ServerStatus>;
|
||||
|
||||
export const BuildStatus = z.enum([
|
||||
'queued',
|
||||
'generating',
|
||||
'building',
|
||||
'deploying',
|
||||
'success',
|
||||
'failed',
|
||||
'cancelled',
|
||||
]);
|
||||
export type BuildStatus = z.infer<typeof BuildStatus>;
|
||||
|
||||
export const Plan = z.enum(['hobby', 'pro', 'team', 'enterprise']);
|
||||
export type Plan = z.infer<typeof Plan>;
|
||||
|
||||
// ---- Generator output spec (what Claude returns) ----
|
||||
|
||||
export const ToolParam = z
|
||||
.object({
|
||||
type: z.enum(['string', 'number', 'boolean', 'array', 'object']),
|
||||
description: z.string().optional(),
|
||||
required: z.boolean().optional(),
|
||||
enum: z.array(z.string()).optional(),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
export const ToolSpec = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(64)
|
||||
.regex(/^[a-z][a-z0-9_]*$/, 'snake_case identifier required'),
|
||||
description: z.string().min(1).max(2000),
|
||||
inputSchema: z.record(z.string(), ToolParam),
|
||||
implementation: z.string().min(1).max(20_000),
|
||||
});
|
||||
export type ToolSpec = z.infer<typeof ToolSpec>;
|
||||
|
||||
export const ResourceSpec = z.object({
|
||||
uri: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
implementation: z.string().min(1),
|
||||
});
|
||||
export type ResourceSpec = z.infer<typeof ResourceSpec>;
|
||||
|
||||
export const PromptSpec = z.object({
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
arguments: z
|
||||
.array(z.object({ name: z.string(), description: z.string().optional(), required: z.boolean().optional() }))
|
||||
.optional(),
|
||||
template: z.string().min(1),
|
||||
});
|
||||
export type PromptSpec = z.infer<typeof PromptSpec>;
|
||||
|
||||
export const GeneratorSpec = z.object({
|
||||
name: z.string().min(1).max(128),
|
||||
description: z.string().max(2000).optional(),
|
||||
tools: z.array(ToolSpec).min(1).max(50),
|
||||
resources: z.array(ResourceSpec).max(50).default([]),
|
||||
prompts: z.array(PromptSpec).max(50).default([]),
|
||||
requiredSecrets: z.array(z.string().regex(/^[A-Z][A-Z0-9_]*$/)).max(30).default([]),
|
||||
scopes: z.array(z.string()).max(50).default([]),
|
||||
dependencies: z.record(z.string(), z.string()).default({}),
|
||||
});
|
||||
export type GeneratorSpec = z.infer<typeof GeneratorSpec>;
|
||||
|
||||
// ---- Build stream events ----
|
||||
|
||||
export const BuildEvent = z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('status'),
|
||||
status: BuildStatus,
|
||||
at: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('log'),
|
||||
level: z.enum(['info', 'warn', 'error']),
|
||||
message: z.string(),
|
||||
at: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('done'),
|
||||
status: BuildStatus,
|
||||
serverId: z.string().uuid(),
|
||||
publicUrl: z.string().nullable(),
|
||||
at: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('error'),
|
||||
message: z.string(),
|
||||
at: z.string(),
|
||||
}),
|
||||
]);
|
||||
export type BuildEvent = z.infer<typeof BuildEvent>;
|
||||
|
||||
// ---- API request payloads ----
|
||||
|
||||
export const CreateServerInput = z.object({
|
||||
name: z.string().min(1).max(128),
|
||||
slug: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(64)
|
||||
.regex(/^[a-z][a-z0-9-]*$/, 'lowercase, hyphenated'),
|
||||
prompt: z.string().min(10).max(8000),
|
||||
secrets: z.record(z.string(), z.string()).default({}),
|
||||
});
|
||||
export type CreateServerInput = z.infer<typeof CreateServerInput>;
|
||||
|
||||
export const IterateServerInput = z.object({
|
||||
prompt: z.string().min(10).max(8000),
|
||||
secrets: z.record(z.string(), z.string()).default({}),
|
||||
});
|
||||
export type IterateServerInput = z.infer<typeof IterateServerInput>;
|
||||
|
||||
// ---- Install snippets ----
|
||||
|
||||
export const InstallTarget = z.enum(['claude-desktop', 'cursor', 'chatgpt']);
|
||||
export type InstallTarget = z.infer<typeof InstallTarget>;
|
||||
Reference in New Issue
Block a user