@flavoai/fastfold
Version:
Flavo frontend package
358 lines • 12.1 kB
TypeScript
export type CrudOperation = 'create' | 'read' | 'update' | 'delete';
export interface SecurityRule {
type: 'public' | 'admin' | 'owner' | 'custom' | 'authenticated';
ownerField?: string;
customRule?: (context: SecurityContext) => boolean | Promise<boolean>;
}
export interface SecurityContext {
user?: {
id: string;
role: string;
[key: string]: any;
};
operation: CrudOperation;
data?: any;
existingData?: any;
tableName: string;
}
export interface TableConfig {
security: SecurityRule;
operations?: CrudOperation[];
}
export interface DrizzleConfig {
db: any;
schema: Record<string, any>;
}
/** Settings for the 'flavo' auth strategy. */
export interface FlavoAuthSettings {
/** App ID. Defaults to process.env.VITE_FASTFOLD_APP_ID || process.env.FLAVO_CONVERSATION_ID */
appId?: string;
/** Name of the user table in schema. When set, user profiles are auto-synced to this table on login. */
userTable?: string;
}
/** Settings for the 'custom' HS256 auth strategy. */
export interface CustomAuthSettings {
/** Required HS256 secret for signing/verifying JWTs. */
secret: string;
/** JWT expiry (e.g. '7d', '1h'). */
expiresIn?: string;
/** Custom auth endpoint paths. */
endpoints?: {
register?: string;
login?: string;
logout?: string;
me?: string;
};
}
export interface AuthConfig {
/**
* Auth providers to enable. Each key activates a strategy; its value
* carries that strategy's settings.
* - flavo: Delegated OAuth via Flavo's login page.
* - custom: HS256 symmetric-key JWT auth.
*/
providers: {
flavo?: FlavoAuthSettings;
custom?: CustomAuthSettings;
};
}
export interface UploadsConfig {
provider: 'local' | 's3' | 'cloudinary';
path?: string;
maxSize?: string;
allowedTypes?: string[];
}
export interface RateLimitConfig {
windowMs: number;
max: number;
}
export interface CorsConfig {
origins?: string[];
}
export interface StaticMount {
directory: string;
urlPath?: string;
spaFallback?: boolean;
excludePaths?: Array<string | RegExp>;
indexFile?: string;
staticOptions?: {
index?: string | false;
maxAge?: number | string;
etag?: boolean;
immutable?: boolean;
cacheControl?: boolean;
setHeaders?: (res: any, path: string, stat: any) => void;
};
}
export type StaticFrontendConfig = StaticMount | StaticMount[];
export interface LoggingConfig {
enabled: boolean;
logFilePath?: string;
logRequests?: boolean;
logResponses?: boolean;
logRequestBody?: boolean;
logResponseBody?: boolean;
excludePaths?: string[];
}
export interface StudioConfig {
enabled: boolean;
path?: string;
frontendPath?: string;
auth?: {
enabled: boolean;
password?: string;
};
}
export type AIProvider = 'openai' | 'anthropic' | 'google';
/**
* Model tier for automatic model selection
* - 'fast': Use cheap/fast models (gpt-4o-mini, claude-haiku-4-5, gemini-3-flash)
* - 'balanced': Use balanced models (gpt-5.2, claude-sonnet-4-5, gemini-3-flash)
* - 'powerful': Use powerful models (gpt-5.2, claude-opus-4-5, gemini-3-pro)
* User-specified models ALWAYS take priority over tier selection
*/
export type ModelTier = 'fast' | 'balanced' | 'powerful';
export interface AIProviderConfig {
apiKey?: string;
baseURL?: string;
organization?: string;
}
export interface AIEndpointsConfig {
/** Enable POST /api/ai/chat for chat completions */
chat?: boolean;
/** Enable POST /api/ai/complete for text completions */
complete?: boolean;
/** Enable POST /api/ai/embed for embeddings */
embed?: boolean;
/** Enable POST /api/ai/generate for structured object generation */
generate?: boolean;
/** Enable POST /api/ai/stream for streaming responses */
stream?: boolean;
}
export interface AIConfig {
/** Enable AI endpoints (default: false) */
enabled: boolean;
/** Which AI endpoints to expose */
endpoints?: AIEndpointsConfig;
/** Default provider to use (default: 'openai') */
defaultProvider?: AIProvider;
/** Default model to use (default: provider-specific based on tier) */
defaultModel?: string;
/**
* Model tier preference (default: 'balanced')
* - 'fast': Use cheap/fast models for simple tasks
* - 'balanced': Use balanced cost/performance models
* - 'powerful': Use most capable models for complex tasks
* User-specified models ALWAYS take priority over tier selection
*/
modelTier?: ModelTier;
/** Provider-specific configuration (overrides env vars) */
providers?: Partial<Record<AIProvider, AIProviderConfig>>;
/** Rate limiting for AI endpoints */
rateLimit?: {
windowMs?: number;
maxRequests?: number;
};
/** Base path for AI endpoints (default: '/api/ai') */
basePath?: string;
}
export interface HooksConfig {
onServerStart?: (server: any) => Promise<void> | void;
onRequest?: (req: any, res: any, next: any) => void;
beforeCreate?: Record<string, (data: any, context: SecurityContext) => Promise<any> | any>;
afterCreate?: Record<string, (record: any, context: SecurityContext) => Promise<void> | void>;
beforeUpdate?: Record<string, (data: any, existing: any, context: SecurityContext) => Promise<any> | any>;
afterUpdate?: Record<string, (record: any, context: SecurityContext) => Promise<void> | void>;
beforeDelete?: Record<string, (id: string | number, context: SecurityContext) => Promise<boolean> | boolean>;
afterDelete?: Record<string, (id: string | number, context: SecurityContext) => Promise<void> | void>;
}
/**
* AI-specific hooks for automatic data transformation
* These hooks integrate with the AI module for embeddings, summarization, etc.
*/
export interface AIHooksConfig {
/** Generate embeddings for specified fields on create/update */
embeddings?: Record<string, {
/** Source field(s) to generate embeddings from */
sourceFields: string[];
/** Target field to store the embedding vector */
targetField: string;
/** Model to use (default: provider default) */
model?: string;
/** Provider to use (default: config default) */
provider?: AIProvider;
}>;
/** Auto-generate summaries for specified fields on create/update */
summarize?: Record<string, {
/** Source field to summarize */
sourceField: string;
/** Target field to store the summary */
targetField: string;
/** Max length of summary (default: 200) */
maxLength?: number;
/** Model to use */
model?: string;
/** Provider to use */
provider?: AIProvider;
}>;
/** Auto-classify/tag content on create/update */
classify?: Record<string, {
/** Source field to classify */
sourceField: string;
/** Target field to store classification */
targetField: string;
/** Categories to classify into */
categories: string[];
/** Model to use */
model?: string;
/** Provider to use */
provider?: AIProvider;
}>;
/** Custom AI transformation function */
transform?: Record<string, (data: any, context: SecurityContext) => Promise<any>>;
}
export interface DrizzleQuickStartConfig {
/** Port to listen on. Use process.env.PORT in Docker/production. */
port?: number;
drizzle: DrizzleConfig;
tables: {
[tableName: string]: TableConfig;
};
auth?: AuthConfig;
uploads?: UploadsConfig;
rateLimit?: RateLimitConfig;
endpoints?: (app: any) => void;
hooks?: HooksConfig;
static?: StaticFrontendConfig;
/**
* Additional Express middleware to attach. Useful for logging, compression, etc.
* Will be registered after CORS/body parsers and before auth/routes.
*/
middleware?: Array<(req: any, res: any, next: any) => void>;
/**
* Logging configuration for development and debugging.
* Logs all incoming/outgoing HTTP requests to a file.
*/
logging?: LoggingConfig;
/**
* Studio configuration for database visualization and CRUD operations.
* Dev-only feature for exploring your database schema and data.
*/
studio?: StudioConfig;
/**
* AI configuration for auto-generated AI endpoints using Vercel AI SDK.
* Provides multi-provider support (OpenAI, Anthropic, Google) with streaming,
* structured output, and tool calling capabilities.
*/
ai?: AIConfig;
/**
* AI hooks for automatic data transformation on CRUD operations.
* Supports auto-generating embeddings, summaries, and classifications.
*/
aiHooks?: AIHooksConfig;
/**
* CORS configuration. If omitted, only localhost origins are allowed in development
* and no origins are allowed in production. Provide explicit origins for production use.
*/
cors?: CorsConfig;
}
export interface LegacyTableDefinition {
schema: {
[fieldName: string]: 'string' | 'number' | 'boolean' | 'date' | 'json';
};
security: SecurityRule;
}
export interface LegacyQuickStartConfig {
tables: {
[tableName: string]: LegacyTableDefinition;
};
endpoints?: (app: any) => void;
hooks?: {
onServerStart?: (server: any) => Promise<void> | void;
onRequest?: (req: any, res: any, next: any) => void;
};
}
export interface QueryParams {
where?: Record<string, any>;
orderBy?: Record<string, 'asc' | 'desc'>;
limit?: number;
offset?: number;
select?: string[];
with?: Record<string, any>;
}
export interface CreateData<T = any> {
data: T;
}
export interface UpdateData<T = any> {
id: string | number;
data: Partial<T>;
}
export interface DeleteData {
id: string | number;
}
export interface ApiResponse<T = any> {
success: boolean;
data?: T;
error?: string;
count?: number;
}
export interface UseQueryOptions {
enabled?: boolean;
refetchOnWindowFocus?: boolean;
refetchInterval?: number;
}
export interface UseMutationOptions<TData = any, TVariables = any> {
onSuccess?: (data: TData) => void;
onError?: (error: Error) => void;
}
export interface QueryState<T = any> {
data: T | undefined;
isLoading: boolean;
error: Error | null;
refetch: () => Promise<void>;
}
export interface MutationState<TData = any, TVariables = any> {
mutate: (variables: TVariables) => Promise<TData>;
isLoading: boolean;
error: Error | null;
reset: () => void;
}
export type DatabaseProvider = 'postgresql' | 'mysql';
export type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'text';
export interface TableSchema {
[fieldName: string]: FieldType;
}
export interface TableDefinition {
schema: TableSchema;
security: SecurityRule;
}
export interface FastfoldConfig {
tables: {
[tableName: string]: TableDefinition;
};
endpoints?: (app: any) => void;
hooks?: {
onServerStart?: (server: any) => Promise<void> | void;
onRequest?: (req: any, res: any, next: any) => void;
};
}
export interface DatabaseAdapter {
connect(): Promise<void>;
disconnect(): Promise<void>;
createTable(tableName: string, schema: TableSchema): Promise<void>;
query<T = any>(tableName: string, params: QueryParams): Promise<T[]>;
create<T = any>(tableName: string, data: any): Promise<T>;
update<T = any>(tableName: string, id: string | number, data: any): Promise<T>;
delete(tableName: string, id: string | number): Promise<boolean>;
count(tableName: string, where?: Record<string, any>): Promise<number>;
}
export interface AuthUser {
id: string;
role: string;
[key: string]: any;
}
export interface RequestContext extends SecurityContext {
req: any;
res: any;
}
//# sourceMappingURL=index.d.ts.map