Files
tibi-types/index.d.ts
T
apairon 40b441df04 feat: add new JSON schemas for Tibi configuration including fields, hooks, jobs, and permissions
- Introduced `field-list.schema.json`, `field-meta.schema.json`, and `field.schema.json` for field configurations.
- Added `hooks.schema.json` for defining hooks in the Tibi project.
- Created `image-filter.schema.json` for image processing configurations.
- Implemented `job.schema.json` for job scheduling configurations.
- Added `openapi.schema.json` for OpenAPI metadata generation.
- Introduced `permissions.schema.json` for managing permissions in the project.
- Created `project.schema.json` for overall project configuration.
- Added `projections.schema.json` for defining projections in the project.
- Implemented a validation script `validate-schemas.mjs` to ensure schema compliance.
2026-07-01 09:23:43 +00:00

1717 lines
52 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
declare global {
export type CollectionDocument<T = {}, D = Date> = T & {
id?: string
insertTime?: D
updateTime?: D
[key: string]: any
}
/**
* Represents a `boolean` value or an object with an `eval` JS expression.
* Used for field-level `readonly` and `hidden` configuration.
*/
export type BoolOrEval = boolean | { eval: string }
/** Structured field validator as defined in Go CollectionField.Validator */
export interface FieldImageValidator {
/** Minimum allowed image width in pixels */
minWidth?: number
/** Maximum allowed image width in pixels */
maxWidth?: number
/** Minimum allowed image height in pixels */
minHeight?: number
/** Maximum allowed image height in pixels */
maxHeight?: number
/** Allow non-image uploads to bypass image dimension checks entirely */
allowNonImages?: boolean
/** Allow image/* uploads to pass when dimensions cannot be determined */
allowUnknownDimensions?: boolean
}
export interface FieldValidator {
/** Array of allowed primitive values the field may equal */
in?: any[]
/** Built-in string format validator */
format?: "email" | "url" | "uuid" | "slug"
/** Whether the field is required */
required?: boolean
/** Whether zero-values are allowed when required is true */
allowZero?: boolean
/** JS eval expression for custom validation */
eval?: string
/** Minimum number of items for array fields */
minItems?: number
/** Maximum number of items for array fields */
maxItems?: number
/** Minimum number of characters for string values */
minLength?: number
/** Maximum number of characters for string values */
maxLength?: number
/** Regex pattern the string value must fully match */
pattern?: string
/** Minimum numeric value */
min?: number
/** Maximum numeric value */
max?: number
/** Earliest allowed date/time value for date, time, and datetime fields */
minDate?: string
/** Latest allowed date/time value for date, time, and datetime fields */
maxDate?: string
/** Minimum decoded file size (e.g. 50KB) for file and file[] fields */
minFileSize?: string
/** Maximum decoded file size (e.g. 5MB) */
maxFileSize?: string
/** Allowed MIME types for file and file[] fields */
accept?: string[]
/** Image dimension bounds for newly uploaded file and file[] images */
image?: FieldImageValidator
}
export interface ScoreConfig {
expr?: { [key: string]: any }
}
export interface RegexConfig {
weights?: { [field: string]: number }
scoring?: "count" | "binary" | "log"
}
export interface NormalizeConfig {
use?: string[]
eval?: string
}
export interface NgramConfig {
sizes?: number[]
normalize?: NormalizeConfig
}
export interface RrfConfig {
k?: number
topK?: number
weights?: { [source: string]: number }
/** Fusion strategy: "rrf" (default), "score_rrf", "score_sum", "rank_score", "hybrid" */
strategy?: "rrf" | "score_rrf" | "score_sum" | "rank_score" | "hybrid"
/** Score normalization: "none" (default), "minmax", "zscore" */
normalize?: "none" | "minmax" | "zscore"
/** Blend factor for "hybrid" strategy: 0.0 = pure rank, 1.0 = pure score */
scoreWeight?: number
/** Per-source overrides for fine-grained fusion tuning */
sourceConfig?: { [source: string]: SourceFusionConfig }
}
/** Per-source overrides for rank fusion */
export interface SourceFusionConfig {
/** Override global scoreWeight for this source */
scoreWeight?: number
/** Score multiplier for this source (default 1.0) */
boost?: number
}
export interface VectorConfig {
provider: string
documentPrefix?: string
queryPrefix?: string
overflow?: "truncate" | "chunk"
chunkSize?: number
chunkOverlap?: number
}
export interface SearchExplainSource {
mode?: string
matched?: boolean
rank?: number
weight?: number
score?: number
/** Normalized score (only present when normalize is active) */
normalizedScore?: number
contribution?: number
details?: SearchExplanation
}
export interface SearchExplanation {
algorithm?: string
/** Fusion strategy used ("score_rrf", "hybrid", etc.). Omitted when default "rrf". */
strategy?: string
/** Normalization mode used ("minmax", "zscore"). Omitted when "none". */
normalize?: string
k?: number
sources?: { [source: string]: SearchExplainSource }
}
export interface SearchMeta {
score?: number
mode?: string
/** Present when the request uses qExplain=1 or qExplain=true. */
details?: SearchExplanation
}
/** Search configuration for a collection */
export interface SearchConfig {
/** Search config name (used in query parameter qName) */
name: string
/** Search mode: text, regex, eval, filter, ngram, vector or combined */
mode:
| "text"
| "regex"
| "eval"
| "filter"
| "ngram"
| "vector"
| "combined"
/** Fields to search in (for regex and ngram mode) */
fields?: string[]
/** Meta information */
meta?: { [key: string]: any }
/** JS eval expression (for eval mode) */
eval?: string
/** MongoDB filter template (for filter mode) */
filter?: { [key: string]: any }
/** Ngram search configuration */
ngram?: NgramConfig
/** Regex search configuration */
regex?: RegexConfig
/** Custom scoring for eval/filter search */
score?: ScoreConfig
/** Vector search configuration */
vector?: VectorConfig
/** Reciprocal rank fusion configuration */
rrf?: RrfConfig
/** Execute synchronously (false) or via background queue (true). Vector mode defaults to true. */
async?: boolean
/** Auto-regenerate enrichment data when the config changes */
autoRegenerate?: boolean
}
/** Query limits configuration for a collection */
export interface QueryLimitsConfig {
/** Default limit for GET queries (if client doesn't specify) */
defaultLimit?: number
/** Maximum allowed limit for GET queries */
maxLimit?: number
}
/** Bulk operation optimization configuration */
export interface BulkOptimizeConfig {
/** Optimize bulk create operations */
create?: boolean
/** Optimize bulk update operations */
update?: boolean
/** Optimize bulk delete operations */
delete?: boolean
}
/** Bulk configuration for a collection */
export interface BulkConfig {
/** Optimization settings for bulk operations */
optimize?: BulkOptimizeConfig
}
/** Collection index definition */
export interface CollectionIndex {
/** Index name */
name?: string
/** Index key fields (prefix with - for descending) */
key: string[]
/** Whether the index enforces uniqueness */
unique?: boolean
/** Whether to drop duplicate entries */
dropDups?: boolean
/** Build index in background */
background?: boolean
/** Only index documents that contain the indexed field */
sparse?: boolean
/** Default language for text indexes */
defaultLanguage?: string
/** Field that contains the language override */
languageOverride?: string
}
/** Audit configuration for a collection */
export interface AuditCollectionConfig {
/** Whether audit logging is enabled for this collection */
enabled?: boolean
/** List of actions to audit */
actions?: Array<
| "create"
| "update"
| "delete"
| "bulkCreate"
| "bulkUpdate"
| "bulkDelete"
>
}
export interface UploadConfig {
maxBodySize?: string
allowedMimeTypes?: string[]
}
export type LocalizedText = string | Record<string, string>
export type ChoiceValue = string | number | boolean | null
export type ChoiceStyle = Record<string, string | number | boolean>
export interface ChoiceItem {
id?: ChoiceValue
value?: ChoiceValue
name?: LocalizedText
label?: LocalizedText
description?: LocalizedText
badgeVariant?: "success" | "error" | "warning" | "info" | "neutral"
chipVariant?: "success" | "error" | "warning" | "info" | "neutral"
/**
* Flat inline CSS properties for badge/chip rendering.
* Supports camelCase, kebab-case, and CSS custom properties.
* `bg` and `text` remain aliases for `background` and `color`.
*/
badgeStyle?: ChoiceStyle
/** Alias for `badgeStyle`. */
chipStyle?: ChoiceStyle
}
export type EvalStringConfig = {
eval: string
select?: string[]
}
export type EvalHtmlConfig = {
eval: string
raw?: boolean
select?: string[]
}
export interface PreviewTableColumn {
source?: string
label?: LocalizedText
align?: "left" | "center" | "right"
eval?: string
raw?: boolean
select?: string[]
}
export type PreviewSlotValue = string | EvalStringConfig
export interface PreviewSlots {
label?: PreviewSlotValue
labelStyle?: PreviewSlotValue
secondary?: PreviewSlotValue
tertiary?: PreviewSlotValue
badge?: PreviewSlotValue
image?: PreviewSlotValue
imageFallback?: PreviewSlotValue
mediaFile?: string
eval?: string
raw?: boolean
table?: Array<string | PreviewTableColumn>
select?: string[]
}
export type PreviewConfig = string | EvalHtmlConfig | PreviewSlots
/** Image filter parameters — used in both CollectionConfig.imageFilter and ImagePackage.filter() */
export interface ImageFilterParams {
width?: number
height?: number
fit?: boolean
fill?: boolean
resampling?:
| "nearestNeighbor"
| "hermite"
| "linear"
| "catmullRom"
| "lanczos"
| "box"
| "mitchellNetravili"
| "bSpline"
| "gaussian"
| "bartlett"
| "hann"
| "hamming"
| "blackman"
| "welch"
| "cosine"
anchor?:
| "center"
| "topLeft"
| "top"
| "topRight"
| "left"
| "right"
| "bottomLeft"
| "bottom"
| "bottomRight"
brightness?: number
saturation?: number
contrast?: number
gamma?: number
blur?: number
sharpen?: number
invert?: boolean
grayscale?: boolean
quality?: number
lossless?: boolean
skipLargerDimension?: boolean
skipLargerFilesize?: boolean
outputType?: "jpg" | "jpeg" | "png" | "webp"
}
/** Collection config as returned by context.collection() JSON-serialized from Go CollectionConfig */
export interface CollectionInfo {
name: string
defaultLanguage?: string
upload?: UploadConfig
permissions?: { [role: string]: PermissionSet }
projections?: { [name: string]: ProjectionConfig }
meta?: { [key: string]: any }
fields?: CollectionFieldInfo[]
/** Named image filter presets for file fields */
imageFilter?: { [name: string]: ImageFilterParams[] }
/** Collection index definitions */
indexes?: CollectionIndex[]
/** Audit configuration */
audit?: AuditCollectionConfig
/** Bulk operation configuration */
bulk?: BulkConfig
/** Query limits for GET requests */
queryLimits?: QueryLimitsConfig
/** Fields that are read-only at collection level */
readonlyFields?: string[]
/** Fields that are hidden at collection level */
hiddenFields?: string[]
/** Search configurations */
search?: SearchConfig[]
/** Reject unknown fields not defined in the fields array */
strictFields?: boolean
[key: string]: any
}
/** Action endpoint descriptor as returned by context.api() for _actions resources */
export interface ActionInfo {
name: string
permissions?: { [role: string]: PermissionSet }
meta?: ActionMeta
audit?: AuditCollectionConfig
[key: string]: any
}
export interface ActionMeta {
label?: LocalizedText
muiIcon?: string
description?: LocalizedText
group?: string
hide?: boolean
methods?: Record<string, ActionMethodMeta>
[key: string]: any
}
export interface ActionMethodMeta {
query?: {
title?: LocalizedText
description?: LocalizedText
fields?: CollectionFieldInfo[]
}
data?: {
title?: LocalizedText
description?: LocalizedText
fields?: CollectionFieldInfo[]
}
execution?: ActionExecutionMeta
output?: ActionOutputMeta
[key: string]: any
}
export interface ActionExecutionMeta {
kind?: "sync" | "sse" | string
cancellable?: boolean
[key: string]: any
}
export interface ActionMappedField extends Omit<
CollectionFieldInfo,
"name"
> {
/** Dot-path in action payload/result/progress. Preferred over `name` for mapped output configs. */
source?: string
/** Legacy fallback for path-based mappings. */
name?: string
}
export interface ActionOutputProgressMapping {
indexField?: string
countField?: string
statusField?: string | string[]
messageField?: string
fields?: ActionMappedField[]
}
export interface ActionOutputMapping {
summary?: {
fields?: ActionMappedField[]
}
details?: {
fields?: ActionMappedField[]
}
progress?: ActionOutputProgressMapping
}
export interface ActionOutputMeta {
display?: "summary" | "detail" | "raw" | "download" | "none" | string
title?: LocalizedText
fields?: CollectionFieldInfo[]
mapping?: ActionOutputMapping
[key: string]: any
}
export type MethodPermission = boolean | { allow: boolean; bulk?: boolean }
export type SimpleMethodPermission = boolean | { allow: boolean }
export interface AllowedMethodPermission {
allow: boolean
bulk?: boolean
}
export interface CollectionYourPermissions {
get?: AllowedMethodPermission
post?: AllowedMethodPermission
put?: AllowedMethodPermission
delete?: AllowedMethodPermission
readonlyFields?: string[]
hiddenFields?: string[]
}
export interface ActionYourPermissions {
get?: { allow: boolean }
post?: { allow: boolean }
}
export interface ProjectYourPermissions {
_actions?: { [actionName: string]: ActionYourPermissions }
[collectionName: string]:
| CollectionYourPermissions
| { [actionName: string]: ActionYourPermissions }
| undefined
}
export interface PermissionSet {
methods?: {
get?: SimpleMethodPermission
/** `true` = allow single POST, `{allow: true, bulk: true}` = allow single + bulk POST */
post?: MethodPermission
/** `true` = allow single PUT, `{allow: true, bulk: true}` = allow single + bulk PUT */
put?: MethodPermission
/** `true` = allow single DELETE, `{allow: true, bulk: true}` = allow single + bulk DELETE */
delete?: MethodPermission
}
/** MongoDB filter applied to all queries for this permission set */
filter?: { [key: string]: any }
/** List of projection names this permission set is allowed to use */
validProjections?: string[]
/** Fields that are read-only for this permission set */
readonlyFields?: string[]
/** Fields that are hidden for this permission set */
hiddenFields?: string[]
[key: string]: any
}
export interface ProjectionConfig {
select?: { [field: string]: 0 | 1 }
[key: string]: any
}
export interface CollectionFieldInfo {
name: string
type: string
subFields?: CollectionFieldInfo[]
index?: string[]
validator?: FieldValidator
meta?: { [key: string]: any }
/** Field-level readonly — boolean or JS eval expression */
readonly?: BoolOrEval
/** Field-level hidden — boolean or JS eval expression */
hidden?: BoolOrEval
/** Reject unknown sub-fields not defined in subFields */
strictFields?: boolean
}
/** API info as returned by context.api() JSON-serialized from Go API struct */
export interface ApiInfo {
isOnline: boolean
lastReload: string
namespace: string
meta?: { [key: string]: any }
assets?: { name: string; path: string }[]
collections?: CollectionInfo[]
actions?: ActionInfo[]
jobs?: JobConfig[]
errors?: { collection?: string; context?: string; error: any }[]
[key: string]: any
}
/** Project info as returned by context.project() JSON-serialized from Go Project struct */
export interface ProjectInfo {
name: string
description?: string
namespace?: string
users?: string[]
configFile?: string
api?: ApiInfo
yourPermissions?: ProjectYourPermissions
[key: string]: any
}
/** Represents a single audit log entry as received in audit.return hooks */
export interface AuditLogEntry {
id?: string
insertTime?: string
updateTime?: string
/** ID of the user who performed the action */
userId?: string
/** Username of the user who performed the action */
username?: string
/** Role of the user (0=admin, 1=user) */
userRole?: number
/** Project namespace */
projectNamespace?: string
/** Project display name */
projectName?: string
/** Collection name */
collection?: string
/** Action performed: create, bulkCreate, update, delete, bulkUpdate, bulkDelete, get, login, reload, shutdown */
action?: string
/** Source information (type, collection, method, step, file, line) */
source?: {
type?: string
collection?: string
method?: string
step?: string
file?: string
line?: number
}
/** Document ID affected */
documentId?: string
/** Full document snapshot at time of action */
snapshot?: { [key: string]: any }
/** Changed fields (for updates) */
changes?: { [key: string]: any }
/** Filter used (for queries/deletes) */
filter?: { [key: string]: any }
/** Number of affected documents (e.g. deleteMany) */
count?: number
/** Client IP address */
ip?: string
/** Authentication method used (e.g. "jwt", "adminToken") */
authMethod?: string
/** Label of the admin token used (if applicable) */
tokenLabel?: string
/** Prefix of the admin token used (if applicable) */
tokenPrefix?: string
[key: string]: any
}
export interface DbReadOptions {
filter?: {
[key: string]: any
}
selector?: {
[key: string]: any
}
projection?: string
offset?: number
limit?: number
sort?: string[]
pipelineMod?: (
pipe: { [key: string]: any }[]
) => { [key: string]: any }[]
}
interface GetHookGetOnlyData {
/**
* true if only one document was requested via /COLLECTION/ID.
* In audit.return hooks this is always true (entries are processed individually).
*/
one?: boolean
/**
* Get list of documents.
* - In get.return hooks: array of collection documents
* - In audit.return hooks: array with a single AuditLogEntry
*/
results(): CollectionDocument[] | AuditLogEntry[]
}
interface GetHookData {
/**
* filter map only valid for "get" hooks
*/
filter?: {
[key: string]: any
}
/**
* selector map only valid for "get" hooks
*/
selector?: {
[key: string]: any
}
/**
* offset only valid for "get" hooks
*/
offset?: number
/**
* limit only valid for "get" hooks
*/
limit?: number
/**
* sort only valid for "get" hooks
*/
sort?: string[] | string
/**
* pipelineMod is a function to modify the mongodb query pipeline
*/
pipelineMod?: (
pipe: { [key: string]: any }[]
) => { [key: string]: any }[]
}
interface PostHookData {
/**
* post data only valid in "post" and "put" hooks.
* For bulk hooks (bulkCreate), this is an array of documents.
*/
data?: CollectionDocument | CollectionDocument[]
/**
* Number of created documents — only set in post.bulkReturn hook
*/
created?: number
/**
* Array of created document IDs — only set in post.bulkReturn hook
*/
ids?: string[]
/**
* Number of modified documents — only set in put.bulkReturn hook
*/
modified?: number
/**
* Number of deleted documents — only set in delete.bulkReturn hook
*/
deleted?: number
}
interface JobConfig {
/**
* meta object
*/
meta?: any
/**
* cron job interval specification
*/
cron?: string
/**
* job program type
*/
type: "javascript"
/**
* jobs program file
*/
file?: string
/**
* execution timeout in seconds
*/
timeout?: number
}
interface JobData {
/**
* job is object of job config
*/
job?: JobConfig
}
interface ConfigPackage {
/**
* get current namespace string
*
*/
namespace(): string
/**
* get current project object
*
*/
project(): ProjectInfo
/**
* get server config object (sensitive fields like jwtSecret, adminTokens, apiKeys are excluded)
*
*/
server(): {
api: {
port: number
secureCookies?: boolean
accessTokenLifetime?: string
refreshTokenLifetime?: string
}
security: {
allowAbsolutePaths: boolean
allowUpperPaths: boolean
}
llm?: {
providers?: {
name: string
type: string
baseURL: string
defaultModel: string
models?: string[]
maxTokensPerRequest?: number
}[]
}
audit?: {
enabled: boolean
defaultTTL: string
defaultLimit?: number
maxLimit?: number
}
ratelimit?: {
enabled?: boolean
loginInitialDelay?: string
loginMaxDelay?: string
loginResetAfter?: string
}
hook?: {
cache: {
maxEntries?: number
defaultTTL?: string
}
ratelimit: {
backoffInitialDelay?: string
backoffMaxDelay?: string
backoffResetAfter?: string
windowSize?: string
windowMaxHits?: number
}
}
}
}
interface DbPackage {
/**
* read results from a collection
*
* @param colName collection name
* @param options options map
*/
find(colName: string, options?: DbReadOptions): CollectionDocument[]
/**
* read count of documents for filter from a collection
*
* @param colName collection name
* @param options options map (only filter is valid)
*/
count(colName: string, options?: DbReadOptions): number
/**
* create a document in a collection
*
* @param colName collection name
* @param data data map
*/
create(colName: string, data: CollectionDocument): CollectionDocument
/**
* update a document in a collection
*
* Supports field-level operators in data:
* - `{ "$inc": value }` — increment by value
* - `{ "$mul": value }` — multiply by value
* - `{ "$unset": true }` — remove the field
* - `{ "$set": value }` — explicit set (same as plain value)
*
* Operators are converted to native MongoDB operators and executed
* atomically in a single DB call.
*
* @param colName collection name
* @param id id of entry
* @param data new/changed data (may contain operators)
* @param options optional: `{ raw: true }` to pass data as raw MongoDB update document
*/
update(
colName: string,
id: string,
data: CollectionDocument,
options?: { raw?: boolean }
): CollectionDocument
/**
* deletes one document by id from collection
*
* @param colName collection name
* @param id id of entry
*/
delete(colName: string, id: string): { message: "ok" }
/**
* deletes documents by filter from collection
*
* @param colName collection name
* @param options options map, only filter valid
*/
deleteMany(
colName: string,
options?: DbReadOptions
): { message: "ok"; removed: number }
/**
* update multiple documents matching a filter
*
* Use `changes` for simple field updates (supports operators like $inc, $mul).
* Use `update` for raw MongoDB update documents.
*
* @param colName collection name
* @param options options with filter and changes/update
*/
updateMany(
colName: string,
options: {
filter?: { [key: string]: any }
/** Field updates — may contain operators like { "$inc": 1 } */
changes?: { [key: string]: any }
/** Raw MongoDB update document (e.g. { "$inc": { stock: -1 } }) */
update?: { [key: string]: any }
}
): { message: "ok"; modified: number }
}
interface SmtpPackage {
/**
* send an email
*
* @param options email options map
*/
sendMail(options: {
host?: string
username?: string
password?: string
to: string | string[]
cc?: string | string[]
bcc?: string | string[]
subject?: string
from: string
fromName?: string
replyTo?: string
plain?: string
html?: string
attach?: string | string[]
}): void
}
interface FsPackage {
/**
* get directory path of api config file
*
*/
configDir(): string
/**
* read a file relative to config dir and return its content
*
* @param path relative file path
* @param options optional options
*/
readFile(
path: string,
options?: {
bytes: boolean // if true return []byte instead of string
}
): string | any
/**
* write data to a file relative to config dir
*
* @param path relative file path
* @param data string or []byte data
*/
writeFile(path: string, data: string | any): null
/**
* stat file or directory
*
* @param path
*/
stat(path: string): {
name: string
size: number
isDir: boolean
modTime: string
}
/**
* list directory entries
*
* @param path
*/
readDir(path: string): {
name: string
size: number
isDir: boolean
modTime: string
}[]
/**
* make directory and all missing sub directories, no error if directory already exists
*
* @param path
*/
mkDir(path: string): void
/**
* remove file or empty directory
*
* @param path
*/
remove(path: string): void
/**
* copy file or directory
*
* @param src
* @param dest
*/
copy(src: string, dest: string): void
}
interface TplPackage {
/**
* execute a template code and return result
*
* @param code template code
* @param contextData template context map
*/
execute(
code: string,
contextData?: {
[key: string]: any
}
): string
}
interface HttpPackage {
/**
* http request — reads the entire response body into memory
*
* @param url url for request
* @param options request options
*/
fetch(
url: string,
options?: {
method?: string
headers?: { [key: string]: string }
body?: string
/** timeout in seconds (default 10) */
timeout?: number
}
): {
status: number
statusText: string
headers: { [key: string]: string }
trailer: { [key: string]: string }
url: string
body: {
text(): string
json(): any
}
}
/**
* streaming http request — response body is NOT read into memory.
* Use body.read() to read line by line (ideal for SSE / newline-delimited
* protocols like OpenAI streaming API).
*
* @param url url for request
* @param options request options
*/
fetchStream(
url: string,
options?: {
method?: string
headers?: { [key: string]: string }
body?: string
/** timeout in seconds (default 0 = no timeout, hook timeout controls duration) */
timeout?: number
}
): {
status: number
statusText: string
headers: { [key: string]: string }
body: {
/** returns the next line as string, or null at EOF */
read(): string | null
/** explicitly closes the response body (auto-closed at EOF) */
close(): void
}
}
}
interface DebugPackage {
/**
* dumps data to header and server log
*
* @param toDump data to dump
*/
dump(...toDump: any): void
/**
* get Sentry trace id
*/
sentryTraceId(): string
/**
* sleep
*
* @param ms sleep time in milliseconds
*/
sleep(ms: number): void
}
interface ResponsePackage {
/**
* set response header (must be called before writeHeader/write)
*
* @param name header name
* @param value value
*/
header(name: string, value: any): void
/**
* set the HTTP status code — must be called before write().
* If not called, the first write() will implicitly send status 200.
*
* @param status HTTP status code
*/
writeHeader(status: number): void
/**
* write data directly to the HTTP response body.
* Use for streaming responses (e.g. SSE to a chat widget).
*
* @param data string or byte data to write
*/
write(data: string | any): void
/**
* flush buffered data to the client immediately.
* Essential for streaming / SSE to push chunks without waiting
* for the full response to complete.
*/
flush(): void
/**
* write a Server-Sent Event and flush immediately.
* Formats the output as SSE: "event: {event}\ndata: {data}\n\n"
* If called with one argument, only "data: {data}\n\n" is written.
*
* @param event SSE event name (optional if using single-argument form)
* @param data SSE data payload
*/
writeSSE(event: string, data: string): void
writeSSE(data: string): void
}
interface UserPackage {
/**
* get JWT authentication
*/
auth(): {
id: string
username: string
role: number
permissions: string[]
}
}
interface BcryptPackage {
/**
* hash password via bcrypt algo
*
* @param password clear text password
* @param options hashing options
*/
hash(
password: string,
options?: {
cost?: number
}
): string
/**
* check password against hashed password via bcrypt algo
*
* @param password clear text password
* @param hash hashed password
*/
check(password: string, hash: string): boolean
}
interface JwtPackage {
/**
* create a jwt signed token string
*
* @param claims data object
* @param options options (secret, validityDuration = expiry in X seconds)
*/
create(
claims: {
[key: string]: any
},
options?: {
secret?: string
validityDuration?: number
}
): string
/**
* parse jwt token string
*
* @param token token string
* @param options options (secret)
*/
parse(
token: string,
options?: {
secret?: string
}
): {
error?: string
valid: boolean
method: {
Name: string
Hash: number
}
header: {
alg: string
typ: string
}
claims: {
exp?: number
[key: string]: any
}
}
}
interface CharsetPackage {
/**
* decode byte-oriented input using the given encoding
*
* supported encodings: utf-8, iso-8859-1
*/
decode(input: string | Int8Array | number[], encoding: string): string
/**
* convert iso8859 to utf8
*
* @param iso8859 iso string or bytes
*/
iso8859ToUtf8(iso8859: string | Int8Array | number[]): string
}
interface ImagePackage {
/**
* convert image from source file to target file with filters
*
* @param sourceFile
* @param targetFile
* @param filters
*/
filter(
sourceFile: string,
targetFile: string,
filters: ImageFilterParams[]
): void
}
interface XmlPackage {
/**
* create xml string
*
* @param data object or array (map with string keys as nodes (-KEY will be attribute in parent node))
* @param options options
*/
create(
data: { [key: string]: any },
options?: {
rootElement?: string
includeHeader?: boolean
}
): string
/**
* parse xml string to json
*
* @param xml xml string
* @param options options
*/
parse(xml: string, options?: {}): any
}
interface CookiePackage {
/**
* get cookie from http header
*
* @param name cookie name
*/
get(name: string): string
/**
* set cookie via http header
*
* @param name cookie name
* @param value cookie value
* @param options cookie options
*/
set(
name: string,
value: string,
options?: {
maxAge?: number
path?: string
domain?: string
secure?: boolean
httpOnly?: boolean
sameSite?: "strict" | "lax" | "none"
}
): void
}
interface PdfPackage {
/**
* generate pdf from html
*
* @param html html string
* @param options options
*
* @returns []byte of pdf data
*/
fromHTML(
html: string,
options?: {
copies?: number // Number of copies to print into the pdf file (default 1)
dpi?: number // Change the dpi explicitly (this has no effect on X11 based systems)
grayscale?: boolean // PDF will be generated in grayscale
imageDpi?: number // When embedding images scale them down to this dpi (default 600)
imageQuality?: number // When jpeg compressing images use this quality (default 94)
lowQuality?: boolean // Generates lower quality pdf/ps. Useful to shrink the result document space
marginBottom?: number // Set the page bottom margin
marginLeft?: number // Set the page left margin (default 10mm)
marginRight?: number // Set the page right margin (default 10mm)
marginTop?: number // Set the page top margin
noCollate?: boolean // Do not collate when printing multiple copies (default collate)
noPdfCompression?: boolean // Do not use lossless compression on pdf objects
orientation?: "Portrait" | "Landscape" // Set orientation to Landscape or Portrait (default Portrait)
pageHeight?: number // Page height
pageSize?: string // Set paper size to: A4, Letter, etc. (default A4)
pageWidth?: number // Page width
title?: string // The title of the generated pdf file (The title of the first document is used if not specified)
// page settings
printMediaType?: boolean // Use print media-type instead of screen
footerCenter?: string // Centered footer text
footerFontName?: string // Set footer font name (default Arial)
footerFontSize?: number // Set footer font size (default 12)
footerLeft?: string // Left aligned footer text
footerLine?: boolean // Display line above the footer
footerRight?: string // Right aligned footer text
footerSpacing?: number // Spacing between footer and content in mm (default 0)
footerHTML?: string // URL to footer html
headerCenter?: string // Centered header text
headerFontName?: string // Set header font name (default Arial)
headerFontSize?: number // Set header font size (default 12)
headerLeft?: string // Left aligned header text
headerLine?: boolean // Display line below the header
headerRight?: string // Right aligned header text
headerSpacing?: number // Spacing between header and content in mm (default 0)
headerHTML?: string // URL to header html
}
): any
/**
* process existing pdf data
*
* @param command pdfcpu command
* @param pdfData []byte of pdf data, multiple []byte as array of pdf's to merge or object with description to create
* @param options options
*
* @returns []byte of new pdf data
*/
cpu(
command: "watermark" | "stamp" | "merge" | "rotate" | "create",
pdfData: any | any[],
options?: {
pages?: (string | number)[]
description?: {
fontname?: string
points?: number
rtl?: boolean
position?:
| "full"
| "tl"
| "tc"
| "tr"
| "l"
| "c"
| "r"
| "bl"
| "bc"
| "br"
offset?: string
scalefactor?: number | string
aligntext?: "left" | "center" | "right" | "justified"
strokecolor?: string
fillcolor?: string
backgroundcolor?: string
rotation?: number
diagonal?: 1 | 2
opacity?: number
rendermode?: 0 | 1 | 2
margins?: number | string
border?: number | string
url?: string
}
mode?: "text" | "image" | "pdf"
bytes?: any // []byte of watermark image
file?: string // file for pdf watermark
text?: string // text for text watermark
rotation?: number
}
): any
}
interface CryptoPackage {
/**
* get hex of sha256 hash
*
* @param sata string
*
* @returns hex hash
*/
sha256(data: string): string
/**
* get hex of md5 hash
*
* @param sata string
*
* @returns hex hash
*/
md5(data: string): string
}
interface JsonPackage {
/**
* parse json string to json
* @param str json string
*/
parse(str: string): any
/**
* stringify json string
* @param json json object
*/
stringify(json: any): string
}
interface ExecPackage {
command(
cmd: string,
options?: {
args?: string[]
stdin?: string
dir?: string
env?: string[]
timeout?: number
returnObject?: boolean
combineOutput?: boolean
}
): string
command<
T extends {
args?: string[]
stdin?: string
dir?: string
env?: string[]
timeout?: number
returnObject?: boolean
combineOutput?: boolean
},
>(
cmd: string,
options: T
): T["returnObject"] extends true
? T["combineOutput"] extends true
? { output: string; exitCode: number }
: { stdout: string; stderr: string; exitCode: number }
: string
}
interface Base64Package {
encode(data: string | Int8Array): string
decode(data: string): string
decode(data: string, options: { returnBytes: true }): Int8Array
decode(data: string, options: { returnBytes: false }): string
decode(
data: string,
options: { returnBytes?: boolean }
): string | Int8Array
}
/**
* Project-scoped in-memory cache.
*
* Entries survive across requests but are cleared on project reload.
* Configured via project config `hook.cache` or server config `hook.cache`.
*/
interface CachePackage {
/**
* Store a value in the cache.
*
* @param key Cache key
* @param value Any JSON-serializable value
* @param ttlMs Optional time-to-live in milliseconds (overrides defaultTTL)
*/
set(key: string, value: any, ttlMs?: number): void
/**
* Retrieve a value from the cache.
*
* @param key Cache key
* @returns The cached value, or `null` if not found / expired.
*/
get(key: string): any | null
/**
* Check whether a key exists (and is not expired) in the cache.
*
* @param key Cache key
*/
has(key: string): boolean
/**
* Delete a single key from the cache.
*
* @param key Cache key
* @returns `true` if the key existed, `false` otherwise.
*/
delete(key: string): boolean
/**
* Remove all entries from the cache.
*/
clear(): void
/**
* Return the number of entries currently in the cache.
*/
count(): number
}
/**
* Project-scoped rate limiter with two strategies:
* - **Backoff**: Exponential back-off per key (e.g. login brute-force protection).
* - **Window**: Sliding-window counter per key (e.g. API call quotas).
*
* Configured via project config `hook.ratelimit` or server config `hook.ratelimit`.
*/
interface RatelimitPackage {
/**
* Check whether a key is currently blocked by the exponential back-off strategy.
*
* @param key Rate-limit key (e.g. IP address or user ID)
* @returns `{ blocked, retryAfterMs }` — if blocked, retryAfterMs indicates how long to wait.
*/
backoffCheck(key: string): { blocked: boolean; retryAfterMs: number }
/**
* Record a failure for the given key, increasing its back-off delay.
*
* @param key Rate-limit key
*/
backoffRecord(key: string): void
/**
* Reset the back-off state for a key (e.g. after a successful login).
*
* @param key Rate-limit key
*/
backoffReset(key: string): void
/**
* Check the sliding-window strategy for a key.
*
* @param key Rate-limit key
* @returns `{ allowed, retryAfterMs }` — if not allowed, retryAfterMs indicates how long to wait.
*/
windowCheck(key: string): { allowed: boolean; retryAfterMs: number }
/**
* Reset the sliding-window counter for a key.
*
* @param key Rate-limit key
*/
windowReset(key: string): void
/**
* Return the current hit count in the sliding window for a key.
*
* @param key Rate-limit key
*/
windowCount(key: string): number
}
/**
* Options for channel.subscribe().
*/
interface ChannelSubscribeOptions {
/** Maximum number of buffered messages per subscriber (default: 64). */
bufferSize?: number
/**
* Behaviour when the buffer is full.
* - "drop-oldest" (default): discard the oldest message
* - "drop-newest": discard the incoming message
*/
onFull?: "drop-oldest" | "drop-newest"
/** Time-to-live per message in milliseconds. Expired messages are skipped on receive. */
messageTTL?: number
/** Replay the last N messages from the channel's ring-buffer to the new subscriber. */
lastN?: number
/** Replay only messages younger than maxAge milliseconds. */
maxAge?: number
}
/**
* A subscription to a real-time channel.
* Returned by channel.subscribe().
*/
interface ChannelSubscription {
/**
* Blocks until a message arrives, the client disconnects, or the
* subscription/channel is closed.
*
* @returns The message data, or `null` when the client disconnects.
* @throws `{error: string, code: "channel_closed"}` when the
* subscription or channel is closed (e.g. project reload).
*/
receive(): any
/** Manually close the subscription (idempotent). */
close(): void
}
/**
* Real-time pub/sub channel package.
*
* Channels are in-memory, project-scoped, and named freely (not bound
* to collections). Every subscriber receives an independent deep-copy
* of each message.
*/
interface ChannelPackage {
/**
* Subscribe to a named channel. The calling hook will block until
* the client disconnects or the subscription is closed.
* The execution timeout is automatically disabled for hooks that subscribe.
*
* @param name Channel name (arbitrary string).
* @param options Optional subscribe options.
*/
subscribe(
name: string,
options?: ChannelSubscribeOptions
): ChannelSubscription
/**
* Publish data to all current subscribers of a named channel.
* This is a fire-and-forget operation; if no one is subscribed, the
* message is buffered in the channel's ring-buffer for future replay.
*
* @param name Channel name.
* @param data Arbitrary data (will be deep-copied per subscriber).
*/
send(name: string, data: any): void
}
export interface HookContext
extends GetHookData, GetHookGetOnlyData, PostHookData, JobData {
request(): {
method: string
remoteAddr: string
clientIp(): string
host: string
url: string
path: string
param(p: string): string
query(q: string): string
header(h: string): string
body(): string
/**
* bodyBytes returns the raw request body bytes for later decoding via charset.decode
*/
bodyBytes(): Int8Array
}
api(): ApiInfo
project(): ProjectInfo
collection(): CollectionInfo
config: ConfigPackage
db: DbPackage
smtp: SmtpPackage
fs: FsPackage
tpl: TplPackage
http: HttpPackage
debug: DebugPackage
response: ResponsePackage
user: UserPackage
bcrypt: BcryptPackage
jwt: JwtPackage
charset: CharsetPackage
image: ImagePackage
xml: XmlPackage
cookie: CookiePackage
pdf: PdfPackage
crypto: CryptoPackage
json: JsonPackage
exec: ExecPackage
base64: Base64Package
channel: ChannelPackage
cache: CachePackage
ratelimit: RatelimitPackage
}
export interface HookException {
status?: number
html?: string
string?: string
bytes?: any
json?: any
file?: string
log?: boolean
[key: string]: any
}
export interface HookResponse extends GetHookData, PostHookData {
data?: CollectionDocument
results?: any
}
var context: HookContext
}
export { HookResponse, HookException, HookContext, CollectionDocument }