40b441df04
- 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.
1717 lines
52 KiB
TypeScript
1717 lines
52 KiB
TypeScript
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 }
|