@infuro/cms-core 1.0.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/README.md +693 -0
- package/dist/admin.cjs +7119 -0
- package/dist/admin.cjs.map +1 -0
- package/dist/admin.css +75 -0
- package/dist/admin.d.cts +209 -0
- package/dist/admin.d.ts +209 -0
- package/dist/admin.js +7079 -0
- package/dist/admin.js.map +1 -0
- package/dist/api.cjs +1158 -0
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.cts +2 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +1112 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.cjs +226 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +99 -0
- package/dist/auth.d.ts +99 -0
- package/dist/auth.js +181 -0
- package/dist/auth.js.map +1 -0
- package/dist/config-DJ5CmQvS.d.cts +8 -0
- package/dist/config-DJ5CmQvS.d.ts +8 -0
- package/dist/hooks.cjs +94 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.cts +22 -0
- package/dist/hooks.d.ts +22 -0
- package/dist/hooks.js +54 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index-DP3LK1XN.d.cts +263 -0
- package/dist/index-DP3LK1XN.d.ts +263 -0
- package/dist/index.cjs +3008 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +543 -0
- package/dist/index.d.ts +543 -0
- package/dist/index.js +2928 -0
- package/dist/index.js.map +1 -0
- package/dist/theme.cjs +113 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.cts +32 -0
- package/dist/theme.d.ts +32 -0
- package/dist/theme.js +73 -0
- package/dist/theme.js.map +1 -0
- package/dist/types-D34wmivy.d.cts +78 -0
- package/dist/types-D34wmivy.d.ts +78 -0
- package/package.json +106 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import * as typeorm from 'typeorm';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Storage plugin contract: upload a file and return its public URL.
|
|
6
|
+
*/
|
|
7
|
+
interface StorageService {
|
|
8
|
+
upload(buffer: Buffer, key: string, contentType: string): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type EntityMap = Record<string, typeorm.EntityTarget<typeorm.ObjectLiteral>>;
|
|
12
|
+
interface CrudHandlerOptions {
|
|
13
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
14
|
+
json: (body: unknown, init?: {
|
|
15
|
+
status?: number;
|
|
16
|
+
}) => Response;
|
|
17
|
+
}
|
|
18
|
+
declare function createCrudHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
|
|
19
|
+
GET(req: Request, resource: string): Promise<Response>;
|
|
20
|
+
POST(req: Request, resource: string): Promise<Response>;
|
|
21
|
+
};
|
|
22
|
+
declare function createCrudByIdHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
|
|
23
|
+
GET(req: Request, resource: string, id: string): Promise<Response>;
|
|
24
|
+
PUT(req: Request, resource: string, id: string): Promise<Response>;
|
|
25
|
+
DELETE(req: Request, resource: string, id: string): Promise<Response>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Auth API handler factories. Inject dataSource + entityMap, sendEmail, hash/compare; optional hooks to customize.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
interface AuthHandlersConfig {
|
|
33
|
+
json: (body: unknown, init?: {
|
|
34
|
+
status?: number;
|
|
35
|
+
}) => Response;
|
|
36
|
+
baseUrl: string;
|
|
37
|
+
hashPassword: (plain: string) => Promise<string>;
|
|
38
|
+
comparePassword: (plain: string, hash: string) => Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
interface ForgotPasswordConfig extends AuthHandlersConfig {
|
|
41
|
+
dataSource: DataSource;
|
|
42
|
+
entityMap: EntityMap;
|
|
43
|
+
sendEmail?: (opts: {
|
|
44
|
+
to: string;
|
|
45
|
+
subject: string;
|
|
46
|
+
html: string;
|
|
47
|
+
text?: string;
|
|
48
|
+
}) => Promise<void>;
|
|
49
|
+
resetExpiryHours?: number;
|
|
50
|
+
afterCreateToken?: (email: string, resetLink: string) => Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
declare function createForgotPasswordHandler(config: ForgotPasswordConfig): (request: Request) => Promise<Response>;
|
|
53
|
+
interface SetPasswordConfig extends AuthHandlersConfig {
|
|
54
|
+
dataSource: DataSource;
|
|
55
|
+
entityMap: EntityMap;
|
|
56
|
+
minPasswordLength?: number;
|
|
57
|
+
beforeUpdate?: (email: string, userId: number) => Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
declare function createSetPasswordHandler(config: SetPasswordConfig): (request: Request) => Promise<Response>;
|
|
60
|
+
interface InviteAcceptConfig extends AuthHandlersConfig {
|
|
61
|
+
dataSource: DataSource;
|
|
62
|
+
entityMap: EntityMap;
|
|
63
|
+
beforeActivate?: (email: string, userId: number) => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/** Decode invite token (base64 email) and set password + unblock user */
|
|
66
|
+
declare function createInviteAcceptHandler(config: InviteAcceptConfig): (request: Request) => Promise<Response>;
|
|
67
|
+
interface ChangePasswordConfig extends AuthHandlersConfig {
|
|
68
|
+
dataSource: DataSource;
|
|
69
|
+
entityMap: EntityMap;
|
|
70
|
+
getSession: () => Promise<{
|
|
71
|
+
user?: {
|
|
72
|
+
email?: string | null;
|
|
73
|
+
};
|
|
74
|
+
} | null>;
|
|
75
|
+
minPasswordLength?: number;
|
|
76
|
+
beforeUpdate?: (email: string) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare function createChangePasswordHandler(config: ChangePasswordConfig): (request: Request) => Promise<Response>;
|
|
79
|
+
interface UserAuthApiConfig extends ForgotPasswordConfig, Omit<SetPasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>, Omit<InviteAcceptConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>, Omit<ChangePasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword' | 'beforeUpdate' | 'getSession'> {
|
|
80
|
+
getSession?: () => Promise<{
|
|
81
|
+
user?: {
|
|
82
|
+
email?: string | null;
|
|
83
|
+
};
|
|
84
|
+
} | null>;
|
|
85
|
+
beforeChangePasswordUpdate?: (email: string) => Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Single router for all user-auth APIs. Mount in the app once.
|
|
89
|
+
* Use when you have no users/[id] route (else Next.js gives [id] precedence and "forgot-password" would match as id).
|
|
90
|
+
* Path is the segment after the mount (e.g. "forgot-password"). Returns 404 for unknown paths.
|
|
91
|
+
*/
|
|
92
|
+
declare function createUserAuthApiRouter(config: UserAuthApiConfig): {
|
|
93
|
+
POST(req: Request, pathname: string): Promise<Response>;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* CMS API handlers: dashboard, analytics, upload, blog/form by slug, users (list/create/get/update/delete/regenerate-invite/avatar/profile).
|
|
98
|
+
* All accept injectable deps; upload supports S3 or local.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
interface CmsHandlersBase {
|
|
102
|
+
json: (body: unknown, init?: {
|
|
103
|
+
status?: number;
|
|
104
|
+
}) => Response;
|
|
105
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
106
|
+
}
|
|
107
|
+
interface DashboardStatsConfig extends CmsHandlersBase {
|
|
108
|
+
dataSource: DataSource;
|
|
109
|
+
entityMap: EntityMap;
|
|
110
|
+
requirePermission?: (req: Request, permission: string) => Promise<Response | null>;
|
|
111
|
+
}
|
|
112
|
+
declare function createDashboardStatsHandler(config: DashboardStatsConfig): (req: Request) => Promise<Response>;
|
|
113
|
+
interface AnalyticsHandlerConfig extends CmsHandlersBase {
|
|
114
|
+
getAnalyticsData?: (days: number) => Promise<unknown>;
|
|
115
|
+
getPropertyId?: () => ({
|
|
116
|
+
currentViewId?: string;
|
|
117
|
+
[k: string]: unknown;
|
|
118
|
+
});
|
|
119
|
+
getPermissions?: () => ({
|
|
120
|
+
serviceAccountEmail?: string;
|
|
121
|
+
currentViewId?: string;
|
|
122
|
+
[k: string]: unknown;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
declare function createAnalyticsHandlers(config: AnalyticsHandlerConfig): {
|
|
126
|
+
GET(req: Request): Promise<Response>;
|
|
127
|
+
propertyId: () => Promise<Response>;
|
|
128
|
+
permissions: () => Promise<Response>;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
interface UploadHandlerConfig extends CmsHandlersBase {
|
|
132
|
+
/** Storage plugin instance or getter (e.g. () => getCms().then(c => c.getPlugin('storage'))). If not set, uses local fallback. */
|
|
133
|
+
storage?: StorageService | (() => StorageService | undefined) | (() => Promise<StorageService | undefined>);
|
|
134
|
+
/** Fallback when storage not set: dir relative to cwd (e.g. "public/uploads") */
|
|
135
|
+
localUploadDir?: string;
|
|
136
|
+
allowedTypes?: string[];
|
|
137
|
+
maxSizeBytes?: number;
|
|
138
|
+
}
|
|
139
|
+
declare function createUploadHandler(config: UploadHandlerConfig): (req: Request) => Promise<Response>;
|
|
140
|
+
interface BlogBySlugConfig extends CmsHandlersBase {
|
|
141
|
+
dataSource: DataSource;
|
|
142
|
+
entityMap: EntityMap;
|
|
143
|
+
}
|
|
144
|
+
declare function createBlogBySlugHandler(config: BlogBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
|
|
145
|
+
interface FormBySlugConfig extends CmsHandlersBase {
|
|
146
|
+
dataSource: DataSource;
|
|
147
|
+
entityMap: EntityMap;
|
|
148
|
+
}
|
|
149
|
+
declare function createFormBySlugHandler(config: FormBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
|
|
150
|
+
interface FormSaveHandlersConfig extends CmsHandlersBase {
|
|
151
|
+
dataSource: DataSource;
|
|
152
|
+
entityMap: EntityMap;
|
|
153
|
+
}
|
|
154
|
+
interface FormSubmissionHandlerConfig {
|
|
155
|
+
dataSource: DataSource;
|
|
156
|
+
entityMap: EntityMap;
|
|
157
|
+
json: (body: unknown, init?: {
|
|
158
|
+
status?: number;
|
|
159
|
+
}) => Response;
|
|
160
|
+
}
|
|
161
|
+
interface FormSubmissionGetByIdConfig extends CmsHandlersBase {
|
|
162
|
+
dataSource: DataSource;
|
|
163
|
+
entityMap: EntityMap;
|
|
164
|
+
json: (body: unknown, init?: {
|
|
165
|
+
status?: number;
|
|
166
|
+
}) => Response;
|
|
167
|
+
}
|
|
168
|
+
interface UsersApiConfig extends CmsHandlersBase {
|
|
169
|
+
dataSource: DataSource;
|
|
170
|
+
entityMap: EntityMap;
|
|
171
|
+
baseUrl: string;
|
|
172
|
+
}
|
|
173
|
+
declare function createUsersApiHandlers(config: UsersApiConfig): {
|
|
174
|
+
list(req: Request): Promise<Response>;
|
|
175
|
+
create(req: Request): Promise<Response>;
|
|
176
|
+
getById(_req: Request, id: string): Promise<Response>;
|
|
177
|
+
update(req: Request, id: string): Promise<Response>;
|
|
178
|
+
delete(_req: Request, id: string): Promise<Response>;
|
|
179
|
+
regenerateInvite(_req: Request, id: string): Promise<Response>;
|
|
180
|
+
};
|
|
181
|
+
interface UserAvatarConfig extends CmsHandlersBase {
|
|
182
|
+
getSession: () => Promise<{
|
|
183
|
+
user?: {
|
|
184
|
+
email?: string | null;
|
|
185
|
+
};
|
|
186
|
+
} | null>;
|
|
187
|
+
/** Save avatar (buffer, fileName) => publicUrl. Default: local public/uploads/avatars */
|
|
188
|
+
saveAvatar?: (buffer: Buffer, fileName: string) => Promise<string>;
|
|
189
|
+
}
|
|
190
|
+
declare function createUserAvatarHandler(config: UserAvatarConfig): (req: Request) => Promise<Response>;
|
|
191
|
+
interface UserProfileConfig extends CmsHandlersBase {
|
|
192
|
+
dataSource: DataSource;
|
|
193
|
+
entityMap: EntityMap;
|
|
194
|
+
getSession: () => Promise<{
|
|
195
|
+
user?: {
|
|
196
|
+
email?: string | null;
|
|
197
|
+
name?: string | null;
|
|
198
|
+
};
|
|
199
|
+
} | null>;
|
|
200
|
+
}
|
|
201
|
+
declare function createUserProfileHandler(config: UserProfileConfig): (req: Request) => Promise<Response>;
|
|
202
|
+
interface SettingsApiConfig extends CmsHandlersBase {
|
|
203
|
+
dataSource: DataSource;
|
|
204
|
+
entityMap: EntityMap;
|
|
205
|
+
encryptionKey?: string;
|
|
206
|
+
/** Groups in this list are readable without auth (GET returns all keys for the group). */
|
|
207
|
+
publicGetGroups?: string[];
|
|
208
|
+
}
|
|
209
|
+
declare function createSettingsApiHandlers(config: SettingsApiConfig): {
|
|
210
|
+
GET(req: Request, group: string): Promise<Response>;
|
|
211
|
+
PUT(req: Request, group: string): Promise<Response>;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Single CMS API handler: dashboard, analytics, upload, blog/form by slug, users API, user auth, CRUD. Mount once (e.g. app/api/[[...path]]/route.ts).
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
/** CMS instance with getPlugin; when provided, analytics and userAuth.sendEmail can be resolved from plugins when not passed. */
|
|
219
|
+
type CmsGetter = () => Promise<{
|
|
220
|
+
getPlugin: (name: string) => unknown;
|
|
221
|
+
}>;
|
|
222
|
+
interface CmsApiHandlerConfig {
|
|
223
|
+
dataSource: DataSource;
|
|
224
|
+
entityMap: EntityMap;
|
|
225
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
226
|
+
json: (body: unknown, init?: {
|
|
227
|
+
status?: number;
|
|
228
|
+
}) => Response;
|
|
229
|
+
pathToModel?: (segment: string) => string;
|
|
230
|
+
crudResources?: string[];
|
|
231
|
+
/** When set, analytics and userAuth.sendEmail can be derived from getPlugin('analytics') and getPlugin('email') when not provided. */
|
|
232
|
+
getCms?: CmsGetter;
|
|
233
|
+
userAuth?: UserAuthApiConfig;
|
|
234
|
+
/** GET /api/dashboard/stats */
|
|
235
|
+
dashboard?: DashboardStatsConfig;
|
|
236
|
+
/** GET /api/analytics. If omitted and getCms is set, uses getCms().getPlugin('analytics'). */
|
|
237
|
+
analytics?: AnalyticsHandlerConfig;
|
|
238
|
+
/** POST /api/upload (S3 or local) */
|
|
239
|
+
upload?: UploadHandlerConfig;
|
|
240
|
+
/** GET /api/blogs/slug/:slug (public) */
|
|
241
|
+
blogBySlug?: BlogBySlugConfig;
|
|
242
|
+
/** GET /api/forms/slug/:slug (public) */
|
|
243
|
+
formBySlug?: FormBySlugConfig;
|
|
244
|
+
/** POST/PUT /api/forms (save form + fields; when set, overrides CRUD for forms) */
|
|
245
|
+
formSave?: FormSaveHandlersConfig;
|
|
246
|
+
/** POST /api/form-submissions (public, no auth) */
|
|
247
|
+
formSubmission?: FormSubmissionHandlerConfig;
|
|
248
|
+
/** GET /api/form-submissions/:id (auth) with form + contact relations */
|
|
249
|
+
formSubmissionGetById?: FormSubmissionGetByIdConfig;
|
|
250
|
+
/** GET/POST /api/users, GET/PUT/DELETE /api/users/:id, POST /api/users/:id/regenerate-invite */
|
|
251
|
+
usersApi?: UsersApiConfig;
|
|
252
|
+
/** POST /api/users/avatar */
|
|
253
|
+
userAvatar?: UserAvatarConfig;
|
|
254
|
+
/** PUT /api/users/profile */
|
|
255
|
+
userProfile?: UserProfileConfig;
|
|
256
|
+
/** GET/PUT /api/settings/:group */
|
|
257
|
+
settings?: SettingsApiConfig;
|
|
258
|
+
}
|
|
259
|
+
declare function createCmsApiHandler(config: CmsApiHandlerConfig): {
|
|
260
|
+
handle(method: string, path: string[], req: Request): Promise<Response>;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export { type AnalyticsHandlerConfig as A, type BlogBySlugConfig as B, type ChangePasswordConfig as C, type DashboardStatsConfig as D, type EntityMap as E, type ForgotPasswordConfig as F, createUserProfileHandler as G, createUsersApiHandlers as H, type InviteAcceptConfig as I, type StorageService as S, type UploadHandlerConfig as U, type AuthHandlersConfig as a, type CmsApiHandlerConfig as b, type CmsGetter as c, type CrudHandlerOptions as d, type FormBySlugConfig as e, type SetPasswordConfig as f, type SettingsApiConfig as g, type UserAuthApiConfig as h, type UserAvatarConfig as i, type UserProfileConfig as j, type UsersApiConfig as k, createAnalyticsHandlers as l, createBlogBySlugHandler as m, createChangePasswordHandler as n, createCmsApiHandler as o, createCrudByIdHandler as p, createCrudHandler as q, createDashboardStatsHandler as r, createForgotPasswordHandler as s, createFormBySlugHandler as t, createInviteAcceptHandler as u, createSetPasswordHandler as v, createSettingsApiHandlers as w, createUploadHandler as x, createUserAuthApiRouter as y, createUserAvatarHandler as z };
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import * as typeorm from 'typeorm';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Storage plugin contract: upload a file and return its public URL.
|
|
6
|
+
*/
|
|
7
|
+
interface StorageService {
|
|
8
|
+
upload(buffer: Buffer, key: string, contentType: string): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type EntityMap = Record<string, typeorm.EntityTarget<typeorm.ObjectLiteral>>;
|
|
12
|
+
interface CrudHandlerOptions {
|
|
13
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
14
|
+
json: (body: unknown, init?: {
|
|
15
|
+
status?: number;
|
|
16
|
+
}) => Response;
|
|
17
|
+
}
|
|
18
|
+
declare function createCrudHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
|
|
19
|
+
GET(req: Request, resource: string): Promise<Response>;
|
|
20
|
+
POST(req: Request, resource: string): Promise<Response>;
|
|
21
|
+
};
|
|
22
|
+
declare function createCrudByIdHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
|
|
23
|
+
GET(req: Request, resource: string, id: string): Promise<Response>;
|
|
24
|
+
PUT(req: Request, resource: string, id: string): Promise<Response>;
|
|
25
|
+
DELETE(req: Request, resource: string, id: string): Promise<Response>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Auth API handler factories. Inject dataSource + entityMap, sendEmail, hash/compare; optional hooks to customize.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
interface AuthHandlersConfig {
|
|
33
|
+
json: (body: unknown, init?: {
|
|
34
|
+
status?: number;
|
|
35
|
+
}) => Response;
|
|
36
|
+
baseUrl: string;
|
|
37
|
+
hashPassword: (plain: string) => Promise<string>;
|
|
38
|
+
comparePassword: (plain: string, hash: string) => Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
interface ForgotPasswordConfig extends AuthHandlersConfig {
|
|
41
|
+
dataSource: DataSource;
|
|
42
|
+
entityMap: EntityMap;
|
|
43
|
+
sendEmail?: (opts: {
|
|
44
|
+
to: string;
|
|
45
|
+
subject: string;
|
|
46
|
+
html: string;
|
|
47
|
+
text?: string;
|
|
48
|
+
}) => Promise<void>;
|
|
49
|
+
resetExpiryHours?: number;
|
|
50
|
+
afterCreateToken?: (email: string, resetLink: string) => Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
declare function createForgotPasswordHandler(config: ForgotPasswordConfig): (request: Request) => Promise<Response>;
|
|
53
|
+
interface SetPasswordConfig extends AuthHandlersConfig {
|
|
54
|
+
dataSource: DataSource;
|
|
55
|
+
entityMap: EntityMap;
|
|
56
|
+
minPasswordLength?: number;
|
|
57
|
+
beforeUpdate?: (email: string, userId: number) => Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
declare function createSetPasswordHandler(config: SetPasswordConfig): (request: Request) => Promise<Response>;
|
|
60
|
+
interface InviteAcceptConfig extends AuthHandlersConfig {
|
|
61
|
+
dataSource: DataSource;
|
|
62
|
+
entityMap: EntityMap;
|
|
63
|
+
beforeActivate?: (email: string, userId: number) => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/** Decode invite token (base64 email) and set password + unblock user */
|
|
66
|
+
declare function createInviteAcceptHandler(config: InviteAcceptConfig): (request: Request) => Promise<Response>;
|
|
67
|
+
interface ChangePasswordConfig extends AuthHandlersConfig {
|
|
68
|
+
dataSource: DataSource;
|
|
69
|
+
entityMap: EntityMap;
|
|
70
|
+
getSession: () => Promise<{
|
|
71
|
+
user?: {
|
|
72
|
+
email?: string | null;
|
|
73
|
+
};
|
|
74
|
+
} | null>;
|
|
75
|
+
minPasswordLength?: number;
|
|
76
|
+
beforeUpdate?: (email: string) => Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
declare function createChangePasswordHandler(config: ChangePasswordConfig): (request: Request) => Promise<Response>;
|
|
79
|
+
interface UserAuthApiConfig extends ForgotPasswordConfig, Omit<SetPasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>, Omit<InviteAcceptConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>, Omit<ChangePasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword' | 'beforeUpdate' | 'getSession'> {
|
|
80
|
+
getSession?: () => Promise<{
|
|
81
|
+
user?: {
|
|
82
|
+
email?: string | null;
|
|
83
|
+
};
|
|
84
|
+
} | null>;
|
|
85
|
+
beforeChangePasswordUpdate?: (email: string) => Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Single router for all user-auth APIs. Mount in the app once.
|
|
89
|
+
* Use when you have no users/[id] route (else Next.js gives [id] precedence and "forgot-password" would match as id).
|
|
90
|
+
* Path is the segment after the mount (e.g. "forgot-password"). Returns 404 for unknown paths.
|
|
91
|
+
*/
|
|
92
|
+
declare function createUserAuthApiRouter(config: UserAuthApiConfig): {
|
|
93
|
+
POST(req: Request, pathname: string): Promise<Response>;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* CMS API handlers: dashboard, analytics, upload, blog/form by slug, users (list/create/get/update/delete/regenerate-invite/avatar/profile).
|
|
98
|
+
* All accept injectable deps; upload supports S3 or local.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
interface CmsHandlersBase {
|
|
102
|
+
json: (body: unknown, init?: {
|
|
103
|
+
status?: number;
|
|
104
|
+
}) => Response;
|
|
105
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
106
|
+
}
|
|
107
|
+
interface DashboardStatsConfig extends CmsHandlersBase {
|
|
108
|
+
dataSource: DataSource;
|
|
109
|
+
entityMap: EntityMap;
|
|
110
|
+
requirePermission?: (req: Request, permission: string) => Promise<Response | null>;
|
|
111
|
+
}
|
|
112
|
+
declare function createDashboardStatsHandler(config: DashboardStatsConfig): (req: Request) => Promise<Response>;
|
|
113
|
+
interface AnalyticsHandlerConfig extends CmsHandlersBase {
|
|
114
|
+
getAnalyticsData?: (days: number) => Promise<unknown>;
|
|
115
|
+
getPropertyId?: () => ({
|
|
116
|
+
currentViewId?: string;
|
|
117
|
+
[k: string]: unknown;
|
|
118
|
+
});
|
|
119
|
+
getPermissions?: () => ({
|
|
120
|
+
serviceAccountEmail?: string;
|
|
121
|
+
currentViewId?: string;
|
|
122
|
+
[k: string]: unknown;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
declare function createAnalyticsHandlers(config: AnalyticsHandlerConfig): {
|
|
126
|
+
GET(req: Request): Promise<Response>;
|
|
127
|
+
propertyId: () => Promise<Response>;
|
|
128
|
+
permissions: () => Promise<Response>;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
interface UploadHandlerConfig extends CmsHandlersBase {
|
|
132
|
+
/** Storage plugin instance or getter (e.g. () => getCms().then(c => c.getPlugin('storage'))). If not set, uses local fallback. */
|
|
133
|
+
storage?: StorageService | (() => StorageService | undefined) | (() => Promise<StorageService | undefined>);
|
|
134
|
+
/** Fallback when storage not set: dir relative to cwd (e.g. "public/uploads") */
|
|
135
|
+
localUploadDir?: string;
|
|
136
|
+
allowedTypes?: string[];
|
|
137
|
+
maxSizeBytes?: number;
|
|
138
|
+
}
|
|
139
|
+
declare function createUploadHandler(config: UploadHandlerConfig): (req: Request) => Promise<Response>;
|
|
140
|
+
interface BlogBySlugConfig extends CmsHandlersBase {
|
|
141
|
+
dataSource: DataSource;
|
|
142
|
+
entityMap: EntityMap;
|
|
143
|
+
}
|
|
144
|
+
declare function createBlogBySlugHandler(config: BlogBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
|
|
145
|
+
interface FormBySlugConfig extends CmsHandlersBase {
|
|
146
|
+
dataSource: DataSource;
|
|
147
|
+
entityMap: EntityMap;
|
|
148
|
+
}
|
|
149
|
+
declare function createFormBySlugHandler(config: FormBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
|
|
150
|
+
interface FormSaveHandlersConfig extends CmsHandlersBase {
|
|
151
|
+
dataSource: DataSource;
|
|
152
|
+
entityMap: EntityMap;
|
|
153
|
+
}
|
|
154
|
+
interface FormSubmissionHandlerConfig {
|
|
155
|
+
dataSource: DataSource;
|
|
156
|
+
entityMap: EntityMap;
|
|
157
|
+
json: (body: unknown, init?: {
|
|
158
|
+
status?: number;
|
|
159
|
+
}) => Response;
|
|
160
|
+
}
|
|
161
|
+
interface FormSubmissionGetByIdConfig extends CmsHandlersBase {
|
|
162
|
+
dataSource: DataSource;
|
|
163
|
+
entityMap: EntityMap;
|
|
164
|
+
json: (body: unknown, init?: {
|
|
165
|
+
status?: number;
|
|
166
|
+
}) => Response;
|
|
167
|
+
}
|
|
168
|
+
interface UsersApiConfig extends CmsHandlersBase {
|
|
169
|
+
dataSource: DataSource;
|
|
170
|
+
entityMap: EntityMap;
|
|
171
|
+
baseUrl: string;
|
|
172
|
+
}
|
|
173
|
+
declare function createUsersApiHandlers(config: UsersApiConfig): {
|
|
174
|
+
list(req: Request): Promise<Response>;
|
|
175
|
+
create(req: Request): Promise<Response>;
|
|
176
|
+
getById(_req: Request, id: string): Promise<Response>;
|
|
177
|
+
update(req: Request, id: string): Promise<Response>;
|
|
178
|
+
delete(_req: Request, id: string): Promise<Response>;
|
|
179
|
+
regenerateInvite(_req: Request, id: string): Promise<Response>;
|
|
180
|
+
};
|
|
181
|
+
interface UserAvatarConfig extends CmsHandlersBase {
|
|
182
|
+
getSession: () => Promise<{
|
|
183
|
+
user?: {
|
|
184
|
+
email?: string | null;
|
|
185
|
+
};
|
|
186
|
+
} | null>;
|
|
187
|
+
/** Save avatar (buffer, fileName) => publicUrl. Default: local public/uploads/avatars */
|
|
188
|
+
saveAvatar?: (buffer: Buffer, fileName: string) => Promise<string>;
|
|
189
|
+
}
|
|
190
|
+
declare function createUserAvatarHandler(config: UserAvatarConfig): (req: Request) => Promise<Response>;
|
|
191
|
+
interface UserProfileConfig extends CmsHandlersBase {
|
|
192
|
+
dataSource: DataSource;
|
|
193
|
+
entityMap: EntityMap;
|
|
194
|
+
getSession: () => Promise<{
|
|
195
|
+
user?: {
|
|
196
|
+
email?: string | null;
|
|
197
|
+
name?: string | null;
|
|
198
|
+
};
|
|
199
|
+
} | null>;
|
|
200
|
+
}
|
|
201
|
+
declare function createUserProfileHandler(config: UserProfileConfig): (req: Request) => Promise<Response>;
|
|
202
|
+
interface SettingsApiConfig extends CmsHandlersBase {
|
|
203
|
+
dataSource: DataSource;
|
|
204
|
+
entityMap: EntityMap;
|
|
205
|
+
encryptionKey?: string;
|
|
206
|
+
/** Groups in this list are readable without auth (GET returns all keys for the group). */
|
|
207
|
+
publicGetGroups?: string[];
|
|
208
|
+
}
|
|
209
|
+
declare function createSettingsApiHandlers(config: SettingsApiConfig): {
|
|
210
|
+
GET(req: Request, group: string): Promise<Response>;
|
|
211
|
+
PUT(req: Request, group: string): Promise<Response>;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Single CMS API handler: dashboard, analytics, upload, blog/form by slug, users API, user auth, CRUD. Mount once (e.g. app/api/[[...path]]/route.ts).
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
/** CMS instance with getPlugin; when provided, analytics and userAuth.sendEmail can be resolved from plugins when not passed. */
|
|
219
|
+
type CmsGetter = () => Promise<{
|
|
220
|
+
getPlugin: (name: string) => unknown;
|
|
221
|
+
}>;
|
|
222
|
+
interface CmsApiHandlerConfig {
|
|
223
|
+
dataSource: DataSource;
|
|
224
|
+
entityMap: EntityMap;
|
|
225
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
226
|
+
json: (body: unknown, init?: {
|
|
227
|
+
status?: number;
|
|
228
|
+
}) => Response;
|
|
229
|
+
pathToModel?: (segment: string) => string;
|
|
230
|
+
crudResources?: string[];
|
|
231
|
+
/** When set, analytics and userAuth.sendEmail can be derived from getPlugin('analytics') and getPlugin('email') when not provided. */
|
|
232
|
+
getCms?: CmsGetter;
|
|
233
|
+
userAuth?: UserAuthApiConfig;
|
|
234
|
+
/** GET /api/dashboard/stats */
|
|
235
|
+
dashboard?: DashboardStatsConfig;
|
|
236
|
+
/** GET /api/analytics. If omitted and getCms is set, uses getCms().getPlugin('analytics'). */
|
|
237
|
+
analytics?: AnalyticsHandlerConfig;
|
|
238
|
+
/** POST /api/upload (S3 or local) */
|
|
239
|
+
upload?: UploadHandlerConfig;
|
|
240
|
+
/** GET /api/blogs/slug/:slug (public) */
|
|
241
|
+
blogBySlug?: BlogBySlugConfig;
|
|
242
|
+
/** GET /api/forms/slug/:slug (public) */
|
|
243
|
+
formBySlug?: FormBySlugConfig;
|
|
244
|
+
/** POST/PUT /api/forms (save form + fields; when set, overrides CRUD for forms) */
|
|
245
|
+
formSave?: FormSaveHandlersConfig;
|
|
246
|
+
/** POST /api/form-submissions (public, no auth) */
|
|
247
|
+
formSubmission?: FormSubmissionHandlerConfig;
|
|
248
|
+
/** GET /api/form-submissions/:id (auth) with form + contact relations */
|
|
249
|
+
formSubmissionGetById?: FormSubmissionGetByIdConfig;
|
|
250
|
+
/** GET/POST /api/users, GET/PUT/DELETE /api/users/:id, POST /api/users/:id/regenerate-invite */
|
|
251
|
+
usersApi?: UsersApiConfig;
|
|
252
|
+
/** POST /api/users/avatar */
|
|
253
|
+
userAvatar?: UserAvatarConfig;
|
|
254
|
+
/** PUT /api/users/profile */
|
|
255
|
+
userProfile?: UserProfileConfig;
|
|
256
|
+
/** GET/PUT /api/settings/:group */
|
|
257
|
+
settings?: SettingsApiConfig;
|
|
258
|
+
}
|
|
259
|
+
declare function createCmsApiHandler(config: CmsApiHandlerConfig): {
|
|
260
|
+
handle(method: string, path: string[], req: Request): Promise<Response>;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export { type AnalyticsHandlerConfig as A, type BlogBySlugConfig as B, type ChangePasswordConfig as C, type DashboardStatsConfig as D, type EntityMap as E, type ForgotPasswordConfig as F, createUserProfileHandler as G, createUsersApiHandlers as H, type InviteAcceptConfig as I, type StorageService as S, type UploadHandlerConfig as U, type AuthHandlersConfig as a, type CmsApiHandlerConfig as b, type CmsGetter as c, type CrudHandlerOptions as d, type FormBySlugConfig as e, type SetPasswordConfig as f, type SettingsApiConfig as g, type UserAuthApiConfig as h, type UserAvatarConfig as i, type UserProfileConfig as j, type UsersApiConfig as k, createAnalyticsHandlers as l, createBlogBySlugHandler as m, createChangePasswordHandler as n, createCmsApiHandler as o, createCrudByIdHandler as p, createCrudHandler as q, createDashboardStatsHandler as r, createForgotPasswordHandler as s, createFormBySlugHandler as t, createInviteAcceptHandler as u, createSetPasswordHandler as v, createSettingsApiHandlers as w, createUploadHandler as x, createUserAuthApiRouter as y, createUserAvatarHandler as z };
|