@momentumcms/core 0.1.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.
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/index.cjs +730 -0
- package/package.json +32 -0
- package/src/generators/types/generator.d.ts +27 -0
- package/src/index.d.ts +14 -0
- package/src/lib/access/access-helpers.d.ts +212 -0
- package/src/lib/access/index.d.ts +6 -0
- package/src/lib/collections/collection.types.d.ts +279 -0
- package/src/lib/collections/define-collection.d.ts +53 -0
- package/src/lib/collections/index.d.ts +5 -0
- package/src/lib/collections/media.collection.d.ts +29 -0
- package/src/lib/config.d.ts +355 -0
- package/src/lib/fields/field-builders.d.ts +131 -0
- package/src/lib/fields/field-validators.d.ts +18 -0
- package/src/lib/fields/field.types.d.ts +271 -0
- package/src/lib/fields/humanize-field-name.d.ts +12 -0
- package/src/lib/fields/index.d.ts +6 -0
- package/src/lib/plugins.d.ts +176 -0
- package/src/lib/seeding/index.d.ts +7 -0
- package/src/lib/seeding/seed-helpers.d.ts +22 -0
- package/src/lib/seeding/seeding.types.d.ts +459 -0
- package/src/lib/storage/index.d.ts +86 -0
- package/src/lib/versions/index.d.ts +5 -0
- package/src/lib/versions/version.types.d.ts +149 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeding Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the Momentum CMS seeding system.
|
|
5
|
+
* Provides declarative data seeding with strict typing and IntelliSense support.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Options for individual seed entity creation.
|
|
9
|
+
*/
|
|
10
|
+
export interface SeedEntityOptions {
|
|
11
|
+
/**
|
|
12
|
+
* What to do if seedId already exists.
|
|
13
|
+
* - 'skip': Don't touch existing seed (default)
|
|
14
|
+
* - 'update': Update if data changed (checksum differs)
|
|
15
|
+
* - 'error': Throw SeedConflictError
|
|
16
|
+
*/
|
|
17
|
+
onConflict?: 'skip' | 'update' | 'error';
|
|
18
|
+
/**
|
|
19
|
+
* Skip lifecycle hooks during seeding.
|
|
20
|
+
* Useful for performance when seeding large amounts of data.
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
23
|
+
skipHooks?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Skip access control checks during seeding.
|
|
26
|
+
* Seeds typically run in a trusted context.
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
skipAccessControl?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Use Better Auth signup API to create this user with proper password hashing.
|
|
32
|
+
* When true, the seed executor will call auth.api.signUpEmail() instead of
|
|
33
|
+
* directly inserting into the database, ensuring passwords are properly hashed
|
|
34
|
+
* and account/session tables are populated.
|
|
35
|
+
*
|
|
36
|
+
* Requires `auth` to be passed to `initializeMomentum` options.
|
|
37
|
+
* Only applies to new seeds (not on 'skip' or 'update').
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
useAuthSignup?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Represents a single seed entity definition.
|
|
44
|
+
*/
|
|
45
|
+
export interface SeedEntity<TData = Record<string, unknown>> {
|
|
46
|
+
/**
|
|
47
|
+
* Unique identifier for this seed (user-provided).
|
|
48
|
+
* Used to track seeding state and prevent duplicates.
|
|
49
|
+
*/
|
|
50
|
+
seedId: string;
|
|
51
|
+
/**
|
|
52
|
+
* Collection slug to seed into.
|
|
53
|
+
*/
|
|
54
|
+
collection: string;
|
|
55
|
+
/**
|
|
56
|
+
* Data to create in the collection.
|
|
57
|
+
*/
|
|
58
|
+
data: TData;
|
|
59
|
+
/**
|
|
60
|
+
* Options for this specific entity.
|
|
61
|
+
*/
|
|
62
|
+
options?: SeedEntityOptions;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Result of a seeded document operation.
|
|
66
|
+
*/
|
|
67
|
+
export interface SeededDocument<T = Record<string, unknown>> {
|
|
68
|
+
/**
|
|
69
|
+
* The actual document ID in the database.
|
|
70
|
+
*/
|
|
71
|
+
id: string;
|
|
72
|
+
/**
|
|
73
|
+
* The seed ID used to create/identify this seed.
|
|
74
|
+
*/
|
|
75
|
+
seedId: string;
|
|
76
|
+
/**
|
|
77
|
+
* Collection slug where the document was seeded.
|
|
78
|
+
*/
|
|
79
|
+
collection: string;
|
|
80
|
+
/**
|
|
81
|
+
* The created/updated document data.
|
|
82
|
+
*/
|
|
83
|
+
data: T;
|
|
84
|
+
/**
|
|
85
|
+
* What action was taken.
|
|
86
|
+
* - 'created': New document was created
|
|
87
|
+
* - 'updated': Existing document was updated (data changed)
|
|
88
|
+
* - 'skipped': Document already exists and was not modified
|
|
89
|
+
*/
|
|
90
|
+
action: 'created' | 'updated' | 'skipped';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Typed seed builder for a specific collection.
|
|
94
|
+
* Provides IntelliSense for collection document types.
|
|
95
|
+
*/
|
|
96
|
+
export interface CollectionSeedBuilder<TDoc> {
|
|
97
|
+
/**
|
|
98
|
+
* Create a seed entity for this collection.
|
|
99
|
+
*
|
|
100
|
+
* @param seedId - Unique identifier for this seed
|
|
101
|
+
* @param data - Document data to seed
|
|
102
|
+
* @param options - Optional seed options
|
|
103
|
+
* @returns Seed entity definition
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* collection<PostDoc>('posts').create('welcome-post', {
|
|
108
|
+
* title: 'Welcome!',
|
|
109
|
+
* status: 'published',
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
create: (seedId: string, data: Partial<TDoc>, options?: SeedEntityOptions) => SeedEntity<TDoc>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* User seed data structure for Better Auth user table.
|
|
117
|
+
*/
|
|
118
|
+
export interface UserSeedData {
|
|
119
|
+
/**
|
|
120
|
+
* User's display name.
|
|
121
|
+
*/
|
|
122
|
+
name: string;
|
|
123
|
+
/**
|
|
124
|
+
* User's email address (unique).
|
|
125
|
+
*/
|
|
126
|
+
email: string;
|
|
127
|
+
/**
|
|
128
|
+
* User's role.
|
|
129
|
+
* @default 'user'
|
|
130
|
+
*/
|
|
131
|
+
role?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Whether email is verified.
|
|
134
|
+
* @default false
|
|
135
|
+
*/
|
|
136
|
+
emailVerified?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* User's avatar image URL.
|
|
139
|
+
*/
|
|
140
|
+
image?: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Admin seed data structure for the first admin user.
|
|
144
|
+
* Same as UserSeedData but with admin-friendly defaults.
|
|
145
|
+
*/
|
|
146
|
+
export interface AdminSeedData {
|
|
147
|
+
/**
|
|
148
|
+
* Admin's display name.
|
|
149
|
+
*/
|
|
150
|
+
name: string;
|
|
151
|
+
/**
|
|
152
|
+
* Admin's email address (unique).
|
|
153
|
+
*/
|
|
154
|
+
email: string;
|
|
155
|
+
/**
|
|
156
|
+
* Admin's role.
|
|
157
|
+
* @default 'admin'
|
|
158
|
+
*/
|
|
159
|
+
role?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Whether email is verified.
|
|
162
|
+
* @default true (admins are typically pre-verified)
|
|
163
|
+
*/
|
|
164
|
+
emailVerified?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Admin's avatar image URL.
|
|
167
|
+
*/
|
|
168
|
+
image?: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Auth user seed data structure.
|
|
172
|
+
* Seeds directly into the Better Auth user table (auth-user collection).
|
|
173
|
+
* When used with the `authUser()` helper, the seed executor calls
|
|
174
|
+
* Better Auth's signUpEmail API to ensure proper password hashing.
|
|
175
|
+
*/
|
|
176
|
+
export interface AuthUserSeedData {
|
|
177
|
+
[key: string]: unknown;
|
|
178
|
+
/**
|
|
179
|
+
* User's display name.
|
|
180
|
+
*/
|
|
181
|
+
name: string;
|
|
182
|
+
/**
|
|
183
|
+
* User's email address (unique).
|
|
184
|
+
*/
|
|
185
|
+
email: string;
|
|
186
|
+
/**
|
|
187
|
+
* User's password (will be hashed by Better Auth).
|
|
188
|
+
* Must be at least 8 characters.
|
|
189
|
+
*/
|
|
190
|
+
password: string;
|
|
191
|
+
/**
|
|
192
|
+
* User's role.
|
|
193
|
+
* @default 'user'
|
|
194
|
+
*/
|
|
195
|
+
role?: string;
|
|
196
|
+
/**
|
|
197
|
+
* Whether email is verified.
|
|
198
|
+
* @default true
|
|
199
|
+
*/
|
|
200
|
+
emailVerified?: boolean;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Default entity helpers with IntelliSense support.
|
|
204
|
+
* Used in the `defaults` function of SeedingConfig.
|
|
205
|
+
*/
|
|
206
|
+
export interface DefaultEntityHelpers {
|
|
207
|
+
/**
|
|
208
|
+
* Create the first admin user seed entity.
|
|
209
|
+
* Pre-configured with admin role and verified email.
|
|
210
|
+
*
|
|
211
|
+
* @param seedId - Unique identifier for this seed
|
|
212
|
+
* @param data - Admin user data
|
|
213
|
+
* @param options - Optional seed options
|
|
214
|
+
* @returns Seed entity definition
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* admin('first-admin', {
|
|
219
|
+
* name: 'System Admin',
|
|
220
|
+
* email: 'admin@example.com',
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
admin: (seedId: string, data: AdminSeedData, options?: SeedEntityOptions) => SeedEntity<UserSeedData>;
|
|
225
|
+
/**
|
|
226
|
+
* Create a user seed entity for the Better Auth user table.
|
|
227
|
+
*
|
|
228
|
+
* @param seedId - Unique identifier for this seed
|
|
229
|
+
* @param data - User data
|
|
230
|
+
* @param options - Optional seed options
|
|
231
|
+
* @returns Seed entity definition
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* user('regular-user', {
|
|
236
|
+
* name: 'John Doe',
|
|
237
|
+
* email: 'john@example.com',
|
|
238
|
+
* });
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
user: (seedId: string, data: UserSeedData, options?: SeedEntityOptions) => SeedEntity<UserSeedData>;
|
|
242
|
+
/**
|
|
243
|
+
* Create a typed collection seed builder.
|
|
244
|
+
* Provides full IntelliSense for the document type.
|
|
245
|
+
*
|
|
246
|
+
* @param slug - Collection slug
|
|
247
|
+
* @returns Collection seed builder
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* collection<PostDoc>('posts').create('welcome', {
|
|
252
|
+
* title: 'Welcome!',
|
|
253
|
+
* status: 'published',
|
|
254
|
+
* });
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
collection: <TDoc>(slug: string) => CollectionSeedBuilder<TDoc>;
|
|
258
|
+
/**
|
|
259
|
+
* Create an auth user seed entity with password support.
|
|
260
|
+
* Seeds into the Better Auth user table using signUpEmail API
|
|
261
|
+
* to ensure proper password hashing and account creation.
|
|
262
|
+
*
|
|
263
|
+
* @param seedId - Unique identifier for this seed
|
|
264
|
+
* @param data - User data including password
|
|
265
|
+
* @param options - Optional seed options
|
|
266
|
+
* @returns Seed entity definition with useAuthSignup enabled
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* authUser('admin-user', {
|
|
271
|
+
* name: 'Admin',
|
|
272
|
+
* email: 'admin@example.com',
|
|
273
|
+
* password: 'SecurePass123!',
|
|
274
|
+
* role: 'admin',
|
|
275
|
+
* });
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
authUser: (seedId: string, data: AuthUserSeedData, options?: SeedEntityOptions) => SeedEntity<AuthUserSeedData>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Context passed to the custom seed function.
|
|
282
|
+
* Provides utilities for seeding with dependency resolution.
|
|
283
|
+
*/
|
|
284
|
+
export interface SeedContext {
|
|
285
|
+
/**
|
|
286
|
+
* Get a previously seeded document by its seedId.
|
|
287
|
+
* Useful for creating relationships between seeded entities.
|
|
288
|
+
*
|
|
289
|
+
* @param seedId - The seed ID to look up
|
|
290
|
+
* @returns The seeded document or null if not found
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```typescript
|
|
294
|
+
* const adminUser = await ctx.getSeeded('admin-user');
|
|
295
|
+
* await ctx.seed({
|
|
296
|
+
* seedId: 'admin-post',
|
|
297
|
+
* collection: 'posts',
|
|
298
|
+
* data: { authorId: adminUser?.id },
|
|
299
|
+
* });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
getSeeded: <T = Record<string, unknown>>(seedId: string) => Promise<SeededDocument<T> | null>;
|
|
303
|
+
/**
|
|
304
|
+
* Create a seed entity with tracking.
|
|
305
|
+
*
|
|
306
|
+
* @param entity - Seed entity definition
|
|
307
|
+
* @returns The seeded document result
|
|
308
|
+
*/
|
|
309
|
+
seed: <T = Record<string, unknown>>(entity: SeedEntity<T>) => Promise<SeededDocument<T>>;
|
|
310
|
+
/**
|
|
311
|
+
* Log a message (respects quiet mode).
|
|
312
|
+
*
|
|
313
|
+
* @param message - Message to log
|
|
314
|
+
*/
|
|
315
|
+
log: (message: string) => void;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Global seeding options.
|
|
319
|
+
*/
|
|
320
|
+
export interface SeedingOptions {
|
|
321
|
+
/**
|
|
322
|
+
* Default conflict handling strategy.
|
|
323
|
+
* @default 'skip'
|
|
324
|
+
*/
|
|
325
|
+
onConflict?: 'skip' | 'update' | 'error';
|
|
326
|
+
/**
|
|
327
|
+
* When to run seeding on server start.
|
|
328
|
+
* - 'development': Only when NODE_ENV is 'development'
|
|
329
|
+
* - 'always': Run on every server start
|
|
330
|
+
* - true: Same as 'always'
|
|
331
|
+
* - false: Never run automatically (can be triggered via CLI)
|
|
332
|
+
* @default 'development'
|
|
333
|
+
*/
|
|
334
|
+
runOnStart?: boolean | 'development' | 'always';
|
|
335
|
+
/**
|
|
336
|
+
* Suppress seeding log messages.
|
|
337
|
+
* @default false
|
|
338
|
+
*/
|
|
339
|
+
quiet?: boolean;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Seeding configuration for Momentum CMS.
|
|
343
|
+
*/
|
|
344
|
+
export interface SeedingConfig {
|
|
345
|
+
/**
|
|
346
|
+
* Default entities to seed first (in order).
|
|
347
|
+
* Uses helper methods for strict typing.
|
|
348
|
+
*
|
|
349
|
+
* @param helpers - Typed entity helpers
|
|
350
|
+
* @returns Array of seed entities to create
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```typescript
|
|
354
|
+
* defaults: ({ user, collection }) => [
|
|
355
|
+
* user('admin', { name: 'Admin', email: 'admin@example.com', role: 'admin' }),
|
|
356
|
+
* collection<PostDoc>('posts').create('welcome', { title: 'Welcome!' }),
|
|
357
|
+
* ]
|
|
358
|
+
* ```
|
|
359
|
+
*/
|
|
360
|
+
defaults?: (helpers: DefaultEntityHelpers) => SeedEntity[];
|
|
361
|
+
/**
|
|
362
|
+
* Custom seed function for complex scenarios.
|
|
363
|
+
* Runs after defaults, has access to SeedContext for dependency resolution.
|
|
364
|
+
*
|
|
365
|
+
* @param ctx - Seeding context with utilities
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```typescript
|
|
369
|
+
* seed: async (ctx) => {
|
|
370
|
+
* const admin = await ctx.getSeeded('admin');
|
|
371
|
+
* await ctx.seed({
|
|
372
|
+
* seedId: 'admin-post',
|
|
373
|
+
* collection: 'posts',
|
|
374
|
+
* data: { authorId: admin?.id },
|
|
375
|
+
* });
|
|
376
|
+
* }
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
seed?: (ctx: SeedContext) => Promise<void>;
|
|
380
|
+
/**
|
|
381
|
+
* Global seeding options.
|
|
382
|
+
*/
|
|
383
|
+
options?: SeedingOptions;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Internal seed tracking document stored in _momentum_seeds table.
|
|
387
|
+
*/
|
|
388
|
+
export interface SeedTrackingDocument {
|
|
389
|
+
/**
|
|
390
|
+
* Primary key (auto-generated UUID).
|
|
391
|
+
*/
|
|
392
|
+
id: string;
|
|
393
|
+
/**
|
|
394
|
+
* User-provided unique seed identifier.
|
|
395
|
+
*/
|
|
396
|
+
seedId: string;
|
|
397
|
+
/**
|
|
398
|
+
* Collection the entity was seeded into.
|
|
399
|
+
*/
|
|
400
|
+
collection: string;
|
|
401
|
+
/**
|
|
402
|
+
* Actual document ID in the target collection.
|
|
403
|
+
*/
|
|
404
|
+
documentId: string;
|
|
405
|
+
/**
|
|
406
|
+
* SHA-256 hash of the seed data for change detection.
|
|
407
|
+
*/
|
|
408
|
+
checksum: string;
|
|
409
|
+
/**
|
|
410
|
+
* When this seed was first created.
|
|
411
|
+
*/
|
|
412
|
+
createdAt: string;
|
|
413
|
+
/**
|
|
414
|
+
* When this seed was last updated.
|
|
415
|
+
*/
|
|
416
|
+
updatedAt: string;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Slug for the internal seed tracking collection.
|
|
420
|
+
*/
|
|
421
|
+
export declare const SEED_TRACKING_COLLECTION_SLUG = "_momentum_seeds";
|
|
422
|
+
/**
|
|
423
|
+
* Error thrown when a seed conflict occurs with onConflict: 'error'.
|
|
424
|
+
*/
|
|
425
|
+
export declare class SeedConflictError extends Error {
|
|
426
|
+
readonly seedId: string;
|
|
427
|
+
readonly collection: string;
|
|
428
|
+
constructor(seedId: string, collection: string);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Information about a seed that was rolled back.
|
|
432
|
+
*/
|
|
433
|
+
export interface RolledBackSeed {
|
|
434
|
+
/** The seed ID that was rolled back */
|
|
435
|
+
seedId: string;
|
|
436
|
+
/** The collection the seed was in */
|
|
437
|
+
collection: string;
|
|
438
|
+
/** The document ID that was deleted */
|
|
439
|
+
documentId: string;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Error thrown when seeding fails and rollback is performed.
|
|
443
|
+
* Contains the original error and information about rolled back seeds.
|
|
444
|
+
*/
|
|
445
|
+
export declare class SeedRollbackError extends Error {
|
|
446
|
+
/** The original error that caused the rollback */
|
|
447
|
+
readonly originalError: Error;
|
|
448
|
+
/** Seeds that were successfully rolled back */
|
|
449
|
+
readonly rolledBackSeeds: RolledBackSeed[];
|
|
450
|
+
/** Seeds that failed to roll back */
|
|
451
|
+
readonly rollbackFailures: Array<{
|
|
452
|
+
seed: RolledBackSeed;
|
|
453
|
+
error: Error;
|
|
454
|
+
}>;
|
|
455
|
+
constructor(originalError: Error, rolledBackSeeds: RolledBackSeed[], rollbackFailures: Array<{
|
|
456
|
+
seed: RolledBackSeed;
|
|
457
|
+
error: Error;
|
|
458
|
+
}>);
|
|
459
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage module for Momentum CMS
|
|
3
|
+
* Defines interfaces for file storage adapters
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Represents an uploaded file before storage.
|
|
7
|
+
*/
|
|
8
|
+
export interface UploadedFile {
|
|
9
|
+
/** Original filename */
|
|
10
|
+
originalName: string;
|
|
11
|
+
/** MIME type of the file */
|
|
12
|
+
mimeType: string;
|
|
13
|
+
/** File size in bytes */
|
|
14
|
+
size: number;
|
|
15
|
+
/** File content as Buffer */
|
|
16
|
+
buffer: Buffer;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Represents a file after it has been stored.
|
|
20
|
+
*/
|
|
21
|
+
export interface StoredFile {
|
|
22
|
+
/** Storage path/key */
|
|
23
|
+
path: string;
|
|
24
|
+
/** Public URL to access the file */
|
|
25
|
+
url: string;
|
|
26
|
+
/** Stored filename */
|
|
27
|
+
filename: string;
|
|
28
|
+
/** MIME type */
|
|
29
|
+
mimeType: string;
|
|
30
|
+
/** File size in bytes */
|
|
31
|
+
size: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Options for upload operations.
|
|
35
|
+
*/
|
|
36
|
+
export interface UploadOptions {
|
|
37
|
+
/** Custom filename (without extension) */
|
|
38
|
+
filename?: string;
|
|
39
|
+
/** Subdirectory within the upload directory */
|
|
40
|
+
directory?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Storage adapter interface.
|
|
44
|
+
* Implement this interface to create custom storage backends.
|
|
45
|
+
*/
|
|
46
|
+
export interface StorageAdapter {
|
|
47
|
+
/**
|
|
48
|
+
* Upload a file to storage.
|
|
49
|
+
* @param file - The file to upload
|
|
50
|
+
* @param options - Upload options
|
|
51
|
+
* @returns The stored file metadata
|
|
52
|
+
*/
|
|
53
|
+
upload(file: UploadedFile, options?: UploadOptions): Promise<StoredFile>;
|
|
54
|
+
/**
|
|
55
|
+
* Delete a file from storage.
|
|
56
|
+
* @param path - The storage path/key of the file
|
|
57
|
+
* @returns True if deleted, false if not found
|
|
58
|
+
*/
|
|
59
|
+
delete(path: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Get the public URL for a stored file.
|
|
62
|
+
* @param path - The storage path/key
|
|
63
|
+
* @returns The public URL
|
|
64
|
+
*/
|
|
65
|
+
getUrl(path: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a file exists in storage.
|
|
68
|
+
* @param path - The storage path/key
|
|
69
|
+
* @returns True if exists
|
|
70
|
+
*/
|
|
71
|
+
exists(path: string): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Get a signed URL for temporary access (optional).
|
|
74
|
+
* Useful for private S3 buckets.
|
|
75
|
+
* @param path - The storage path/key
|
|
76
|
+
* @param expiresIn - Expiration time in seconds
|
|
77
|
+
* @returns The signed URL
|
|
78
|
+
*/
|
|
79
|
+
getSignedUrl?(path: string, expiresIn?: number): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Read a file from storage.
|
|
82
|
+
* @param path - The storage path/key
|
|
83
|
+
* @returns The file as a Buffer, or null if not found
|
|
84
|
+
*/
|
|
85
|
+
read?(path: string): Promise<Buffer | null>;
|
|
86
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version Types for Momentum CMS
|
|
3
|
+
* Defines the structure of document versions and drafts
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Status of a document in a versioned collection.
|
|
7
|
+
* - 'draft': Document is not publicly visible
|
|
8
|
+
* - 'published': Document is publicly visible
|
|
9
|
+
*/
|
|
10
|
+
export type DocumentStatus = 'draft' | 'published';
|
|
11
|
+
/**
|
|
12
|
+
* Represents a single version of a document.
|
|
13
|
+
* Each version stores a full snapshot of the document at a point in time.
|
|
14
|
+
*/
|
|
15
|
+
export interface DocumentVersion {
|
|
16
|
+
/** Unique identifier for this version */
|
|
17
|
+
id: string;
|
|
18
|
+
/** ID of the parent document this version belongs to */
|
|
19
|
+
parent: string;
|
|
20
|
+
/** Full document snapshot stored as JSON string */
|
|
21
|
+
version: string;
|
|
22
|
+
/** Status of this version */
|
|
23
|
+
_status: DocumentStatus;
|
|
24
|
+
/** Whether this version was created by autosave */
|
|
25
|
+
autosave: boolean;
|
|
26
|
+
/** When this version was published (if published) */
|
|
27
|
+
publishedAt?: string;
|
|
28
|
+
/** When this version was created */
|
|
29
|
+
createdAt: string;
|
|
30
|
+
/** When this version was last updated */
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Document version with parsed version data.
|
|
35
|
+
* Used when returning versions to the API layer.
|
|
36
|
+
*/
|
|
37
|
+
export interface DocumentVersionParsed<T = Record<string, unknown>> {
|
|
38
|
+
/** Unique identifier for this version */
|
|
39
|
+
id: string;
|
|
40
|
+
/** ID of the parent document this version belongs to */
|
|
41
|
+
parent: string;
|
|
42
|
+
/** Parsed document snapshot */
|
|
43
|
+
version: T;
|
|
44
|
+
/** Status of this version */
|
|
45
|
+
_status: DocumentStatus;
|
|
46
|
+
/** Whether this version was created by autosave */
|
|
47
|
+
autosave: boolean;
|
|
48
|
+
/** When this version was published (if published) */
|
|
49
|
+
publishedAt?: string;
|
|
50
|
+
/** When this version was created */
|
|
51
|
+
createdAt: string;
|
|
52
|
+
/** When this version was last updated */
|
|
53
|
+
updatedAt: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Options for counting versions (filter options only, no pagination).
|
|
57
|
+
*/
|
|
58
|
+
export interface VersionCountOptions {
|
|
59
|
+
/** Include autosave versions in count (default: false) */
|
|
60
|
+
includeAutosave?: boolean;
|
|
61
|
+
/** Filter by status */
|
|
62
|
+
status?: DocumentStatus;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Options for querying versions of a document.
|
|
66
|
+
*/
|
|
67
|
+
export interface VersionQueryOptions extends VersionCountOptions {
|
|
68
|
+
/** Maximum number of versions to return */
|
|
69
|
+
limit?: number;
|
|
70
|
+
/** Page number for pagination (1-based) */
|
|
71
|
+
page?: number;
|
|
72
|
+
/** Sort order (default: 'desc' = newest first) */
|
|
73
|
+
sort?: 'asc' | 'desc';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Result of a version query with pagination info.
|
|
77
|
+
*/
|
|
78
|
+
export interface VersionQueryResult<T = Record<string, unknown>> {
|
|
79
|
+
/** Array of versions */
|
|
80
|
+
docs: DocumentVersionParsed<T>[];
|
|
81
|
+
/** Total number of versions */
|
|
82
|
+
totalDocs: number;
|
|
83
|
+
/** Total number of pages */
|
|
84
|
+
totalPages: number;
|
|
85
|
+
/** Current page number */
|
|
86
|
+
page: number;
|
|
87
|
+
/** Items per page */
|
|
88
|
+
limit: number;
|
|
89
|
+
/** Whether there is a next page */
|
|
90
|
+
hasNextPage: boolean;
|
|
91
|
+
/** Whether there is a previous page */
|
|
92
|
+
hasPrevPage: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Options for restoring a version.
|
|
96
|
+
*/
|
|
97
|
+
export interface RestoreVersionOptions {
|
|
98
|
+
/** The version ID to restore */
|
|
99
|
+
versionId: string;
|
|
100
|
+
/** The document ID that the version must belong to (validated when provided) */
|
|
101
|
+
docId?: string;
|
|
102
|
+
/** Whether to publish the restored version immediately (default: false) */
|
|
103
|
+
publish?: boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Options for creating a version.
|
|
107
|
+
*/
|
|
108
|
+
export interface CreateVersionOptions {
|
|
109
|
+
/** Status of the new version */
|
|
110
|
+
status?: DocumentStatus;
|
|
111
|
+
/** Whether this is an autosave version */
|
|
112
|
+
autosave?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Options for publishing a document.
|
|
116
|
+
*/
|
|
117
|
+
export interface PublishOptions {
|
|
118
|
+
/** Scheduled publish date (ISO string). If provided, document will be scheduled for future publishing. */
|
|
119
|
+
scheduledPublishAt?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Options for scheduling a document publish.
|
|
123
|
+
*/
|
|
124
|
+
export interface SchedulePublishOptions {
|
|
125
|
+
/** ISO date string for when the document should be published. */
|
|
126
|
+
publishAt: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Result of a schedule publish operation.
|
|
130
|
+
*/
|
|
131
|
+
export interface SchedulePublishResult {
|
|
132
|
+
/** Document ID */
|
|
133
|
+
id: string;
|
|
134
|
+
/** Scheduled publish date (ISO string) */
|
|
135
|
+
scheduledPublishAt: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Event data passed to version-related hooks.
|
|
139
|
+
*/
|
|
140
|
+
export interface VersionHookArgs {
|
|
141
|
+
/** The version being operated on */
|
|
142
|
+
version: DocumentVersion;
|
|
143
|
+
/** The parent document ID */
|
|
144
|
+
parentId: string;
|
|
145
|
+
/** The collection slug */
|
|
146
|
+
collection: string;
|
|
147
|
+
/** The operation being performed */
|
|
148
|
+
operation: 'create' | 'restore' | 'publish' | 'unpublish' | 'delete';
|
|
149
|
+
}
|