@dyrected/core 0.0.1 → 1.0.1

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