@dyrected/core 2.0.0 → 2.4.0

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