@momentumcms/core 0.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/CHANGELOG.md +34 -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,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field Types for Momentum CMS
|
|
3
|
+
* Defines all available field types and their configurations
|
|
4
|
+
*/
|
|
5
|
+
export interface BaseFieldOptions {
|
|
6
|
+
required?: boolean;
|
|
7
|
+
unique?: boolean;
|
|
8
|
+
defaultValue?: unknown;
|
|
9
|
+
label?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
admin?: FieldAdminConfig;
|
|
12
|
+
access?: FieldAccessConfig;
|
|
13
|
+
hooks?: FieldHooksConfig;
|
|
14
|
+
validate?: ValidateFunction;
|
|
15
|
+
}
|
|
16
|
+
export interface FieldAdminConfig {
|
|
17
|
+
position?: 'sidebar' | 'main';
|
|
18
|
+
width?: 'full' | 'half' | 'third';
|
|
19
|
+
condition?: (data: Record<string, unknown>) => boolean;
|
|
20
|
+
readOnly?: boolean;
|
|
21
|
+
hidden?: boolean;
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
/** For blocks fields: editor rendering mode. 'visual' enables the WYSIWYG block editor. */
|
|
24
|
+
editor?: 'visual' | 'form';
|
|
25
|
+
/** Render this group field as a collapsible accordion section */
|
|
26
|
+
collapsible?: boolean;
|
|
27
|
+
/** Whether the collapsible section starts expanded (default: false) */
|
|
28
|
+
defaultOpen?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface FieldAccessConfig {
|
|
31
|
+
create?: FieldAccessFunction;
|
|
32
|
+
read?: FieldAccessFunction;
|
|
33
|
+
update?: FieldAccessFunction;
|
|
34
|
+
}
|
|
35
|
+
export type FieldAccessFunction = (args: {
|
|
36
|
+
req: unknown;
|
|
37
|
+
data?: Record<string, unknown>;
|
|
38
|
+
doc?: Record<string, unknown>;
|
|
39
|
+
}) => boolean | Promise<boolean>;
|
|
40
|
+
export interface FieldHooksConfig {
|
|
41
|
+
beforeValidate?: FieldHookFunction[];
|
|
42
|
+
beforeChange?: FieldHookFunction[];
|
|
43
|
+
afterChange?: FieldHookFunction[];
|
|
44
|
+
afterRead?: FieldHookFunction[];
|
|
45
|
+
}
|
|
46
|
+
export type FieldHookFunction = (args: {
|
|
47
|
+
value: unknown;
|
|
48
|
+
data: Record<string, unknown>;
|
|
49
|
+
req: unknown;
|
|
50
|
+
operation: 'create' | 'update' | 'read';
|
|
51
|
+
}) => unknown | Promise<unknown>;
|
|
52
|
+
export type ValidateFunction = (value: unknown, args: {
|
|
53
|
+
data: Record<string, unknown>;
|
|
54
|
+
req: unknown;
|
|
55
|
+
}) => string | true | Promise<string | true>;
|
|
56
|
+
/** Display format configuration for number fields. Maps to Intl.NumberFormat options. */
|
|
57
|
+
export interface NumberDisplayFormat {
|
|
58
|
+
/** Formatting style: 'currency' for prices, 'percent' for percentages, 'decimal' for plain numbers */
|
|
59
|
+
style?: 'decimal' | 'currency' | 'percent';
|
|
60
|
+
/** ISO 4217 currency code (e.g. 'USD', 'EUR'). Required when style is 'currency'. */
|
|
61
|
+
currency?: string;
|
|
62
|
+
/** BCP 47 locale tag (e.g. 'en-US'). Defaults to browser locale. */
|
|
63
|
+
locale?: string;
|
|
64
|
+
/** Minimum number of fraction digits to display */
|
|
65
|
+
minimumFractionDigits?: number;
|
|
66
|
+
/** Maximum number of fraction digits to display */
|
|
67
|
+
maximumFractionDigits?: number;
|
|
68
|
+
}
|
|
69
|
+
/** Preset date/time format styles, mapping to Intl.DateTimeFormat dateStyle/timeStyle */
|
|
70
|
+
export type DateDisplayPreset = 'short' | 'medium' | 'long' | 'full';
|
|
71
|
+
/** Display format configuration for date fields. Maps to Intl.DateTimeFormat options. */
|
|
72
|
+
export interface DateDisplayFormat {
|
|
73
|
+
/** Preset format style (maps to Intl.DateTimeFormat dateStyle) */
|
|
74
|
+
preset?: DateDisplayPreset;
|
|
75
|
+
/** BCP 47 locale tag. Defaults to browser locale. */
|
|
76
|
+
locale?: string;
|
|
77
|
+
/** Whether to include time in the display. Defaults to false. */
|
|
78
|
+
includeTime?: boolean;
|
|
79
|
+
/** Time style when includeTime is true (maps to Intl.DateTimeFormat timeStyle) */
|
|
80
|
+
timePreset?: DateDisplayPreset;
|
|
81
|
+
}
|
|
82
|
+
export type FieldType = 'text' | 'textarea' | 'richText' | 'number' | 'date' | 'checkbox' | 'select' | 'radio' | 'email' | 'password' | 'upload' | 'relationship' | 'array' | 'group' | 'blocks' | 'json' | 'point' | 'slug' | 'tabs' | 'collapsible' | 'row';
|
|
83
|
+
/** Layout field types that organize form fields visually but don't store data */
|
|
84
|
+
export declare const LAYOUT_FIELD_TYPES: ReadonlySet<FieldType>;
|
|
85
|
+
export interface BaseField {
|
|
86
|
+
name: string;
|
|
87
|
+
type: FieldType;
|
|
88
|
+
required?: boolean;
|
|
89
|
+
unique?: boolean;
|
|
90
|
+
defaultValue?: unknown;
|
|
91
|
+
label?: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
admin?: FieldAdminConfig;
|
|
94
|
+
access?: FieldAccessConfig;
|
|
95
|
+
hooks?: FieldHooksConfig;
|
|
96
|
+
validate?: ValidateFunction;
|
|
97
|
+
}
|
|
98
|
+
export interface TextField extends BaseField {
|
|
99
|
+
type: 'text';
|
|
100
|
+
minLength?: number;
|
|
101
|
+
maxLength?: number;
|
|
102
|
+
}
|
|
103
|
+
export interface TextareaField extends BaseField {
|
|
104
|
+
type: 'textarea';
|
|
105
|
+
minLength?: number;
|
|
106
|
+
maxLength?: number;
|
|
107
|
+
rows?: number;
|
|
108
|
+
}
|
|
109
|
+
export interface RichTextField extends BaseField {
|
|
110
|
+
type: 'richText';
|
|
111
|
+
}
|
|
112
|
+
export interface NumberField extends BaseField {
|
|
113
|
+
type: 'number';
|
|
114
|
+
min?: number;
|
|
115
|
+
max?: number;
|
|
116
|
+
step?: number;
|
|
117
|
+
/** Display format for read-only views (e.g. currency, percent) */
|
|
118
|
+
displayFormat?: NumberDisplayFormat;
|
|
119
|
+
}
|
|
120
|
+
export interface DateField extends BaseField {
|
|
121
|
+
type: 'date';
|
|
122
|
+
/** Display format for read-only views (e.g. preset style, locale) */
|
|
123
|
+
displayFormat?: DateDisplayFormat;
|
|
124
|
+
}
|
|
125
|
+
export interface CheckboxField extends BaseField {
|
|
126
|
+
type: 'checkbox';
|
|
127
|
+
}
|
|
128
|
+
export interface SelectOption {
|
|
129
|
+
label: string;
|
|
130
|
+
value: string | number;
|
|
131
|
+
}
|
|
132
|
+
export interface SelectField extends BaseField {
|
|
133
|
+
type: 'select';
|
|
134
|
+
options: SelectOption[];
|
|
135
|
+
hasMany?: boolean;
|
|
136
|
+
}
|
|
137
|
+
export interface RadioField extends BaseField {
|
|
138
|
+
type: 'radio';
|
|
139
|
+
options: SelectOption[];
|
|
140
|
+
}
|
|
141
|
+
export interface EmailField extends BaseField {
|
|
142
|
+
type: 'email';
|
|
143
|
+
}
|
|
144
|
+
export interface PasswordField extends BaseField {
|
|
145
|
+
type: 'password';
|
|
146
|
+
minLength?: number;
|
|
147
|
+
}
|
|
148
|
+
export interface UploadField extends BaseField {
|
|
149
|
+
type: 'upload';
|
|
150
|
+
/** Collection slug where media documents are stored (default: 'media') */
|
|
151
|
+
relationTo: string;
|
|
152
|
+
/** Allowed MIME types (e.g., ['image/*', 'application/pdf']) */
|
|
153
|
+
mimeTypes?: string[];
|
|
154
|
+
/** Maximum file size in bytes */
|
|
155
|
+
maxSize?: number;
|
|
156
|
+
/** Allow multiple file uploads */
|
|
157
|
+
hasMany?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/** Behavior when a referenced document is deleted. Maps to SQL FK constraint. */
|
|
160
|
+
export type OnDeleteAction = 'set-null' | 'restrict' | 'cascade';
|
|
161
|
+
/**
|
|
162
|
+
* Error thrown when a delete or update violates a foreign key constraint.
|
|
163
|
+
* Lives in core because it represents a domain-level referential integrity violation,
|
|
164
|
+
* not an HTTP concern. Mapped to HTTP 409 by server-core's handleError.
|
|
165
|
+
*/
|
|
166
|
+
export declare class ReferentialIntegrityError extends Error {
|
|
167
|
+
readonly constraint: string;
|
|
168
|
+
readonly table: string;
|
|
169
|
+
constructor(table: string, constraint: string);
|
|
170
|
+
}
|
|
171
|
+
export interface RelationshipField extends BaseField {
|
|
172
|
+
type: 'relationship';
|
|
173
|
+
/** Single target collection (lazy reference to avoid circular imports) */
|
|
174
|
+
collection: () => unknown;
|
|
175
|
+
/** Multiple target collections for polymorphic relationships */
|
|
176
|
+
relationTo?: Array<() => unknown>;
|
|
177
|
+
hasMany?: boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Behavior when the referenced document is deleted.
|
|
180
|
+
* Maps to SQL FK constraint: 'set-null' → ON DELETE SET NULL, etc.
|
|
181
|
+
* Only applies to single-value relationships (not hasMany or polymorphic).
|
|
182
|
+
* @default 'set-null'
|
|
183
|
+
*/
|
|
184
|
+
onDelete?: OnDeleteAction;
|
|
185
|
+
/** Filter which related documents can be selected */
|
|
186
|
+
filterOptions?: (args: {
|
|
187
|
+
data: Record<string, unknown>;
|
|
188
|
+
}) => Record<string, unknown>;
|
|
189
|
+
}
|
|
190
|
+
/** Value shape for polymorphic relationships (when relationTo is set) */
|
|
191
|
+
export interface PolymorphicRelationshipValue {
|
|
192
|
+
relationTo: string;
|
|
193
|
+
value: string;
|
|
194
|
+
}
|
|
195
|
+
export interface ArrayField extends BaseField {
|
|
196
|
+
type: 'array';
|
|
197
|
+
fields: Field[];
|
|
198
|
+
minRows?: number;
|
|
199
|
+
maxRows?: number;
|
|
200
|
+
/** Name of the sub-field to use as summary label in read-only views. Falls back to first text sub-field. */
|
|
201
|
+
displayField?: string;
|
|
202
|
+
}
|
|
203
|
+
export interface GroupField extends BaseField {
|
|
204
|
+
type: 'group';
|
|
205
|
+
fields: Field[];
|
|
206
|
+
}
|
|
207
|
+
/** Editor configuration for a block type in the visual block editor */
|
|
208
|
+
export interface BlockEditorConfig {
|
|
209
|
+
/** Custom Angular component for visual rendering in the editor */
|
|
210
|
+
component?: unknown;
|
|
211
|
+
/** Which fields should be inline-editable (defaults to auto-detect text/textarea/richText) */
|
|
212
|
+
inlineFields?: string[];
|
|
213
|
+
}
|
|
214
|
+
export interface BlockConfig {
|
|
215
|
+
slug: string;
|
|
216
|
+
fields: Field[];
|
|
217
|
+
labels?: {
|
|
218
|
+
singular?: string;
|
|
219
|
+
plural?: string;
|
|
220
|
+
};
|
|
221
|
+
/** Visual editor customization for this block type */
|
|
222
|
+
editor?: BlockEditorConfig;
|
|
223
|
+
}
|
|
224
|
+
export interface BlocksField extends BaseField {
|
|
225
|
+
type: 'blocks';
|
|
226
|
+
blocks: BlockConfig[];
|
|
227
|
+
minRows?: number;
|
|
228
|
+
maxRows?: number;
|
|
229
|
+
}
|
|
230
|
+
export interface JSONField extends BaseField {
|
|
231
|
+
type: 'json';
|
|
232
|
+
}
|
|
233
|
+
export interface PointField extends BaseField {
|
|
234
|
+
type: 'point';
|
|
235
|
+
}
|
|
236
|
+
export interface SlugField extends BaseField {
|
|
237
|
+
type: 'slug';
|
|
238
|
+
from: string;
|
|
239
|
+
}
|
|
240
|
+
/** Tab definition within a tabs layout field */
|
|
241
|
+
export interface TabConfig {
|
|
242
|
+
label: string;
|
|
243
|
+
description?: string;
|
|
244
|
+
fields: Field[];
|
|
245
|
+
}
|
|
246
|
+
/** Tabs layout field - organizes fields into tabbed sections */
|
|
247
|
+
export interface TabsField extends BaseField {
|
|
248
|
+
type: 'tabs';
|
|
249
|
+
tabs: TabConfig[];
|
|
250
|
+
}
|
|
251
|
+
/** Collapsible layout field - wraps fields in an expandable section */
|
|
252
|
+
export interface CollapsibleField extends BaseField {
|
|
253
|
+
type: 'collapsible';
|
|
254
|
+
fields: Field[];
|
|
255
|
+
/** Whether the section starts expanded (default: false) */
|
|
256
|
+
defaultOpen?: boolean;
|
|
257
|
+
}
|
|
258
|
+
/** Row layout field - displays child fields in a horizontal row */
|
|
259
|
+
export interface RowField extends BaseField {
|
|
260
|
+
type: 'row';
|
|
261
|
+
fields: Field[];
|
|
262
|
+
}
|
|
263
|
+
export type Field = TextField | TextareaField | RichTextField | NumberField | DateField | CheckboxField | SelectField | RadioField | EmailField | PasswordField | UploadField | RelationshipField | ArrayField | GroupField | BlocksField | JSONField | PointField | SlugField | TabsField | CollapsibleField | RowField;
|
|
264
|
+
/** Check if a field type is a layout type (no data storage) */
|
|
265
|
+
export declare function isLayoutField(field: Field): field is TabsField | CollapsibleField | RowField;
|
|
266
|
+
/**
|
|
267
|
+
* Extracts all data fields from a field list, flattening through layout fields.
|
|
268
|
+
* Layout fields (tabs, collapsible, row) are containers that don't store data;
|
|
269
|
+
* their child data fields are stored at the same level as sibling fields.
|
|
270
|
+
*/
|
|
271
|
+
export declare function flattenDataFields(fields: Field[]): Field[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a field name to a human-readable title.
|
|
3
|
+
*
|
|
4
|
+
* Supports camelCase, PascalCase, snake_case, kebab-case, and combinations.
|
|
5
|
+
*
|
|
6
|
+
* Examples:
|
|
7
|
+
* firstName -> "First Name"
|
|
8
|
+
* first_name -> "First Name"
|
|
9
|
+
* SEOTitle -> "SEO Title"
|
|
10
|
+
* createdAt -> "Created At"
|
|
11
|
+
*/
|
|
12
|
+
export declare function humanizeFieldName(name: string): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './field.types';
|
|
2
|
+
export { text, textarea, richText, number, date, checkbox, select, radio, email, password, upload, relationship, array, group, blocks, json, point, slug, tabs, collapsible, row, } from './field-builders';
|
|
3
|
+
export type { TextFieldOptions, TextareaFieldOptions, RichTextFieldOptions, NumberFieldOptions, DateFieldOptions, CheckboxFieldOptions, SelectFieldOptions, RadioFieldOptions, EmailFieldOptions, PasswordFieldOptions, UploadFieldOptions, RelationshipFieldOptions, ArrayFieldOptions, GroupFieldOptions, BlocksFieldOptions, JSONFieldOptions, PointFieldOptions, SlugFieldOptions, TabsFieldOptions, CollapsibleFieldOptions, RowFieldOptions, } from './field-builders';
|
|
4
|
+
export { validateFieldConstraints } from './field-validators';
|
|
5
|
+
export type { FieldConstraintError } from './field-validators';
|
|
6
|
+
export { humanizeFieldName } from './humanize-field-name';
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin System Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Canonical type definitions for the Momentum CMS plugin system.
|
|
5
|
+
* These live in @momentumcms/core to avoid circular dependencies.
|
|
6
|
+
* Runtime implementations (PluginRunner, etc.) live in @momentumcms/plugins/core.
|
|
7
|
+
*/
|
|
8
|
+
import type { CollectionConfig } from './collections';
|
|
9
|
+
import type { MomentumConfig } from './config';
|
|
10
|
+
/**
|
|
11
|
+
* Descriptor for Express middleware/routes that a plugin wants auto-mounted.
|
|
12
|
+
* Plugins register these during onInit via context.registerMiddleware().
|
|
13
|
+
* The framework mounts them automatically in momentumApiMiddleware().
|
|
14
|
+
*/
|
|
15
|
+
export interface PluginMiddlewareDescriptor {
|
|
16
|
+
/** Mount path relative to the API root (e.g. '/analytics/collect', '/') */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Express Router or middleware function. Typed as unknown to avoid Express dependency in core. */
|
|
19
|
+
handler: unknown;
|
|
20
|
+
/** Where to mount relative to collection CRUD routes. @default 'before-api' */
|
|
21
|
+
position?: 'before-api' | 'after-api';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Descriptor for Angular DI providers that a plugin wants auto-registered during SSR.
|
|
25
|
+
* Plugins register these during onInit via context.registerProvider().
|
|
26
|
+
* The framework exposes them via getPluginProviders() for Angular SSR injection.
|
|
27
|
+
*/
|
|
28
|
+
export interface PluginProviderDescriptor {
|
|
29
|
+
/** Provider name (for debugging/logging) */
|
|
30
|
+
name: string;
|
|
31
|
+
/** The InjectionToken. Typed as unknown to avoid Angular dependency in core. */
|
|
32
|
+
token: unknown;
|
|
33
|
+
/** The value to provide */
|
|
34
|
+
value: unknown;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Descriptor for an admin UI route that a plugin wants to register.
|
|
38
|
+
* Plugins can declare these statically on the plugin object via `adminRoutes`,
|
|
39
|
+
* or register them during onInit via context.registerAdminRoute().
|
|
40
|
+
*
|
|
41
|
+
* The framework mounts them as lazy-loaded Angular routes inside the admin shell
|
|
42
|
+
* and renders corresponding sidebar navigation items.
|
|
43
|
+
*
|
|
44
|
+
* Mirrors Angular Route concepts (path, loadComponent, data) with
|
|
45
|
+
* additional Momentum sidebar metadata (label, icon, group).
|
|
46
|
+
*/
|
|
47
|
+
export interface PluginAdminRouteDescriptor {
|
|
48
|
+
/** Route path under admin (e.g., 'analytics') -- same as Angular Route.path */
|
|
49
|
+
path: string;
|
|
50
|
+
/** Lazy-loaded component -- same concept as Angular Route.loadComponent.
|
|
51
|
+
* Typed as unknown to avoid Angular dependency in core. */
|
|
52
|
+
loadComponent: unknown;
|
|
53
|
+
/** Optional route data -- same concept as Angular Route.data */
|
|
54
|
+
data?: Record<string, unknown>;
|
|
55
|
+
/** Sidebar display label */
|
|
56
|
+
label: string;
|
|
57
|
+
/** Icon name from ng-icons (e.g., 'heroChartBarSquare') */
|
|
58
|
+
icon: string;
|
|
59
|
+
/** Sidebar section name. @default 'Plugins' */
|
|
60
|
+
group?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Collection event types that plugins can listen to.
|
|
64
|
+
*/
|
|
65
|
+
export type CollectionEventType = 'beforeChange' | 'afterChange' | 'beforeDelete' | 'afterDelete' | 'beforeRead' | 'afterRead';
|
|
66
|
+
/**
|
|
67
|
+
* A collection event emitted by the hook system.
|
|
68
|
+
*/
|
|
69
|
+
export interface CollectionEvent {
|
|
70
|
+
/** The collection slug */
|
|
71
|
+
collection: string;
|
|
72
|
+
/** The event type */
|
|
73
|
+
event: CollectionEventType;
|
|
74
|
+
/** The operation (create/update/delete/softDelete/restore) */
|
|
75
|
+
operation?: 'create' | 'update' | 'delete' | 'softDelete' | 'restore';
|
|
76
|
+
/** The document data (after operation) */
|
|
77
|
+
doc?: Record<string, unknown>;
|
|
78
|
+
/** The document data before the operation */
|
|
79
|
+
previousDoc?: Record<string, unknown>;
|
|
80
|
+
/** ISO timestamp of the event */
|
|
81
|
+
timestamp: string;
|
|
82
|
+
}
|
|
83
|
+
/** Logger interface for plugins (avoids importing @momentumcms/logger in core) */
|
|
84
|
+
export interface PluginLogger {
|
|
85
|
+
debug(message: string, ...args: unknown[]): void;
|
|
86
|
+
info(message: string, ...args: unknown[]): void;
|
|
87
|
+
warn(message: string, ...args: unknown[]): void;
|
|
88
|
+
error(message: string, ...args: unknown[]): void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Context available to plugins during onInit.
|
|
92
|
+
* Collections are mutable -- plugins can inject hooks here.
|
|
93
|
+
*/
|
|
94
|
+
export interface PluginContext {
|
|
95
|
+
/** The full Momentum config */
|
|
96
|
+
config: MomentumConfig;
|
|
97
|
+
/** Mutable collections array -- plugins can add hooks */
|
|
98
|
+
collections: CollectionConfig[];
|
|
99
|
+
/** Logger scoped to the plugin name */
|
|
100
|
+
logger: PluginLogger;
|
|
101
|
+
/** Register Express middleware/routes to be auto-mounted by the framework */
|
|
102
|
+
registerMiddleware(descriptor: PluginMiddlewareDescriptor): void;
|
|
103
|
+
/** Register Angular providers for SSR (available to admin UI during server rendering) */
|
|
104
|
+
registerProvider(descriptor: PluginProviderDescriptor): void;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Extended context available during onReady.
|
|
108
|
+
* The API is fully initialized at this point.
|
|
109
|
+
*/
|
|
110
|
+
export interface PluginReadyContext extends PluginContext {
|
|
111
|
+
/** The initialized Momentum API singleton */
|
|
112
|
+
api: MomentumAPI;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Minimal MomentumAPI interface to avoid circular dependencies.
|
|
116
|
+
* The real MomentumAPI from server-core is structurally compatible.
|
|
117
|
+
* Plugins that need full typing can import from @momentumcms/server-core.
|
|
118
|
+
*/
|
|
119
|
+
export interface MomentumAPI {
|
|
120
|
+
/** Get operations for a specific collection */
|
|
121
|
+
collection(slug: string): unknown;
|
|
122
|
+
/** Get the current config */
|
|
123
|
+
getConfig(): MomentumConfig;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A Momentum CMS plugin.
|
|
127
|
+
*
|
|
128
|
+
* Plugins participate in the server lifecycle:
|
|
129
|
+
* - `onInit`: Before API initialization. Inject hooks into collections here.
|
|
130
|
+
* - `onReady`: After API + seeding. The API is ready for queries.
|
|
131
|
+
* - `onShutdown`: Graceful shutdown. Clean up resources.
|
|
132
|
+
*
|
|
133
|
+
* Plugins can declare admin routes statically via `adminRoutes`.
|
|
134
|
+
* These are read at config time by `momentumAdminRoutes(config)` to generate
|
|
135
|
+
* Angular routes without any manual wiring.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const myPlugin: MomentumPlugin = {
|
|
140
|
+
* name: 'my-plugin',
|
|
141
|
+
* adminRoutes: [{
|
|
142
|
+
* path: 'my-page',
|
|
143
|
+
* label: 'My Page',
|
|
144
|
+
* icon: 'heroCog6Tooth',
|
|
145
|
+
* loadComponent: () => import('./my-page').then(m => m.MyPage),
|
|
146
|
+
* }],
|
|
147
|
+
* async onInit({ collections, logger }) {
|
|
148
|
+
* logger.info('Initializing...');
|
|
149
|
+
* },
|
|
150
|
+
* };
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export interface MomentumPlugin {
|
|
154
|
+
/** Unique plugin name */
|
|
155
|
+
name: string;
|
|
156
|
+
/** Static collections declared by this plugin.
|
|
157
|
+
* Read at config time by `momentumAdminRoutes(config)` to include
|
|
158
|
+
* plugin collections in the admin UI route data.
|
|
159
|
+
* Plugins should still push collections in `onInit` for server-side
|
|
160
|
+
* schema generation and API registration. */
|
|
161
|
+
collections?: CollectionConfig[];
|
|
162
|
+
/** Static admin routes declared by this plugin.
|
|
163
|
+
* Read at config time — no async needed. */
|
|
164
|
+
adminRoutes?: PluginAdminRouteDescriptor[];
|
|
165
|
+
/** Synchronously transform the merged collections at config time.
|
|
166
|
+
* Called by `momentumAdminRoutes()` so the admin UI reflects plugin modifications
|
|
167
|
+
* (e.g., injected fields). Also called during server-side `initializeMomentum()`.
|
|
168
|
+
* Must be idempotent — may be called more than once. */
|
|
169
|
+
modifyCollections?(collections: CollectionConfig[]): void;
|
|
170
|
+
/** Called before API initialization. Inject hooks here. */
|
|
171
|
+
onInit?(context: PluginContext): void | Promise<void>;
|
|
172
|
+
/** Called after API + seeding complete. API is ready for queries. */
|
|
173
|
+
onReady?(context: PluginReadyContext): void | Promise<void>;
|
|
174
|
+
/** Called on graceful shutdown. Clean up resources. */
|
|
175
|
+
onShutdown?(context: PluginContext): void | Promise<void>;
|
|
176
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed Helpers
|
|
3
|
+
*
|
|
4
|
+
* Factory functions for creating typed seed entity definitions.
|
|
5
|
+
* Provides IntelliSense support for common entity types.
|
|
6
|
+
*/
|
|
7
|
+
import type { DefaultEntityHelpers } from './seeding.types';
|
|
8
|
+
/**
|
|
9
|
+
* Creates the default entity helpers with full type safety.
|
|
10
|
+
* Used internally by the seeding system to provide the `helpers` parameter.
|
|
11
|
+
*
|
|
12
|
+
* @returns Default entity helpers object
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const helpers = createSeedHelpers();
|
|
17
|
+
* const adminSeed = helpers.admin('first-admin', { name: 'Admin', email: 'admin@example.com' });
|
|
18
|
+
* const userSeed = helpers.user('regular-user', { name: 'John', email: 'john@example.com' });
|
|
19
|
+
* const postSeed = helpers.collection<PostDoc>('posts').create('welcome', { title: 'Hello' });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSeedHelpers(): DefaultEntityHelpers;
|