@infuro/cms-core 1.0.34 → 1.0.36

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.
Files changed (152) hide show
  1. package/README.md +13 -0
  2. package/dist/OrderTrackPage-W3J6WIG2.js +426 -0
  3. package/dist/OrderTrackPage-Z6FCJQYY.cjs +428 -0
  4. package/dist/admin.cjs +35254 -21613
  5. package/dist/admin.d.cts +192 -9
  6. package/dist/admin.d.ts +192 -9
  7. package/dist/admin.js +34301 -20755
  8. package/dist/api.cjs +137 -17531
  9. package/dist/api.d.cts +633 -3
  10. package/dist/api.d.ts +633 -3
  11. package/dist/api.js +15 -17528
  12. package/dist/auth.cjs +192 -1034
  13. package/dist/auth.d.cts +197 -54
  14. package/dist/auth.d.ts +197 -54
  15. package/dist/auth.js +4 -966
  16. package/dist/chunk-2AEVFOQP.cjs +30436 -0
  17. package/dist/chunk-3DZRIZOD.cjs +52 -0
  18. package/dist/chunk-5ELSW2UP.js +150 -0
  19. package/dist/chunk-7NMT3GBR.cjs +29 -0
  20. package/dist/chunk-COBORIJH.cjs +2373 -0
  21. package/dist/chunk-CRFV5WJK.js +16 -0
  22. package/dist/chunk-D5FBNKQM.cjs +104 -0
  23. package/dist/chunk-FG6I64HP.js +604 -0
  24. package/dist/chunk-GO7PPYNU.js +76 -0
  25. package/dist/chunk-HCIRL37O.js +21 -0
  26. package/dist/chunk-HF3L2GIT.cjs +194 -0
  27. package/dist/chunk-HT5DI3XW.cjs +82 -0
  28. package/dist/chunk-JC6DLWTE.js +21 -0
  29. package/dist/chunk-JS2W7XZ4.js +30312 -0
  30. package/dist/chunk-JXF23MPG.js +25 -0
  31. package/dist/chunk-KFFB6EMZ.js +123 -0
  32. package/dist/chunk-KPKFNLQQ.cjs +648 -0
  33. package/dist/chunk-LI2IXVAY.js +171 -0
  34. package/dist/chunk-MQBT33IV.js +48 -0
  35. package/dist/chunk-OOTLNH63.cjs +18 -0
  36. package/dist/chunk-PNOKNSG2.cjs +222 -0
  37. package/dist/chunk-SHUYVCID.js +4 -0
  38. package/dist/chunk-SPQFNIYJ.cjs +132 -0
  39. package/dist/chunk-SYBOCAWB.js +97 -0
  40. package/dist/chunk-TDV6EJHV.js +192 -0
  41. package/dist/chunk-UCKN4BBY.cjs +24 -0
  42. package/dist/chunk-UF3BYUXY.js +616 -0
  43. package/dist/chunk-UPLVMVRX.cjs +23 -0
  44. package/dist/chunk-USNT2KNT.cjs +6 -0
  45. package/dist/chunk-VMY2S32H.js +2342 -0
  46. package/dist/chunk-WEMDMVHQ.js +216 -0
  47. package/dist/chunk-WO2DW4AU.cjs +182 -0
  48. package/dist/chunk-X47PBV4I.js +79 -0
  49. package/dist/chunk-X6H5VBQ2.cjs +620 -0
  50. package/dist/chunk-XQ3QUHWR.cjs +83 -0
  51. package/dist/chunk-XW5ATPRW.cjs +155 -0
  52. package/dist/cli.cjs +107 -86
  53. package/dist/cli.js +66 -29
  54. package/dist/email-queue-CGZBVVAS.js +2 -0
  55. package/dist/email-queue-TPZWLTIV.cjs +23 -0
  56. package/dist/emit-order-notification-trigger-D2N3KFHL.cjs +16 -0
  57. package/dist/emit-order-notification-trigger-IVLWKKJL.js +3 -0
  58. package/dist/erp-config-enabled-CUMQ6N2V.cjs +11 -0
  59. package/dist/erp-config-enabled-T37X7T34.js +2 -0
  60. package/dist/erp-order-invoice-3YISSOWW.js +3 -0
  61. package/dist/erp-order-invoice-ZR5F2KTA.cjs +12 -0
  62. package/dist/event-order-defaults-EMWBIGL3.cjs +39 -0
  63. package/dist/event-order-defaults-SDRNAZHC.js +2 -0
  64. package/dist/hooks.cjs +259 -132
  65. package/dist/hooks.d.cts +42 -1
  66. package/dist/hooks.d.ts +42 -1
  67. package/dist/hooks.js +234 -91
  68. package/dist/index.cjs +3679 -22356
  69. package/dist/index.d.cts +2173 -643
  70. package/dist/index.d.ts +2173 -643
  71. package/dist/index.js +2587 -22119
  72. package/dist/interpolate-WAKPN56R.cjs +11 -0
  73. package/dist/interpolate-WDUWDF3I.js +2 -0
  74. package/dist/migrations/1779400000000-ConvertStatusToEnum.ts +142 -0
  75. package/dist/migrations/1779400000000-SeedDefaultCurrencies.ts +33 -0
  76. package/dist/migrations/1779500000000-VendorRolesAndPermissions.ts +102 -0
  77. package/dist/migrations/1779600000000-VendorRegistrationProfile.ts +52 -0
  78. package/dist/migrations/1779700000000-CollectionIsCatalog.ts +22 -0
  79. package/dist/migrations/1779710000000-CollectionPlatformCatalog.ts +60 -0
  80. package/dist/migrations/1779720000000-ProductCategoryPlatformCatalog.ts +157 -0
  81. package/dist/migrations/1779800000000-EventsAndEventProducts.ts +173 -0
  82. package/dist/migrations/1779810000000-BackfillVendorRoleEventsPermissions.ts +38 -0
  83. package/dist/migrations/1779820000000-FixProductsCategoryForeignKey.ts +70 -0
  84. package/dist/migrations/1779830000000-ProductTitleColumn.ts +32 -0
  85. package/dist/migrations/1779840000000-EventAboutAndVisibilityFields.ts +34 -0
  86. package/dist/migrations/1779850000000-EventCityCountrySplit.ts +43 -0
  87. package/dist/migrations/1779860000000-CreateCombos.ts +140 -0
  88. package/dist/migrations/1780100000000-OrderAttendeesEventId.ts +55 -0
  89. package/dist/migrations/1780110000000-EventContactFormId.ts +49 -0
  90. package/dist/migrations/1780130000000-ProductVariants.ts +54 -0
  91. package/dist/migrations/1780140000000-EventManagementEnhancements.ts +44 -0
  92. package/dist/migrations/1780160000000-EventRegistrationGstProductContactForm.ts +79 -0
  93. package/dist/migrations/1780170000000-ComboCurrencyPrices.ts +20 -0
  94. package/dist/migrations/1781110000000-VendorOwnerCombosPermission.ts +38 -0
  95. package/dist/migrations/1781120000000-RefundPoliciesAndRequests.ts +225 -0
  96. package/dist/migrations/1781130000000-CreateAttendees.ts +44 -0
  97. package/dist/migrations/1781140000000-EventOrderNotifications.ts +29 -0
  98. package/dist/migrations/1781150000000-EventNamedLists.ts +28 -0
  99. package/dist/migrations/1781160000000-RefundPolicyEventTiers.ts +27 -0
  100. package/dist/migrations/1781170000000-EventRefundPolicy.ts +42 -0
  101. package/dist/migrations/1781180000000-RemoveCartItemsUniqueConstraint.ts +15 -0
  102. package/dist/migrations/1781190000000-RenameProductTaxesToProductConfig.ts +84 -0
  103. package/dist/migrations/1781200000000-VendorOwnerProductConfigPermissions.ts +51 -0
  104. package/dist/migrations/1781210000000-VendorRoleProductConfigPermissions.ts +46 -0
  105. package/dist/migrations/1781220000000-AddWhatsappTriggerBindings.ts +23 -0
  106. package/dist/migrations/1781230000000-AddOrderNotificationTriggers.ts +46 -0
  107. package/dist/migrations/1781240000000-DropEventOrderNotificationColumns.ts +29 -0
  108. package/dist/migrations/1781250000000-RemoveOrderRefundedTrigger.ts +36 -0
  109. package/dist/migrations/helpers/vendor-role-seed.ts +243 -0
  110. package/dist/paid-order-erp-3USEG6WL.js +3 -0
  111. package/dist/paid-order-erp-FSQ3GSXE.cjs +12 -0
  112. package/dist/pg-boss-service-4XF2TQ2E.js +2 -0
  113. package/dist/pg-boss-service-L6MTF4EQ.cjs +15 -0
  114. package/dist/razorpay-KLO2KNCB.js +49 -0
  115. package/dist/razorpay-U23LGY72.cjs +56 -0
  116. package/dist/rbac-debug-db-HWP65A4O.cjs +35 -0
  117. package/dist/rbac-debug-db-QJH3AD34.js +33 -0
  118. package/dist/sms-defaults-2NL24H57.js +2 -0
  119. package/dist/sms-defaults-KCOPKQBA.cjs +19 -0
  120. package/dist/stripe-4FD27QVJ.js +51 -0
  121. package/dist/stripe-VU6OEG2D.cjs +57 -0
  122. package/dist/theme.cjs +31 -59
  123. package/dist/theme.d.cts +78 -3
  124. package/dist/theme.d.ts +78 -3
  125. package/dist/theme.js +23 -20
  126. package/dist/vendor-invite-status-77O7ZQ3U.cjs +19 -0
  127. package/dist/vendor-invite-status-PWJ3DE76.js +2 -0
  128. package/dist/whatsapp-trigger-dispatcher-ONHXI7UY.cjs +19 -0
  129. package/dist/whatsapp-trigger-dispatcher-PWFI4FKP.js +6 -0
  130. package/package.json +147 -142
  131. package/dist/admin.cjs.map +0 -1
  132. package/dist/admin.js.map +0 -1
  133. package/dist/api.cjs.map +0 -1
  134. package/dist/api.js.map +0 -1
  135. package/dist/auth.cjs.map +0 -1
  136. package/dist/auth.js.map +0 -1
  137. package/dist/cli.cjs.map +0 -1
  138. package/dist/cli.js.map +0 -1
  139. package/dist/config-DJ5CmQvS.d.cts +0 -8
  140. package/dist/config-DJ5CmQvS.d.ts +0 -8
  141. package/dist/hooks.cjs.map +0 -1
  142. package/dist/hooks.js.map +0 -1
  143. package/dist/index-Bf5GO8fu.d.cts +0 -583
  144. package/dist/index-DOiJuMQA.d.ts +0 -583
  145. package/dist/index.cjs.map +0 -1
  146. package/dist/index.js.map +0 -1
  147. package/dist/theme.cjs.map +0 -1
  148. package/dist/theme.js.map +0 -1
  149. package/dist/types-DCVaXlPV.d.cts +0 -78
  150. package/dist/types-DCVaXlPV.d.ts +0 -78
  151. package/dist/vendor-scope-DTYhJk_I.d.cts +0 -129
  152. package/dist/vendor-scope-DTYhJk_I.d.ts +0 -129
package/dist/api.d.ts CHANGED
@@ -1,3 +1,633 @@
1
- export { A as AnalyticsHandlerConfig, a as AuthHandlersConfig, B as BlogBySlugConfig, C as ChangePasswordConfig, b as ChatPublicConfig, c as CmsApiHandlerConfig, d as CmsGetter, f as CrudHandlerOptions, D as DashboardStatsConfig, E as EcommerceAnalyticsConfig, i as EntityMap, F as ForgotPasswordConfig, j as FormBySlugConfig, G as GetPublicSettingsGroupConfig, k as GetPublicSettingsGroupDataSource, I as InviteAcceptConfig, J as JobScheduleApiConfig, L as LlmAgentKnowledgeApiConfig, l as LlmAgentValidationRulesJson, P as ParsedLlmAgentValidation, S as SetPasswordConfig, m as SettingsApiConfig, p as StorefrontApiConfig, q as StorefrontOtpFlags, U as UploadHandlerConfig, r as UserAuthApiConfig, s as UserAvatarConfig, t as UserProfileConfig, u as UsersApiConfig, V as VendorOnboardHandlersConfig, v as VendorOwnerActivation, w as createAnalyticsHandlers, x as createBlogBySlugHandler, y as createChangePasswordHandler, z as createCmsApiHandler, H as createCrudByIdHandler, K as createCrudHandler, M as createDashboardStatsHandler, N as createEcommerceAnalyticsHandler, Q as createForgotPasswordHandler, R as createFormBySlugHandler, W as createInviteAcceptHandler, X as createJobScheduleHandlers, Y as createLlmAgentKnowledgeHandlers, Z as createMediaZipExtractHandler, _ as createSetPasswordHandler, $ as createSettingsApiHandlers, a0 as createStorefrontApiHandler, a1 as createUploadHandler, a2 as createUserAuthApiRouter, a3 as createUserAvatarHandler, a4 as createUserProfileHandler, a5 as createUsersApiHandlers, a6 as createVendorOnboardHandlers, a8 as getPublicSettingsGroup, aa as mergeGuardrailsIntoSystemPrompt, ab as parseLlmAgentValidationRules, ac as simpleDecrypt, ad as simpleEncrypt, ae as validateUserMessageAgainstAgentRules, af as validateUserMessageAgainstStructuredRules } from './index-DOiJuMQA.js';
2
- export { k as createCmsAuthBundle } from './vendor-scope-DTYhJk_I.js';
3
- import 'typeorm';
1
+ import * as typeorm from 'typeorm';
2
+ import { DataSource } from 'typeorm';
3
+
4
+ type EntityCrudAction = 'create' | 'read' | 'update' | 'delete';
5
+ type EntityPermissionFlags = {
6
+ c: boolean;
7
+ r: boolean;
8
+ u: boolean;
9
+ d: boolean;
10
+ };
11
+
12
+ interface SessionUser {
13
+ id?: string;
14
+ email?: string | null;
15
+ name?: string | null;
16
+ groupId?: number;
17
+ /** User group display name (from login). */
18
+ groupName?: string | null;
19
+ /** @deprecated use entityPerms / isRBACAdmin */
20
+ permissions?: string[];
21
+ /** Administrator group: bypasses entity-level RBAC on all resources */
22
+ isRBACAdmin?: boolean;
23
+ entityPerms?: Record<string, EntityPermissionFlags>;
24
+ /** When false and not isRBACAdmin, admin API/UI is denied. */
25
+ adminAccess?: boolean;
26
+ /** Vendor stores this user can access (from vendor_users). */
27
+ vendorIds?: number[];
28
+ /** Active vendor for scoped CRUD (vendor staff). */
29
+ activeVendorId?: number | null;
30
+ /** Role for the active vendor link (`vendor_users.role`). */
31
+ vendorRole?: 'owner' | 'staff' | null;
32
+ /** Active vendor-scoped role id (`vendor_users.vendorRoleId`). */
33
+ vendorRoleId?: number | null;
34
+ vendorRoleName?: string | null;
35
+ /** True when active vendor role has `isOwnerRole`. */
36
+ isVendorRoleOwner?: boolean;
37
+ /** Permissions from active vendor role (`vendor_role_permissions`). */
38
+ vendorEntityPerms?: Record<string, EntityPermissionFlags>;
39
+ /** Set at login: vendor store portal (not platform admin). */
40
+ isVendorPortal?: boolean;
41
+ /** Set at login: vendor store owner (team + permissions). */
42
+ isVendorOwner?: boolean;
43
+ }
44
+ type GetSession = () => Promise<{
45
+ user?: SessionUser;
46
+ } | null>;
47
+ /** Pass return value into `createCmsApiHandler` (includes `getSessionUser` for vendor store APIs). */
48
+ declare function createCmsAuthBundle(getSession: GetSession, NextResponse: {
49
+ json: (body: unknown, init?: {
50
+ status?: number;
51
+ }) => Response;
52
+ }): {
53
+ requireAuth: (req: Request) => Promise<Response | null>;
54
+ requireAdminAccess: (req: Request) => Promise<Response | null>;
55
+ requireEntityPermission: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
56
+ getSessionUser: () => Promise<SessionUser | null>;
57
+ getAuthenticatedUser: () => Promise<SessionUser | null>;
58
+ };
59
+
60
+ type VendorScope = {
61
+ type: 'all';
62
+ } | {
63
+ type: 'vendor';
64
+ vendorId: number;
65
+ vendorIds: number[];
66
+ } | {
67
+ type: 'deny';
68
+ };
69
+
70
+ type EntityMap = Record<string, typeorm.EntityTarget<typeorm.ObjectLiteral>>;
71
+ interface CrudHandlerOptions {
72
+ requireAuth: (req: Request) => Promise<Response | null>;
73
+ json: (body: unknown, init?: {
74
+ status?: number;
75
+ }) => Response;
76
+ requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
77
+ /** When set, contact create/update enqueues ERP `create-contact` (non-fatal). */
78
+ getCms?: () => Promise<{
79
+ getPlugin: (name: string) => unknown;
80
+ }>;
81
+ /** When set, soft-delete sets `deletedBy` from the current admin user. */
82
+ getDeletedByUserId?: (req: Request) => Promise<number | null>;
83
+ /** When set, store rows are filtered by session vendor (platform admin bypasses). */
84
+ getVendorScope?: () => Promise<VendorScope>;
85
+ /** Hydrated session (group + vendor context) for vendorId resolution on create. */
86
+ getHydratedSessionUser?: () => Promise<SessionUser | null>;
87
+ }
88
+ declare function createCrudHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
89
+ GET(req: Request, resource: string): Promise<Response>;
90
+ POST(req: Request, resource: string): Promise<Response>;
91
+ GET_METADATA(req: Request, resource: string): Promise<Response>;
92
+ BULK_POST(req: Request, resource: string): Promise<Response>;
93
+ GET_EXPORT(req: Request, resource: string): Promise<Response>;
94
+ };
95
+ declare function createCrudByIdHandler(dataSource: DataSource, entityMap: EntityMap, options: CrudHandlerOptions): {
96
+ GET(req: Request, resource: string, id: string): Promise<Response>;
97
+ PUT(req: Request, resource: string, id: string): Promise<Response>;
98
+ DELETE(req: Request, resource: string, id: string): Promise<Response>;
99
+ };
100
+
101
+ /**
102
+ * Auth API handler factories. Inject dataSource + entityMap, sendEmail, hash/compare; optional hooks to customize.
103
+ */
104
+
105
+ interface AuthHandlersConfig {
106
+ json: (body: unknown, init?: {
107
+ status?: number;
108
+ }) => Response;
109
+ baseUrl: string;
110
+ hashPassword: (plain: string) => Promise<string>;
111
+ comparePassword: (plain: string, hash: string) => Promise<boolean>;
112
+ }
113
+ interface ForgotPasswordConfig extends AuthHandlersConfig {
114
+ dataSource: DataSource;
115
+ entityMap: EntityMap;
116
+ sendEmail?: (opts: {
117
+ to: string;
118
+ subject: string;
119
+ html: string;
120
+ text?: string;
121
+ /** Plain reset URL for templated emails (preferred over parsing html). */
122
+ resetLink?: string;
123
+ }) => Promise<void>;
124
+ resetExpiryHours?: number;
125
+ afterCreateToken?: (email: string, resetLink: string) => Promise<void>;
126
+ }
127
+ declare function createForgotPasswordHandler(config: ForgotPasswordConfig): (request: Request) => Promise<Response>;
128
+ interface SetPasswordConfig extends AuthHandlersConfig {
129
+ dataSource: DataSource;
130
+ entityMap: EntityMap;
131
+ minPasswordLength?: number;
132
+ beforeUpdate?: (email: string, userId: number) => Promise<void>;
133
+ }
134
+ declare function createSetPasswordHandler(config: SetPasswordConfig): (request: Request) => Promise<Response>;
135
+ interface InviteAcceptConfig extends AuthHandlersConfig {
136
+ dataSource: DataSource;
137
+ entityMap: EntityMap;
138
+ beforeActivate?: (email: string, userId: number) => Promise<void>;
139
+ }
140
+ /** Decode invite token (base64 email) and set password + unblock user */
141
+ declare function createInviteAcceptHandler(config: InviteAcceptConfig): (request: Request) => Promise<Response>;
142
+ interface ChangePasswordConfig extends AuthHandlersConfig {
143
+ dataSource: DataSource;
144
+ entityMap: EntityMap;
145
+ getSession: () => Promise<{
146
+ user?: {
147
+ email?: string | null;
148
+ };
149
+ } | null>;
150
+ minPasswordLength?: number;
151
+ beforeUpdate?: (email: string) => Promise<void>;
152
+ }
153
+ declare function createChangePasswordHandler(config: ChangePasswordConfig): (request: Request) => Promise<Response>;
154
+ 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'> {
155
+ getSession?: () => Promise<{
156
+ user?: {
157
+ email?: string | null;
158
+ };
159
+ } | null>;
160
+ beforeChangePasswordUpdate?: (email: string) => Promise<void>;
161
+ }
162
+ /**
163
+ * Single router for all user-auth APIs. Mount in the app once.
164
+ * Use when you have no users/[id] route (else Next.js gives [id] precedence and "forgot-password" would match as id).
165
+ * Path is the segment after the mount (e.g. "forgot-password"). Returns 404 for unknown paths.
166
+ */
167
+ declare function createUserAuthApiRouter(config: UserAuthApiConfig): {
168
+ POST(req: Request, pathname: string): Promise<Response>;
169
+ };
170
+
171
+ /** Social entry: use `iconUrl` for an image, or `icon` (emoji/text) as fallback when no image. */
172
+ interface SocialLinkItem {
173
+ url: string;
174
+ iconUrl?: string;
175
+ icon?: string;
176
+ }
177
+ interface CompanyDetails {
178
+ logoUrl?: string;
179
+ companyName?: string;
180
+ supportEmail?: string;
181
+ supportPhone?: string;
182
+ socialLinks?: SocialLinkItem[];
183
+ /** Shown below footer rows; from email plugin settings */
184
+ footerDisclaimer?: string;
185
+ /** Heading above social icons (default "Follow Us") */
186
+ followUsTitle?: string;
187
+ }
188
+
189
+ /**
190
+ * Storage plugin contract: upload a file and return its public URL.
191
+ */
192
+ interface StorageService {
193
+ upload(buffer: Buffer, key: string, contentType: string): Promise<string>;
194
+ }
195
+
196
+ /**
197
+ * CMS API handlers: dashboard, analytics, upload, blog/form by slug, users (list/create/get/update/delete/regenerate-invite/avatar/profile).
198
+ * All accept injectable deps; upload supports S3 or local.
199
+ */
200
+
201
+ type RequireEntityPermissionFn = (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
202
+ /**
203
+ * Optional JSON in `LlmAgent.validationRules`. Used for programmatic checks before the LLM call.
204
+ * For natural-language output rules, use `guardrails` / `outputRules` / `outputInstructions` (merged into system prompt).
205
+ */
206
+ type LlmAgentValidationRulesJson = {
207
+ maxUserChars?: number;
208
+ maxMessageLength?: number;
209
+ minUserChars?: number;
210
+ minMessageLength?: number;
211
+ blockedSubstrings?: string[];
212
+ /** Shown to the model as output guardrails (first non-empty of guardrails | outputRules | outputInstructions wins). */
213
+ guardrails?: string;
214
+ outputRules?: string;
215
+ outputInstructions?: string;
216
+ };
217
+ type ParsedLlmAgentValidation = {
218
+ /** Subset used for length / substring checks only. */
219
+ structured: Pick<LlmAgentValidationRulesJson, 'maxUserChars' | 'maxMessageLength' | 'minUserChars' | 'minMessageLength' | 'blockedSubstrings'>;
220
+ /** Appended to system prompt so the model follows output guardrails. */
221
+ guardrailsForPrompt: string | null;
222
+ };
223
+ /**
224
+ * - Valid JSON object: structural keys → validation; `guardrails` / `outputRules` / `outputInstructions` → prompt suffix.
225
+ * - Not JSON: entire string is treated as prose guardrails for the prompt (no programmatic rules unless you use JSON).
226
+ */
227
+ declare function parseLlmAgentValidationRules(validationRulesText: string | null | undefined): ParsedLlmAgentValidation;
228
+ declare function validateUserMessageAgainstStructuredRules(message: string, structured: ParsedLlmAgentValidation['structured']): {
229
+ ok: true;
230
+ } | {
231
+ ok: false;
232
+ error: string;
233
+ };
234
+ /** Parses `validationRules` then runs programmatic checks only. */
235
+ declare function validateUserMessageAgainstAgentRules(message: string, validationRulesText: string | null | undefined): {
236
+ ok: true;
237
+ } | {
238
+ ok: false;
239
+ error: string;
240
+ };
241
+ /** Merges guardrails prose into the system instruction sent to the model. */
242
+ declare function mergeGuardrailsIntoSystemPrompt(baseSystem: string | undefined, guardrailsForPrompt: string | null): string;
243
+ interface CmsHandlersBase {
244
+ json: (body: unknown, init?: {
245
+ status?: number;
246
+ }) => Response;
247
+ requireAuth: (req: Request) => Promise<Response | null>;
248
+ requireEntityPermission?: RequireEntityPermissionFn;
249
+ }
250
+ interface DashboardStatsConfig extends CmsHandlersBase {
251
+ dataSource: DataSource;
252
+ entityMap: EntityMap;
253
+ requirePermission?: (req: Request, permission: string) => Promise<Response | null>;
254
+ }
255
+ declare function createDashboardStatsHandler(config: DashboardStatsConfig): (req: Request) => Promise<Response>;
256
+ interface EcommerceAnalyticsConfig extends CmsHandlersBase {
257
+ dataSource: DataSource;
258
+ entityMap: EntityMap;
259
+ }
260
+ declare function createEcommerceAnalyticsHandler(config: EcommerceAnalyticsConfig): (req: Request) => Promise<Response>;
261
+ interface VendorDashboardConfig extends CmsHandlersBase {
262
+ dataSource: DataSource;
263
+ entityMap: EntityMap;
264
+ getSessionUser: () => Promise<SessionUser | null>;
265
+ }
266
+ declare function createVendorDashboardHandler(config: VendorDashboardConfig): (req: Request) => Promise<Response>;
267
+ interface AnalyticsHandlerConfig extends CmsHandlersBase {
268
+ getAnalyticsData?: (days: number) => Promise<unknown>;
269
+ getPropertyId?: () => ({
270
+ currentViewId?: string;
271
+ [k: string]: unknown;
272
+ });
273
+ getPermissions?: () => ({
274
+ serviceAccountEmail?: string;
275
+ currentViewId?: string;
276
+ [k: string]: unknown;
277
+ });
278
+ }
279
+ declare function createAnalyticsHandlers(config: AnalyticsHandlerConfig): {
280
+ GET(req: Request): Promise<Response>;
281
+ propertyId: () => Promise<Response>;
282
+ permissions: () => Promise<Response>;
283
+ };
284
+
285
+ interface UploadHandlerConfig extends CmsHandlersBase {
286
+ /** Storage plugin instance or getter (e.g. () => getCms().then(c => c.getPlugin('storage'))). If not set, uses local fallback. */
287
+ storage?: StorageService | (() => StorageService | undefined) | (() => Promise<StorageService | undefined>);
288
+ /** Fallback when storage not set: dir relative to cwd (e.g. "public/uploads") */
289
+ localUploadDir?: string;
290
+ allowedTypes?: string[];
291
+ maxSizeBytes?: number;
292
+ /** Resolve folder chain for `parentId` (merged from createCmsApiHandler when omitted). */
293
+ dataSource?: DataSource;
294
+ entityMap?: EntityMap;
295
+ }
296
+ declare function createUploadHandler(config: UploadHandlerConfig): (req: Request) => Promise<Response>;
297
+ /** POST /api/media/extract/:id — expand a zip media row into folders/files under the zip’s parent folder. */
298
+ declare function createMediaZipExtractHandler(config: UploadHandlerConfig): (_req: Request, zipMediaId: string) => Promise<Response>;
299
+ interface BlogBySlugConfig extends CmsHandlersBase {
300
+ dataSource: DataSource;
301
+ entityMap: EntityMap;
302
+ }
303
+ declare function createBlogBySlugHandler(config: BlogBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
304
+ interface FormBySlugConfig extends CmsHandlersBase {
305
+ dataSource: DataSource;
306
+ entityMap: EntityMap;
307
+ }
308
+ declare function createFormBySlugHandler(config: FormBySlugConfig): (_req: Request, slug: string) => Promise<Response>;
309
+ interface FormSaveHandlersConfig extends CmsHandlersBase {
310
+ dataSource: DataSource;
311
+ entityMap: EntityMap;
312
+ }
313
+ interface FormSubmissionHandlerConfig {
314
+ dataSource: DataSource;
315
+ entityMap: EntityMap;
316
+ json: (body: unknown, init?: {
317
+ status?: number;
318
+ }) => Response;
319
+ /** When set, form submission notification email is queued (CRM recipient). */
320
+ getCms?: () => Promise<{
321
+ getPlugin: (name: string) => unknown;
322
+ }>;
323
+ getCompanyDetails?: () => Promise<CompanyDetails>;
324
+ getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;
325
+ }
326
+ interface FormSubmissionGetByIdConfig extends CmsHandlersBase {
327
+ dataSource: DataSource;
328
+ entityMap: EntityMap;
329
+ json: (body: unknown, init?: {
330
+ status?: number;
331
+ }) => Response;
332
+ }
333
+ interface UsersApiConfig extends CmsHandlersBase {
334
+ dataSource: DataSource;
335
+ entityMap: EntityMap;
336
+ baseUrl: string;
337
+ /** When set with email queue/plugin, invite emails are sent on user create and regenerate-invite. */
338
+ getCms?: () => Promise<{
339
+ getPlugin: (name: string) => unknown;
340
+ }>;
341
+ getCompanyDetails?: () => Promise<CompanyDetails>;
342
+ /** When set, soft-delete sets `deletedBy` on the user row. */
343
+ getSessionUser?: () => Promise<SessionUser | null>;
344
+ }
345
+ declare function createUsersApiHandlers(config: UsersApiConfig): {
346
+ list(req: Request): Promise<Response>;
347
+ create(req: Request): Promise<Response>;
348
+ getById(_req: Request, id: string): Promise<Response>;
349
+ update(req: Request, id: string): Promise<Response>;
350
+ delete(_req: Request, id: string): Promise<Response>;
351
+ regenerateInvite(_req: Request, id: string): Promise<Response>;
352
+ };
353
+ interface UserAvatarConfig extends CmsHandlersBase {
354
+ getSession: () => Promise<{
355
+ user?: {
356
+ email?: string | null;
357
+ };
358
+ } | null>;
359
+ /** Save avatar (buffer, fileName) => publicUrl. Default: local public/uploads/avatars */
360
+ saveAvatar?: (buffer: Buffer, fileName: string) => Promise<string>;
361
+ }
362
+ declare function createUserAvatarHandler(config: UserAvatarConfig): (req: Request) => Promise<Response>;
363
+ interface UserProfileConfig extends CmsHandlersBase {
364
+ dataSource: DataSource;
365
+ entityMap: EntityMap;
366
+ getSession: () => Promise<{
367
+ user?: {
368
+ id?: string;
369
+ email?: string | null;
370
+ name?: string | null;
371
+ };
372
+ } | null>;
373
+ /** Optional hook after a successful profile PUT (e.g. audit logging). */
374
+ onProfileUpdated?: (req: Request, user: {
375
+ id: number;
376
+ name: string;
377
+ email: string;
378
+ phone: string | null;
379
+ }) => Promise<void>;
380
+ }
381
+ /**
382
+ * GET / PUT handlers for `/api/users/profile` (current session user).
383
+ * GET merges DB fields with the session; PUT updates the user row and callers should refresh the client session (e.g. `useSession().update()`).
384
+ */
385
+ declare function createUserProfileHandler(config: UserProfileConfig): {
386
+ GET(_req: Request): Promise<Response>;
387
+ PUT(req: Request): Promise<Response>;
388
+ };
389
+ interface SettingsApiConfig extends CmsHandlersBase {
390
+ dataSource: DataSource;
391
+ entityMap: EntityMap;
392
+ encryptionKey?: string;
393
+ /** Groups in this list are readable without auth (GET returns all keys for the group). */
394
+ publicGetGroups?: string[];
395
+ }
396
+ declare function simpleEncrypt(text: string, key: string): string;
397
+ declare function simpleDecrypt(encoded: string, key: string): string;
398
+ /**
399
+ * Structural types so apps with their own `typeorm` install (e.g. npm link) typecheck without duplicate-package errors.
400
+ */
401
+ type GetPublicSettingsGroupDataSource = {
402
+ getRepository(entity: unknown): {
403
+ find(options: object): Promise<unknown[]>;
404
+ };
405
+ };
406
+ interface GetPublicSettingsGroupConfig {
407
+ dataSource: GetPublicSettingsGroupDataSource;
408
+ entityMap: Record<string, unknown>;
409
+ encryptionKey?: string;
410
+ }
411
+ /** Same rows as unauthenticated GET /api/settings/:group when the group is in publicGetGroups. */
412
+ declare function getPublicSettingsGroup(config: GetPublicSettingsGroupConfig, group: string): Promise<Record<string, string>>;
413
+ declare function createSettingsApiHandlers(config: SettingsApiConfig): {
414
+ GET(req: Request, group: string): Promise<Response>;
415
+ PUT(req: Request, group: string): Promise<Response>;
416
+ };
417
+ interface ChatApiConfig extends CmsHandlersBase {
418
+ dataSource: DataSource;
419
+ entityMap: EntityMap;
420
+ getCms: () => Promise<{
421
+ getPlugin: (name: string) => unknown;
422
+ }>;
423
+ }
424
+ /** Safe subset of `llm` settings for the storefront chat widget (`GET /api/chat/config`). */
425
+ interface ChatPublicConfig {
426
+ enabled: boolean;
427
+ chatMode: 'whatsapp' | 'external' | 'llm';
428
+ /** When `chatMode === 'llm'`, slug of the chatbot-scoped agent (`llm_agents.scope = chatbot`). */
429
+ agentSlug: string;
430
+ botName: string;
431
+ icon: string;
432
+ iconImageUrl: string;
433
+ iconBackgroundColor: string;
434
+ headerColor: string;
435
+ whatsappPhone: string;
436
+ }
437
+
438
+ /**
439
+ * Admin API: attach knowledge base documents to an LLM agent, ingest text into chunks + embeddings.
440
+ * Routes: GET/POST /api/llm_agents/:slug/knowledge, DELETE /api/llm_agents/:slug/knowledge/:documentId
441
+ *
442
+ * Pipeline logs (grep `[llm-agent-knowledge] pipeline`):
443
+ * - 01_request — incoming POST, content-type preview
444
+ * - 02_agent_loaded — agent id for slug
445
+ * - 03_body_parsed — JSON vs multipart, sizes / documentId
446
+ * - 04_* — file decode or PDF extract (multipart)
447
+ * - 05_branch — link_existing_document | new_upload_ingest
448
+ * - 06_* — KB row + junction (link create / exists)
449
+ * - 06b_chunks_existing_count — link path: existing chunk rows
450
+ * - 06_knowledge_document_saved — new ingest: document row id
451
+ * - 07_chunk_split — split stats
452
+ * - 07b_chunks_persisted — chunk rows saved
453
+ * - 07_query_chunks_missing_embedding — link path: rows with NULL embedding
454
+ * - 08_* — resolve LLM plugin, embed availability or skip
455
+ * - 09_embedding_workers_start / 10_embedding_workers_finished — concurrent embed+DB update
456
+ * - 11_response — final outcome summary
457
+ * - 99_pipeline_error — uncaught exception
458
+ */
459
+
460
+ interface LlmAgentKnowledgeApiConfig {
461
+ dataSource: DataSource;
462
+ entityMap: EntityMap;
463
+ getCms: () => Promise<{
464
+ getPlugin: (name: string) => unknown;
465
+ }>;
466
+ json: (body: unknown, init?: {
467
+ status?: number;
468
+ }) => Response;
469
+ requireAuth: (req: Request) => Promise<Response | null>;
470
+ requireEntityPermission?: RequireEntityPermissionFn;
471
+ }
472
+ declare function createLlmAgentKnowledgeHandlers(config: LlmAgentKnowledgeApiConfig): {
473
+ list(req: Request, slug: string): Promise<Response>;
474
+ post(req: Request, slug: string): Promise<Response>;
475
+ unlink(req: Request, slug: string, documentIdStr: string): Promise<Response>;
476
+ } | null;
477
+
478
+ /**
479
+ * Single CMS API handler: dashboard, analytics, upload, media zip extract, blog/form by slug, users API, user auth, CRUD. Mount once (e.g. app/api/[[...path]]/route.ts).
480
+ */
481
+
482
+ /** CMS instance with getPlugin; when provided, analytics and userAuth.sendEmail can be resolved from plugins when not passed. */
483
+ type CmsGetter = () => Promise<{
484
+ getPlugin: (name: string) => unknown;
485
+ }>;
486
+ interface CmsApiHandlerConfig {
487
+ dataSource: DataSource;
488
+ entityMap: EntityMap;
489
+ requireAuth: (req: Request) => Promise<Response | null>;
490
+ json: (body: unknown, init?: {
491
+ status?: number;
492
+ }) => Response;
493
+ pathToModel?: (segment: string) => string;
494
+ crudResources?: string[];
495
+ /** When set, analytics and userAuth.sendEmail can be derived from getPlugin('analytics') and getPlugin('email') when not provided. */
496
+ getCms?: CmsGetter;
497
+ /** Optional: used when deriving userAuth.sendEmail to pass company details into email templates (e.g. from settings). */
498
+ getCompanyDetails?: () => Promise<CompanyDetails>;
499
+ /** Optional: used for form submission and other channel-based email recipients (from settings group "email"). */
500
+ getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;
501
+ userAuth?: UserAuthApiConfig;
502
+ /** GET /api/dashboard/stats */
503
+ dashboard?: DashboardStatsConfig;
504
+ /** GET /api/dashboard/ecommerce */
505
+ ecommerceAnalytics?: EcommerceAnalyticsConfig;
506
+ /** GET /api/analytics. If omitted and getCms is set, uses getCms().getPlugin('analytics'). */
507
+ analytics?: AnalyticsHandlerConfig;
508
+ /** POST /api/upload (S3 or local) */
509
+ upload?: UploadHandlerConfig;
510
+ /** GET /api/blogs/slug/:slug (public) */
511
+ blogBySlug?: BlogBySlugConfig;
512
+ /** GET /api/forms/slug/:slug (public) */
513
+ formBySlug?: FormBySlugConfig;
514
+ /** POST/PUT /api/forms (save form + fields; when set, overrides CRUD for forms) */
515
+ formSave?: FormSaveHandlersConfig;
516
+ /** POST /api/form-submissions (public, no auth) */
517
+ formSubmission?: FormSubmissionHandlerConfig;
518
+ /** GET /api/form-submissions/:id (auth) with form + contact relations */
519
+ formSubmissionGetById?: FormSubmissionGetByIdConfig;
520
+ /** GET/POST /api/users, GET/PUT/DELETE /api/users/:id, POST /api/users/:id/regenerate-invite */
521
+ usersApi?: UsersApiConfig;
522
+ /** POST /api/users/avatar */
523
+ userAvatar?: UserAvatarConfig;
524
+ /** GET/PUT /api/users/profile (current session user) */
525
+ userProfile?: UserProfileConfig;
526
+ /** GET/PUT /api/settings/:group */
527
+ settings?: SettingsApiConfig;
528
+ /** GET /api/chat/config (public); POST /api/chat/identify; GET /api/chat/conversations/:id/messages; POST /api/chat/messages */
529
+ chat?: ChatApiConfig;
530
+ /**
531
+ * GET/POST /api/llm_agents/:slug/knowledge; DELETE …/knowledge/:documentId — agent KB ingest + links.
532
+ * When omitted but `chat` is set, the same dataSource / entityMap / getCms / json / requireAuth are reused automatically.
533
+ */
534
+ llmAgentKnowledge?: LlmAgentKnowledgeApiConfig;
535
+ /**
536
+ * Entity-level RBAC (session `entityPerms` / Administrator). When omitted, admin routes that need it respond with 403
537
+ * (`entity_rbac_required`) so CRUD cannot run as auth-only. Pass `createAuthHelpers(...).requireEntityPermission` from the app.
538
+ */
539
+ requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
540
+ /** Required for vendor store RBAC + scoping. Alias: `getAuthenticatedUser`. */
541
+ getSessionUser?: () => Promise<SessionUser | null>;
542
+ /** Same as `getSessionUser` (from `createAuthHelpers().getAuthenticatedUser`). */
543
+ getAuthenticatedUser?: () => Promise<SessionUser | null>;
544
+ }
545
+ declare function createCmsApiHandler(config: CmsApiHandlerConfig): {
546
+ handle(method: string, pathInput: string[], req: Request): Promise<Response>;
547
+ };
548
+
549
+ type VendorOwnerActivation = 'invite' | 'password';
550
+ interface VendorOnboardHandlersConfig {
551
+ dataSource: DataSource;
552
+ entityMap: EntityMap;
553
+ json: (body: unknown, init?: {
554
+ status?: number;
555
+ }) => Response;
556
+ getSessionUser: () => Promise<SessionUser | null>;
557
+ baseUrl: string;
558
+ getCms?: () => Promise<{
559
+ getPlugin: (name: string) => unknown;
560
+ }>;
561
+ hashPassword?: (plain: string) => Promise<string>;
562
+ minPasswordLength?: number;
563
+ }
564
+ declare function createVendorOnboardHandlers(config: VendorOnboardHandlersConfig): {
565
+ /** POST /api/admin/vendors/onboard — create vendor + owner user + vendor_users + invite */
566
+ onboard(req: Request): Promise<Response>;
567
+ /** POST /api/admin/vendor/switch — set active vendor in session (JWT update via client) */
568
+ switchVendor(req: Request): Promise<Response>;
569
+ /** GET /api/admin/vendor/team */
570
+ listTeam(): Promise<Response>;
571
+ /** POST /api/admin/vendor/team — add staff to vendor */
572
+ addTeamMember(req: Request): Promise<Response>;
573
+ /** PATCH /api/admin/vendor/team/:userId — change member store role */
574
+ updateTeamMemberRole(req: Request, userIdStr: string): Promise<Response>;
575
+ /** DELETE /api/admin/vendor/team/:userId */
576
+ removeTeamMember(_req: Request, userIdStr: string): Promise<Response>;
577
+ };
578
+
579
+ interface JobScheduleApiConfig {
580
+ dataSource: DataSource;
581
+ entityMap: EntityMap;
582
+ json: (body: unknown, init?: ResponseInit) => Response;
583
+ requireAuth: (req: Request) => Promise<Response | null>;
584
+ requireEntityPermission?: (req: Request, entity: string, action: 'read' | 'create' | 'update' | 'delete') => Promise<Response | null>;
585
+ getCms?: CmsGetter;
586
+ config?: Record<string, string>;
587
+ }
588
+ declare function createJobScheduleHandlers(apiConfig: JobScheduleApiConfig): {
589
+ list(req: Request): Promise<Response>;
590
+ getById(req: Request, id: string): Promise<Response>;
591
+ create(req: Request): Promise<Response>;
592
+ update(req: Request, id: string): Promise<Response>;
593
+ remove(req: Request, id: string): Promise<Response>;
594
+ runNow(req: Request, id: string): Promise<Response>;
595
+ listRuns(req: Request, id: string): Promise<Response>;
596
+ };
597
+
598
+ interface StorefrontOtpFlags {
599
+ login?: boolean;
600
+ verifyEmail?: boolean;
601
+ verifyPhone?: boolean;
602
+ }
603
+ interface StorefrontApiConfig {
604
+ dataSource: DataSource;
605
+ entityMap: EntityMap;
606
+ json: (body: unknown, init?: {
607
+ status?: number;
608
+ headers?: HeadersInit;
609
+ }) => Response;
610
+ getSessionUser: () => Promise<SessionUser | null>;
611
+ guestCookieName?: string;
612
+ /** Required for POST storefront/register */
613
+ hashPassword?: (plain: string) => Promise<string>;
614
+ /** When set, new registrations are blocked until email is verified and a signup email is sent. */
615
+ getCms?: () => Promise<{
616
+ getPlugin: (name: string) => unknown;
617
+ }>;
618
+ getCompanyDetails?: () => Promise<CompanyDetails>;
619
+ /** Origin for verify links (e.g. process.env.NEXTAUTH_URL). Required with getCms for verification URLs. */
620
+ publicSiteUrl?: string;
621
+ /** When a flag is true, the corresponding OTP storefront route is enabled. */
622
+ otpFlags?: StorefrontOtpFlags;
623
+ /** Defaults to OTP_PEPPER or NEXTAUTH_SECRET. */
624
+ otpPepper?: string;
625
+ defaultPhoneCountryCode?: string;
626
+ /** When false, login OTP send accepts email only (no phone). Default true. */
627
+ otpAllowPhoneLogin?: boolean;
628
+ }
629
+ declare function createStorefrontApiHandler(config: StorefrontApiConfig): {
630
+ handle(method: string, path: string[], req: Request): Promise<Response>;
631
+ };
632
+
633
+ export { type AnalyticsHandlerConfig, type AuthHandlersConfig, type BlogBySlugConfig, type ChangePasswordConfig, type ChatPublicConfig, type CmsApiHandlerConfig, type CmsGetter, type CrudHandlerOptions, type DashboardStatsConfig, type EcommerceAnalyticsConfig, type EntityMap, type ForgotPasswordConfig, type FormBySlugConfig, type GetPublicSettingsGroupConfig, type GetPublicSettingsGroupDataSource, type InviteAcceptConfig, type JobScheduleApiConfig, type LlmAgentKnowledgeApiConfig, type LlmAgentValidationRulesJson, type ParsedLlmAgentValidation, type SetPasswordConfig, type SettingsApiConfig, type StorefrontApiConfig, type StorefrontOtpFlags, type UploadHandlerConfig, type UserAuthApiConfig, type UserAvatarConfig, type UserProfileConfig, type UsersApiConfig, type VendorDashboardConfig, type VendorOnboardHandlersConfig, type VendorOwnerActivation, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsAuthBundle, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createSetPasswordHandler, createSettingsApiHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, getPublicSettingsGroup, mergeGuardrailsIntoSystemPrompt, parseLlmAgentValidationRules, simpleDecrypt, simpleEncrypt, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules };