runwork 0.2.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 +21 -0
- package/README.md +134 -0
- package/bin/runwork.js +2 -0
- package/bundled-types/agents.d.ts +3 -0
- package/bundled-types/ai.d.ts +2 -0
- package/bundled-types/app-registry.d.ts +74 -0
- package/bundled-types/channels.d.ts +2 -0
- package/bundled-types/components.d.ts +1 -0
- package/bundled-types/core-agent.d.ts +265 -0
- package/bundled-types/core-ai.d.ts +170 -0
- package/bundled-types/core-base-agent.d.ts +89 -0
- package/bundled-types/core-channels.d.ts +42 -0
- package/bundled-types/core-components.d.ts +21 -0
- package/bundled-types/core-endpoints.d.ts +198 -0
- package/bundled-types/core-entities.d.ts +276 -0
- package/bundled-types/core-entity-do.d.ts +119 -0
- package/bundled-types/core-events.d.ts +52 -0
- package/bundled-types/core-file-storage.d.ts +216 -0
- package/bundled-types/core-integration-entities.d.ts +147 -0
- package/bundled-types/core-integrations.d.ts +143 -0
- package/bundled-types/core-routes.d.ts +33 -0
- package/bundled-types/core-scheduler.d.ts +180 -0
- package/bundled-types/core-utils.d.ts +85 -0
- package/bundled-types/core-workflow-cloudflare.d.ts +85 -0
- package/bundled-types/core-workflow-config.d.ts +18 -0
- package/bundled-types/core-workflow-coordinator.d.ts +78 -0
- package/bundled-types/core-workflow-instance.d.ts +82 -0
- package/bundled-types/core-workflow-types.d.ts +251 -0
- package/bundled-types/core-workflows.d.ts +75 -0
- package/bundled-types/core-workspace.d.ts +454 -0
- package/bundled-types/create-app.d.ts +57 -0
- package/bundled-types/endpoints.d.ts +2 -0
- package/bundled-types/entities.d.ts +5 -0
- package/bundled-types/events.d.ts +2 -0
- package/bundled-types/index.d.ts +19 -0
- package/bundled-types/integrations.d.ts +2 -0
- package/bundled-types/routes.d.ts +2 -0
- package/bundled-types/scheduler.d.ts +2 -0
- package/bundled-types/storage.d.ts +2 -0
- package/bundled-types/test-entry.d.ts +21 -0
- package/bundled-types/types.d.ts +1 -0
- package/bundled-types/vite.d.ts +23 -0
- package/bundled-types/workflows.d.ts +14 -0
- package/bundled-types/workspace.d.ts +2 -0
- package/dist/__tests__/types-manager.test.d.ts +1 -0
- package/dist/__tests__/types-manager.test.js +85 -0
- package/dist/api/__tests__/client.test.d.ts +1 -0
- package/dist/api/__tests__/client.test.js +264 -0
- package/dist/api/client.d.ts +72 -0
- package/dist/api/client.js +144 -0
- package/dist/auth/__tests__/store.test.d.ts +1 -0
- package/dist/auth/__tests__/store.test.js +103 -0
- package/dist/auth/browser.d.ts +2 -0
- package/dist/auth/browser.js +7 -0
- package/dist/auth/store.d.ts +5 -0
- package/dist/auth/store.js +33 -0
- package/dist/commands/clone.d.ts +2 -0
- package/dist/commands/clone.js +90 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.js +43 -0
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.js +188 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +87 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +32 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +13 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +166 -0
- package/dist/generated/bundled-types.d.ts +1 -0
- package/dist/generated/bundled-types.js +44 -0
- package/dist/generated/version.d.ts +1 -0
- package/dist/generated/version.js +2 -0
- package/dist/git/__tests__/credentials.test.d.ts +1 -0
- package/dist/git/__tests__/credentials.test.js +128 -0
- package/dist/git/auto-commit.d.ts +3 -0
- package/dist/git/auto-commit.js +209 -0
- package/dist/git/credentials.d.ts +15 -0
- package/dist/git/credentials.js +65 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +31 -0
- package/dist/logs/tailer.d.ts +13 -0
- package/dist/logs/tailer.js +135 -0
- package/dist/template/manifest.d.ts +17 -0
- package/dist/template/manifest.js +102 -0
- package/dist/types-manager.d.ts +1 -0
- package/dist/types-manager.js +35 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.js +1 -0
- package/dist/utils/__tests__/prompt.test.d.ts +1 -0
- package/dist/utils/__tests__/prompt.test.js +103 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.js +23 -0
- package/dist/utils/prompt.d.ts +4 -0
- package/dist/utils/prompt.js +34 -0
- package/dist/utils/zip.d.ts +1 -0
- package/dist/utils/zip.js +17 -0
- package/package.json +66 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Agent - Durable Object for AI Agents
|
|
3
|
+
* DO NOT MODIFY THIS FILE - You may break the agent functionality
|
|
4
|
+
*
|
|
5
|
+
* This is the Durable Object class for AI agents built on Cloudflare's Agents SDK.
|
|
6
|
+
* It extends AIChatAgent which provides:
|
|
7
|
+
* - WebSocket connection handling
|
|
8
|
+
* - Message persistence (SQLite)
|
|
9
|
+
* - Streaming response resumption
|
|
10
|
+
* - State management
|
|
11
|
+
*
|
|
12
|
+
* LLM calls go through runwork's AI proxy, which:
|
|
13
|
+
* - Handles API keys securely (no keys in vibe-app)
|
|
14
|
+
* - Provides analytics, caching, and rate limiting via AI Gateway
|
|
15
|
+
* - Supports multiple providers (OpenAI, Anthropic, etc.)
|
|
16
|
+
*
|
|
17
|
+
* Agent definitions are loaded from the APP_AGENTS registry based on
|
|
18
|
+
* the agent name stored in the DO's storage.
|
|
19
|
+
*/
|
|
20
|
+
import { AIChatAgent } from 'agents/ai-chat-agent';
|
|
21
|
+
import { type StreamTextOnFinishCallback, type ToolSet } from 'ai';
|
|
22
|
+
import { type Env } from './core-utils';
|
|
23
|
+
import { type AgentDefinition, type AgentRuntimeStatus } from './core-agent';
|
|
24
|
+
/**
|
|
25
|
+
* BaseAgent - The Durable Object for all agents
|
|
26
|
+
*
|
|
27
|
+
* This class extends AIChatAgent directly, which means:
|
|
28
|
+
* - The class itself IS the Durable Object (not wrapped in another DO)
|
|
29
|
+
* - AIChatAgent handles WebSocket connections, message persistence, and streaming
|
|
30
|
+
* - We implement onChatMessage() to process incoming messages using the AI SDK
|
|
31
|
+
*
|
|
32
|
+
* Agent instances are identified by DO ID format: "{agentName}:{sessionId}"
|
|
33
|
+
*/
|
|
34
|
+
export declare class BaseAgent extends AIChatAgent<Env> {
|
|
35
|
+
private definition;
|
|
36
|
+
private integrationClient;
|
|
37
|
+
private agentName;
|
|
38
|
+
/**
|
|
39
|
+
* Called when the agent starts (on first request or after hibernation)
|
|
40
|
+
* Load the agent definition from storage
|
|
41
|
+
*/
|
|
42
|
+
onStart(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Set the agent name and load its definition
|
|
45
|
+
* Called when initializing a new agent instance
|
|
46
|
+
*/
|
|
47
|
+
setAgentName(name: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Handle incoming chat messages using AI SDK
|
|
50
|
+
* This is the main entry point called by AIChatAgent when a message arrives
|
|
51
|
+
*/
|
|
52
|
+
onChatMessage(onFinish: StreamTextOnFinishCallback<ToolSet>): Promise<Response>;
|
|
53
|
+
/**
|
|
54
|
+
* Build tools from agent definition using AI SDK tool() helper
|
|
55
|
+
*/
|
|
56
|
+
private buildTools;
|
|
57
|
+
/**
|
|
58
|
+
* Build tools for accessing integrations using AI SDK tool() helper
|
|
59
|
+
* Uses shared definitions from core-agent.ts, wraps with executors
|
|
60
|
+
* @param integrations - List of integration IDs to build tools for
|
|
61
|
+
*/
|
|
62
|
+
private buildIntegrationTools;
|
|
63
|
+
/**
|
|
64
|
+
* Build tools for accessing entities using AI SDK tool() helper
|
|
65
|
+
* Uses entity classes directly with EntityContext
|
|
66
|
+
*/
|
|
67
|
+
private buildEntityTools;
|
|
68
|
+
/**
|
|
69
|
+
* Get integration client (lazy-loaded)
|
|
70
|
+
*/
|
|
71
|
+
private getIntegrationClient;
|
|
72
|
+
/**
|
|
73
|
+
* Get tool execution context
|
|
74
|
+
*/
|
|
75
|
+
private getToolContext;
|
|
76
|
+
/**
|
|
77
|
+
* Get the agent's name
|
|
78
|
+
*/
|
|
79
|
+
getAgentName(): string | null;
|
|
80
|
+
/**
|
|
81
|
+
* Get the agent's definition
|
|
82
|
+
*/
|
|
83
|
+
getDefinition(): AgentDefinition | null;
|
|
84
|
+
/**
|
|
85
|
+
* Get runtime status - actual availability of tools and integrations
|
|
86
|
+
* This checks real connectivity, not just declared capabilities
|
|
87
|
+
*/
|
|
88
|
+
getStatus(): Promise<AgentRuntimeStatus>;
|
|
89
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Channels
|
|
3
|
+
* DO NOT MODIFY THIS FILE - You may break the project functionality
|
|
4
|
+
*
|
|
5
|
+
* This module provides:
|
|
6
|
+
* - postToChannel(): Post rich markdown messages to workspace channels
|
|
7
|
+
*
|
|
8
|
+
* Channels are auto-created if they don't exist, with automatic app event filtering.
|
|
9
|
+
* When running outside a workspace (standalone mode), calls are silently skipped.
|
|
10
|
+
*/
|
|
11
|
+
export interface PostToChannelParams {
|
|
12
|
+
/** Channel name (e.g., "#inventory-alerts" or "inventory-alerts"). Auto-normalized: # stripped, lowercased, trimmed. */
|
|
13
|
+
channel: string;
|
|
14
|
+
/** Markdown message content */
|
|
15
|
+
content: string;
|
|
16
|
+
/** Optional structured metadata attached to the message */
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
interface ChannelEnv {
|
|
20
|
+
WORKSPACE_API_URL?: string;
|
|
21
|
+
WORKSPACE_API_KEY?: string;
|
|
22
|
+
WORKSPACE_ID?: string;
|
|
23
|
+
APP_ID?: string;
|
|
24
|
+
APP_NAME?: string;
|
|
25
|
+
DEPLOYMENT_MODE?: 'preview' | 'production';
|
|
26
|
+
WorkspaceObject?: DurableObjectNamespace;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Any context that supports waitUntil - compatible with both
|
|
30
|
+
* ExecutionContext (Hono route handlers) and DurableObjectState (DOs).
|
|
31
|
+
*/
|
|
32
|
+
type WaitUntilContext = Pick<ExecutionContext, 'waitUntil'>;
|
|
33
|
+
/**
|
|
34
|
+
* Post a rich markdown message to a workspace channel.
|
|
35
|
+
* Fire-and-forget: uses ctx.waitUntil so it doesn't block the response.
|
|
36
|
+
* Silently skips if workspace env vars are not configured (standalone mode).
|
|
37
|
+
*
|
|
38
|
+
* Channels are auto-created on first use. The channel will automatically
|
|
39
|
+
* include this app's system events via filter projection.
|
|
40
|
+
*/
|
|
41
|
+
export declare function postToChannel(ctx: WaitUntilContext, env: ChannelEnv, params: PostToChannelParams): void;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Component Routes
|
|
3
|
+
* DO NOT MODIFY THIS FILE - You may break the project functionality
|
|
4
|
+
*
|
|
5
|
+
* This module provides:
|
|
6
|
+
* 1. Component manifest API at /api/components/manifest.json
|
|
7
|
+
* 2. Auto-mounting of backend Hono handlers from worker/components/
|
|
8
|
+
*
|
|
9
|
+
* Frontend component pages live in src/pages/components/ and are served
|
|
10
|
+
* by the SPA via React Router (no Worker routing needed).
|
|
11
|
+
*/
|
|
12
|
+
import type { Hono } from 'hono';
|
|
13
|
+
import type { Env } from './core-utils';
|
|
14
|
+
/**
|
|
15
|
+
* Mount component routes on the Hono app.
|
|
16
|
+
* - Serves manifest at /api/components/manifest.json
|
|
17
|
+
* - Auto-mounts backend handlers at /api/components/{path}/*
|
|
18
|
+
*/
|
|
19
|
+
export declare function componentRoutes(app: Hono<{
|
|
20
|
+
Bindings: Env;
|
|
21
|
+
}>): void;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Public Endpoints Framework
|
|
3
|
+
* DO NOT MODIFY THIS FILE - You may break the project functionality
|
|
4
|
+
*
|
|
5
|
+
* This module provides the infrastructure for exposing public API endpoints
|
|
6
|
+
* that external systems can consume with API key authentication or public access.
|
|
7
|
+
*/
|
|
8
|
+
import { type Env } from './core-utils';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import type { Hono } from 'hono';
|
|
11
|
+
type ZodSchema = z.ZodType<any, any, any>;
|
|
12
|
+
/**
|
|
13
|
+
* Authentication type for public endpoints
|
|
14
|
+
*/
|
|
15
|
+
export type EndpointAuthType = 'apiKey' | 'public';
|
|
16
|
+
/**
|
|
17
|
+
* HTTP methods supported by endpoints
|
|
18
|
+
*/
|
|
19
|
+
export type EndpointMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
20
|
+
/**
|
|
21
|
+
* Schema definition for endpoint validation
|
|
22
|
+
*/
|
|
23
|
+
export interface EndpointSchema<TQuery = unknown, TBody = unknown, TResponse = unknown> {
|
|
24
|
+
/** Query parameters schema */
|
|
25
|
+
query?: ZodSchema;
|
|
26
|
+
/** Request body schema (for POST/PUT/PATCH) */
|
|
27
|
+
body?: ZodSchema;
|
|
28
|
+
/** Response schema for documentation */
|
|
29
|
+
response?: ZodSchema;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Context provided to endpoint handlers
|
|
33
|
+
*/
|
|
34
|
+
export interface EndpointContext<TQuery = Record<string, unknown>, TBody = unknown> {
|
|
35
|
+
/** Environment bindings */
|
|
36
|
+
env: Env;
|
|
37
|
+
/** Original request object */
|
|
38
|
+
request: Request;
|
|
39
|
+
/** Validated query parameters */
|
|
40
|
+
query: TQuery;
|
|
41
|
+
/** Validated request body (null for GET/DELETE) */
|
|
42
|
+
body: TBody | null;
|
|
43
|
+
/** Path parameters extracted from URL */
|
|
44
|
+
params: Record<string, string>;
|
|
45
|
+
/** Authentication information */
|
|
46
|
+
auth: EndpointAuthInfo;
|
|
47
|
+
/** Request headers */
|
|
48
|
+
headers: Headers;
|
|
49
|
+
/** Logger for endpoint operations */
|
|
50
|
+
logger: EndpointLogger;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Authentication information passed to handlers
|
|
54
|
+
*/
|
|
55
|
+
export interface EndpointAuthInfo {
|
|
56
|
+
/** Authentication type used */
|
|
57
|
+
type: EndpointAuthType;
|
|
58
|
+
/** API key ID (if authenticated with API key) */
|
|
59
|
+
apiKeyId?: string;
|
|
60
|
+
/** Scopes granted to the API key */
|
|
61
|
+
scopes?: string[];
|
|
62
|
+
/** Whether request is authenticated */
|
|
63
|
+
authenticated: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Logger for endpoint operations
|
|
67
|
+
*/
|
|
68
|
+
export interface EndpointLogger {
|
|
69
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
70
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
71
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Metadata for endpoint documentation
|
|
75
|
+
*/
|
|
76
|
+
export interface EndpointMeta {
|
|
77
|
+
/** Human-readable description */
|
|
78
|
+
description?: string;
|
|
79
|
+
/** Tags for grouping in documentation */
|
|
80
|
+
tags?: string[];
|
|
81
|
+
/** Deprecated flag */
|
|
82
|
+
deprecated?: boolean;
|
|
83
|
+
/** Deprecation message */
|
|
84
|
+
deprecationMessage?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Public endpoint definition
|
|
88
|
+
*/
|
|
89
|
+
export interface EndpointDefinition<TQuery = Record<string, unknown>, TBody = unknown, TResponse = unknown> {
|
|
90
|
+
/** URL path (e.g., '/v1/todos', '/users/:id') */
|
|
91
|
+
path: string;
|
|
92
|
+
/** HTTP method */
|
|
93
|
+
method: EndpointMethod;
|
|
94
|
+
/** Authentication requirement */
|
|
95
|
+
auth: EndpointAuthType;
|
|
96
|
+
/** Validation schemas */
|
|
97
|
+
schema?: EndpointSchema<TQuery, TBody, TResponse>;
|
|
98
|
+
/** Request handler */
|
|
99
|
+
handler: EndpointHandler<TQuery, TBody, TResponse>;
|
|
100
|
+
/** Endpoint metadata for documentation */
|
|
101
|
+
meta?: EndpointMeta;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Endpoint handler function type
|
|
105
|
+
*/
|
|
106
|
+
export type EndpointHandler<TQuery = Record<string, unknown>, TBody = unknown, TResponse = unknown> = (ctx: EndpointContext<TQuery, TBody>) => Promise<TResponse>;
|
|
107
|
+
/** Type guard to distinguish EndpointDefinition from function-based route registrars */
|
|
108
|
+
export declare function isEndpointDefinition(entry: unknown): entry is EndpointDefinition;
|
|
109
|
+
/**
|
|
110
|
+
* Internal: Parsed endpoint info from request headers
|
|
111
|
+
*/
|
|
112
|
+
export interface ParsedEndpointRequest {
|
|
113
|
+
endpointId: string;
|
|
114
|
+
appId: string;
|
|
115
|
+
authType: EndpointAuthType;
|
|
116
|
+
apiKeyId?: string;
|
|
117
|
+
scopes?: string[];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create a JSON response
|
|
121
|
+
*/
|
|
122
|
+
export declare function jsonResponse<T>(data: T, status?: number): Response;
|
|
123
|
+
/**
|
|
124
|
+
* Create an error response
|
|
125
|
+
*/
|
|
126
|
+
export declare function errorResponse(message: string, status?: number, code?: string): Response;
|
|
127
|
+
/**
|
|
128
|
+
* Convert Zod schema to JSON Schema for documentation
|
|
129
|
+
* This is a simplified conversion that handles common cases
|
|
130
|
+
*/
|
|
131
|
+
export declare function zodToJsonSchema(schema: ZodSchema | undefined): Record<string, unknown> | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Endpoint router that matches requests to handlers
|
|
134
|
+
*/
|
|
135
|
+
export declare class EndpointRouter {
|
|
136
|
+
private endpoints;
|
|
137
|
+
/**
|
|
138
|
+
* Register endpoints
|
|
139
|
+
*/
|
|
140
|
+
register(endpoints: EndpointDefinition<unknown, unknown, unknown>[]): void;
|
|
141
|
+
/**
|
|
142
|
+
* Find endpoint matching the request
|
|
143
|
+
*/
|
|
144
|
+
findEndpoint(method: string, path: string): {
|
|
145
|
+
endpoint: EndpointDefinition<unknown, unknown, unknown>;
|
|
146
|
+
params: Record<string, string>;
|
|
147
|
+
} | null;
|
|
148
|
+
/**
|
|
149
|
+
* Get all registered endpoints for documentation
|
|
150
|
+
*/
|
|
151
|
+
getAllEndpoints(): EndpointDefinition<unknown, unknown, unknown>[];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Mount an EndpointDefinition as a native Hono route.
|
|
155
|
+
*
|
|
156
|
+
* Registers the endpoint at its natural path using the correct HTTP method,
|
|
157
|
+
* with Zod validation for query/body schemas and full EndpointContext support.
|
|
158
|
+
* This allows EndpointDefinition entries in APP_ROUTES to work as first-class
|
|
159
|
+
* Hono routes with middleware, streaming, and WebSocket support intact.
|
|
160
|
+
*/
|
|
161
|
+
export declare function mountEndpointAsHonoRoute(app: Hono<{
|
|
162
|
+
Bindings: Env;
|
|
163
|
+
}>, endpoint: EndpointDefinition): void;
|
|
164
|
+
/**
|
|
165
|
+
* Handle an incoming public endpoint request.
|
|
166
|
+
* Called by the platform when routing requests to the app.
|
|
167
|
+
*/
|
|
168
|
+
export declare function handleEndpointRequest<TQuery = unknown, TBody = unknown, TResponse = unknown>(request: Request, env: Env, endpoints: EndpointDefinition<TQuery, TBody, TResponse>[]): Promise<Response>;
|
|
169
|
+
/**
|
|
170
|
+
* Custom error for endpoint handlers
|
|
171
|
+
* Use this to return specific HTTP status codes
|
|
172
|
+
*/
|
|
173
|
+
export declare class EndpointError extends Error {
|
|
174
|
+
status: number;
|
|
175
|
+
code?: string | undefined;
|
|
176
|
+
constructor(message: string, status?: number, code?: string | undefined);
|
|
177
|
+
static badRequest(message: string): EndpointError;
|
|
178
|
+
static unauthorized(message?: string): EndpointError;
|
|
179
|
+
static forbidden(message?: string): EndpointError;
|
|
180
|
+
static notFound(message?: string): EndpointError;
|
|
181
|
+
static conflict(message: string): EndpointError;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Convert endpoint definition to registration data for workspace
|
|
185
|
+
*/
|
|
186
|
+
export declare function endpointToRegistration<TQuery = unknown, TBody = unknown, TResponse = unknown>(endpoint: EndpointDefinition<TQuery, TBody, TResponse>): {
|
|
187
|
+
path: string;
|
|
188
|
+
method: EndpointMethod;
|
|
189
|
+
auth: EndpointAuthType;
|
|
190
|
+
description?: string;
|
|
191
|
+
tags?: string[];
|
|
192
|
+
schema?: {
|
|
193
|
+
query?: Record<string, unknown>;
|
|
194
|
+
body?: Record<string, unknown>;
|
|
195
|
+
response?: Record<string, unknown>;
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
export {};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Entity System
|
|
3
|
+
* DO NOT MODIFY THIS FILE - You may break the entity functionality
|
|
4
|
+
*
|
|
5
|
+
* This module provides:
|
|
6
|
+
* - EntityContext: Unified context for all entity operations
|
|
7
|
+
* - EntityClass: Interface that all entity types implement
|
|
8
|
+
* - EntityBase: Base class with instance methods for state management
|
|
9
|
+
* - Entity: Local storage-backed entity class (replaces IndexedEntity)
|
|
10
|
+
*/
|
|
11
|
+
import type { IntegrationClient } from './core-integrations';
|
|
12
|
+
export interface EntityDOStub {
|
|
13
|
+
getDoc<T>(key: string): Promise<{
|
|
14
|
+
v: number;
|
|
15
|
+
data: T;
|
|
16
|
+
} | null>;
|
|
17
|
+
casPut<T>(key: string, expectedV: number, data: T): Promise<{
|
|
18
|
+
ok: boolean;
|
|
19
|
+
v: number;
|
|
20
|
+
}>;
|
|
21
|
+
del(key: string): Promise<boolean>;
|
|
22
|
+
has(key: string): Promise<boolean>;
|
|
23
|
+
bulkCreate(items: Array<{
|
|
24
|
+
key: string;
|
|
25
|
+
data: unknown;
|
|
26
|
+
}>): Promise<Array<{
|
|
27
|
+
key: string;
|
|
28
|
+
v: number;
|
|
29
|
+
data: unknown;
|
|
30
|
+
}>>;
|
|
31
|
+
bulkUpdate(updates: Array<{
|
|
32
|
+
key: string;
|
|
33
|
+
data: Record<string, unknown>;
|
|
34
|
+
}>): Promise<Array<{
|
|
35
|
+
key: string;
|
|
36
|
+
ok: boolean;
|
|
37
|
+
v: number;
|
|
38
|
+
data: unknown;
|
|
39
|
+
}>>;
|
|
40
|
+
bulkDelete(keys: string[]): Promise<number>;
|
|
41
|
+
queryEntities(options?: {
|
|
42
|
+
limit?: number;
|
|
43
|
+
offset?: number;
|
|
44
|
+
cursor?: string | null;
|
|
45
|
+
filters?: Record<string, unknown>;
|
|
46
|
+
search?: {
|
|
47
|
+
query: string;
|
|
48
|
+
fields: string[];
|
|
49
|
+
};
|
|
50
|
+
sort?: {
|
|
51
|
+
field: string;
|
|
52
|
+
order: 'asc' | 'desc';
|
|
53
|
+
};
|
|
54
|
+
}): Promise<{
|
|
55
|
+
items: Array<{
|
|
56
|
+
key: string;
|
|
57
|
+
v: number;
|
|
58
|
+
data: unknown;
|
|
59
|
+
}>;
|
|
60
|
+
total: number;
|
|
61
|
+
hasMore: boolean;
|
|
62
|
+
next: string | null;
|
|
63
|
+
}>;
|
|
64
|
+
countEntities(filters?: Record<string, unknown>): Promise<number>;
|
|
65
|
+
exportAll(): Promise<Array<{
|
|
66
|
+
key: string;
|
|
67
|
+
v: number;
|
|
68
|
+
data: unknown;
|
|
69
|
+
}>>;
|
|
70
|
+
importAll(items: Array<{
|
|
71
|
+
key: string;
|
|
72
|
+
v: number;
|
|
73
|
+
data: unknown;
|
|
74
|
+
}>): Promise<{
|
|
75
|
+
imported: number;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
78
|
+
import type { Env } from './core-utils';
|
|
79
|
+
/**
|
|
80
|
+
* EntityContext - Unified context for all entity operations
|
|
81
|
+
* Both Entity and IntegrationEntity use this same context type
|
|
82
|
+
*/
|
|
83
|
+
export interface EntityContext {
|
|
84
|
+
env: Env;
|
|
85
|
+
client?: IntegrationClient;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Options for list operations
|
|
89
|
+
*/
|
|
90
|
+
export interface ListOptions {
|
|
91
|
+
limit?: number;
|
|
92
|
+
offset?: number;
|
|
93
|
+
cursor?: string | null;
|
|
94
|
+
filters?: Record<string, unknown>;
|
|
95
|
+
search?: {
|
|
96
|
+
query: string;
|
|
97
|
+
fields: string[];
|
|
98
|
+
};
|
|
99
|
+
sort?: {
|
|
100
|
+
field: string;
|
|
101
|
+
order: 'asc' | 'desc';
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Paginated result from list operations
|
|
106
|
+
*/
|
|
107
|
+
export interface PaginatedResult<T> {
|
|
108
|
+
items: T[];
|
|
109
|
+
total: number;
|
|
110
|
+
next: string | null;
|
|
111
|
+
hasMore: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* EntityClass - Unified interface for ALL entity types
|
|
115
|
+
*
|
|
116
|
+
* Both Entity (local storage) and IntegrationEntity (external API) implement this.
|
|
117
|
+
* All static CRUD methods take ctx as the first parameter for consistency.
|
|
118
|
+
*/
|
|
119
|
+
export interface EntityClass<T extends {
|
|
120
|
+
id: string;
|
|
121
|
+
}> {
|
|
122
|
+
readonly entityName: string;
|
|
123
|
+
readonly schema?: Record<string, unknown>;
|
|
124
|
+
list(ctx: EntityContext, options?: ListOptions): Promise<PaginatedResult<T>>;
|
|
125
|
+
get(ctx: EntityContext, id: string): Promise<T | null>;
|
|
126
|
+
create(ctx: EntityContext, data: Partial<T>): Promise<T>;
|
|
127
|
+
update(ctx: EntityContext, id: string, data: Partial<T>): Promise<T>;
|
|
128
|
+
delete(ctx: EntityContext, id: string): Promise<void>;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Type-safe entity registry
|
|
132
|
+
* Maps entity names to their class implementations
|
|
133
|
+
*/
|
|
134
|
+
export declare const entityRegistry: Map<string, EntityClass<{
|
|
135
|
+
id: string;
|
|
136
|
+
}>>;
|
|
137
|
+
/**
|
|
138
|
+
* Register an entity class with the registry
|
|
139
|
+
*/
|
|
140
|
+
export declare function registerEntity<T extends {
|
|
141
|
+
id: string;
|
|
142
|
+
}>(entityClass: EntityClass<T>): void;
|
|
143
|
+
/**
|
|
144
|
+
* Register multiple entity classes at once
|
|
145
|
+
*/
|
|
146
|
+
export declare function registerEntities(classes: readonly EntityClass<{
|
|
147
|
+
id: string;
|
|
148
|
+
}>[]): void;
|
|
149
|
+
export type Doc<T> = {
|
|
150
|
+
v: number;
|
|
151
|
+
data: T;
|
|
152
|
+
};
|
|
153
|
+
export interface EntityStatics<S, T extends EntityBase<S>> {
|
|
154
|
+
new (env: Env, id: string): T;
|
|
155
|
+
readonly entityName: string;
|
|
156
|
+
readonly initialState: S;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* EntityBase - Internal base class with instance methods for state management
|
|
160
|
+
*
|
|
161
|
+
* Provides CAS-based (Compare-And-Swap) state mutations for optimistic concurrency.
|
|
162
|
+
* Extended by Entity class which adds static CRUD methods.
|
|
163
|
+
*/
|
|
164
|
+
export declare abstract class EntityBase<State> {
|
|
165
|
+
protected _state: State;
|
|
166
|
+
protected _version: number;
|
|
167
|
+
protected readonly stub: EntityDOStub;
|
|
168
|
+
protected readonly _id: string;
|
|
169
|
+
protected readonly entityName: string;
|
|
170
|
+
protected readonly env: Env;
|
|
171
|
+
constructor(env: Env, id: string);
|
|
172
|
+
get id(): string;
|
|
173
|
+
get state(): State;
|
|
174
|
+
protected key(): string;
|
|
175
|
+
save(next: State): Promise<void>;
|
|
176
|
+
protected ensureState(): Promise<State>;
|
|
177
|
+
mutate(updater: (current: State) => State): Promise<State>;
|
|
178
|
+
getState(): Promise<State>;
|
|
179
|
+
patch(p: Partial<State>): Promise<void>;
|
|
180
|
+
exists(): Promise<boolean>;
|
|
181
|
+
delete(): Promise<boolean>;
|
|
182
|
+
}
|
|
183
|
+
type EntityState<T> = T extends new (env: Env, id: string) => Entity<infer S> ? S : never;
|
|
184
|
+
type EntityCtor = new (env: Env, id: string) => Entity<{
|
|
185
|
+
id: string;
|
|
186
|
+
}>;
|
|
187
|
+
type EntityCtorStatic<TCtor> = TCtor & {
|
|
188
|
+
entityName: string;
|
|
189
|
+
keyOf(state: EntityState<TCtor>): string;
|
|
190
|
+
seedData?: ReadonlyArray<EntityState<TCtor>>;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Entity - Local storage-backed entity class
|
|
194
|
+
*
|
|
195
|
+
* Implements the unified EntityClass interface for local DO-backed storage.
|
|
196
|
+
* All methods take EntityContext as the first parameter.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* export class TodoEntity extends Entity<Todo> {
|
|
201
|
+
* static readonly entityName = 'Todo';
|
|
202
|
+
* static readonly initialState: Todo = { id: '', title: '', completed: false };
|
|
203
|
+
* }
|
|
204
|
+
*
|
|
205
|
+
* // Usage:
|
|
206
|
+
* const ctx = { env };
|
|
207
|
+
* const todos = await TodoEntity.list(ctx, { limit: 50 });
|
|
208
|
+
* const todo = await TodoEntity.get(ctx, 'todo-123');
|
|
209
|
+
* await TodoEntity.create(ctx, { title: 'New task' });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export declare abstract class Entity<S extends {
|
|
213
|
+
id: string;
|
|
214
|
+
}> extends EntityBase<S> {
|
|
215
|
+
static readonly entityName: string;
|
|
216
|
+
static readonly schema?: Record<string, unknown>;
|
|
217
|
+
static keyOf<U extends {
|
|
218
|
+
id: string;
|
|
219
|
+
}>(state: U): string;
|
|
220
|
+
/**
|
|
221
|
+
* List entities with server-side filtering, search, sort, and pagination.
|
|
222
|
+
* All query operations run in SQL via EntityDO.queryEntities().
|
|
223
|
+
*/
|
|
224
|
+
static list<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, options?: ListOptions): Promise<PaginatedResult<EntityState<TCtor>>>;
|
|
225
|
+
/**
|
|
226
|
+
* Get a single entity by ID
|
|
227
|
+
*/
|
|
228
|
+
static get<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, id: string): Promise<EntityState<TCtor> | null>;
|
|
229
|
+
/**
|
|
230
|
+
* Count entities with optional filters
|
|
231
|
+
*/
|
|
232
|
+
static count<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, filters?: Record<string, unknown>): Promise<number>;
|
|
233
|
+
/**
|
|
234
|
+
* Create a new entity
|
|
235
|
+
*/
|
|
236
|
+
static create<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, data: Partial<EntityState<TCtor>>): Promise<EntityState<TCtor>>;
|
|
237
|
+
/**
|
|
238
|
+
* Update an existing entity (throws if missing)
|
|
239
|
+
*/
|
|
240
|
+
static update<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, id: string, data: Partial<EntityState<TCtor>>): Promise<EntityState<TCtor>>;
|
|
241
|
+
/**
|
|
242
|
+
* Delete an entity
|
|
243
|
+
*/
|
|
244
|
+
static delete<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, id: string): Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Ensure seed data exists (for initial data population)
|
|
247
|
+
*/
|
|
248
|
+
static ensureSeed<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext): Promise<void>;
|
|
249
|
+
/**
|
|
250
|
+
* Create multiple entities in a single RPC call to the DO.
|
|
251
|
+
* Generates UUIDs for items without an id. Returns all created items.
|
|
252
|
+
*/
|
|
253
|
+
static createMany<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, dataArray: Partial<EntityState<TCtor>>[]): Promise<EntityState<TCtor>[]>;
|
|
254
|
+
/**
|
|
255
|
+
* Update multiple entities in a single RPC call to the DO.
|
|
256
|
+
* Each update must include an id. Throws if any items are not found.
|
|
257
|
+
*/
|
|
258
|
+
static updateMany<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, updates: (Partial<EntityState<TCtor>> & {
|
|
259
|
+
id: string;
|
|
260
|
+
})[]): Promise<EntityState<TCtor>[]>;
|
|
261
|
+
/**
|
|
262
|
+
* Delete multiple entities in a single RPC call to the DO.
|
|
263
|
+
* Returns the count of items that actually existed and were deleted.
|
|
264
|
+
*/
|
|
265
|
+
static deleteMany<TCtor extends EntityCtor>(this: EntityCtorStatic<TCtor>, ctx: EntityContext, ids: string[]): Promise<number>;
|
|
266
|
+
protected ensureState(): Promise<S>;
|
|
267
|
+
}
|
|
268
|
+
import type { Hono } from 'hono';
|
|
269
|
+
/**
|
|
270
|
+
* Mount entity routes on the Hono app
|
|
271
|
+
* Provides internal API for entity CRUD from workspace (cross-app operations)
|
|
272
|
+
*/
|
|
273
|
+
export declare function entityRoutes(app: Hono<{
|
|
274
|
+
Bindings: Env;
|
|
275
|
+
}>): void;
|
|
276
|
+
export {};
|