@dyrected/core 2.5.9 → 2.5.10

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.
@@ -1,374 +1,377 @@
1
- import * as hono_types from 'hono/types';
2
- import { Hono } from 'hono';
1
+ import * as hono_types from "hono/types";
2
+ import { Hono } from "hono";
3
3
 
4
- type FieldType = "text" | "textarea" | "richText" | "number" | "boolean" | "date" | "select" | "multiSelect" | "relationship" | "array" | "object" | "json" | "blocks" | "image" | "email" | "url" | "icon" | "join" | "row";
4
+ type FieldType =
5
+ | "text"
6
+ | "textarea"
7
+ | "richText"
8
+ | "number"
9
+ | "boolean"
10
+ | "date"
11
+ | "select"
12
+ | "multiSelect"
13
+ | "relationship"
14
+ | "array"
15
+ | "object"
16
+ | "json"
17
+ | "blocks"
18
+ | "image"
19
+ | "email"
20
+ | "url"
21
+ | "icon"
22
+ | "join"
23
+ | "row";
5
24
  interface Block {
6
- slug: string;
7
- labels?: {
8
- singular: string;
9
- plural: string;
10
- };
11
- fields: Field[];
25
+ slug: string;
26
+ labels?: {
27
+ singular: string;
28
+ plural: string;
29
+ };
30
+ fields: Field[];
12
31
  }
13
32
  interface Field {
14
- name?: string;
15
- type: FieldType;
16
- label?: string;
17
- required?: boolean;
18
- unique?: boolean;
19
- defaultValue?: any;
20
- options?: string[] | {
33
+ name?: string;
34
+ type: FieldType;
35
+ label?: string;
36
+ required?: boolean;
37
+ unique?: boolean;
38
+ defaultValue?: any;
39
+ options?:
40
+ | string[]
41
+ | {
21
42
  label: string;
22
43
  value: string;
23
- }[];
24
- relationTo?: string;
25
- hasMany?: boolean;
26
- fields?: Field[];
27
- blocks?: Block[];
28
- collection?: string;
29
- on?: string;
30
- access?: {
31
- read?: AccessFunction;
32
- update?: AccessFunction;
33
- };
34
- hooks?: {
35
- beforeChange?: FieldHook[];
36
- afterRead?: FieldHook[];
37
- };
38
- admin?: {
39
- placeholder?: string;
40
- description?: string;
41
- hidden?: boolean;
42
- readOnly?: boolean;
43
- condition?: ((data: any, siblingData: any) => boolean) | string;
44
- layout?: "radio" | "select" | string;
45
- direction?: "horizontal" | "vertical";
46
- tab?: string;
47
- width?: string;
48
- };
49
- /** For database migrations: if set, data from this key will be migrated to the current field name. */
50
- renameTo?: string;
51
- /** For database migrations: if true, this field will be extracted to a real SQL column for performance. */
52
- promoted?: boolean;
44
+ }[];
45
+ relationTo?: string;
46
+ hasMany?: boolean;
47
+ fields?: Field[];
48
+ blocks?: Block[];
49
+ collection?: string;
50
+ on?: string;
51
+ access?: {
52
+ read?: AccessFunction;
53
+ update?: AccessFunction;
54
+ };
55
+ hooks?: {
56
+ beforeChange?: FieldHook[];
57
+ afterRead?: FieldHook[];
58
+ };
59
+ admin?: {
60
+ placeholder?: string;
61
+ description?: string;
62
+ hidden?: boolean;
63
+ readOnly?: boolean;
64
+ condition?: ((data: any, siblingData: any) => boolean) | string;
65
+ layout?: "radio" | "select" | string;
66
+ direction?: "horizontal" | "vertical";
67
+ tab?: string;
68
+ width?: string;
69
+ };
70
+ /** For database migrations: if set, data from this key will be migrated to the current field name. */
71
+ renameTo?: string;
72
+ /** For database migrations: if true, this field will be extracted to a real SQL column for performance. */
73
+ promoted?: boolean;
53
74
  }
54
75
  type AccessFunction = (args: {
55
- user: any;
56
- doc?: any;
57
- data?: any;
58
- req: any;
76
+ user: any;
77
+ doc?: any;
78
+ data?: any;
79
+ req: any;
59
80
  }) => boolean | object | Promise<boolean | object>;
60
81
  type HookFunction = (args: {
61
- data?: any;
62
- doc?: any;
63
- user?: any;
64
- req?: any;
65
- /** The operation that triggered this hook. */
66
- operation?: 'create' | 'update' | 'delete';
67
- }) => any | Promise<any>;
68
- type FieldHook = (args: {
69
- value: any;
70
- originalDoc?: any;
71
- data?: any;
72
- user?: any;
82
+ data?: any;
83
+ doc?: any;
84
+ user?: any;
85
+ req?: any;
86
+ /** The operation that triggered this hook. */
87
+ operation?: "create" | "update" | "delete";
73
88
  }) => any | Promise<any>;
89
+ type FieldHook<T, V> = (args: { value: V; originalDoc?: T; data?: any; user?: any }) => any | Promise<any>;
74
90
  interface CollectionConfig {
75
- slug: string;
76
- siteId?: string;
77
- shared?: boolean;
78
- labels?: {
79
- singular: string;
80
- plural: string;
81
- };
82
- auth?: boolean;
83
- upload?: boolean | UploadConfig;
84
- fields: Field[];
85
- timestamps?: boolean;
86
- /** Initial data to seed this collection with on first fetch if it is empty. */
87
- initialData?: any[];
88
- /** Enable full activity logging to the __audit collection for this collection. */
89
- audit?: boolean;
90
- access?: {
91
- read?: AccessFunction;
92
- create?: AccessFunction;
93
- update?: AccessFunction;
94
- delete?: AccessFunction;
95
- };
96
- hooks?: {
97
- beforeRead?: HookFunction[];
98
- afterRead?: HookFunction[];
99
- beforeChange?: HookFunction[];
100
- afterChange?: HookFunction[];
101
- beforeDelete?: HookFunction[];
102
- afterDelete?: HookFunction[];
103
- };
104
- admin?: {
105
- useAsTitle?: string;
106
- defaultColumns?: string[];
107
- group?: string;
108
- hidden?: boolean;
109
- /**
110
- * URL to open in the Live Preview pane.
111
- * Accepts a static string or a function that receives the document and returns a URL.
112
- */
113
- previewUrl?: string | ((doc: any, opts: {
91
+ slug: string;
92
+ siteId?: string;
93
+ shared?: boolean;
94
+ labels?: {
95
+ singular: string;
96
+ plural: string;
97
+ };
98
+ auth?: boolean;
99
+ upload?: boolean | UploadConfig;
100
+ fields: Field[];
101
+ timestamps?: boolean;
102
+ /** Initial data to seed this collection with on first fetch if it is empty. */
103
+ initialData?: any[];
104
+ /** Enable full activity logging to the __audit collection for this collection. */
105
+ audit?: boolean;
106
+ access?: {
107
+ read?: AccessFunction;
108
+ create?: AccessFunction;
109
+ update?: AccessFunction;
110
+ delete?: AccessFunction;
111
+ };
112
+ hooks?: {
113
+ beforeRead?: HookFunction[];
114
+ afterRead?: HookFunction[];
115
+ beforeChange?: HookFunction[];
116
+ afterChange?: HookFunction[];
117
+ beforeDelete?: HookFunction[];
118
+ afterDelete?: HookFunction[];
119
+ };
120
+ admin?: {
121
+ useAsTitle?: string;
122
+ defaultColumns?: string[];
123
+ group?: string;
124
+ hidden?: boolean;
125
+ /**
126
+ * URL to open in the Live Preview pane.
127
+ * Accepts a static string or a function that receives the document and returns a URL.
128
+ */
129
+ previewUrl?:
130
+ | string
131
+ | ((
132
+ doc: any,
133
+ opts: {
114
134
  locale?: string;
115
- }) => string | null);
116
- /** Which mode to use for live preview. Defaults to 'postMessage'. */
117
- previewMode?: 'postMessage' | 'token';
118
- };
135
+ },
136
+ ) => string | null);
137
+ /** Which mode to use for live preview. Defaults to 'postMessage'. */
138
+ previewMode?: "postMessage" | "token";
139
+ };
119
140
  }
120
141
  interface UploadConfig {
121
- allowedMimeTypes?: string[];
122
- maxFileSize?: number;
123
- /** Local disk path where files are stored. Only used by LocalStorage adapter. */
124
- staticDir?: string;
125
- /** Public URL prefix for locally stored files. Only used by LocalStorage adapter. */
126
- staticURL?: string;
127
- /** Which imageSizes entry to use as the thumbnail in the Admin media grid. */
128
- adminThumbnail?: string;
129
- imageSizes?: {
130
- name: string;
131
- width?: number;
132
- height?: number;
133
- crop?: string;
134
- /** sharp fit strategy: 'cover' | 'contain' | 'fill' | 'inside' | 'outside' */
135
- fit?: string;
136
- /** Never upscale images smaller than the target size. Default: true. */
137
- withoutEnlargement?: boolean;
138
- /** Additional sharp format options. */
139
- formatOptions?: Record<string, any>;
140
- }[];
142
+ allowedMimeTypes?: string[];
143
+ maxFileSize?: number;
144
+ /** Local disk path where files are stored. Only used by LocalStorage adapter. */
145
+ staticDir?: string;
146
+ /** Public URL prefix for locally stored files. Only used by LocalStorage adapter. */
147
+ staticURL?: string;
148
+ /** Which imageSizes entry to use as the thumbnail in the Admin media grid. */
149
+ adminThumbnail?: string;
150
+ imageSizes?: {
151
+ name: string;
152
+ width?: number;
153
+ height?: number;
154
+ crop?: string;
155
+ /** sharp fit strategy: 'cover' | 'contain' | 'fill' | 'inside' | 'outside' */
156
+ fit?: string;
157
+ /** Never upscale images smaller than the target size. Default: true. */
158
+ withoutEnlargement?: boolean;
159
+ /** Additional sharp format options. */
160
+ formatOptions?: Record<string, any>;
161
+ }[];
141
162
  }
142
163
  interface GlobalConfig {
143
- slug: string;
144
- siteId?: string;
145
- shared?: boolean;
146
- label?: string;
147
- fields: Field[];
148
- access?: {
149
- read?: AccessFunction;
150
- update?: AccessFunction;
151
- };
152
- hooks?: {
153
- beforeRead?: HookFunction[];
154
- afterRead?: HookFunction[];
155
- beforeChange?: HookFunction[];
156
- afterChange?: HookFunction[];
157
- };
158
- admin?: {
159
- group?: string;
160
- hidden?: boolean;
161
- };
162
- /** Initial data to seed this global with on first fetch if it is empty. */
163
- initialData?: any;
164
+ slug: string;
165
+ siteId?: string;
166
+ shared?: boolean;
167
+ label?: string;
168
+ fields: Field[];
169
+ access?: {
170
+ read?: AccessFunction;
171
+ update?: AccessFunction;
172
+ };
173
+ hooks?: {
174
+ beforeRead?: HookFunction[];
175
+ afterRead?: HookFunction[];
176
+ beforeChange?: HookFunction[];
177
+ afterChange?: HookFunction[];
178
+ };
179
+ admin?: {
180
+ group?: string;
181
+ hidden?: boolean;
182
+ };
183
+ /** Initial data to seed this global with on first fetch if it is empty. */
184
+ initialData?: any;
164
185
  }
165
186
  interface PaginatedResult<T = any> {
166
- docs: T[];
167
- total: number;
168
- limit: number;
169
- page: number;
170
- /** Total number of pages given the current limit. */
171
- totalPages: number;
172
- hasNextPage: boolean;
173
- hasPrevPage: boolean;
187
+ docs: T[];
188
+ total: number;
189
+ limit: number;
190
+ page: number;
191
+ /** Total number of pages given the current limit. */
192
+ totalPages: number;
193
+ hasNextPage: boolean;
194
+ hasPrevPage: boolean;
174
195
  }
175
196
  interface DatabaseAdapter {
176
- find(args: {
177
- collection: string;
178
- where?: any;
179
- limit?: number;
180
- page?: number;
181
- sort?: string;
182
- }): Promise<PaginatedResult>;
183
- findOne(args: {
184
- collection: string;
185
- id: string;
186
- }): Promise<any>;
187
- create(args: {
188
- collection: string;
189
- data: any;
190
- }): Promise<any>;
191
- update(args: {
192
- collection: string;
193
- id: string;
194
- data: any;
195
- }): Promise<any>;
196
- delete(args: {
197
- collection: string;
198
- id: string;
199
- }): Promise<any>;
200
- getGlobal(args: {
201
- slug: string;
202
- }): Promise<any>;
203
- updateGlobal(args: {
204
- slug: string;
205
- data: any;
206
- }): Promise<any>;
207
- /**
208
- * Sync the database schema with the provided collections and globals.
209
- * Useful for creating tables on startup.
210
- */
211
- sync?(collections: CollectionConfig[], globals: GlobalConfig[]): Promise<void>;
212
- /**
213
- * Low-level raw query execution.
214
- * Optional as not all adapters may support raw SQL/commands.
215
- */
216
- execute?(query: string, params?: any[]): Promise<any>;
197
+ find(args: {
198
+ collection: string;
199
+ where?: any;
200
+ limit?: number;
201
+ page?: number;
202
+ sort?: string;
203
+ }): Promise<PaginatedResult>;
204
+ findOne(args: { collection: string; id: string }): Promise<any>;
205
+ create(args: { collection: string; data: any }): Promise<any>;
206
+ update(args: { collection: string; id: string; data: any }): Promise<any>;
207
+ delete(args: { collection: string; id: string }): Promise<any>;
208
+ getGlobal(args: { slug: string }): Promise<any>;
209
+ updateGlobal(args: { slug: string; data: any }): Promise<any>;
210
+ /**
211
+ * Sync the database schema with the provided collections and globals.
212
+ * Useful for creating tables on startup.
213
+ */
214
+ sync?(collections: CollectionConfig[], globals: GlobalConfig[]): Promise<void>;
215
+ /**
216
+ * Low-level raw query execution.
217
+ * Optional as not all adapters may support raw SQL/commands.
218
+ */
219
+ execute?(query: string, params?: any[]): Promise<any>;
217
220
  }
218
221
  interface FileData {
219
- filename: string;
220
- filesize?: number;
221
- mimeType: string;
222
- url: string;
223
- width?: number;
224
- height?: number;
225
- focalPoint?: {
226
- x: number;
227
- y: number;
228
- };
229
- blurhash?: string;
230
- type?: "upload" | "external";
231
- provider?: string;
232
- provider_metadata?: any;
233
- [key: string]: any;
222
+ filename: string;
223
+ filesize?: number;
224
+ mimeType: string;
225
+ url: string;
226
+ width?: number;
227
+ height?: number;
228
+ focalPoint?: {
229
+ x: number;
230
+ y: number;
231
+ };
232
+ blurhash?: string;
233
+ type?: "upload" | "external";
234
+ provider?: string;
235
+ provider_metadata?: any;
236
+ [key: string]: any;
234
237
  }
235
238
  interface StorageAdapter {
236
- upload(args: {
237
- filename: string;
238
- buffer: Uint8Array;
239
- mimeType: string;
240
- prefix?: string;
241
- }): Promise<FileData>;
242
- delete(args: {
243
- filename: string;
244
- }): Promise<void>;
245
- getURL(args: {
246
- filename: string;
247
- }): string;
248
- /** Retrieve file content for serving via API */
249
- resolve?(args: {
250
- filename: string;
251
- }): Promise<{
252
- buffer: Uint8Array;
253
- mimeType: string;
254
- } | null>;
239
+ upload(args: { filename: string; buffer: Uint8Array; mimeType: string; prefix?: string }): Promise<FileData>;
240
+ delete(args: { filename: string }): Promise<void>;
241
+ getURL(args: { filename: string }): string;
242
+ /** Retrieve file content for serving via API */
243
+ resolve?(args: { filename: string }): Promise<{
244
+ buffer: Uint8Array;
245
+ mimeType: string;
246
+ } | null>;
255
247
  }
256
248
  /** Branding and metadata configuration for the Admin UI. */
257
249
  interface AdminConfig {
258
- branding?: {
259
- /** URL or imported image for the full logo shown in the sidebar. */
260
- logo?: string;
261
- /** URL or imported image for the compact logo mark used in collapsed sidebar. */
262
- logoMark?: string;
263
- /** Primary accent colour as a CSS value (e.g. '#6366f1' or 'hsl(240 50% 60%)') */
264
- primaryColor?: string;
265
- /** URL for the browser tab favicon. */
266
- favicon?: string;
267
- /** Default font family for body and UI elements (sans-serif). */
268
- fontSans?: string;
269
- /** Default font family for headings and display elements (serif). */
270
- fontSerif?: string;
271
- };
272
- meta?: {
273
- /** Appended to every Admin page title. Default: '- Dyrected' */
274
- titleSuffix?: string;
275
- };
250
+ branding?: {
251
+ /** URL or imported image for the full logo shown in the sidebar. */
252
+ logo?: string;
253
+ /** URL or imported image for the compact logo mark used in collapsed sidebar. */
254
+ logoMark?: string;
255
+ /** Primary accent colour as a CSS value (e.g. '#6366f1' or 'hsl(240 50% 60%)') */
256
+ primaryColor?: string;
257
+ /** URL for the browser tab favicon. */
258
+ favicon?: string;
259
+ /** Default font family for body and UI elements (sans-serif). */
260
+ fontSans?: string;
261
+ /** Default font family for headings and display elements (serif). */
262
+ fontSerif?: string;
263
+ };
264
+ meta?: {
265
+ /** Appended to every Admin page title. Default: '- Dyrected' */
266
+ titleSuffix?: string;
267
+ };
276
268
  }
277
269
  interface ImageService {
278
- process(args: {
270
+ process(args: {
271
+ buffer: Uint8Array;
272
+ mimeType: string;
273
+ config?: CollectionConfig["upload"];
274
+ focalPoint?: {
275
+ x: number;
276
+ y: number;
277
+ };
278
+ }): Promise<{
279
+ metadata: {
280
+ width?: number;
281
+ height?: number;
282
+ blurhash?: string;
283
+ };
284
+ sizes?: Record<
285
+ string,
286
+ {
279
287
  buffer: Uint8Array;
280
- mimeType: string;
281
- config?: CollectionConfig['upload'];
282
- focalPoint?: {
283
- x: number;
284
- y: number;
285
- };
286
- }): Promise<{
287
- metadata: {
288
- width?: number;
289
- height?: number;
290
- blurhash?: string;
291
- };
292
- sizes?: Record<string, {
293
- buffer: Uint8Array;
294
- width: number;
295
- height: number;
296
- filename: string;
297
- }>;
298
- }>;
288
+ width: number;
289
+ height: number;
290
+ filename: string;
291
+ }
292
+ >;
293
+ }>;
299
294
  }
300
295
  interface DyrectedConfig {
301
- collections: CollectionConfig[];
302
- globals: GlobalConfig[];
303
- db?: DatabaseAdapter;
304
- storage?: StorageAdapter;
305
- image?: ImageService;
306
- /** Admin UI branding and meta configuration. */
307
- admin?: AdminConfig;
308
- email?: {
309
- from: string;
310
- send: (args: {
311
- to: string;
312
- subject: string;
313
- html: string;
314
- }) => Promise<void>;
315
- templates?: {
316
- welcome?: (args: {
317
- email: string;
318
- }) => {
319
- subject?: string;
320
- html: string;
321
- };
322
- invite?: (args: {
323
- token: string;
324
- invitedByEmail?: string;
325
- }) => {
326
- subject?: string;
327
- html: string;
328
- };
329
- resetPassword?: (args: {
330
- token: string;
331
- }) => {
332
- subject?: string;
333
- html: string;
334
- };
335
- passwordChanged?: (args: {
336
- email: string;
337
- }) => {
338
- subject?: string;
339
- html: string;
340
- };
341
- };
342
- };
343
- redis?: {
344
- url: string;
345
- };
346
- cors?: {
347
- origins: string[];
296
+ collections: CollectionConfig[];
297
+ globals: GlobalConfig[];
298
+ db?: DatabaseAdapter;
299
+ storage?: StorageAdapter;
300
+ image?: ImageService;
301
+ /** Admin UI branding and meta configuration. */
302
+ admin?: AdminConfig;
303
+ email?: {
304
+ from: string;
305
+ send: (args: { to: string; subject: string; html: string }) => Promise<void>;
306
+ templates?: {
307
+ welcome?: (args: { email: string }) => {
308
+ subject?: string;
309
+ html: string;
310
+ };
311
+ invite?: (args: { token: string; invitedByEmail?: string }) => {
312
+ subject?: string;
313
+ html: string;
314
+ };
315
+ resetPassword?: (args: { token: string }) => {
316
+ subject?: string;
317
+ html: string;
318
+ };
319
+ passwordChanged?: (args: { email: string }) => {
320
+ subject?: string;
321
+ html: string;
322
+ };
348
323
  };
349
- onSchemaFetch?: (siteId: string) => Promise<{
350
- collections?: CollectionConfig[];
351
- globals?: GlobalConfig[];
352
- }>;
324
+ };
325
+ redis?: {
326
+ url: string;
327
+ };
328
+ cors?: {
329
+ origins: string[];
330
+ };
331
+ onSchemaFetch?: (siteId: string) => Promise<{
332
+ collections?: CollectionConfig[];
333
+ globals?: GlobalConfig[];
334
+ }>;
353
335
  }
354
336
 
355
337
  interface DyrectedContext {
356
- Variables: {
357
- config: DyrectedConfig;
358
- siteId?: string;
359
- workspaceId?: string;
360
- /** Decoded JWT payload set by requireAuth() or optionalAuth() middleware. */
361
- user?: {
362
- sub: string;
363
- email: string;
364
- collection: string;
365
- [key: string]: any;
366
- };
338
+ Variables: {
339
+ config: DyrectedConfig;
340
+ siteId?: string;
341
+ workspaceId?: string;
342
+ /** Decoded JWT payload set by requireAuth() or optionalAuth() middleware. */
343
+ user?: {
344
+ sub: string;
345
+ email: string;
346
+ collection: string;
347
+ [key: string]: any;
367
348
  };
349
+ };
368
350
  }
369
351
  /**
370
352
  * Create the main Dyrected Hono application.
371
353
  */
372
- declare function createDyrectedApp(rawConfig: DyrectedConfig): Promise<Hono<DyrectedContext, hono_types.BlankSchema, "/">>;
354
+ declare function createDyrectedApp(
355
+ rawConfig: DyrectedConfig,
356
+ ): Promise<Hono<DyrectedContext, hono_types.BlankSchema, "/">>;
373
357
 
374
- export { type AccessFunction as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type Field as F, type GlobalConfig as G, type HookFunction as H, type ImageService as I, type PaginatedResult as P, type StorageAdapter as S, type UploadConfig as U, type AdminConfig as a, type DatabaseAdapter as b, type DyrectedContext as c, type FieldHook as d, type FieldType as e, type FileData as f, createDyrectedApp as g };
358
+ export {
359
+ type AccessFunction as A,
360
+ type Block as B,
361
+ type CollectionConfig as C,
362
+ type DyrectedConfig as D,
363
+ type Field as F,
364
+ type GlobalConfig as G,
365
+ type HookFunction as H,
366
+ type ImageService as I,
367
+ type PaginatedResult as P,
368
+ type StorageAdapter as S,
369
+ type UploadConfig as U,
370
+ type AdminConfig as a,
371
+ type DatabaseAdapter as b,
372
+ type DyrectedContext as c,
373
+ type FieldHook as d,
374
+ type FieldType as e,
375
+ type FileData as f,
376
+ createDyrectedApp as g,
377
+ };