@dyrected/core 0.0.0-pr-18-20260828214838
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +50 -0
- package/README.md +37 -0
- package/dist/access-WWVHSLQZ.js +9 -0
- package/dist/ai-X3M2SE5A.js +17 -0
- package/dist/app-config-BgV9qpFu.d.cts +3224 -0
- package/dist/app-config-BgV9qpFu.d.ts +3224 -0
- package/dist/chunk-4RAQJVJM.js +18 -0
- package/dist/chunk-67ZMBYY3.js +1820 -0
- package/dist/chunk-FRSJJO27.js +519 -0
- package/dist/chunk-JSBRDJBE.js +30 -0
- package/dist/chunk-QDKVTDDU.js +625 -0
- package/dist/chunk-VH56DIUA.js +5173 -0
- package/dist/index.cjs +8519 -0
- package/dist/index.d.cts +1399 -0
- package/dist/index.d.ts +1399 -0
- package/dist/index.js +627 -0
- package/dist/observability-HQF4EUSV.js +35 -0
- package/dist/rag.service-PESCTCRX.js +9 -0
- package/dist/server.cjs +13835 -0
- package/dist/server.d.cts +602 -0
- package/dist/server.d.ts +602 -0
- package/dist/server.js +5966 -0
- package/dist/where-sanitizer-3MNFMYA2.js +56 -0
- package/package.json +69 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1399 @@
|
|
|
1
|
+
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, G as GlobalConfig, a as DeclarativeHookExpression, W as WorkflowConfig, b as AuthenticatedUser, c as WorkflowTransition, L as LifecycleEventName, d as LifecycleEvent, e as BaseDocument, H as HookRequestContext, f as DetailComputedOptions, g as ComputedHandler, h as DetailComputed, i as DetailCustomOptions, j as DetailCustom, k as DetailDividerOptions, l as DetailDivider, m as DisplayFieldOptions, n as DetailField, o as DetailItem, p as DetailGridOptions, q as DetailGrid, r as DetailRepeatOptions, s as DetailRepeat, t as DetailSectionOptions, u as DetailSection, v as DetailTabOptions, w as DetailTab, x as DetailTabsOptions, y as DetailTabs, z as DetailTextOptions, E as DetailText, I as DetailSchema, J as DatabaseAdapter, K as DyrectedAIContext, M as AIThread, N as AIMessage, R as RAGSearchResult, O as ArrayField, Q as BlocksField, S as BooleanField, T as AuthConfig, U as AccessPolicyResolver, V as DateField, X as DateTimeField, Y as EmailField, Z as IconField, _ as ImageField, $ as JoinField, a0 as JsonField, a1 as MultiSelectField, a2 as NumberField, a3 as ObjectField, a4 as RadioField, a5 as RelationshipField, a6 as RichTextField, a7 as RowField, a8 as SelectField, a9 as TextField, aa as TextareaField, ab as TimeField, ac as UrlField } from './app-config-BgV9qpFu.cjs';
|
|
2
|
+
export { ad as AIAction, ae as AIActionStatus, af as AIActionType, ag as AIAuditRecord, ah as AIChunk, ai as AIConfig, aj as AIToolContext, ak as AIToolDefinition, al as AI_ACTIONS_COLLECTION, am as AI_AUDIT_COLLECTION, an as AI_CHUNKS_COLLECTION, ao as AI_MESSAGES_COLLECTION, ap as AI_THREADS_COLLECTION, aq as AccessConfig, ar as AccessFunction, as as AccessFunctionArgs, at as AccessResult, au as AccessRule, av as ActionConfig, aw as ActionContext, ax as ActionType, ay as AdminAuthAccessResolution, az as AdminAuthClaimMapping, aA as AdminAuthMember, aB as AdminAuthProvider, aC as AdminAuthProviderMembersConfig, aD as AdminAuthProvisioningMode, aE as AdminAuthResolveAccessArgs, aF as AdminAuthResolvedIdentity, aG as AdminConfig, aH as AdminDashboardComponentSlots, aI as AdminIconName, aJ as AggregateArgs, aK as AggregateCastType, aL as AggregateCollectionResult, aM as AggregateInput, aN as AggregateOperation, aO as AggregateResult, aP as BaseAdminAuthProvider, aQ as BaseFieldAdmin, aR as BlockVariant, aS as BooleanFieldAdmin, aT as BooleanFormat, aU as CharacterLimitFieldAdmin, aV as CharacterLimitFieldConfig, aW as CollectionAfterChangeHook, aX as CollectionAfterDeleteHook, aY as CollectionAfterReadHook, aZ as CollectionAfterReadHookEntry, a_ as CollectionAfterTransitionHook, a$ as CollectionBeforeChangeHook, b0 as CollectionBeforeChangeHookEntry, b1 as CollectionBeforeDeleteHook, b2 as CollectionBeforeReadHook, b3 as CollectionBeforeReadHookEntry, b4 as CollectionBeforeTransitionHook, b5 as CollectionListComponentSlots, b6 as CollectionRAGConfig, b7 as CollectionSchemaResult, b8 as CollectionSummaryResult, b9 as CountOperation, ba as CustomAdminAuthProvider, bb as DateFieldAdmin, bc as DateFormat, bd as DefineActionOptions, be as DefineViewOptions, bf as DetailSpan, bg as DisplayTone, bh as DisplayVariant, bi as DistinctCountOperation, bj as DistinctValuesOperation, bk as DynamicOptionItem, bl as DynamicOptionsConfig, bm as DynamicOptionsResolver, bn as DynamicOptionsResolverArgs, bo as DyrectedLoggerConfig, bp as DyrectedObservabilityConfig, bq as EmailFieldAdmin, br as FieldAdminHooks, bs as FieldAdminOnChangeHook, bt as FieldAdminOnChangeHookArgs, bu as FieldAdminOptionsHook, bv as FieldAdminOptionsHookArgs, bw as FieldAdminOptionsHookResult, bx as FieldAfterReadHook, by as FieldAfterReadHookArgs, bz as FieldBase, bA as FieldBeforeChangeHook, bB as FieldBeforeChangeHookArgs, bC as FieldHook, bD as FieldHooks, bE as FieldType, bF as FileData, bG as GetDocumentResult, bH as GlobalAfterChangeHook, bI as GlobalAfterReadHook, bJ as GlobalAfterReadHookEntry, bK as GlobalBeforeChangeHook, bL as GlobalBeforeChangeHookEntry, bM as GlobalBeforeReadHook, bN as GlobalBeforeReadHookEntry, bO as GlobalRAGConfig, bP as GlobalSchemaResult, bQ as GlobalSummaryResult, bR as HeadingLevel, bS as HookFunction, bT as IconFieldAdmin, bU as ImageService, bV as InferAggregateResult, bW as JoinFieldAdmin, bX as JsonFieldAdmin, bY as JsonFormat, bZ as LIFECYCLE_EVENT_NAMES, b_ as LifecycleEventHandler, b$ as LinkFormat, c0 as MetricColor, c1 as MultiSelectFieldAdmin, c2 as NamedAccessPolicy, c3 as NumberFieldAdmin, c4 as NumberFormat, c5 as NumberLimitFieldAdmin, c6 as NumberLimitFieldConfig, c7 as NumericOperation, c8 as OIDCAdminAuthProvider, c9 as OptionFormat, ca as PaginatedResult, cb as PublicAdminAuthProvider, cc as QueryCollectionResult, cd as RadioFieldAdmin, ce as RateLimitConfig, cf as ReadonlyDatabaseAdapter, cg as RichTextFeature, ch as RichTextFieldConfig, ci as SelectFieldAdmin, cj as StorageAdapter, ck as TextFieldAdmin, cl as TextFormat, cm as TextareaFieldAdmin, cn as TrustProxyConfig, co as TypedField, cp as UploadConfig, cq as UrlFieldAdmin, cr as UrlLinkValue, cs as ViewActionFeatures, ct as ViewConfig, cu as ViewLayout, cv as ViewMetric, cw as ViewSubMetric, cx as WordLimitFieldAdmin, cy as WordLimitFieldConfig, cz as WorkflowMetadata, cA as WorkflowRole, cB as WorkflowState, cC as WorkflowTransitionContext, cD as defineAction, cE as defineView, cF as isAICollection } from './app-config-BgV9qpFu.cjs';
|
|
3
|
+
import jexl from 'jexl';
|
|
4
|
+
import { LanguageModel, EmbeddingModel } from 'ai';
|
|
5
|
+
export { z } from 'zod';
|
|
6
|
+
import 'lucide-react';
|
|
7
|
+
import 'pino';
|
|
8
|
+
|
|
9
|
+
type Prettify<T> = {
|
|
10
|
+
[K in keyof T]: T[K];
|
|
11
|
+
};
|
|
12
|
+
type FieldValueType<F extends Field> = F["type"] extends "text" | "textarea" | "email" | "url" | "icon" | "date" | "datetime" | "time" | "select" | "radio" ? string : F["type"] extends "number" ? number : F["type"] extends "boolean" ? boolean : F["type"] extends "multiSelect" ? string[] : F["type"] extends "relationship" ? F extends {
|
|
13
|
+
hasMany: true;
|
|
14
|
+
} ? string[] : string : F["type"] extends "image" ? F extends {
|
|
15
|
+
hasMany: true;
|
|
16
|
+
} ? string[] : string : F["type"] extends "richText" | "json" ? Record<string, unknown> : F["type"] extends "object" ? F extends {
|
|
17
|
+
fields: infer SF extends readonly Field[];
|
|
18
|
+
} ? Prettify<InferDocShape<SF>> : Record<string, unknown> : F["type"] extends "array" ? F extends {
|
|
19
|
+
fields: infer SF extends readonly Field[];
|
|
20
|
+
} ? Array<Prettify<InferDocShape<SF>>> : unknown[] : F["type"] extends "blocks" ? F extends {
|
|
21
|
+
blocks: infer B extends readonly Block[];
|
|
22
|
+
} ? Array<InferBlocksUnion<B>> : Array<{
|
|
23
|
+
blockType: string;
|
|
24
|
+
} & Record<string, unknown>> : unknown;
|
|
25
|
+
type InferBlocksUnion<Blocks extends readonly Block[]> = Blocks extends readonly [
|
|
26
|
+
infer B extends Block,
|
|
27
|
+
...infer Rest extends readonly Block[]
|
|
28
|
+
] ? B["fields"] extends readonly Field[] ? ({
|
|
29
|
+
blockType: B["slug"];
|
|
30
|
+
} & Prettify<InferDocShape<B["fields"]>>) | InferBlocksUnion<Rest> : ({
|
|
31
|
+
blockType: B["slug"];
|
|
32
|
+
} & Record<string, unknown>) | InferBlocksUnion<Rest> : never;
|
|
33
|
+
type InferFieldEntry<F extends Field> = F extends {
|
|
34
|
+
type: "row";
|
|
35
|
+
fields: infer SF extends readonly Field[];
|
|
36
|
+
} ? InferDocShape<SF> : F extends {
|
|
37
|
+
type: "join";
|
|
38
|
+
} ? Record<never, never> : F extends {
|
|
39
|
+
name: infer N extends string;
|
|
40
|
+
required: true;
|
|
41
|
+
} ? {
|
|
42
|
+
[K in N]: FieldValueType<F>;
|
|
43
|
+
} : F extends {
|
|
44
|
+
name: infer N extends string;
|
|
45
|
+
} ? {
|
|
46
|
+
[K in N]?: FieldValueType<F>;
|
|
47
|
+
} : Record<never, never>;
|
|
48
|
+
type InferDocShape<Fields extends readonly Field[]> = Fields extends readonly [] ? Record<never, never> : Fields extends readonly [infer Head extends Field, ...infer Tail extends readonly Field[]] ? InferFieldEntry<Head> & InferDocShape<Tail> : Record<string, unknown>;
|
|
49
|
+
type SystemDocFields = {
|
|
50
|
+
createdAt?: string;
|
|
51
|
+
updatedAt?: string;
|
|
52
|
+
createdBy?: string;
|
|
53
|
+
updatedBy?: string;
|
|
54
|
+
};
|
|
55
|
+
type AuthDocFields = {
|
|
56
|
+
email: string;
|
|
57
|
+
password?: string;
|
|
58
|
+
roles?: string[];
|
|
59
|
+
};
|
|
60
|
+
type UploadDocFields = {
|
|
61
|
+
filename: string;
|
|
62
|
+
filesize?: number;
|
|
63
|
+
mimeType: string;
|
|
64
|
+
url: string;
|
|
65
|
+
width?: number;
|
|
66
|
+
height?: number;
|
|
67
|
+
focalPoint?: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
};
|
|
71
|
+
blurhash?: string;
|
|
72
|
+
sizes?: Record<string, {
|
|
73
|
+
filename?: string;
|
|
74
|
+
url?: string;
|
|
75
|
+
width?: number;
|
|
76
|
+
height?: number;
|
|
77
|
+
}>;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
type AIErrorCode = 'AI_UNCONFIGURED' | 'AI_RATE_LIMITED' | 'AI_QUOTA_EXHAUSTED' | 'AI_TIMEOUT' | 'AI_TOOL_VALIDATION_ERROR' | 'AI_PERMISSION_DENIED' | 'AI_TENANT_VIOLATION' | 'AI_ACTION_EXPIRED' | 'AI_ACTION_ALREADY_EXECUTED' | 'AI_INTERNAL_ERROR';
|
|
81
|
+
declare class DyrectedAIError extends Error {
|
|
82
|
+
readonly code: AIErrorCode;
|
|
83
|
+
readonly status: number;
|
|
84
|
+
readonly details?: Record<string, unknown>;
|
|
85
|
+
constructor(code: AIErrorCode, message: string, status?: number, details?: Record<string, unknown>);
|
|
86
|
+
toJSON(): {
|
|
87
|
+
error: boolean;
|
|
88
|
+
code: AIErrorCode;
|
|
89
|
+
message: string;
|
|
90
|
+
status: number;
|
|
91
|
+
details: Record<string, unknown> | undefined;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Normalizes the Dyrected configuration by injecting system fields
|
|
97
|
+
* (createdAt, updatedAt, createdBy, updatedBy) into every collection and
|
|
98
|
+
* registering the __audit collection if any collection has audit: true.
|
|
99
|
+
*/
|
|
100
|
+
declare function normalizeConfig(config: DyrectedConfig): DyrectedConfig;
|
|
101
|
+
|
|
102
|
+
declare function getAdminAuthCollection(config: Pick<DyrectedConfig, "collections" | "adminAuth">): CollectionConfig | null;
|
|
103
|
+
declare function resolveAdminAuthCollection(collections: CollectionConfig[], collectionSlug?: string): CollectionConfig | undefined;
|
|
104
|
+
declare function getPublicAdminAuthConfig(adminAuth?: AdminAuthConfig, collections?: CollectionConfig[]): PublicAdminAuthConfig;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Dyrected Where Clause DSL — shared query language across all database adapters.
|
|
108
|
+
*
|
|
109
|
+
* Adapters translate this DSL into their native format:
|
|
110
|
+
* - SQL adapters (SQLite, Postgres, MySQL): use parseSqlWhere()
|
|
111
|
+
* - MongoDB adapter: use parseMongoWhere()
|
|
112
|
+
* - Future adapters: implement their own translator against WhereClause
|
|
113
|
+
*
|
|
114
|
+
* Exhaustive operator handling is enforced at compile time via `assertNever`,
|
|
115
|
+
* so adding a new operator without handling it will produce a TypeScript error
|
|
116
|
+
* in every adapter translator.
|
|
117
|
+
*/
|
|
118
|
+
type WhereOperatorName = 'equals' | 'not_equals' | 'in' | 'not_in' | 'gt' | 'greater_than' | 'gte' | 'greater_than_equal' | 'greater_than_or_equal' | 'lt' | 'less_than' | 'lte' | 'less_than_equal' | 'less_than_or_equal' | 'contains' | 'like' | 'starts_with' | 'exists';
|
|
119
|
+
type WhereOperator = {
|
|
120
|
+
equals: any;
|
|
121
|
+
} | {
|
|
122
|
+
not_equals: any;
|
|
123
|
+
} | {
|
|
124
|
+
in: any[];
|
|
125
|
+
} | {
|
|
126
|
+
not_in: any[];
|
|
127
|
+
} | {
|
|
128
|
+
gt: any;
|
|
129
|
+
} | {
|
|
130
|
+
greater_than: any;
|
|
131
|
+
} | {
|
|
132
|
+
gte: any;
|
|
133
|
+
} | {
|
|
134
|
+
greater_than_equal: any;
|
|
135
|
+
} | {
|
|
136
|
+
greater_than_or_equal: any;
|
|
137
|
+
} | {
|
|
138
|
+
lt: any;
|
|
139
|
+
} | {
|
|
140
|
+
less_than: any;
|
|
141
|
+
} | {
|
|
142
|
+
lte: any;
|
|
143
|
+
} | {
|
|
144
|
+
less_than_equal: any;
|
|
145
|
+
} | {
|
|
146
|
+
less_than_or_equal: any;
|
|
147
|
+
} | {
|
|
148
|
+
contains: string;
|
|
149
|
+
} | {
|
|
150
|
+
like: string;
|
|
151
|
+
} | {
|
|
152
|
+
starts_with: string;
|
|
153
|
+
} | {
|
|
154
|
+
exists: boolean;
|
|
155
|
+
};
|
|
156
|
+
/** Top-level where clause. Fields map to operator objects or shorthand scalar values. */
|
|
157
|
+
type WhereClause = {
|
|
158
|
+
[field: string]: WhereOperator | any;
|
|
159
|
+
OR?: WhereClause[];
|
|
160
|
+
AND?: WhereClause[];
|
|
161
|
+
};
|
|
162
|
+
interface SqlWhereResult {
|
|
163
|
+
sql: string;
|
|
164
|
+
params: any[];
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Translates a WhereClause into a parameterized SQL WHERE fragment.
|
|
168
|
+
*
|
|
169
|
+
* @param where The Dyrected where DSL object
|
|
170
|
+
* @param getJsonField Returns the SQL expression for a JSON-stored field (dialect-specific):
|
|
171
|
+
* SQLite: (f) => `json_extract(data, '$.${f}')`
|
|
172
|
+
* Postgres: (f) => `data->>'${f}'`
|
|
173
|
+
* MySQL: (f) => `JSON_UNQUOTE(JSON_EXTRACT(data, '$.${f}'))`
|
|
174
|
+
* @param placeholder '?' for SQLite/MySQL, 'pg' for auto-incrementing Postgres $1/$2/…
|
|
175
|
+
*/
|
|
176
|
+
declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg',
|
|
177
|
+
/**
|
|
178
|
+
* SQL keyword used for `contains`/`starts_with`. Postgres `LIKE` is
|
|
179
|
+
* case-sensitive, so the Postgres adapter defaults to `'ILIKE'` to keep substring
|
|
180
|
+
* matching case-insensitive like SQLite and MySQL.
|
|
181
|
+
*/
|
|
182
|
+
likeOperator?: 'LIKE' | 'ILIKE'): SqlWhereResult;
|
|
183
|
+
/**
|
|
184
|
+
* Translates a WhereClause into a MongoDB filter object.
|
|
185
|
+
* Handles nested OR/AND via $or/$and, and all operators via $eq/$in/$gt etc.
|
|
186
|
+
*/
|
|
187
|
+
declare function parseMongoWhere(where: WhereClause): Record<string, any>;
|
|
188
|
+
|
|
189
|
+
type SortDirection = 'ASC' | 'DESC';
|
|
190
|
+
interface SortClause {
|
|
191
|
+
field: string;
|
|
192
|
+
direction: SortDirection;
|
|
193
|
+
}
|
|
194
|
+
declare function parseSort(sort: string | undefined, fallback?: SortClause): SortClause[];
|
|
195
|
+
/**
|
|
196
|
+
* Collects the names of top-level fields declared as numbers. SQL adapters use
|
|
197
|
+
* this to decide which JSON-extracted sort fields need a numeric cast.
|
|
198
|
+
*/
|
|
199
|
+
declare function numericFieldNames(fields?: Field[]): Set<string>;
|
|
200
|
+
/**
|
|
201
|
+
* Dialect hooks for turning a parsed sort into a SQL `ORDER BY` body.
|
|
202
|
+
* Each SQL adapter supplies its own quoting, JSON extraction, and numeric cast.
|
|
203
|
+
*/
|
|
204
|
+
interface SqlSortDialect {
|
|
205
|
+
/** Quote a real column identifier (e.g. `"created_at"` or \`created_at\`). */
|
|
206
|
+
quoteIdent: (identifier: string) => string;
|
|
207
|
+
/** SQL expression that reads a top-level field out of the JSON `data` column. */
|
|
208
|
+
jsonExtract: (field: string) => string;
|
|
209
|
+
/**
|
|
210
|
+
* Wrap a JSON-extracted expression so it sorts numerically instead of
|
|
211
|
+
* lexicographically. Adapters whose JSON extraction already preserves number
|
|
212
|
+
* types (SQLite) can return the expression unchanged.
|
|
213
|
+
*/
|
|
214
|
+
castNumeric: (expr: string) => string;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Builds the `ORDER BY` body shared by the SQL adapters.
|
|
218
|
+
*
|
|
219
|
+
* Real (promoted) columns and the `created_at`/`updated_at` timestamps are
|
|
220
|
+
* ordered by their typed column directly. Everything else is read out of the
|
|
221
|
+
* JSON `data` column — and when a field is declared as a `number`, its extracted
|
|
222
|
+
* value is cast so it orders by magnitude rather than as text ("9" < "10").
|
|
223
|
+
*
|
|
224
|
+
* @param sort The raw sort string (e.g. `"-createdAt"`, `"priority,-views"`).
|
|
225
|
+
* @param existingColumns Real column names present on the table.
|
|
226
|
+
* @param numericFields Names of top-level fields declared with `type: 'number'`.
|
|
227
|
+
* @param dialect Adapter-specific quoting, extraction, and numeric cast.
|
|
228
|
+
*/
|
|
229
|
+
declare function buildSqlOrderBy(sort: string | undefined, existingColumns: string[], numericFields: Set<string>, dialect: SqlSortDialect): string;
|
|
230
|
+
|
|
231
|
+
type DeclarativeHookSurface = "collection.beforeRead" | "collection.afterRead" | "collection.beforeChange" | "global.beforeRead" | "global.afterRead" | "global.beforeChange" | "field.beforeChange" | "field.admin.onChange";
|
|
232
|
+
interface DeclarativeHookValidationIssue {
|
|
233
|
+
path: string;
|
|
234
|
+
surface: DeclarativeHookSurface | "unsupported";
|
|
235
|
+
expression: string;
|
|
236
|
+
message: string;
|
|
237
|
+
}
|
|
238
|
+
type DeclarativeAccessSurface = "config.accessPolicy" | "collection.access" | "global.access" | "field.access";
|
|
239
|
+
interface DeclarativeAccessValidationIssue {
|
|
240
|
+
path: string;
|
|
241
|
+
surface: DeclarativeAccessSurface;
|
|
242
|
+
expression: string;
|
|
243
|
+
message: string;
|
|
244
|
+
}
|
|
245
|
+
type DeclarativeAdminSurface = "field.admin.condition";
|
|
246
|
+
type DeclarativePreviewSurface = "collection.admin.previewUrl";
|
|
247
|
+
interface DeclarativeAdminValidationIssue {
|
|
248
|
+
path: string;
|
|
249
|
+
surface: DeclarativeAdminSurface;
|
|
250
|
+
expression: string;
|
|
251
|
+
message: string;
|
|
252
|
+
}
|
|
253
|
+
interface DeclarativePreviewValidationIssue {
|
|
254
|
+
path: string;
|
|
255
|
+
surface: DeclarativePreviewSurface;
|
|
256
|
+
expression: string;
|
|
257
|
+
message: string;
|
|
258
|
+
}
|
|
259
|
+
interface ConfigDiagnostic {
|
|
260
|
+
severity: "error" | "warning";
|
|
261
|
+
source: "declarativeHook" | "declarativeAccess" | "adminCondition" | "previewUrl";
|
|
262
|
+
path: string;
|
|
263
|
+
surface: string;
|
|
264
|
+
message: string;
|
|
265
|
+
expression: string;
|
|
266
|
+
}
|
|
267
|
+
type DiagnosticFormatOptions = {
|
|
268
|
+
color?: boolean;
|
|
269
|
+
};
|
|
270
|
+
type DeclarativeValidationConfig = {
|
|
271
|
+
blocks?: Array<Pick<Block, "fields"> & Partial<Pick<Block, "slug">>>;
|
|
272
|
+
collections: Array<Pick<CollectionConfig, "fields" | "hooks" | "access" | "admin"> & Partial<Pick<CollectionConfig, "slug">>>;
|
|
273
|
+
globals?: Array<Pick<GlobalConfig, "fields" | "hooks" | "access"> & Partial<Pick<GlobalConfig, "slug">>>;
|
|
274
|
+
accessPolicies?: Record<string, unknown>;
|
|
275
|
+
};
|
|
276
|
+
declare function validateDeclarativeHookExpression(expression: string, surface: DeclarativeHookSurface, path: string): DeclarativeHookValidationIssue[];
|
|
277
|
+
declare function validateDeclarativeAccessExpression(expression: string, surface: DeclarativeAccessSurface, path: string): DeclarativeAccessValidationIssue[];
|
|
278
|
+
declare function validateAdminConditionExpression(expression: string, path: string, allowedRoots: readonly string[]): DeclarativeAdminValidationIssue[];
|
|
279
|
+
declare function validatePreviewUrlExpression(expression: string, path: string, allowedRoots: readonly string[]): DeclarativePreviewValidationIssue[];
|
|
280
|
+
declare function assertValidDeclarativeHookExpression(expression: string, surface: DeclarativeHookSurface, path: string): void;
|
|
281
|
+
declare function assertValidDeclarativeHookResult(result: unknown, surface: "collection.beforeRead" | "collection.afterRead" | "collection.beforeChange" | "global.beforeRead" | "global.afterRead" | "global.beforeChange", path: string): void;
|
|
282
|
+
declare function collectDeclarativeHookValidationIssues(config: DeclarativeValidationConfig): DeclarativeHookValidationIssue[];
|
|
283
|
+
declare function collectDeclarativeAccessValidationIssues(config: DeclarativeValidationConfig): DeclarativeAccessValidationIssue[];
|
|
284
|
+
declare function collectAdminConditionValidationIssues(config: DeclarativeValidationConfig): DeclarativeAdminValidationIssue[];
|
|
285
|
+
declare function collectPreviewUrlValidationIssues(config: DeclarativeValidationConfig): DeclarativePreviewValidationIssue[];
|
|
286
|
+
declare function assertValidAdminConditionsInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
287
|
+
declare function assertValidPreviewUrlsInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
288
|
+
declare function collectConfigDiagnostics(config: DeclarativeValidationConfig): ConfigDiagnostic[];
|
|
289
|
+
declare function formatConfigDiagnostics(source: string, diagnostics: ConfigDiagnostic[], options?: DiagnosticFormatOptions): string;
|
|
290
|
+
declare class ConfigValidationError extends Error {
|
|
291
|
+
diagnostics: ConfigDiagnostic[];
|
|
292
|
+
source: string;
|
|
293
|
+
constructor(source: string, diagnostics: ConfigDiagnostic[]);
|
|
294
|
+
}
|
|
295
|
+
declare function isConfigValidationError(error: unknown): error is ConfigValidationError;
|
|
296
|
+
declare function assertValidDeclarativeHooksInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
297
|
+
declare function assertValidDeclarativeAccessInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Transforms a string into a clean, URL-safe slug.
|
|
301
|
+
* Strips accents, lowercases, removes non-alphanumeric characters, and hyphens whitespace.
|
|
302
|
+
*
|
|
303
|
+
* @example `slugify("Hello World!")` => `"hello-world"`
|
|
304
|
+
*/
|
|
305
|
+
declare function slugify(val: unknown): string;
|
|
306
|
+
/**
|
|
307
|
+
* Converts a string value to lowercase.
|
|
308
|
+
*
|
|
309
|
+
* @example `lower("Dyrected")` => `"dyrected"`
|
|
310
|
+
*/
|
|
311
|
+
declare function lower(val: unknown): string;
|
|
312
|
+
/**
|
|
313
|
+
* Converts a string value to uppercase.
|
|
314
|
+
*
|
|
315
|
+
* @example `upper("dyrected")` => `"DYRECTED"`
|
|
316
|
+
*/
|
|
317
|
+
declare function upper(val: unknown): string;
|
|
318
|
+
/**
|
|
319
|
+
* Trims leading and trailing whitespace from a string.
|
|
320
|
+
*
|
|
321
|
+
* @example `trim(" hello ")` => `"hello"`
|
|
322
|
+
*/
|
|
323
|
+
declare function trim(val: unknown): string;
|
|
324
|
+
/**
|
|
325
|
+
* Capitalizes the first letter of a string and lowercases the rest.
|
|
326
|
+
*
|
|
327
|
+
* @example `capitalize("hELLO")` => `"Hello"`
|
|
328
|
+
*/
|
|
329
|
+
declare function capitalize(val: unknown): string;
|
|
330
|
+
/**
|
|
331
|
+
* Truncates a string to a maximum length and appends an ellipsis.
|
|
332
|
+
*
|
|
333
|
+
* @example `truncate("Long article text...", 10)` => `"Long artic..."`
|
|
334
|
+
*/
|
|
335
|
+
declare function truncate(val: unknown, length: unknown, ellipsis?: string): string;
|
|
336
|
+
/**
|
|
337
|
+
* Calculates estimated reading time in minutes based on word count.
|
|
338
|
+
*
|
|
339
|
+
* @example `readingTime(articleText)` => `3`
|
|
340
|
+
*/
|
|
341
|
+
declare function readingTime(val: unknown, wpm?: number): number;
|
|
342
|
+
/**
|
|
343
|
+
* Returns the word count of a text string.
|
|
344
|
+
*
|
|
345
|
+
* @example `wordCount("Quick brown fox")` => `3`
|
|
346
|
+
*/
|
|
347
|
+
declare function wordCount(val: unknown): number;
|
|
348
|
+
/**
|
|
349
|
+
* Replaces occurrences of a substring or pattern with a replacement string.
|
|
350
|
+
*
|
|
351
|
+
* @example `replace("hello world", "world", "there")` => `"hello there"`
|
|
352
|
+
*/
|
|
353
|
+
declare function replace(val: unknown, search: unknown, replacement: unknown): string;
|
|
354
|
+
/**
|
|
355
|
+
* Checks if a string starts with a given prefix.
|
|
356
|
+
*
|
|
357
|
+
* @example `startsWith("dyrected.com", "dyrected")` => `true`
|
|
358
|
+
*/
|
|
359
|
+
declare function startsWith(str: unknown, prefix: unknown): boolean;
|
|
360
|
+
/**
|
|
361
|
+
* Checks if a string ends with a given suffix.
|
|
362
|
+
*
|
|
363
|
+
* @example `endsWith("image.png", ".png")` => `true`
|
|
364
|
+
*/
|
|
365
|
+
declare function endsWith(str: unknown, suffix: unknown): boolean;
|
|
366
|
+
/**
|
|
367
|
+
* Returns the current date and time as an ISO 8601 string.
|
|
368
|
+
*
|
|
369
|
+
* @example `now()` => `"2026-07-27T00:00:00.000Z"`
|
|
370
|
+
*/
|
|
371
|
+
declare function now(): string;
|
|
372
|
+
/**
|
|
373
|
+
* Returns the current date as a YYYY-MM-DD string.
|
|
374
|
+
*
|
|
375
|
+
* @example `today()` => `"2026-07-27"`
|
|
376
|
+
*/
|
|
377
|
+
declare function today(): string;
|
|
378
|
+
/**
|
|
379
|
+
* Formats a date string, number, or Date instance into a formatted string.
|
|
380
|
+
*
|
|
381
|
+
* @param style `'short'` (default), `'iso'`, `'date'`, `'datetime'`, or `'full'`
|
|
382
|
+
* @example `formatDate("2026-07-27T12:00:00Z", "short")` => `"Jul 27, 2026"`
|
|
383
|
+
*/
|
|
384
|
+
declare function formatDate(val: unknown, style?: unknown): string;
|
|
385
|
+
/**
|
|
386
|
+
* Adds or subtracts a specified number of days to a date.
|
|
387
|
+
*
|
|
388
|
+
* @example `addDays(now(), 7)` => `"2026-08-03T00:00:00.000Z"`
|
|
389
|
+
*/
|
|
390
|
+
declare function addDays(val: unknown, days: unknown): string;
|
|
391
|
+
/**
|
|
392
|
+
* Calculates the integer difference in days between two dates.
|
|
393
|
+
*
|
|
394
|
+
* @example `diffDays("2026-07-27", "2026-07-20")` => `7`
|
|
395
|
+
*/
|
|
396
|
+
declare function diffDays(dateA: unknown, dateB: unknown): number;
|
|
397
|
+
/**
|
|
398
|
+
* Checks if a date is in the past relative to the current timestamp.
|
|
399
|
+
*
|
|
400
|
+
* @example `isPast("2020-01-01")` => `true`
|
|
401
|
+
*/
|
|
402
|
+
declare function isPast(val: unknown): boolean;
|
|
403
|
+
/**
|
|
404
|
+
* Checks if a date is in the future relative to the current timestamp.
|
|
405
|
+
*
|
|
406
|
+
* @example `isFuture("2030-01-01")` => `true`
|
|
407
|
+
*/
|
|
408
|
+
declare function isFuture(val: unknown): boolean;
|
|
409
|
+
/**
|
|
410
|
+
* Checks if an item exists within an array or if a substring exists within a string.
|
|
411
|
+
*
|
|
412
|
+
* @example `includes(["admin", "editor"], "admin")` => `true`
|
|
413
|
+
*/
|
|
414
|
+
declare function includes(arrOrStr: unknown, item: unknown): boolean;
|
|
415
|
+
/**
|
|
416
|
+
* Joins array elements into a string separated by a delimiter.
|
|
417
|
+
*
|
|
418
|
+
* @example `join(["Apple", "Banana"], ", ")` => `"Apple, Banana"`
|
|
419
|
+
*/
|
|
420
|
+
declare function join(arr: unknown, separator?: string): string;
|
|
421
|
+
/**
|
|
422
|
+
* Returns the first item in an array.
|
|
423
|
+
*
|
|
424
|
+
* @example `first(["a", "b", "c"])` => `"a"`
|
|
425
|
+
*/
|
|
426
|
+
declare function first(arr: unknown): unknown;
|
|
427
|
+
/**
|
|
428
|
+
* Returns the last item in an array.
|
|
429
|
+
*
|
|
430
|
+
* @example `last(["a", "b", "c"])` => `"c"`
|
|
431
|
+
*/
|
|
432
|
+
declare function last(arr: unknown): unknown;
|
|
433
|
+
/**
|
|
434
|
+
* Removes null, undefined, and empty string elements from an array.
|
|
435
|
+
*
|
|
436
|
+
* @example `compact(["a", null, "b", ""])` => `["a", "b"]`
|
|
437
|
+
*/
|
|
438
|
+
declare function compact(arr: unknown): unknown[];
|
|
439
|
+
/**
|
|
440
|
+
* Removes duplicate items from an array.
|
|
441
|
+
*
|
|
442
|
+
* @example `unique(["a", "b", "a"])` => `["a", "b"]`
|
|
443
|
+
*/
|
|
444
|
+
declare function unique(arr: unknown): unknown[];
|
|
445
|
+
/**
|
|
446
|
+
* Returns the length of an array, string, or object.
|
|
447
|
+
*
|
|
448
|
+
* @example `length("hello")` => `5`
|
|
449
|
+
*/
|
|
450
|
+
declare function length(val: unknown): number;
|
|
451
|
+
/**
|
|
452
|
+
* Rounds a number to a specified number of decimal places.
|
|
453
|
+
*
|
|
454
|
+
* @example `round(3.14159, 2)` => `3.14`
|
|
455
|
+
*/
|
|
456
|
+
declare function round(val: unknown, decimals?: number): number;
|
|
457
|
+
/**
|
|
458
|
+
* Clamps a number between a minimum and maximum threshold.
|
|
459
|
+
*
|
|
460
|
+
* @example `clamp(150, 0, 100)` => `100`
|
|
461
|
+
*/
|
|
462
|
+
declare function clamp(val: unknown, minVal: unknown, maxVal: unknown): number;
|
|
463
|
+
declare function ceil(val: unknown): number;
|
|
464
|
+
declare function floor(val: unknown): number;
|
|
465
|
+
declare function abs(val: unknown): number;
|
|
466
|
+
declare function min(...args: unknown[]): number;
|
|
467
|
+
declare function max(...args: unknown[]): number;
|
|
468
|
+
declare function pow(base: unknown, exp: unknown): number;
|
|
469
|
+
declare function sqrt(val: unknown): number;
|
|
470
|
+
declare function sum(arr: unknown): number;
|
|
471
|
+
declare function count(val: unknown): number;
|
|
472
|
+
/**
|
|
473
|
+
* Returns a fallback value if the target value is undefined, null, or an empty string.
|
|
474
|
+
*
|
|
475
|
+
* @example `default(siblingData.title, "Untitled")` => `"Untitled"`
|
|
476
|
+
*/
|
|
477
|
+
declare function defaultValue(val: unknown, fallback: unknown): unknown;
|
|
478
|
+
/**
|
|
479
|
+
* Returns the first non-empty value among the arguments provided.
|
|
480
|
+
*
|
|
481
|
+
* @example `coalesce(null, "", "Fallback")` => `"Fallback"`
|
|
482
|
+
*/
|
|
483
|
+
declare function coalesce(...args: unknown[]): unknown;
|
|
484
|
+
/**
|
|
485
|
+
* Checks if a value is empty (undefined, null, empty string, empty array, or empty object).
|
|
486
|
+
*
|
|
487
|
+
* @example `isEmpty([])` => `true`
|
|
488
|
+
*/
|
|
489
|
+
declare function isEmpty(val: unknown): boolean;
|
|
490
|
+
/**
|
|
491
|
+
* Safely accesses a nested object property by a dot-separated key path.
|
|
492
|
+
*
|
|
493
|
+
* @example `get(siblingData, "author.name", "Guest")` => `"John"`
|
|
494
|
+
*/
|
|
495
|
+
declare function get(obj: unknown, path: unknown, fallback?: unknown): unknown;
|
|
496
|
+
/**
|
|
497
|
+
* Registers all Dyrected built-in helper functions onto a Jexl evaluation instance.
|
|
498
|
+
*/
|
|
499
|
+
declare function registerJexlHelpers(jexlInstance?: typeof jexl): void;
|
|
500
|
+
/**
|
|
501
|
+
* Standard shared evaluator for JEXL expressions across server and browser.
|
|
502
|
+
* Injects math namespace and standard helpers into the context.
|
|
503
|
+
*/
|
|
504
|
+
declare function evaluateJexl(expression: string, context?: Record<string, any>): Promise<any>;
|
|
505
|
+
/**
|
|
506
|
+
* Synchronous standard shared evaluator for JEXL expressions.
|
|
507
|
+
* Injects math namespace and standard helpers into the context.
|
|
508
|
+
*/
|
|
509
|
+
declare function evaluateJexlSync(expression: string, context?: Record<string, any>): any;
|
|
510
|
+
/** List of all built-in Jexl helper function names for AST validation. */
|
|
511
|
+
declare const BUILTIN_JEXL_HELPERS: readonly ["slugify", "lower", "upper", "trim", "capitalize", "truncate", "readingTime", "wordCount", "replace", "startsWith", "endsWith", "now", "today", "formatDate", "addDays", "diffDays", "isPast", "isFuture", "includes", "join", "first", "last", "compact", "unique", "length", "round", "clamp", "default", "coalesce", "isEmpty", "get"];
|
|
512
|
+
|
|
513
|
+
type AnyHookFn = (args: any) => any;
|
|
514
|
+
type AnyHook = AnyHookFn | DeclarativeHookExpression;
|
|
515
|
+
/**
|
|
516
|
+
* Run a list of hook functions sequentially.
|
|
517
|
+
*
|
|
518
|
+
* Each hook receives the output of the previous hook merged back into the
|
|
519
|
+
* original `args`. When a hook returns a non-undefined value it becomes the
|
|
520
|
+
* `data` / `doc` for the next hook in the chain.
|
|
521
|
+
*
|
|
522
|
+
* Pass `{ isolated: true }` for hooks that run **after** a DB write has already
|
|
523
|
+
* been committed (`afterChange`, `afterDelete`). In isolated mode each hook is
|
|
524
|
+
* wrapped in a try/catch so a failing side-effect (email, webhook, etc.) never
|
|
525
|
+
* surfaces as an HTTP 500 to the caller — the write already succeeded.
|
|
526
|
+
*/
|
|
527
|
+
declare function runCollectionHooks(hooks: AnyHook[] | undefined, args: {
|
|
528
|
+
data?: unknown;
|
|
529
|
+
doc?: unknown;
|
|
530
|
+
query?: unknown;
|
|
531
|
+
user?: unknown;
|
|
532
|
+
req?: unknown;
|
|
533
|
+
db?: unknown;
|
|
534
|
+
operation?: "create" | "update" | "delete";
|
|
535
|
+
[key: string]: unknown;
|
|
536
|
+
}, options?: {
|
|
537
|
+
isolated?: boolean;
|
|
538
|
+
surface?: "collection.beforeRead" | "collection.afterRead" | "collection.beforeChange" | "global.beforeRead" | "global.afterRead" | "global.beforeChange";
|
|
539
|
+
path?: string;
|
|
540
|
+
}): Promise<any>;
|
|
541
|
+
/**
|
|
542
|
+
* Execute field-level `beforeChange` hooks recursively on a data payload.
|
|
543
|
+
*
|
|
544
|
+
* Traverses `array`, `object`, and `blocks` fields depth-first so that nested
|
|
545
|
+
* field hooks fire on every item automatically.
|
|
546
|
+
*/
|
|
547
|
+
declare function executeFieldBeforeChange(fields: Field[], data: Record<string, unknown>, originalDoc: Record<string, unknown> | null, user: unknown, db?: unknown, pathPrefix?: string): Promise<Record<string, unknown>>;
|
|
548
|
+
/**
|
|
549
|
+
* Execute field-level `afterRead` hooks recursively on a document.
|
|
550
|
+
*
|
|
551
|
+
* Traverses `array`, `object`, and `blocks` fields depth-first so that nested
|
|
552
|
+
* field hooks fire on every item automatically.
|
|
553
|
+
*/
|
|
554
|
+
declare function executeFieldAfterRead(fields: Field[], doc: Record<string, unknown>, user: unknown, db?: unknown): Promise<Record<string, unknown>>;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Generate an OpenAPI 3.0 specification based on the Dyrected configuration.
|
|
558
|
+
*/
|
|
559
|
+
declare function generateOpenApi(config: DyrectedConfig): any;
|
|
560
|
+
|
|
561
|
+
declare const WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
562
|
+
declare const LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
563
|
+
/**
|
|
564
|
+
* Role mapping for {@link definePublishingWorkflow}. Map your app's own role
|
|
565
|
+
* values onto the publishing workflow's two capability tiers.
|
|
566
|
+
*/
|
|
567
|
+
interface PublishingWorkflowOptions {
|
|
568
|
+
/** Role values allowed to edit and submit for review. Defaults to `["editor"]`. */
|
|
569
|
+
editors?: string[];
|
|
570
|
+
/** Role values allowed to also publish and unpublish. Defaults to `["publisher", "admin"]`. */
|
|
571
|
+
publishers?: string[];
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Build a `draft → in review → published` editorial workflow, mapping your own
|
|
575
|
+
* role values onto its capability tiers. Reach for this instead of
|
|
576
|
+
* {@link publishingWorkflow} when your roles aren't named
|
|
577
|
+
* `editor`/`publisher`/`admin`.
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* workflow: definePublishingWorkflow({
|
|
581
|
+
* editors: ["writer"],
|
|
582
|
+
* publishers: ["managing-editor", "admin"],
|
|
583
|
+
* })
|
|
584
|
+
*/
|
|
585
|
+
declare function definePublishingWorkflow(options?: PublishingWorkflowOptions): WorkflowConfig;
|
|
586
|
+
/**
|
|
587
|
+
* The default `draft → in review → published` editorial workflow, using the
|
|
588
|
+
* conventional role names `editor`, `publisher`, and `admin`. Shorthand for
|
|
589
|
+
* `definePublishingWorkflow()` — use {@link definePublishingWorkflow} to map
|
|
590
|
+
* your own role names onto its capability tiers.
|
|
591
|
+
*/
|
|
592
|
+
declare function publishingWorkflow(): WorkflowConfig;
|
|
593
|
+
declare function simplePublishingWorkflow(): WorkflowConfig;
|
|
594
|
+
declare function workflowCapabilities(workflow: WorkflowConfig, user?: AuthenticatedUser): Set<string>;
|
|
595
|
+
declare function canViewWorkflowDraft(workflow: WorkflowConfig, user?: AuthenticatedUser): boolean;
|
|
596
|
+
declare function availableWorkflowTransitions(workflow: WorkflowConfig, state: string, user?: AuthenticatedUser): WorkflowTransition[];
|
|
597
|
+
declare function initializeWorkflowDocument(data: Record<string, unknown>, workflow: WorkflowConfig): {
|
|
598
|
+
__workflow: {
|
|
599
|
+
state: string;
|
|
600
|
+
revision: number;
|
|
601
|
+
};
|
|
602
|
+
};
|
|
603
|
+
/** The state a legacy document is treated as: the published one, else the last. */
|
|
604
|
+
declare function publishedStateName(workflow: WorkflowConfig): string;
|
|
605
|
+
declare function materializeWorkflowDocument(doc: BaseDocument, workflow: WorkflowConfig, user?: AuthenticatedUser): BaseDocument | null;
|
|
606
|
+
declare function createLifecycleEvent(args: {
|
|
607
|
+
name: LifecycleEventName;
|
|
608
|
+
collection: string;
|
|
609
|
+
documentId: string;
|
|
610
|
+
actorId?: string;
|
|
611
|
+
payload: Record<string, unknown>;
|
|
612
|
+
}): LifecycleEvent;
|
|
613
|
+
declare function dispatchLifecycleEvent(config: DyrectedConfig, event: LifecycleEvent): Promise<void>;
|
|
614
|
+
declare function dispatchPendingLifecycleEvents(config: DyrectedConfig, limit?: number): Promise<number>;
|
|
615
|
+
declare function saveWorkflowDraft(args: {
|
|
616
|
+
config: DyrectedConfig;
|
|
617
|
+
collection: CollectionConfig;
|
|
618
|
+
id: string;
|
|
619
|
+
originalDoc: BaseDocument;
|
|
620
|
+
data: Record<string, unknown>;
|
|
621
|
+
user?: AuthenticatedUser;
|
|
622
|
+
}): Promise<{
|
|
623
|
+
doc: BaseDocument;
|
|
624
|
+
event: LifecycleEvent;
|
|
625
|
+
}>;
|
|
626
|
+
declare function createWorkflowDocument(args: {
|
|
627
|
+
config: DyrectedConfig;
|
|
628
|
+
collection: CollectionConfig;
|
|
629
|
+
data: Record<string, unknown>;
|
|
630
|
+
user?: AuthenticatedUser;
|
|
631
|
+
}): Promise<{
|
|
632
|
+
doc: BaseDocument;
|
|
633
|
+
event: LifecycleEvent;
|
|
634
|
+
}>;
|
|
635
|
+
declare function transitionWorkflow(args: {
|
|
636
|
+
config: DyrectedConfig;
|
|
637
|
+
collection: CollectionConfig;
|
|
638
|
+
id: string;
|
|
639
|
+
transitionName: string;
|
|
640
|
+
expectedRevision?: number;
|
|
641
|
+
comment?: string;
|
|
642
|
+
user?: AuthenticatedUser;
|
|
643
|
+
req: HookRequestContext;
|
|
644
|
+
}): Promise<BaseDocument>;
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Normalizes a DetailItem (which may be a shorthand string) into a standard DetailItem object.
|
|
648
|
+
*
|
|
649
|
+
* @example `normalizeDetailItem('title')` => `{ type: 'field', field: 'title' }`
|
|
650
|
+
*/
|
|
651
|
+
declare function normalizeDetailItem(item: DetailItem): Exclude<DetailItem, string>;
|
|
652
|
+
/**
|
|
653
|
+
* Creates a section container in a Detail View layout.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```ts
|
|
657
|
+
* displaySection('Product Information', [
|
|
658
|
+
* displayField('name', { span: 8 }),
|
|
659
|
+
* displayField('sku', { span: 4 }),
|
|
660
|
+
* ], { span: 8, icon: 'package' })
|
|
661
|
+
* ```
|
|
662
|
+
*/
|
|
663
|
+
declare function displaySection(title: string, items: DetailItem[], options?: DetailSectionOptions): DetailSection;
|
|
664
|
+
/**
|
|
665
|
+
* Creates a single tab entry for use within `displayTabs()`.
|
|
666
|
+
*/
|
|
667
|
+
declare function displayTab(label: string, items: DetailItem[], options?: DetailTabOptions): DetailTab;
|
|
668
|
+
/**
|
|
669
|
+
* Creates a tabbed container in a Detail View layout.
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* displayTabs([
|
|
674
|
+
* displayTab('Specifications', [displayField('specs')]),
|
|
675
|
+
* displayTab('Reviews', [displayRepeat('reviews', [...])], { badge: '3' }),
|
|
676
|
+
* ])
|
|
677
|
+
* ```
|
|
678
|
+
*/
|
|
679
|
+
declare function displayTabs(tabs: DetailTab[], options?: DetailTabsOptions): DetailTabs;
|
|
680
|
+
/**
|
|
681
|
+
* Creates a multi-column grid layout inside a section or detail schema.
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```ts
|
|
685
|
+
* displayGrid(2, [
|
|
686
|
+
* displayField('firstName'),
|
|
687
|
+
* displayField('lastName'),
|
|
688
|
+
* ])
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
declare function displayGrid(columns: number, items: DetailItem[], options?: DetailGridOptions): DetailGrid;
|
|
692
|
+
/**
|
|
693
|
+
* Declares a field for presentation in a Detail View.
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* ```ts
|
|
697
|
+
* displayField('status', { display: 'badge', badgeColors: { active: 'emerald' } })
|
|
698
|
+
* displayField('author.name', { label: 'Written By' })
|
|
699
|
+
* displayField('specs', { display: 'key-value', keyLabel: 'Spec', valueLabel: 'Detail' })
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
declare function displayField(fieldName: string, options?: DisplayFieldOptions): DetailField;
|
|
703
|
+
/**
|
|
704
|
+
* Renders an array/repeated field using a delegated display schema.
|
|
705
|
+
* Supports `'table'`, `'cards'`, and `'list'` layouts.
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```ts
|
|
709
|
+
* displayRepeat('items', [
|
|
710
|
+
* displayField('product'),
|
|
711
|
+
* displayField('quantity'),
|
|
712
|
+
* displayField('price'),
|
|
713
|
+
* ], { layout: 'table' })
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
declare function displayRepeat(fieldName: string, items: DetailItem[], options?: DetailRepeatOptions): DetailRepeat;
|
|
717
|
+
/**
|
|
718
|
+
* Renders a computed value calculated from document and user context.
|
|
719
|
+
*
|
|
720
|
+
* @example
|
|
721
|
+
* ```ts
|
|
722
|
+
* displayComputed('Reading Time', 'math.ceil(doc.wordCount / 200) + " min"')
|
|
723
|
+
* displayComputed('Total', ({ doc }) => `$${doc.price * doc.quantity}`)
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
declare function displayComputed<TDoc = any>(label: string, expressionOrOptionsOrHandler: string | DetailComputedOptions<TDoc> | ComputedHandler<TDoc>, options?: DetailComputedOptions<TDoc>): DetailComputed<TDoc>;
|
|
727
|
+
/**
|
|
728
|
+
* Creates a horizontal divider line in a Detail View layout.
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```ts
|
|
732
|
+
* displayDivider({ spacing: 'md' })
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
declare function displayDivider(options?: DetailDividerOptions): DetailDivider;
|
|
736
|
+
/**
|
|
737
|
+
* Renders static text, heading, callout, or information notice in a Detail View layout.
|
|
738
|
+
*
|
|
739
|
+
* @example
|
|
740
|
+
* ```ts
|
|
741
|
+
* displayText('Please note this action is permanent.', { variant: 'warning' })
|
|
742
|
+
* displayText('Overview Notes', { variant: 'heading' })
|
|
743
|
+
* ```
|
|
744
|
+
*/
|
|
745
|
+
declare function displayText(content: string, options?: DetailTextOptions): DetailText;
|
|
746
|
+
/**
|
|
747
|
+
* Renders a custom React component registered by name in the Admin panel.
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* ```ts
|
|
751
|
+
* displayCustom('AnalyticsChart', { props: { timeframe: '30d' } })
|
|
752
|
+
* ```
|
|
753
|
+
*/
|
|
754
|
+
declare function displayCustom<TDoc = any>(name: string, options?: DetailCustomOptions<TDoc>): DetailCustom<TDoc>;
|
|
755
|
+
/**
|
|
756
|
+
* Alias for `displayCustom` to render a custom component in a Detail View layout.
|
|
757
|
+
*/
|
|
758
|
+
declare function displayCustomComponent<TDoc = any>(name: string, options?: DetailCustomOptions<TDoc>): DetailCustom<TDoc>;
|
|
759
|
+
/**
|
|
760
|
+
* Evaluates server-side computed functions and JEXL expressions from a detail schema
|
|
761
|
+
* and attaches them to `doc._meta.computed`.
|
|
762
|
+
*/
|
|
763
|
+
declare function evaluateDetailComputed(detail: DetailSchema | boolean | undefined, doc: any, user: any, db: any): Promise<any>;
|
|
764
|
+
/**
|
|
765
|
+
* Generates an automatic default 12-column Detail View schema for a collection or global
|
|
766
|
+
* when no explicit `detail` configuration is provided.
|
|
767
|
+
*/
|
|
768
|
+
declare function generateDefaultDetailSchema(schema: {
|
|
769
|
+
fields?: Field[];
|
|
770
|
+
labels?: {
|
|
771
|
+
singular?: string;
|
|
772
|
+
plural?: string;
|
|
773
|
+
};
|
|
774
|
+
label?: string;
|
|
775
|
+
slug?: string;
|
|
776
|
+
}): DetailSchema;
|
|
777
|
+
/**
|
|
778
|
+
* Evaluates whether a detail item should be visible based on its `options.visible` rule.
|
|
779
|
+
* Supports boolean values or JEXL expressions evaluated against `{ doc, user }`.
|
|
780
|
+
* Works consistently for top-level and nested detail items.
|
|
781
|
+
*
|
|
782
|
+
* @example
|
|
783
|
+
* ```ts
|
|
784
|
+
* isDetailItemVisible(displayField('secret', { visible: false }), doc, user) // false
|
|
785
|
+
* isDetailItemVisible(displayField('publishedAt', { visible: "doc.status == 'published'" }), doc, user)
|
|
786
|
+
* ```
|
|
787
|
+
*/
|
|
788
|
+
declare function isDetailItemVisible(item: DetailItem, doc: any, user?: any): boolean;
|
|
789
|
+
|
|
790
|
+
declare function getAIModel(config?: DyrectedConfig): LanguageModel;
|
|
791
|
+
declare function formatAIErrorMessage(error: any): string;
|
|
792
|
+
declare function buildDyrectedSystemPrompt(context: DyrectedAIContext): string;
|
|
793
|
+
interface AIAgentOptions {
|
|
794
|
+
db: DatabaseAdapter;
|
|
795
|
+
config: DyrectedConfig;
|
|
796
|
+
projectId: string;
|
|
797
|
+
userId: string;
|
|
798
|
+
userName?: string;
|
|
799
|
+
userRole?: string;
|
|
800
|
+
user?: AuthenticatedUser;
|
|
801
|
+
}
|
|
802
|
+
declare class AIAgent {
|
|
803
|
+
private db;
|
|
804
|
+
private config;
|
|
805
|
+
private projectId;
|
|
806
|
+
private userId;
|
|
807
|
+
private userName?;
|
|
808
|
+
private userRole?;
|
|
809
|
+
private user?;
|
|
810
|
+
private contextCache;
|
|
811
|
+
constructor(options: AIAgentOptions);
|
|
812
|
+
getContext(): Promise<DyrectedAIContext>;
|
|
813
|
+
getThread(threadId: string): Promise<AIThread | null>;
|
|
814
|
+
updateThreadTitle(threadId: string, title: string): Promise<void>;
|
|
815
|
+
createThread(title?: string): Promise<AIThread>;
|
|
816
|
+
listThreads(limit?: number): Promise<AIThread[]>;
|
|
817
|
+
deleteThread(threadId: string): Promise<boolean>;
|
|
818
|
+
clearAllThreads(): Promise<number>;
|
|
819
|
+
getMessages(threadId: string): Promise<AIMessage[]>;
|
|
820
|
+
persistUserMessage(threadId: string, content: string): Promise<AIMessage>;
|
|
821
|
+
persistAssistantMessage(threadId: string, content: string, metadata?: Record<string, unknown>, parts?: any[]): Promise<AIMessage>;
|
|
822
|
+
generateTitle(userMessage: string): Promise<string>;
|
|
823
|
+
streamReply(threadId: string, userMessage: string): AsyncGenerator<string, {
|
|
824
|
+
text: string;
|
|
825
|
+
usage?: any;
|
|
826
|
+
finishReason: string;
|
|
827
|
+
}, void>;
|
|
828
|
+
createStreamResponse(threadId: string, userMessage: string, clientMessages?: any[], abortSignal?: AbortSignal, requestId?: string): Promise<Response>;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
declare function createDyrectedAITools({ db, config, user, projectId, }: {
|
|
832
|
+
db: DatabaseAdapter;
|
|
833
|
+
config: DyrectedConfig;
|
|
834
|
+
user?: AuthenticatedUser;
|
|
835
|
+
projectId: string;
|
|
836
|
+
}): Record<string, any>;
|
|
837
|
+
|
|
838
|
+
interface IndexDocumentOptions {
|
|
839
|
+
db: DatabaseAdapter;
|
|
840
|
+
config: DyrectedConfig;
|
|
841
|
+
collection: string;
|
|
842
|
+
doc: Record<string, unknown>;
|
|
843
|
+
projectId: string;
|
|
844
|
+
force?: boolean;
|
|
845
|
+
}
|
|
846
|
+
interface DeleteDocumentChunksOptions {
|
|
847
|
+
db: DatabaseAdapter;
|
|
848
|
+
collection: string;
|
|
849
|
+
documentId: string;
|
|
850
|
+
projectId: string;
|
|
851
|
+
}
|
|
852
|
+
interface ReindexCollectionOptions {
|
|
853
|
+
db: DatabaseAdapter;
|
|
854
|
+
config: DyrectedConfig;
|
|
855
|
+
collection: string;
|
|
856
|
+
projectId: string;
|
|
857
|
+
force?: boolean;
|
|
858
|
+
}
|
|
859
|
+
interface ReindexAllOptions {
|
|
860
|
+
db: DatabaseAdapter;
|
|
861
|
+
config: DyrectedConfig;
|
|
862
|
+
projectId: string;
|
|
863
|
+
force?: boolean;
|
|
864
|
+
}
|
|
865
|
+
interface RAGSearchOptions {
|
|
866
|
+
db: DatabaseAdapter;
|
|
867
|
+
config: DyrectedConfig;
|
|
868
|
+
query: string;
|
|
869
|
+
projectId: string;
|
|
870
|
+
collections?: string[];
|
|
871
|
+
limit?: number;
|
|
872
|
+
minScore?: number;
|
|
873
|
+
user?: AuthenticatedUser;
|
|
874
|
+
}
|
|
875
|
+
declare class RAGService {
|
|
876
|
+
private static embeddingServiceCache;
|
|
877
|
+
private static getEmbeddingService;
|
|
878
|
+
/**
|
|
879
|
+
* Determines whether RAG indexing is enabled for a given collection.
|
|
880
|
+
*/
|
|
881
|
+
static isCollectionRAGEnabled(config: DyrectedConfig, col: CollectionConfig): boolean;
|
|
882
|
+
/**
|
|
883
|
+
* Indexes a single document's text fields into `_dyrected_ai_chunks`.
|
|
884
|
+
*/
|
|
885
|
+
static indexDocument(options: IndexDocumentOptions): Promise<{
|
|
886
|
+
indexed: number;
|
|
887
|
+
skipped: number;
|
|
888
|
+
}>;
|
|
889
|
+
/**
|
|
890
|
+
* Deletes all vector chunks associated with a specific document.
|
|
891
|
+
*/
|
|
892
|
+
static deleteDocumentChunks(options: DeleteDocumentChunksOptions): Promise<number>;
|
|
893
|
+
/**
|
|
894
|
+
* Reindexes all documents in a specific collection.
|
|
895
|
+
*/
|
|
896
|
+
static reindexCollection(options: ReindexCollectionOptions): Promise<{
|
|
897
|
+
collection: string;
|
|
898
|
+
totalDocs: number;
|
|
899
|
+
indexedChunks: number;
|
|
900
|
+
}>;
|
|
901
|
+
/**
|
|
902
|
+
* Reindexes all RAG-enabled collections across the project.
|
|
903
|
+
*/
|
|
904
|
+
static reindexAll(options: ReindexAllOptions): Promise<{
|
|
905
|
+
collections: Array<{
|
|
906
|
+
collection: string;
|
|
907
|
+
totalDocs: number;
|
|
908
|
+
indexedChunks: number;
|
|
909
|
+
}>;
|
|
910
|
+
totalChunks: number;
|
|
911
|
+
}>;
|
|
912
|
+
/**
|
|
913
|
+
* Performs semantic vector search over project chunks with access filtering.
|
|
914
|
+
*/
|
|
915
|
+
static search(options: RAGSearchOptions): Promise<{
|
|
916
|
+
query: string;
|
|
917
|
+
resultsCount: number;
|
|
918
|
+
sources: RAGSearchResult[];
|
|
919
|
+
}>;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Content normalizer for Dyrected CMS fields before chunking and embedding.
|
|
924
|
+
* Converts raw rich-text ASTs (Lexical, Slate, TipTap, custom blocks), HTML,
|
|
925
|
+
* JSON objects, and arrays into clean, structured Markdown.
|
|
926
|
+
*/
|
|
927
|
+
/**
|
|
928
|
+
* Normalizes an unknown field value into clean Markdown/text.
|
|
929
|
+
*/
|
|
930
|
+
declare function normalizeFieldValue(value: unknown, _fieldType?: string): string;
|
|
931
|
+
/**
|
|
932
|
+
* Extracts searchable text from target fields of a document.
|
|
933
|
+
*/
|
|
934
|
+
declare function extractTextFromDoc(doc: Record<string, unknown>, targetFields?: string[]): Array<{
|
|
935
|
+
field: string;
|
|
936
|
+
text: string;
|
|
937
|
+
}>;
|
|
938
|
+
|
|
939
|
+
interface ChunkOptions {
|
|
940
|
+
/** Maximum target characters per chunk. Defaults to 1500 (~375-500 tokens). */
|
|
941
|
+
maxChunkSize?: number;
|
|
942
|
+
/** Overlap in characters between consecutive chunks. Defaults to 150. */
|
|
943
|
+
chunkOverlap?: number;
|
|
944
|
+
/** Hierarchy of string separators for recursive splitting. */
|
|
945
|
+
separators?: string[];
|
|
946
|
+
}
|
|
947
|
+
interface ChunkResult {
|
|
948
|
+
text: string;
|
|
949
|
+
tokenCount: number;
|
|
950
|
+
index: number;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Computes a fast, collision-resistant 53-bit hex hash of a string.
|
|
954
|
+
* 100% isomorphic and pure JavaScript (safe across Node.js, Vite, Nuxt, and browsers).
|
|
955
|
+
*/
|
|
956
|
+
declare function hashContent(content: string, seed?: number): string;
|
|
957
|
+
/**
|
|
958
|
+
* Estimates token count based on standard ~4 characters per token heuristic.
|
|
959
|
+
*/
|
|
960
|
+
declare function estimateTokens(text: string): number;
|
|
961
|
+
/**
|
|
962
|
+
* Recursively splits a text into coherent chunks with overlap.
|
|
963
|
+
*/
|
|
964
|
+
declare function chunkText(text: string, options?: ChunkOptions): ChunkResult[];
|
|
965
|
+
|
|
966
|
+
declare function getEmbeddingModel(config?: DyrectedConfig): EmbeddingModel;
|
|
967
|
+
declare class EmbeddingService {
|
|
968
|
+
private config?;
|
|
969
|
+
private model;
|
|
970
|
+
constructor(config?: DyrectedConfig);
|
|
971
|
+
embedText(text: string): Promise<number[]>;
|
|
972
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Computes cosine similarity between two float vector arrays.
|
|
976
|
+
* Returns a value between -1.0 and 1.0 (typically 0.0 to 1.0 for normalized text embeddings).
|
|
977
|
+
*/
|
|
978
|
+
declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
979
|
+
|
|
980
|
+
type TopLevelFieldName<TFields extends readonly Field[]> = Extract<TFields[number], {
|
|
981
|
+
name: string;
|
|
982
|
+
}>["name"];
|
|
983
|
+
type InvalidReference<TLabel extends string, TReceived, TExpected extends string> = {
|
|
984
|
+
__dyrected_error__: `Invalid ${TLabel}`;
|
|
985
|
+
__dyrected_received__: TReceived;
|
|
986
|
+
__dyrected_expected__: TExpected;
|
|
987
|
+
};
|
|
988
|
+
type TypedReference<TValue, TExpected extends string, TLabel extends string> = TValue extends undefined ? undefined : TValue extends TExpected ? TValue : InvalidReference<TLabel, TValue, TExpected>;
|
|
989
|
+
type TypedReferenceList<TValue, TExpected extends string, TLabel extends string> = TValue extends readonly unknown[] ? {
|
|
990
|
+
[K in keyof TValue]: TypedReference<TValue[K], TExpected, TLabel>;
|
|
991
|
+
} : InvalidReference<`${TLabel} list`, TValue, TExpected>;
|
|
992
|
+
type TypedCollectionAdmin<TFields extends readonly Field[], TDoc extends object, TAdmin extends NonNullable<CollectionConfig<TDoc>["admin"]> | undefined> = Omit<NonNullable<CollectionConfig<TDoc>["admin"]>, "useAsTitle" | "defaultColumns" | "searchableFields"> & {
|
|
993
|
+
useAsTitle?: TypedReference<PropertyType<NonNullable<TAdmin>, "useAsTitle">, TopLevelFieldName<TFields>, "field name">;
|
|
994
|
+
defaultColumns?: TypedReferenceList<PropertyType<NonNullable<TAdmin>, "defaultColumns">, TopLevelFieldName<TFields>, "field name">;
|
|
995
|
+
searchableFields?: TypedReferenceList<PropertyType<NonNullable<TAdmin>, "searchableFields">, TopLevelFieldName<TFields>, "field name">;
|
|
996
|
+
};
|
|
997
|
+
type TypedNestedFieldAdmin<TFields extends readonly Field[], TAdmin extends NonNullable<Field["admin"]> | undefined> = Omit<NonNullable<Field["admin"]>, "useAsTitle"> & {
|
|
998
|
+
useAsTitle?: TypedReference<PropertyType<NonNullable<TAdmin>, "useAsTitle">, TopLevelFieldName<TFields>, "field name">;
|
|
999
|
+
};
|
|
1000
|
+
type PropertyType<T, K extends PropertyKey> = T extends {
|
|
1001
|
+
[P in K]?: infer V;
|
|
1002
|
+
} ? V : never;
|
|
1003
|
+
type PolicyNames<TPolicies> = Extract<keyof NonNullable<TPolicies>, string>;
|
|
1004
|
+
type TypedPolicyReference<TPolicyNames extends string, TPolicy extends string | undefined> = {
|
|
1005
|
+
policy: TypedReference<TPolicy, TPolicyNames, "policy name">;
|
|
1006
|
+
params?: Record<string, unknown>;
|
|
1007
|
+
};
|
|
1008
|
+
type TypedAccessRule<TRule, TPolicyNames extends string> = Exclude<TRule, {
|
|
1009
|
+
policy: string;
|
|
1010
|
+
}> | TypedPolicyReference<TPolicyNames, Extract<PropertyType<TRule, "policy">, string>>;
|
|
1011
|
+
type RetypeAccessObject<TAccess, TKeys extends PropertyKey, TPolicyNames extends string> = TAccess extends object ? Omit<TAccess, Extract<TKeys, keyof TAccess>> & {
|
|
1012
|
+
[K in Extract<TKeys, keyof TAccess>]?: TypedAccessRule<PropertyType<TAccess, K>, TPolicyNames>;
|
|
1013
|
+
} : TAccess;
|
|
1014
|
+
type TypedFieldAccess<TAccess, TPolicyNames extends string> = RetypeAccessObject<TAccess, "read" | "create" | "update", TPolicyNames>;
|
|
1015
|
+
type TypedCollectionAccess<TAccess, TPolicyNames extends string> = RetypeAccessObject<TAccess, "read" | "create" | "update" | "delete" | "readAudit", TPolicyNames>;
|
|
1016
|
+
type TypedGlobalAccess<TAccess, TPolicyNames extends string> = RetypeAccessObject<TAccess, "read" | "update", TPolicyNames>;
|
|
1017
|
+
type SlugOf<T> = T extends {
|
|
1018
|
+
slug: infer TSlug extends string;
|
|
1019
|
+
} ? TSlug : never;
|
|
1020
|
+
type CollectionSlug<TCollections extends readonly unknown[]> = SlugOf<TCollections[number]>;
|
|
1021
|
+
type BlockSlug<TBlocks extends readonly unknown[]> = SlugOf<TBlocks[number]>;
|
|
1022
|
+
type UploadCollectionSlug<TCollections extends readonly unknown[]> = SlugOf<Extract<TCollections[number], {
|
|
1023
|
+
upload: unknown;
|
|
1024
|
+
}>>;
|
|
1025
|
+
type AuthCollectionSlug<TCollections extends readonly unknown[]> = SlugOf<Extract<TCollections[number], {
|
|
1026
|
+
auth: unknown;
|
|
1027
|
+
}>>;
|
|
1028
|
+
type CollectionBySlug<TCollections extends readonly unknown[], TSlug extends string> = Extract<TCollections[number], {
|
|
1029
|
+
slug: TSlug;
|
|
1030
|
+
}>;
|
|
1031
|
+
type CollectionFieldNamesBySlug<TCollections extends readonly unknown[], TSlug extends string> = CollectionBySlug<TCollections, TSlug> extends {
|
|
1032
|
+
fields: infer TFields extends readonly Field[];
|
|
1033
|
+
} ? TopLevelFieldName<TFields> : never;
|
|
1034
|
+
type WorkflowStateName<TWorkflow> = TWorkflow extends {
|
|
1035
|
+
states: infer TStates extends readonly unknown[];
|
|
1036
|
+
} ? Extract<TStates[number], {
|
|
1037
|
+
name: string;
|
|
1038
|
+
}>["name"] : never;
|
|
1039
|
+
type TypedWorkflowStateValue<TValue, TWorkflow> = TValue extends readonly unknown[] ? {
|
|
1040
|
+
[K in keyof TValue]: TypedReference<TValue[K], WorkflowStateName<TWorkflow>, "workflow state name">;
|
|
1041
|
+
} : TypedReference<TValue, WorkflowStateName<TWorkflow>, "workflow state name">;
|
|
1042
|
+
type TypedWorkflowTransition<TTransition, TWorkflow> = Omit<TTransition, "from" | "to"> & {
|
|
1043
|
+
from: TypedWorkflowStateValue<PropertyType<TTransition, "from">, TWorkflow>;
|
|
1044
|
+
to: TypedReference<PropertyType<TTransition, "to">, WorkflowStateName<TWorkflow>, "workflow state name">;
|
|
1045
|
+
};
|
|
1046
|
+
type TypedWorkflow<TWorkflow> = TWorkflow extends {
|
|
1047
|
+
transitions: infer TTransitions extends readonly unknown[];
|
|
1048
|
+
} ? Omit<TWorkflow, "initialState" | "draftState" | "transitions"> & {
|
|
1049
|
+
initialState: TypedReference<PropertyType<TWorkflow, "initialState">, WorkflowStateName<TWorkflow>, "workflow state name">;
|
|
1050
|
+
draftState?: TypedReference<PropertyType<TWorkflow, "draftState">, WorkflowStateName<TWorkflow>, "workflow state name">;
|
|
1051
|
+
transitions: {
|
|
1052
|
+
[K in keyof TTransitions]: TypedWorkflowTransition<TTransitions[K], TWorkflow>;
|
|
1053
|
+
};
|
|
1054
|
+
} : TWorkflow;
|
|
1055
|
+
type TypedBlockForConfig<TBlock extends Block, TCollections extends readonly unknown[], TRootBlocks extends readonly Block[], TPolicyNames extends string> = Omit<TBlock, "fields"> & {
|
|
1056
|
+
fields: TBlock["fields"] extends readonly Field[] ? TypedFields<TBlock["fields"], TCollections, TRootBlocks, TPolicyNames> : TBlock["fields"];
|
|
1057
|
+
};
|
|
1058
|
+
type TypedBlocksForConfig<TBlocks extends readonly Block[], TCollections extends readonly unknown[], TRootBlocks extends readonly Block[], TPolicyNames extends string> = {
|
|
1059
|
+
[K in keyof TBlocks]: TBlocks[K] extends Block ? TypedBlockForConfig<TBlocks[K], TCollections, TRootBlocks, TPolicyNames> : TBlocks[K];
|
|
1060
|
+
};
|
|
1061
|
+
type TypedFieldForConfig<TField extends Field, TCollections extends readonly unknown[], TBlocks extends readonly Block[], TPolicyNames extends string> = TField extends {
|
|
1062
|
+
type: "relationship";
|
|
1063
|
+
} ? Omit<TField, "relationTo" | "access"> & {
|
|
1064
|
+
relationTo?: TypedReference<PropertyType<TField, "relationTo">, CollectionSlug<TCollections>, "collection slug">;
|
|
1065
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1066
|
+
} : TField extends {
|
|
1067
|
+
type: "image";
|
|
1068
|
+
} ? Omit<TField, "relationTo" | "access"> & {
|
|
1069
|
+
relationTo?: TypedReference<PropertyType<TField, "relationTo">, UploadCollectionSlug<TCollections>, "upload collection slug">;
|
|
1070
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1071
|
+
} : TField extends {
|
|
1072
|
+
type: "richText";
|
|
1073
|
+
} ? Omit<TField, "uploadCollection" | "access"> & {
|
|
1074
|
+
uploadCollection?: TypedReference<PropertyType<TField, "uploadCollection">, UploadCollectionSlug<TCollections>, "upload collection slug">;
|
|
1075
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1076
|
+
} : TField extends {
|
|
1077
|
+
type: "join";
|
|
1078
|
+
} ? Omit<TField, "collection" | "on" | "access"> & {
|
|
1079
|
+
collection?: TypedReference<PropertyType<TField, "collection">, CollectionSlug<TCollections>, "collection slug">;
|
|
1080
|
+
on?: TypedReference<PropertyType<TField, "on">, CollectionFieldNamesBySlug<TCollections, Extract<PropertyType<TField, "collection">, string>> | TopLevelFieldName<Extract<CollectionBySlug<TCollections, CollectionSlug<TCollections>>, {
|
|
1081
|
+
fields: readonly Field[];
|
|
1082
|
+
}>["fields"]>, "field name">;
|
|
1083
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1084
|
+
} : TField extends {
|
|
1085
|
+
type: "blocks";
|
|
1086
|
+
} ? Omit<TField, "blocks" | "blockReferences" | "access"> & {
|
|
1087
|
+
blocks?: TField["blocks"] extends readonly Block[] ? TypedBlocksForConfig<TField["blocks"], TCollections, TBlocks, TPolicyNames> : TField["blocks"];
|
|
1088
|
+
blockReferences?: TypedReferenceList<PropertyType<TField, "blockReferences">, BlockSlug<TBlocks>, "block slug">;
|
|
1089
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1090
|
+
} : TField extends {
|
|
1091
|
+
type: "array";
|
|
1092
|
+
fields: infer TSubFields extends readonly Field[];
|
|
1093
|
+
} ? Omit<TField, "fields" | "access" | "admin"> & {
|
|
1094
|
+
fields: TypedFields<TSubFields, TCollections, TBlocks, TPolicyNames>;
|
|
1095
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1096
|
+
admin?: TypedNestedFieldAdmin<TSubFields, PropertyType<TField, "admin">>;
|
|
1097
|
+
} : TField extends {
|
|
1098
|
+
type: "object";
|
|
1099
|
+
fields: infer TSubFields extends readonly Field[];
|
|
1100
|
+
} ? Omit<TField, "fields" | "access" | "admin"> & {
|
|
1101
|
+
fields: TypedFields<TSubFields, TCollections, TBlocks, TPolicyNames>;
|
|
1102
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1103
|
+
admin?: TypedNestedFieldAdmin<TSubFields, PropertyType<TField, "admin">>;
|
|
1104
|
+
} : TField extends {
|
|
1105
|
+
fields: infer TSubFields extends readonly Field[];
|
|
1106
|
+
} ? Omit<TField, "fields" | "access"> & {
|
|
1107
|
+
fields: TypedFields<TSubFields, TCollections, TBlocks, TPolicyNames>;
|
|
1108
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1109
|
+
} : Omit<TField, "access"> & {
|
|
1110
|
+
access?: TypedFieldAccess<NonNullable<TField["access"]>, TPolicyNames>;
|
|
1111
|
+
};
|
|
1112
|
+
type TypedFields<TFields extends readonly Field[], TCollections extends readonly unknown[], TBlocks extends readonly Block[], TPolicyNames extends string> = {
|
|
1113
|
+
[K in keyof TFields]: TFields[K] extends Field ? TypedFieldForConfig<TFields[K], TCollections, TBlocks, TPolicyNames> : TFields[K];
|
|
1114
|
+
};
|
|
1115
|
+
type TypedCollectionForConfig<TCollection extends CollectionConfig<any>, TCollections extends readonly CollectionConfig<any>[], TBlocks extends readonly Block[], TPolicyNames extends string> = Omit<TCollection, "fields" | "access" | "workflow" | "views"> & {
|
|
1116
|
+
fields: TCollection["fields"] extends readonly Field[] ? TypedFields<TCollection["fields"], TCollections, TBlocks, TPolicyNames> : TCollection["fields"];
|
|
1117
|
+
access?: TypedCollectionAccess<NonNullable<TCollection["access"]>, TPolicyNames>;
|
|
1118
|
+
workflow?: TypedWorkflow<NonNullable<TCollection["workflow"]>>;
|
|
1119
|
+
views?: TCollection["views"];
|
|
1120
|
+
};
|
|
1121
|
+
type TypedCollections<TCollections extends readonly CollectionConfig<any>[], TAllCollections extends readonly CollectionConfig<any>[], TBlocks extends readonly Block[], TPolicyNames extends string> = {
|
|
1122
|
+
[K in keyof TCollections]: TCollections[K] extends CollectionConfig<any> ? TypedCollectionForConfig<TCollections[K], TAllCollections, TBlocks, TPolicyNames> : TCollections[K];
|
|
1123
|
+
};
|
|
1124
|
+
type TypedGlobalForConfig<TGlobal extends GlobalConfig<any>, TCollections extends readonly CollectionConfig<any>[], TBlocks extends readonly Block[], TPolicyNames extends string> = Omit<TGlobal, "fields" | "access"> & {
|
|
1125
|
+
fields: TGlobal["fields"] extends readonly Field[] ? TypedFields<TGlobal["fields"], TCollections, TBlocks, TPolicyNames> : TGlobal["fields"];
|
|
1126
|
+
access?: TypedGlobalAccess<NonNullable<TGlobal["access"]>, TPolicyNames>;
|
|
1127
|
+
};
|
|
1128
|
+
type TypedGlobals<TGlobals extends readonly GlobalConfig<any>[], TCollections extends readonly CollectionConfig<any>[], TBlocks extends readonly Block[], TPolicyNames extends string> = {
|
|
1129
|
+
[K in keyof TGlobals]: TGlobals[K] extends GlobalConfig<any> ? TypedGlobalForConfig<TGlobals[K], TCollections, TBlocks, TPolicyNames> : TGlobals[K];
|
|
1130
|
+
};
|
|
1131
|
+
type TypedAdminAuthConfig<TAdminAuth, TCollections extends readonly CollectionConfig<any>[]> = TAdminAuth extends object ? Omit<TAdminAuth, "collectionSlug"> & {
|
|
1132
|
+
collectionSlug?: TypedReference<PropertyType<TAdminAuth, "collectionSlug">, AuthCollectionSlug<TCollections>, "auth collection slug">;
|
|
1133
|
+
} : TAdminAuth;
|
|
1134
|
+
/**
|
|
1135
|
+
* Define a collection. When called without an explicit type argument, TypeScript
|
|
1136
|
+
* automatically infers the document shape from the `fields` array you provide —
|
|
1137
|
+
* no manual interface required:
|
|
1138
|
+
*
|
|
1139
|
+
* ```ts
|
|
1140
|
+
* export const Posts = defineCollection({
|
|
1141
|
+
* slug: 'posts',
|
|
1142
|
+
* fields: [
|
|
1143
|
+
* defineTextField({ name: 'title', required: true }),
|
|
1144
|
+
* defineSelectField({ name: 'status', options: ['draft', 'published'], required: true }),
|
|
1145
|
+
* ],
|
|
1146
|
+
* hooks: {
|
|
1147
|
+
* beforeChange: [({ data }) => {
|
|
1148
|
+
* // data is { title: string; status: 'draft' | 'published' } — fully inferred
|
|
1149
|
+
* }],
|
|
1150
|
+
* },
|
|
1151
|
+
* })
|
|
1152
|
+
* ```
|
|
1153
|
+
*
|
|
1154
|
+
* When you need a richer interface (e.g. with methods, JSDoc, or types that
|
|
1155
|
+
* can't be derived from fields), pass it explicitly:
|
|
1156
|
+
*
|
|
1157
|
+
* ```ts
|
|
1158
|
+
* interface Post { id: string; title: string; status: 'draft' | 'published' }
|
|
1159
|
+
*
|
|
1160
|
+
* export const Posts = defineCollection<Post>({ ... })
|
|
1161
|
+
* ```
|
|
1162
|
+
*/
|
|
1163
|
+
declare function defineCollection<const TSlug extends string, const TFields extends Field[], const TAdmin extends NonNullable<CollectionConfig<Prettify<{
|
|
1164
|
+
id: string;
|
|
1165
|
+
} & InferDocShape<TFields> & SystemDocFields & AuthDocFields>>["admin"]> | undefined, const TConfig extends Omit<CollectionConfig<Prettify<{
|
|
1166
|
+
id: string;
|
|
1167
|
+
} & InferDocShape<TFields> & SystemDocFields & AuthDocFields>>, "fields" | "auth" | "admin"> & {
|
|
1168
|
+
slug: TSlug;
|
|
1169
|
+
fields: TFields;
|
|
1170
|
+
auth: true | AuthConfig;
|
|
1171
|
+
admin?: TypedCollectionAdmin<TFields, Prettify<{
|
|
1172
|
+
id: string;
|
|
1173
|
+
} & InferDocShape<TFields> & SystemDocFields & AuthDocFields>, TAdmin>;
|
|
1174
|
+
}>(config: TConfig): TConfig;
|
|
1175
|
+
declare function defineCollection<const TSlug extends string, const TFields extends Field[], const TAdmin extends NonNullable<CollectionConfig<Prettify<{
|
|
1176
|
+
id: string;
|
|
1177
|
+
} & InferDocShape<TFields> & SystemDocFields & UploadDocFields>>["admin"]> | undefined, const TConfig extends Omit<CollectionConfig<Prettify<{
|
|
1178
|
+
id: string;
|
|
1179
|
+
} & InferDocShape<TFields> & SystemDocFields & UploadDocFields>>, "fields" | "upload" | "admin"> & {
|
|
1180
|
+
slug: TSlug;
|
|
1181
|
+
fields: TFields;
|
|
1182
|
+
upload: true;
|
|
1183
|
+
admin?: TypedCollectionAdmin<TFields, Prettify<{
|
|
1184
|
+
id: string;
|
|
1185
|
+
} & InferDocShape<TFields> & SystemDocFields & UploadDocFields>, TAdmin>;
|
|
1186
|
+
}>(config: TConfig): TConfig;
|
|
1187
|
+
declare function defineCollection<const TSlug extends string, const TFields extends Field[], const TAdmin extends NonNullable<CollectionConfig<Prettify<{
|
|
1188
|
+
id: string;
|
|
1189
|
+
} & InferDocShape<TFields> & SystemDocFields>>["admin"]> | undefined, const TConfig extends Omit<CollectionConfig<Prettify<{
|
|
1190
|
+
id: string;
|
|
1191
|
+
} & InferDocShape<TFields> & SystemDocFields>>, "fields" | "admin"> & {
|
|
1192
|
+
slug: TSlug;
|
|
1193
|
+
fields: TFields;
|
|
1194
|
+
admin?: TypedCollectionAdmin<TFields, Prettify<{
|
|
1195
|
+
id: string;
|
|
1196
|
+
} & InferDocShape<TFields> & SystemDocFields>, TAdmin>;
|
|
1197
|
+
}>(config: TConfig): TConfig;
|
|
1198
|
+
declare function defineCollection<TDoc extends object, const TConfig extends CollectionConfig<TDoc>>(config: TConfig): TConfig;
|
|
1199
|
+
/**
|
|
1200
|
+
* Define a global (singleton document). TypeScript automatically infers the
|
|
1201
|
+
* document shape from the `fields` array, or you can pass an explicit type:
|
|
1202
|
+
*
|
|
1203
|
+
* ```ts
|
|
1204
|
+
* // Inferred — no interface needed
|
|
1205
|
+
* export const Settings = defineGlobal({
|
|
1206
|
+
* slug: 'site-settings',
|
|
1207
|
+
* fields: [
|
|
1208
|
+
* defineTextField({ name: 'siteName', required: true }),
|
|
1209
|
+
* defineBooleanField({ name: 'maintenanceMode' }),
|
|
1210
|
+
* ],
|
|
1211
|
+
* hooks: {
|
|
1212
|
+
* afterChange: [({ doc }) => {
|
|
1213
|
+
* // doc.siteName is string, doc.maintenanceMode is boolean | undefined
|
|
1214
|
+
* if (doc.maintenanceMode) alertOnCall()
|
|
1215
|
+
* }],
|
|
1216
|
+
* },
|
|
1217
|
+
* })
|
|
1218
|
+
*
|
|
1219
|
+
* // Explicit type
|
|
1220
|
+
* interface SiteSettings { siteName: string; maintenanceMode?: boolean }
|
|
1221
|
+
* export const Settings = defineGlobal<SiteSettings>({ ... })
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
declare function defineGlobal<const TSlug extends string, const TFields extends Field[], const TConfig extends Omit<GlobalConfig<Prettify<InferDocShape<TFields>>>, "fields"> & {
|
|
1225
|
+
slug: TSlug;
|
|
1226
|
+
fields: TFields;
|
|
1227
|
+
}>(config: TConfig): TConfig;
|
|
1228
|
+
declare function defineGlobal<TDoc extends object, const TConfig extends GlobalConfig<TDoc>>(config: TConfig): TConfig;
|
|
1229
|
+
/**
|
|
1230
|
+
* Define the root Dyrected configuration.
|
|
1231
|
+
*
|
|
1232
|
+
* This is the single object passed to `createDyrectedApp`. It wires together
|
|
1233
|
+
* the database adapter, collections, globals, storage, email, and all other
|
|
1234
|
+
* server-level configuration.
|
|
1235
|
+
*/
|
|
1236
|
+
declare function defineConfig<TUser extends AuthenticatedUser = AuthenticatedUser, const TBlocks extends readonly Block[] = [], const TCollections extends readonly CollectionConfig<any>[] = [], const TGlobals extends readonly GlobalConfig<any>[] = [], const TAdminAuth extends DyrectedConfig<TUser>["adminAuth"] | undefined = undefined, const TPolicies extends Record<string, AccessPolicyResolver<Record<string, unknown>, TUser> | string | boolean> | undefined = undefined>(config: Omit<DyrectedConfig<TUser>, "blocks" | "collections" | "globals" | "accessPolicies" | "adminAuth"> & {
|
|
1237
|
+
blocks?: TypedBlocksForConfig<TBlocks, TCollections, TBlocks, PolicyNames<TPolicies>>;
|
|
1238
|
+
collections: TypedCollections<TCollections, TCollections, TBlocks, PolicyNames<TPolicies>>;
|
|
1239
|
+
globals: TypedGlobals<TGlobals, TCollections, TBlocks, PolicyNames<TPolicies>>;
|
|
1240
|
+
accessPolicies?: TPolicies;
|
|
1241
|
+
adminAuth?: TypedAdminAuthConfig<TAdminAuth, TCollections>;
|
|
1242
|
+
}): typeof config;
|
|
1243
|
+
/**
|
|
1244
|
+
* Define a single field of any type. This is an identity helper: it returns the
|
|
1245
|
+
* field unchanged at runtime but preserves the exact literal type, so document
|
|
1246
|
+
* shapes still infer correctly when the field is placed in a `defineCollection`
|
|
1247
|
+
* or `defineGlobal` `fields` array.
|
|
1248
|
+
*
|
|
1249
|
+
* Use it when you want autocomplete and type-checking on a field written on its
|
|
1250
|
+
* own — for example a shared field reused across collections:
|
|
1251
|
+
*
|
|
1252
|
+
* ```ts
|
|
1253
|
+
* const slug = defineField({ name: 'slug', type: 'text', required: true, unique: true })
|
|
1254
|
+
*
|
|
1255
|
+
* export const Posts = defineCollection({ slug: 'posts', fields: [slug, ...] })
|
|
1256
|
+
* ```
|
|
1257
|
+
*
|
|
1258
|
+
* For a field of a known type, prefer the dedicated helper (e.g.
|
|
1259
|
+
* {@link defineTextField}) so you don't have to repeat the `type`.
|
|
1260
|
+
*/
|
|
1261
|
+
declare function defineField<const T extends Field>(field: T): T;
|
|
1262
|
+
/**
|
|
1263
|
+
* Define a {@link Block} for use in a `blocks` field. Identity helper that
|
|
1264
|
+
* preserves the block's literal type (slug + fields) so `blocks`-field values
|
|
1265
|
+
* stay fully inferred.
|
|
1266
|
+
*
|
|
1267
|
+
* ```ts
|
|
1268
|
+
* const Hero = defineBlock({
|
|
1269
|
+
* slug: 'hero',
|
|
1270
|
+
* fields: [defineTextField({ name: 'heading', required: true })],
|
|
1271
|
+
* })
|
|
1272
|
+
*
|
|
1273
|
+
* defineBlocksField({ name: 'layout', blocks: [Hero] })
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
1276
|
+
declare function defineBlock<const T extends Block>(block: T): T;
|
|
1277
|
+
/** Define a `text` field. */
|
|
1278
|
+
declare const defineTextField: <const T extends Omit<TextField, "type">>(field: T) => T & {
|
|
1279
|
+
type: "text";
|
|
1280
|
+
};
|
|
1281
|
+
/** Define a `textarea` field. */
|
|
1282
|
+
declare const defineTextareaField: <const T extends Omit<TextareaField, "type">>(field: T) => T & {
|
|
1283
|
+
type: "textarea";
|
|
1284
|
+
};
|
|
1285
|
+
/** Define a `richText` field, including its editor `features` and `headingLevels`. */
|
|
1286
|
+
declare const defineRichTextField: <const T extends Omit<RichTextField, "type">>(field: T) => T & {
|
|
1287
|
+
type: "richText";
|
|
1288
|
+
};
|
|
1289
|
+
/** Define a `number` field. */
|
|
1290
|
+
declare const defineNumberField: <const T extends Omit<NumberField, "type">>(field: T) => T & {
|
|
1291
|
+
type: "number";
|
|
1292
|
+
};
|
|
1293
|
+
/** Define a `boolean` field. */
|
|
1294
|
+
declare const defineBooleanField: <const T extends Omit<BooleanField, "type">>(field: T) => T & {
|
|
1295
|
+
type: "boolean";
|
|
1296
|
+
};
|
|
1297
|
+
/** Define a `date` field. */
|
|
1298
|
+
declare const defineDateField: <const T extends Omit<DateField, "type">>(field: T) => T & {
|
|
1299
|
+
type: "date";
|
|
1300
|
+
};
|
|
1301
|
+
/** Define a `datetime` field. */
|
|
1302
|
+
declare const defineDateTimeField: <const T extends Omit<DateTimeField, "type">>(field: T) => T & {
|
|
1303
|
+
type: "datetime";
|
|
1304
|
+
};
|
|
1305
|
+
/** Define a `time` field. */
|
|
1306
|
+
declare const defineTimeField: <const T extends Omit<TimeField, "type">>(field: T) => T & {
|
|
1307
|
+
type: "time";
|
|
1308
|
+
};
|
|
1309
|
+
/** Define a `select` field. */
|
|
1310
|
+
declare const defineSelectField: <const T extends Omit<SelectField, "type">>(field: T) => T & {
|
|
1311
|
+
type: "select";
|
|
1312
|
+
};
|
|
1313
|
+
/** Define a `multiSelect` field. */
|
|
1314
|
+
declare const defineMultiSelectField: <const T extends Omit<MultiSelectField, "type">>(field: T) => T & {
|
|
1315
|
+
type: "multiSelect";
|
|
1316
|
+
};
|
|
1317
|
+
/** Define a `radio` field. */
|
|
1318
|
+
declare const defineRadioField: <const T extends Omit<RadioField, "type">>(field: T) => T & {
|
|
1319
|
+
type: "radio";
|
|
1320
|
+
};
|
|
1321
|
+
/** Define a `relationship` field. */
|
|
1322
|
+
declare const defineRelationshipField: <const T extends Omit<RelationshipField, "type">>(field: T) => T & {
|
|
1323
|
+
type: "relationship";
|
|
1324
|
+
};
|
|
1325
|
+
/** Define an `array` field. */
|
|
1326
|
+
declare const defineArrayField: <const T extends Omit<ArrayField, "type">>(field: T) => T & {
|
|
1327
|
+
type: "array";
|
|
1328
|
+
};
|
|
1329
|
+
/** Define an `object` field. */
|
|
1330
|
+
declare const defineObjectField: <const T extends Omit<ObjectField, "type">>(field: T) => T & {
|
|
1331
|
+
type: "object";
|
|
1332
|
+
};
|
|
1333
|
+
/** Define a `json` field. */
|
|
1334
|
+
declare const defineJsonField: <const T extends Omit<JsonField, "type">>(field: T) => T & {
|
|
1335
|
+
type: "json";
|
|
1336
|
+
};
|
|
1337
|
+
/** Define a `blocks` field. */
|
|
1338
|
+
declare const defineBlocksField: <const T extends Omit<BlocksField, "type">>(field: T) => T & {
|
|
1339
|
+
type: "blocks";
|
|
1340
|
+
};
|
|
1341
|
+
/** Define an `image` field. */
|
|
1342
|
+
declare const defineImageField: <const T extends Omit<ImageField, "type">>(field: T) => T & {
|
|
1343
|
+
type: "image";
|
|
1344
|
+
};
|
|
1345
|
+
/** Define an `email` field. */
|
|
1346
|
+
declare const defineEmailField: <const T extends Omit<EmailField, "type">>(field: T) => T & {
|
|
1347
|
+
type: "email";
|
|
1348
|
+
};
|
|
1349
|
+
/** Define a `url` field. */
|
|
1350
|
+
declare const defineUrlField: <const T extends Omit<UrlField, "type">>(field: T) => T & {
|
|
1351
|
+
type: "url";
|
|
1352
|
+
};
|
|
1353
|
+
/** Define an `icon` field. */
|
|
1354
|
+
declare const defineIconField: <const T extends Omit<IconField, "type">>(field: T) => T & {
|
|
1355
|
+
type: "icon";
|
|
1356
|
+
};
|
|
1357
|
+
/** Define a `join` field. */
|
|
1358
|
+
declare const defineJoinField: <const T extends Omit<JoinField, "type">>(field: T) => T & {
|
|
1359
|
+
type: "join";
|
|
1360
|
+
};
|
|
1361
|
+
/** Define a layout-only `row` field. */
|
|
1362
|
+
declare const defineRowField: <const T extends Omit<RowField, "type">>(field: T) => T & {
|
|
1363
|
+
type: "row";
|
|
1364
|
+
};
|
|
1365
|
+
/**
|
|
1366
|
+
* Group fields under a named tab in the Admin edit form. Tabs are presentational
|
|
1367
|
+
* only: `defineTab` returns the given fields unchanged except that each one's
|
|
1368
|
+
* `admin.tab` is set to `label`, and the Admin panel renders fields that share a
|
|
1369
|
+
* tab name together under that tab. Spread the result into a collection, global,
|
|
1370
|
+
* or group `fields` array, and add one `defineTab` call per tab. Fields left
|
|
1371
|
+
* without a tab are collected into a leading tab named after the collection.
|
|
1372
|
+
*
|
|
1373
|
+
* ```ts
|
|
1374
|
+
* defineCollection({
|
|
1375
|
+
* slug: 'pages',
|
|
1376
|
+
* fields: [
|
|
1377
|
+
* ...defineTab({
|
|
1378
|
+
* label: 'Content',
|
|
1379
|
+
* fields: [
|
|
1380
|
+
* defineTextField({ name: 'title', required: true }),
|
|
1381
|
+
* defineRichTextField({ name: 'body' }),
|
|
1382
|
+
* ],
|
|
1383
|
+
* }),
|
|
1384
|
+
* ...defineTab({
|
|
1385
|
+
* label: 'SEO',
|
|
1386
|
+
* fields: [defineTextField({ name: 'metaTitle' })],
|
|
1387
|
+
* }),
|
|
1388
|
+
* ],
|
|
1389
|
+
* })
|
|
1390
|
+
* ```
|
|
1391
|
+
*/
|
|
1392
|
+
declare function defineTab<const T extends readonly Field[]>(args: {
|
|
1393
|
+
/** Tab name shown in the Admin edit form's tab bar. */
|
|
1394
|
+
label: string;
|
|
1395
|
+
/** Fields to place under this tab; each field's `admin.tab` is set to `label`. */
|
|
1396
|
+
fields: T;
|
|
1397
|
+
}): T;
|
|
1398
|
+
|
|
1399
|
+
export { AIAgent, type AIAgentOptions, type AIErrorCode, AIMessage, AIThread, AccessPolicyResolver, AdminAuthConfig, ArrayField, AuthConfig, type AuthDocFields, AuthenticatedUser, BUILTIN_JEXL_HELPERS, BaseDocument, Block, BlocksField, BooleanField, type ChunkOptions, type ChunkResult, CollectionConfig, ComputedHandler, type ConfigDiagnostic, ConfigValidationError, DatabaseAdapter, DateField, DateTimeField, type DeclarativeAccessSurface, type DeclarativeAccessValidationIssue, type DeclarativeAdminSurface, type DeclarativeAdminValidationIssue, DeclarativeHookExpression, type DeclarativeHookSurface, type DeclarativeHookValidationIssue, type DeclarativePreviewSurface, type DeclarativePreviewValidationIssue, type DeleteDocumentChunksOptions, DetailComputed, DetailComputedOptions, DetailCustom, DetailCustomOptions, DetailDivider, DetailDividerOptions, DetailField, DetailGrid, DetailGridOptions, DetailItem, DetailRepeat, DetailRepeatOptions, DetailSchema, DetailSection, DetailSectionOptions, DetailTab, DetailTabOptions, DetailTabs, DetailTabsOptions, DetailText, DetailTextOptions, DisplayFieldOptions, DyrectedAIContext, DyrectedAIError, DyrectedConfig, EmailField, EmbeddingService, Field, GlobalConfig, HookRequestContext, IconField, ImageField, type IndexDocumentOptions, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, LifecycleEvent, LifecycleEventName, MultiSelectField, NumberField, ObjectField, type Prettify, PublicAdminAuthConfig, type PublishingWorkflowOptions, type RAGSearchOptions, RAGSearchResult, RAGService, RadioField, type ReindexAllOptions, type ReindexCollectionOptions, RelationshipField, RichTextField, RowField, SelectField, type SortClause, type SortDirection, type SqlSortDialect, type SqlWhereResult, type SystemDocFields, TextField, TextareaField, TimeField, type UploadDocFields, UrlField, WORKFLOW_HISTORY_COLLECTION, type WhereClause, type WhereOperator, type WhereOperatorName, WorkflowConfig, WorkflowTransition, abs, addDays, assertValidAdminConditionsInConfig, assertValidDeclarativeAccessInConfig, assertValidDeclarativeHookExpression, assertValidDeclarativeHookResult, assertValidDeclarativeHooksInConfig, assertValidPreviewUrlsInConfig, availableWorkflowTransitions, buildDyrectedSystemPrompt, buildSqlOrderBy, canViewWorkflowDraft, capitalize, ceil, chunkText, clamp, coalesce, collectAdminConditionValidationIssues, collectConfigDiagnostics, collectDeclarativeAccessValidationIssues, collectDeclarativeHookValidationIssues, collectPreviewUrlValidationIssues, compact, cosineSimilarity, count, createDyrectedAITools, createLifecycleEvent, createWorkflowDocument, defaultValue, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMultiSelectField, defineNumberField, defineObjectField, definePublishingWorkflow, defineRadioField, defineRelationshipField, defineRichTextField, defineRowField, defineSelectField, defineTab, defineTextField, defineTextareaField, defineTimeField, defineUrlField, diffDays, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, displayComputed, displayCustom, displayCustomComponent, displayDivider, displayField, displayGrid, displayRepeat, displaySection, displayTab, displayTabs, displayText, endsWith, estimateTokens, evaluateDetailComputed, evaluateJexl, evaluateJexlSync, executeFieldAfterRead, executeFieldBeforeChange, extractTextFromDoc, first, floor, formatAIErrorMessage, formatConfigDiagnostics, formatDate, generateDefaultDetailSchema, generateOpenApi, get, getAIModel, getAdminAuthCollection, getEmbeddingModel, getPublicAdminAuthConfig, hashContent, includes, initializeWorkflowDocument, isConfigValidationError, isDetailItemVisible, isEmpty, isFuture, isPast, join, last, length, lower, materializeWorkflowDocument, max, min, normalizeConfig, normalizeDetailItem, normalizeFieldValue, now, numericFieldNames, parseMongoWhere, parseSort, parseSqlWhere, pow, publishedStateName, publishingWorkflow, readingTime, registerJexlHelpers, replace, resolveAdminAuthCollection, round, runCollectionHooks, saveWorkflowDraft, simplePublishingWorkflow, slugify, sqrt, startsWith, sum, today, transitionWorkflow, trim, truncate, unique, upper, validateAdminConditionExpression, validateDeclarativeAccessExpression, validateDeclarativeHookExpression, validatePreviewUrlExpression, wordCount, workflowCapabilities };
|