@rebasepro/server-core 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e

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 (176) hide show
  1. package/dist/common/src/collections/CollectionRegistry.d.ts +8 -0
  2. package/dist/common/src/util/entities.d.ts +22 -0
  3. package/dist/common/src/util/relations.d.ts +14 -4
  4. package/dist/common/src/util/resolutions.d.ts +1 -1
  5. package/dist/index-DXVBFp5V.js +37 -0
  6. package/dist/index-DXVBFp5V.js.map +1 -0
  7. package/dist/index.es.js +49931 -55
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.umd.js +28475 -34569
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/server-core/src/api/openapi-generator.d.ts +15 -1
  12. package/dist/server-core/src/api/types.d.ts +1 -1
  13. package/dist/server-core/src/auth/admin-routes.d.ts +10 -1
  14. package/dist/server-core/src/auth/apple-oauth.d.ts +30 -0
  15. package/dist/server-core/src/auth/bitbucket-oauth.d.ts +11 -0
  16. package/dist/server-core/src/auth/discord-oauth.d.ts +14 -0
  17. package/dist/server-core/src/auth/facebook-oauth.d.ts +14 -0
  18. package/dist/server-core/src/auth/github-oauth.d.ts +15 -0
  19. package/dist/server-core/src/auth/gitlab-oauth.d.ts +13 -0
  20. package/dist/server-core/src/auth/google-oauth.d.ts +5 -11
  21. package/dist/server-core/src/auth/index.d.ts +13 -2
  22. package/dist/server-core/src/auth/interfaces.d.ts +45 -6
  23. package/dist/server-core/src/auth/jwt.d.ts +1 -0
  24. package/dist/server-core/src/auth/linkedin-oauth.d.ts +18 -0
  25. package/dist/server-core/src/auth/microsoft-oauth.d.ts +16 -0
  26. package/dist/server-core/src/auth/middleware.d.ts +36 -11
  27. package/dist/server-core/src/auth/rate-limiter.d.ts +2 -2
  28. package/dist/server-core/src/auth/routes.d.ts +13 -3
  29. package/dist/server-core/src/auth/slack-oauth.d.ts +12 -0
  30. package/dist/server-core/src/auth/spotify-oauth.d.ts +12 -0
  31. package/dist/server-core/src/auth/twitter-oauth.d.ts +18 -0
  32. package/dist/server-core/src/cron/cron-loader.d.ts +17 -0
  33. package/dist/server-core/src/cron/cron-routes.d.ts +14 -0
  34. package/dist/server-core/src/cron/cron-scheduler.d.ts +61 -0
  35. package/dist/server-core/src/cron/cron-store.d.ts +32 -0
  36. package/dist/server-core/src/cron/index.d.ts +6 -0
  37. package/dist/server-core/src/email/index.d.ts +2 -2
  38. package/dist/server-core/src/email/templates.d.ts +9 -0
  39. package/dist/server-core/src/email/types.d.ts +20 -23
  40. package/dist/server-core/src/history/history-routes.d.ts +2 -2
  41. package/dist/server-core/src/index.d.ts +5 -0
  42. package/dist/server-core/src/init.d.ts +112 -2
  43. package/dist/server-core/src/singleton.d.ts +35 -0
  44. package/dist/server-core/src/storage/LocalStorageController.d.ts +9 -9
  45. package/dist/server-core/src/storage/S3StorageController.d.ts +8 -8
  46. package/dist/server-core/src/storage/index.d.ts +18 -11
  47. package/dist/server-core/src/storage/routes.d.ts +3 -3
  48. package/dist/server-core/src/storage/types.d.ts +28 -16
  49. package/dist/server-core/src/utils/dev-port.d.ts +35 -0
  50. package/dist/server-core/src/utils/logger.d.ts +31 -0
  51. package/dist/server-core/src/utils/request-logger.d.ts +19 -0
  52. package/dist/types/src/controllers/auth.d.ts +2 -0
  53. package/dist/types/src/controllers/client.d.ts +119 -7
  54. package/dist/types/src/controllers/collection_registry.d.ts +4 -3
  55. package/dist/types/src/controllers/customization_controller.d.ts +7 -1
  56. package/dist/types/src/controllers/data.d.ts +34 -7
  57. package/dist/types/src/controllers/data_driver.d.ts +20 -28
  58. package/dist/types/src/controllers/database_admin.d.ts +2 -2
  59. package/dist/types/src/controllers/email.d.ts +34 -0
  60. package/dist/types/src/controllers/index.d.ts +1 -0
  61. package/dist/types/src/controllers/local_config_persistence.d.ts +4 -4
  62. package/dist/types/src/controllers/navigation.d.ts +5 -5
  63. package/dist/types/src/controllers/registry.d.ts +6 -3
  64. package/dist/types/src/controllers/side_entity_controller.d.ts +7 -6
  65. package/dist/types/src/controllers/storage.d.ts +24 -26
  66. package/dist/types/src/rebase_context.d.ts +8 -4
  67. package/dist/types/src/types/backend.d.ts +4 -1
  68. package/dist/types/src/types/builders.d.ts +5 -4
  69. package/dist/types/src/types/chips.d.ts +1 -1
  70. package/dist/types/src/types/collections.d.ts +169 -125
  71. package/dist/types/src/types/cron.d.ts +102 -0
  72. package/dist/types/src/types/data_source.d.ts +1 -1
  73. package/dist/types/src/types/entity_actions.d.ts +8 -8
  74. package/dist/types/src/types/entity_callbacks.d.ts +15 -15
  75. package/dist/types/src/types/entity_link_builder.d.ts +1 -1
  76. package/dist/types/src/types/entity_overrides.d.ts +2 -1
  77. package/dist/types/src/types/entity_views.d.ts +8 -8
  78. package/dist/types/src/types/export_import.d.ts +3 -3
  79. package/dist/types/src/types/index.d.ts +1 -0
  80. package/dist/types/src/types/plugins.d.ts +72 -18
  81. package/dist/types/src/types/properties.d.ts +118 -33
  82. package/dist/types/src/types/relations.d.ts +1 -1
  83. package/dist/types/src/types/slots.d.ts +30 -6
  84. package/dist/types/src/types/translations.d.ts +44 -0
  85. package/dist/types/src/types/user_management_delegate.d.ts +1 -0
  86. package/package.json +84 -84
  87. package/scratch.ts +6 -5
  88. package/src/api/ast-schema-editor.ts +11 -11
  89. package/src/api/collections_for_test/callbacks_test_collection.ts +5 -2
  90. package/src/api/errors.ts +38 -14
  91. package/src/api/graphql/graphql-schema-generator.ts +5 -3
  92. package/src/api/openapi-generator.ts +613 -58
  93. package/src/api/rest/api-generator.ts +17 -11
  94. package/src/api/rest/query-parser.ts +1 -1
  95. package/src/api/schema-editor-routes.ts +2 -0
  96. package/src/api/server.ts +8 -5
  97. package/src/api/types.ts +1 -1
  98. package/src/auth/admin-routes.ts +58 -17
  99. package/src/auth/apple-oauth.ts +130 -0
  100. package/src/auth/bitbucket-oauth.ts +82 -0
  101. package/src/auth/discord-oauth.ts +83 -0
  102. package/src/auth/facebook-oauth.ts +72 -0
  103. package/src/auth/github-oauth.ts +110 -0
  104. package/src/auth/gitlab-oauth.ts +70 -0
  105. package/src/auth/google-oauth.ts +34 -46
  106. package/src/auth/index.ts +15 -2
  107. package/src/auth/interfaces.ts +54 -7
  108. package/src/auth/jwt.ts +22 -5
  109. package/src/auth/linkedin-oauth.ts +81 -0
  110. package/src/auth/microsoft-oauth.ts +88 -0
  111. package/src/auth/middleware.ts +194 -45
  112. package/src/auth/password.ts +3 -1
  113. package/src/auth/rate-limiter.ts +4 -4
  114. package/src/auth/routes.ts +197 -139
  115. package/src/auth/slack-oauth.ts +71 -0
  116. package/src/auth/spotify-oauth.ts +67 -0
  117. package/src/auth/twitter-oauth.ts +120 -0
  118. package/src/collections/loader.ts +6 -6
  119. package/src/cron/cron-loader.ts +89 -0
  120. package/src/cron/cron-routes.test.ts +265 -0
  121. package/src/cron/cron-routes.ts +85 -0
  122. package/src/cron/cron-scheduler.test.ts +421 -0
  123. package/src/cron/cron-scheduler.ts +413 -0
  124. package/src/cron/cron-store.ts +163 -0
  125. package/src/cron/index.ts +6 -0
  126. package/src/db/interfaces.ts +2 -2
  127. package/src/email/index.ts +3 -2
  128. package/src/email/smtp-email-service.ts +5 -2
  129. package/src/email/templates.ts +93 -6
  130. package/src/email/types.ts +17 -24
  131. package/src/functions/function-loader.ts +34 -6
  132. package/src/functions/function-routes.ts +2 -2
  133. package/src/history/history-routes.ts +4 -3
  134. package/src/index.ts +10 -0
  135. package/src/init.ts +475 -57
  136. package/src/services/driver-registry.ts +1 -1
  137. package/src/singleton.test.ts +28 -0
  138. package/src/singleton.ts +70 -0
  139. package/src/storage/LocalStorageController.ts +50 -53
  140. package/src/storage/S3StorageController.ts +49 -46
  141. package/src/storage/index.ts +27 -16
  142. package/src/storage/routes.ts +76 -59
  143. package/src/storage/storage-registry.ts +5 -5
  144. package/src/storage/types.ts +44 -32
  145. package/src/types/index.ts +4 -4
  146. package/src/utils/dev-port.ts +176 -0
  147. package/src/utils/logger.ts +143 -0
  148. package/src/utils/logging.ts +5 -2
  149. package/src/utils/request-logger.ts +66 -0
  150. package/test/admin-routes.test.ts +114 -65
  151. package/test/api-generator.test.ts +73 -30
  152. package/test/ast-schema-editor.test.ts +5 -3
  153. package/test/auth-middleware-hono.test.ts +268 -33
  154. package/test/auth-routes.test.ts +325 -146
  155. package/test/driver-registry.test.ts +4 -2
  156. package/test/error-propagation.test.ts +226 -0
  157. package/test/errors.test.ts +12 -7
  158. package/test/jwt-security.test.ts +18 -9
  159. package/test/jwt.test.ts +26 -13
  160. package/test/middleware.test.ts +13 -8
  161. package/test/query-parser.test.ts +13 -8
  162. package/test/rate-limiter.test.ts +7 -7
  163. package/test/safe-compare.test.ts +66 -0
  164. package/test/singleton.test.ts +59 -0
  165. package/test/storage-local.test.ts +36 -43
  166. package/test/storage-registry.test.ts +38 -36
  167. package/test/storage-routes.test.ts +9 -5
  168. package/test/storage-s3.test.ts +51 -48
  169. package/test.ts +6 -0
  170. package/tsconfig.json +1 -1
  171. package/vite.config.ts +7 -5
  172. package/dist/index-BeMqpmfQ.js +0 -239
  173. package/dist/index-BeMqpmfQ.js.map +0 -1
  174. package/dist/index-bl4J3lNb.js +0 -55823
  175. package/dist/index-bl4J3lNb.js.map +0 -1
  176. package/vite.config.ts.timestamp-1775065397568-8a853255edf6e.mjs +0 -46
@@ -77,7 +77,7 @@ const styles = {
77
77
  export function getPasswordResetTemplate(
78
78
  resetUrl: string,
79
79
  user: TemplateUser,
80
- appName: string = "Rebase"
80
+ appName = "Rebase"
81
81
  ): { subject: string; html: string; text: string } {
82
82
  const greeting = getGreeting(user);
83
83
 
@@ -148,7 +148,9 @@ If you didn't request a password reset, you can safely ignore this email.
148
148
  Your password will remain unchanged.
149
149
  `.trim();
150
150
 
151
- return { subject, html, text };
151
+ return { subject,
152
+ html,
153
+ text };
152
154
  }
153
155
 
154
156
  /**
@@ -157,7 +159,7 @@ Your password will remain unchanged.
157
159
  export function getEmailVerificationTemplate(
158
160
  verifyUrl: string,
159
161
  user: TemplateUser,
160
- appName: string = "Rebase"
162
+ appName = "Rebase"
161
163
  ): { subject: string; html: string; text: string } {
162
164
  const greeting = getGreeting(user);
163
165
 
@@ -218,7 +220,9 @@ ${verifyUrl}
218
220
  If you didn't create an account with ${appName}, you can safely ignore this email.
219
221
  `.trim();
220
222
 
221
- return { subject, html, text };
223
+ return { subject,
224
+ html,
225
+ text };
222
226
  }
223
227
 
224
228
  /**
@@ -228,7 +232,7 @@ If you didn't create an account with ${appName}, you can safely ignore this emai
228
232
  export function getUserInvitationTemplate(
229
233
  setPasswordUrl: string,
230
234
  user: TemplateUser,
231
- appName: string = "Rebase"
235
+ appName = "Rebase"
232
236
  ): { subject: string; html: string; text: string } {
233
237
  const greeting = getGreeting(user);
234
238
 
@@ -297,5 +301,88 @@ This link will expire in 1 hour for security reasons.
297
301
  If you weren't expecting this invitation, you can safely ignore this email.
298
302
  `.trim();
299
303
 
300
- return { subject, html, text };
304
+ return { subject,
305
+ html,
306
+ text };
307
+ }
308
+
309
+ /**
310
+ * Default welcome email template
311
+ * Sent automatically when a new user registers
312
+ */
313
+ export function getWelcomeEmailTemplate(
314
+ user: TemplateUser,
315
+ appName = "Rebase",
316
+ loginUrl?: string
317
+ ): { subject: string; html: string; text: string } {
318
+ const greeting = getGreeting(user);
319
+ const url = loginUrl || "";
320
+
321
+ const subject = `¡Bienvenido/a a ${appName}!`;
322
+
323
+ const html = `
324
+ <!DOCTYPE html>
325
+ <html>
326
+ <head>
327
+ <meta charset="utf-8">
328
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
329
+ <title>${subject}</title>
330
+ </head>
331
+ <body style="margin: 0; padding: 0; background-color: #f8fafc;">
332
+ <div style="${styles.container}">
333
+ <div style="${styles.card}">
334
+ <h1 style="${styles.heading}">¡Bienvenido/a a ${appName}!</h1>
335
+
336
+ <p style="${styles.paragraph}">
337
+ Hola ${greeting},
338
+ </p>
339
+
340
+ <p style="${styles.paragraph}">
341
+ Tu cuenta en ${appName} ha sido creada exitosamente.
342
+ Estamos encantados de tenerte con nosotros.
343
+ </p>
344
+
345
+ <p style="${styles.paragraph}">
346
+ Ya puedes acceder a tu panel y empezar a explorar todas las oportunidades
347
+ que tenemos para ti.
348
+ </p>
349
+
350
+ ${url ? `
351
+ <div style="text-align: center;">
352
+ <a href="${url}" style="${styles.button}">Ir a mi Panel</a>
353
+ </div>
354
+ ` : ""}
355
+
356
+ <p style="${styles.paragraph}">
357
+ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
358
+ </p>
359
+
360
+ <div style="${styles.footer}">
361
+ <p style="margin: 0;">
362
+ Este correo fue enviado porque se creó una cuenta con esta dirección de email en ${appName}.
363
+ </p>
364
+ </div>
365
+ </div>
366
+ </div>
367
+ </body>
368
+ </html>
369
+ `.trim();
370
+
371
+ const text = `
372
+ ¡Bienvenido/a a ${appName}!
373
+
374
+ Hola ${greeting},
375
+
376
+ Tu cuenta en ${appName} ha sido creada exitosamente. Estamos encantados de tenerte con nosotros.
377
+
378
+ Ya puedes acceder a tu panel y empezar a explorar todas las oportunidades que tenemos para ti.
379
+
380
+ ${url ? `Ir a mi panel: ${url}` : ""}
381
+
382
+ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
383
+ `.trim();
384
+
385
+ return { subject,
386
+ html,
387
+ text };
301
388
  }
@@ -1,31 +1,15 @@
1
1
  /**
2
- * Email service types and interfaces
2
+ * Email service types and interfaces.
3
+ *
4
+ * The canonical `EmailService` and `EmailSendOptions` live in `@rebasepro/types`
5
+ * so they can be used on the `RebaseClient` interface without pulling in nodemailer.
6
+ * This file re-exports them for backward compatibility and adds server-specific
7
+ * config types (SMTP, template functions, etc.).
3
8
  */
4
9
 
5
- /**
6
- * Options for sending an email
7
- */
8
- export interface EmailSendOptions {
9
- to: string;
10
- subject: string;
11
- html: string;
12
- text?: string;
13
- }
10
+ import type { EmailService, EmailSendOptions } from "@rebasepro/types";
14
11
 
15
- /**
16
- * Email service interface - abstraction for sending emails
17
- */
18
- export interface EmailService {
19
- /**
20
- * Send an email
21
- */
22
- send(options: EmailSendOptions): Promise<void>;
23
-
24
- /**
25
- * Check if the email service is properly configured
26
- */
27
- isConfigured(): boolean;
28
- }
12
+ export type { EmailService, EmailSendOptions };
29
13
 
30
14
  /**
31
15
  * SMTP server configuration
@@ -64,6 +48,14 @@ export type UserInvitationTemplateFunction = (
64
48
  user: { email: string; displayName?: string | null }
65
49
  ) => { subject: string; html: string; text?: string };
66
50
 
51
+ /**
52
+ * Template function for welcome emails sent after registration
53
+ */
54
+ export type WelcomeEmailTemplateFunction = (
55
+ user: { email: string; displayName?: string | null },
56
+ appName: string
57
+ ) => { subject: string; html: string; text?: string };
58
+
67
59
  /**
68
60
  * Complete email configuration
69
61
  */
@@ -108,5 +100,6 @@ export interface EmailConfig {
108
100
  passwordReset?: PasswordResetTemplateFunction;
109
101
  emailVerification?: EmailVerificationTemplateFunction;
110
102
  userInvitation?: UserInvitationTemplateFunction;
103
+ welcomeEmail?: WelcomeEmailTemplateFunction;
111
104
  };
112
105
  }
@@ -55,10 +55,12 @@ export async function loadFunctionsFromDirectory(
55
55
  continue;
56
56
  }
57
57
 
58
- // Accept a Hono instance directly
59
- if (exported instanceof Hono) {
58
+ // Accept a Hono instance — use duck-typing to handle different
59
+ // Hono versions which may not share the same prototype.
60
+ if (isHonoLike(exported)) {
60
61
  const name = path.basename(file, path.extname(file));
61
- functions.push({ name, app: exported });
62
+ functions.push({ name,
63
+ app: exported as Hono });
62
64
  console.log(`⚡ Loaded function route: ${name}`);
63
65
  continue;
64
66
  }
@@ -66,16 +68,26 @@ export async function loadFunctionsFromDirectory(
66
68
  // Also accept a factory function that returns a Hono instance
67
69
  if (typeof exported === "function") {
68
70
  const result = exported();
69
- if (result instanceof Hono) {
71
+ if (isHonoLike(result)) {
70
72
  const name = path.basename(file, path.extname(file));
71
- functions.push({ name, app: result });
73
+ functions.push({ name,
74
+ app: result as Hono });
72
75
  console.log(`⚡ Loaded function route: ${name}`);
73
76
  continue;
74
77
  }
75
78
  }
76
79
 
80
+ // Provide actionable diagnostics
81
+ const exportType = typeof exported;
82
+ const keys = exported && typeof exported === "object"
83
+ ? Object.getOwnPropertyNames(Object.getPrototypeOf(exported)).slice(0, 10).join(", ")
84
+ : "N/A";
77
85
  console.warn(
78
- `[functions] ${file}: default export is not a Hono app or factory. Skipping.`
86
+ `[functions] ${file}: default export is not a Hono app or factory. Skipping.\n` +
87
+ ` export type: ${exportType}${exported?.constructor?.name ? ` (${exported.constructor.name})` : ""}\n` +
88
+ ` prototype methods: ${keys}\n` +
89
+ " Hint: ensure the function exports a Hono app created with the same hono version as the server.\n" +
90
+ " The loader checks for .fetch() and .routes — any Hono-compatible app will work."
79
91
  );
80
92
  } catch (err: unknown) {
81
93
  const message =
@@ -89,3 +101,19 @@ export async function loadFunctionsFromDirectory(
89
101
 
90
102
  return functions;
91
103
  }
104
+
105
+ /**
106
+ * Duck-type check for Hono apps.
107
+ * We avoid `instanceof Hono` because different Hono versions
108
+ * installed in the user's project vs. our dependencies will
109
+ * not share the same prototype, causing false negatives.
110
+ */
111
+ function isHonoLike(obj: unknown): boolean {
112
+ if (!obj || typeof obj !== "object") return false;
113
+ // Hono instances always have .fetch() and .routes
114
+ const record = obj as Record<string, unknown>;
115
+ return (
116
+ typeof record.fetch === "function" &&
117
+ Array.isArray(record.routes)
118
+ );
119
+ }
@@ -18,8 +18,8 @@ export function createFunctionRoutes(
18
18
  return c.json({
19
19
  functions: functions.map((fn) => ({
20
20
  name: fn.name,
21
- endpoint: `/functions/${fn.name}`,
22
- })),
21
+ endpoint: `/functions/${fn.name}`
22
+ }))
23
23
  });
24
24
  });
25
25
 
@@ -1,15 +1,15 @@
1
1
  import { Hono } from "hono";
2
2
  import { HonoEnv } from "../api/types";
3
3
  import { BackendCollectionRegistry } from "../collections/BackendCollectionRegistry";
4
- import { ApiError } from "../api/errors";
4
+ import { ApiError, errorHandler } from "../api/errors";
5
5
  import { DataDriver } from "@rebasepro/types";
6
6
  /**
7
7
  * Create Hono routes for entity history.
8
8
  * Mounted at `{basePath}/data/:slug/:entityId/history`.
9
9
  */
10
10
  export interface HistoryService {
11
- fetchHistory(tableName: string, entityId: string, options: { limit: number, offset: number }): Promise<{ data: any[], total: number }>;
12
- fetchHistoryEntry(historyId: string): Promise<any>;
11
+ fetchHistory(tableName: string, entityId: string, options: { limit: number, offset: number }): Promise<{ data: Record<string, unknown>[], total: number }>;
12
+ fetchHistoryEntry(historyId: string): Promise<Record<string, unknown> | null>;
13
13
  }
14
14
 
15
15
  export function createHistoryRoutes(params: {
@@ -19,6 +19,7 @@ export function createHistoryRoutes(params: {
19
19
  }): Hono<HonoEnv> {
20
20
  const { historyService, registry, driver } = params;
21
21
  const router = new Hono<HonoEnv>();
22
+ router.onError(errorHandler);
22
23
 
23
24
  /**
24
25
  * GET /:slug/:entityId/history - List history entries for an entity
package/src/index.ts CHANGED
@@ -16,6 +16,9 @@ export * from "./auth/interfaces";
16
16
  // Core functionality
17
17
  export * from "./init";
18
18
 
19
+ // Server-side singleton (import { rebase } from "@rebasepro/server-core")
20
+ export { rebase, _setRebaseMock, _resetRebaseMock } from "./singleton";
21
+
19
22
  // Services
20
23
  export * from "./services/driver-registry";
21
24
 
@@ -39,6 +42,8 @@ export * from "./email";
39
42
  export * from "./storage";
40
43
 
41
44
  export * from "./utils/logging";
45
+ export * from "./utils/logger";
46
+ export * from "./utils/request-logger";
42
47
  export * from "./utils/sql";
43
48
 
44
49
  // Entity history
@@ -47,10 +52,15 @@ export * from "./history";
47
52
  // Custom Functions (auto-discovered Hono routes)
48
53
  export * from "./functions";
49
54
 
55
+ // Cron Jobs (auto-discovered scheduled tasks)
56
+ export * from "./cron";
50
57
 
51
58
 
52
59
  // SPA serving helper
53
60
  export * from "./serve-spa";
54
61
 
62
+ // Dev-mode port resolution (retry on EADDRINUSE)
63
+ export * from "./utils/dev-port";
64
+
55
65
  // Backend bootstrappers (pluggable driver initialization)
56
66