@rebasepro/server-core 0.7.0 → 0.8.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/build-errors.txt +52 -0
- package/dist/api/ast-schema-editor.d.ts +21 -0
- package/dist/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
- package/dist/api/errors.d.ts +53 -0
- package/dist/api/graphql/graphql-schema-generator.d.ts +44 -0
- package/dist/api/graphql/index.d.ts +1 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/logs-routes.d.ts +37 -0
- package/dist/api/openapi-generator.d.ts +16 -0
- package/dist/api/rest/api-generator.d.ts +76 -0
- package/dist/api/rest/index.d.ts +1 -0
- package/dist/api/rest/query-parser.d.ts +8 -0
- package/dist/api/schema-editor-routes.d.ts +3 -0
- package/dist/api/server.d.ts +40 -0
- package/dist/api/types.d.ts +104 -0
- package/dist/auth/adapter-middleware.d.ts +43 -0
- package/dist/auth/admin-roles-route.d.ts +18 -0
- package/dist/auth/admin-user-ops.d.ts +79 -0
- package/dist/auth/admin-users-route.d.ts +28 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +39 -0
- package/dist/auth/api-keys/api-key-permission-guard.d.ts +32 -0
- package/dist/auth/api-keys/api-key-routes.d.ts +20 -0
- package/dist/auth/api-keys/api-key-store.d.ts +35 -0
- package/dist/auth/api-keys/api-key-types.d.ts +96 -0
- package/dist/auth/api-keys/index.d.ts +17 -0
- package/dist/auth/apple-oauth.d.ts +30 -0
- package/dist/auth/auth-hooks.d.ts +242 -0
- package/dist/auth/bitbucket-oauth.d.ts +11 -0
- package/dist/auth/builtin-auth-adapter.d.ts +51 -0
- package/dist/auth/crypto-utils.d.ts +16 -0
- package/dist/auth/custom-auth-adapter.d.ts +39 -0
- package/dist/auth/discord-oauth.d.ts +14 -0
- package/dist/auth/facebook-oauth.d.ts +14 -0
- package/dist/auth/github-oauth.d.ts +15 -0
- package/dist/auth/gitlab-oauth.d.ts +13 -0
- package/dist/auth/google-oauth.d.ts +47 -0
- package/dist/auth/index.d.ts +37 -0
- package/dist/auth/interfaces.d.ts +431 -0
- package/dist/auth/jwt.d.ts +55 -0
- package/dist/auth/linkedin-oauth.d.ts +18 -0
- package/dist/auth/magic-link-routes.d.ts +30 -0
- package/dist/auth/mfa-crypto.d.ts +23 -0
- package/dist/auth/mfa-routes.d.ts +7 -0
- package/dist/auth/mfa.d.ts +49 -0
- package/dist/auth/microsoft-oauth.d.ts +16 -0
- package/dist/auth/middleware.d.ts +113 -0
- package/dist/auth/password.d.ts +22 -0
- package/dist/auth/rate-limiter.d.ts +50 -0
- package/dist/auth/reset-password-admin.d.ts +29 -0
- package/dist/auth/rls-scope.d.ts +31 -0
- package/dist/auth/routes.d.ts +35 -0
- package/dist/auth/session-routes.d.ts +27 -0
- package/dist/auth/slack-oauth.d.ts +12 -0
- package/dist/auth/spotify-oauth.d.ts +12 -0
- package/dist/auth/twitter-oauth.d.ts +18 -0
- package/dist/backend-CIxN4FVm.js +15 -0
- package/dist/backend-CIxN4FVm.js.map +1 -0
- package/dist/base64-js-C_frYBkI.js +1687 -0
- package/dist/base64-js-C_frYBkI.js.map +1 -0
- package/dist/chunk-Dze3rakg.js +42 -0
- package/dist/collections/BackendCollectionRegistry.d.ts +13 -0
- package/dist/collections/loader.d.ts +5 -0
- package/dist/cron/cron-loader.d.ts +17 -0
- package/dist/cron/cron-routes.d.ts +14 -0
- package/dist/cron/cron-scheduler.d.ts +106 -0
- package/dist/cron/cron-store.d.ts +32 -0
- package/dist/cron/index.d.ts +6 -0
- package/dist/db/interfaces.d.ts +18 -0
- package/dist/dist-DMO-zF6D.js +832 -0
- package/dist/dist-DMO-zF6D.js.map +1 -0
- package/dist/email/index.d.ts +6 -0
- package/dist/email/smtp-email-service.d.ts +25 -0
- package/dist/email/templates.d.ts +50 -0
- package/dist/email/types.d.ts +126 -0
- package/dist/env.d.ts +102 -0
- package/dist/from-VbwD7xRf.js +3849 -0
- package/dist/from-VbwD7xRf.js.map +1 -0
- package/dist/functions/define-function.d.ts +50 -0
- package/dist/functions/function-loader.d.ts +17 -0
- package/dist/functions/function-routes.d.ts +10 -0
- package/dist/functions/index.d.ts +5 -0
- package/dist/history/history-routes.d.ts +23 -0
- package/dist/history/index.d.ts +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.es.js +61322 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +103633 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/init/docs.d.ts +4 -0
- package/dist/init/health.d.ts +2 -0
- package/dist/init/middlewares.d.ts +10 -0
- package/dist/init/shutdown.d.ts +11 -0
- package/dist/init/storage.d.ts +5 -0
- package/dist/init.d.ts +314 -0
- package/dist/jws-BqRRaK11.js +616 -0
- package/dist/jws-BqRRaK11.js.map +1 -0
- package/dist/jwt-BETC8a1J.js +3560 -0
- package/dist/jwt-BETC8a1J.js.map +1 -0
- package/dist/logger-BYU66ENZ.js +94 -0
- package/dist/logger-BYU66ENZ.js.map +1 -0
- package/dist/ms-BeBSuOXN.js +125 -0
- package/dist/ms-BeBSuOXN.js.map +1 -0
- package/dist/multipart-parser-CedBDOeC.js +299 -0
- package/dist/multipart-parser-CedBDOeC.js.map +1 -0
- package/dist/serve-spa.d.ts +30 -0
- package/dist/services/driver-registry.d.ts +78 -0
- package/dist/services/routed-realtime-service.d.ts +43 -0
- package/dist/services/webhook-service.d.ts +29 -0
- package/dist/singleton.d.ts +35 -0
- package/dist/src-CB2PIpBe.js +1182 -0
- package/dist/src-CB2PIpBe.js.map +1 -0
- package/dist/src-DjzOT1kG.js +29746 -0
- package/dist/src-DjzOT1kG.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +43 -0
- package/dist/storage/LocalStorageController.d.ts +46 -0
- package/dist/storage/S3StorageController.d.ts +36 -0
- package/dist/storage/image-transform.d.ts +50 -0
- package/dist/storage/index.d.ts +31 -0
- package/dist/storage/routes.d.ts +70 -0
- package/dist/storage/storage-registry.d.ts +78 -0
- package/dist/storage/tus-handler.d.ts +53 -0
- package/dist/storage/types.d.ts +128 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/utils/dev-port.d.ts +37 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logging.d.ts +9 -0
- package/dist/utils/request-id.d.ts +4 -0
- package/dist/utils/request-logger.d.ts +19 -0
- package/dist/utils/sql.d.ts +27 -0
- package/package.json +22 -14
- package/src/api/graphql/graphql-schema-generator.ts +5 -5
- package/src/api/openapi-generator.ts +2 -2
- package/src/api/rest/api-generator.ts +44 -123
- package/src/api/rest/query-parser.ts +6 -23
- package/src/api/types.ts +2 -2
- package/src/auth/auth-hooks.ts +1 -1
- package/src/auth/builtin-auth-adapter.ts +1 -2
- package/src/auth/interfaces.ts +11 -2
- package/src/auth/middleware.ts +4 -4
- package/src/auth/routes.ts +1 -2
- package/src/functions/define-function.ts +59 -0
- package/src/functions/function-loader.ts +16 -0
- package/src/functions/index.ts +2 -0
- package/src/index.ts +70 -37
- package/src/init.ts +78 -21
- package/src/storage/GCSStorageController.ts +334 -0
- package/src/storage/index.ts +9 -3
- package/src/storage/routes.ts +191 -23
- package/src/storage/tus-handler.ts +16 -4
- package/src/storage/types.ts +25 -3
- package/test/api-generator.test.ts +1 -1
- package/test/auth-config-types.test.ts +40 -0
- package/test/define-function.test.ts +45 -0
- package/test/storage-routes.test.ts +160 -0
- package/test/backend-hooks-data.test.ts +0 -477
package/build-errors.txt
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
|
|
2
|
+
> @rebasepro/server-core@0.0.1 build /Users/francesco/rebase/packages/server-core
|
|
3
|
+
> vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json
|
|
4
|
+
|
|
5
|
+
vite v5.4.21 building for production...
|
|
6
|
+
transforming...
|
|
7
|
+
✓ 1641 modules transformed.
|
|
8
|
+
rendering chunks...
|
|
9
|
+
computing gzip size...
|
|
10
|
+
dist/index.es.js 1.68 kB │ gzip: 0.80 kB │ map: 0.09 kB
|
|
11
|
+
dist/index-CvlusawO.js 8.86 kB │ gzip: 2.11 kB │ map: 16.79 kB
|
|
12
|
+
dist/index-BGGPU0RK.js 1,946.14 kB │ gzip: 411.28 kB │ map: 4,292.57 kB
|
|
13
|
+
dist/index.umd.js 2,070.48 kB │ gzip: 419.31 kB │ map: 4,326.51 kB
|
|
14
|
+
✓ built in 2.97s
|
|
15
|
+
src/api/graphql/graphql-schema-generator.ts(65,34): error TS18046: 'source' is of type 'unknown'.
|
|
16
|
+
src/api/graphql/graphql-schema-generator.ts(72,51): error TS18046: 'source' is of type 'unknown'.
|
|
17
|
+
src/api/graphql/graphql-schema-generator.ts(136,13): error TS2322: Type 'Record<string, unknown>' is not assignable to type 'ThunkObjMap<GraphQLInputFieldConfig>'.
|
|
18
|
+
src/api/graphql/graphql-schema-generator.ts(178,17): error TS2322: Type '(_: unknown, args: any, context: { driver: DataDriver; }) => Promise<Entity<Record<string, unknown>> | undefined>' is not assignable to type 'GraphQLFieldResolver<unknown, unknown, any, unknown>'.
|
|
19
|
+
Types of parameters 'context' and 'context' are incompatible.
|
|
20
|
+
Type 'unknown' is not assignable to type '{ driver: DataDriver; }'.
|
|
21
|
+
src/api/graphql/graphql-schema-generator.ts(198,17): error TS2322: Type '(_: unknown, args: any, context: { driver: DataDriver; }) => Promise<Entity<Record<string, unknown>>[]>' is not assignable to type 'GraphQLFieldResolver<unknown, unknown, any, unknown>'.
|
|
22
|
+
Types of parameters 'context' and 'context' are incompatible.
|
|
23
|
+
Type 'unknown' is not assignable to type '{ driver: DataDriver; }'.
|
|
24
|
+
src/api/graphql/graphql-schema-generator.ts(249,17): error TS2322: Type '(_: unknown, args: any, context: { driver: DataDriver; }) => Promise<Entity<Record<string, unknown>>>' is not assignable to type 'GraphQLFieldResolver<unknown, unknown, any, unknown>'.
|
|
25
|
+
Types of parameters 'context' and 'context' are incompatible.
|
|
26
|
+
Type 'unknown' is not assignable to type '{ driver: DataDriver; }'.
|
|
27
|
+
src/api/graphql/graphql-schema-generator.ts(269,17): error TS2322: Type '(_: unknown, args: any, context: { driver: DataDriver; }) => Promise<Entity<Record<string, unknown>>>' is not assignable to type 'GraphQLFieldResolver<unknown, unknown, any, unknown>'.
|
|
28
|
+
Types of parameters 'context' and 'context' are incompatible.
|
|
29
|
+
Type 'unknown' is not assignable to type '{ driver: DataDriver; }'.
|
|
30
|
+
src/api/graphql/graphql-schema-generator.ts(288,17): error TS2322: Type '(_: unknown, args: any, context: { driver: DataDriver; }) => Promise<boolean>' is not assignable to type 'GraphQLFieldResolver<unknown, unknown, any, unknown>'.
|
|
31
|
+
Types of parameters 'context' and 'context' are incompatible.
|
|
32
|
+
Type 'unknown' is not assignable to type '{ driver: DataDriver; }'.
|
|
33
|
+
src/api/rest/api-generator.ts(90,63): error TS18046: 'entities' is of type 'unknown'.
|
|
34
|
+
src/collections/BackendCollectionRegistry.ts(18,9): error TS2322: Type '{}[]' is not assignable to type 'string[]'.
|
|
35
|
+
Type '{}' is not assignable to type 'string'.
|
|
36
|
+
src/functions/function-loader.ts(10,15): error TS2344: Type 'unknown' does not satisfy the constraint 'Env'.
|
|
37
|
+
src/functions/function-routes.ts(27,37): error TS2345: Argument of type 'Hono<unknown, BlankSchema, "/">' is not assignable to parameter of type 'Hono<Env, BlankSchema, "/", "/">'.
|
|
38
|
+
The types of 'get(...).get' are incompatible between these types.
|
|
39
|
+
Type 'HandlerInterface<unknown, "get", BlankSchema, "/", any>' is not assignable to type 'HandlerInterface<Env, "get", BlankSchema, "/", any>'.
|
|
40
|
+
Types of parameters 'handlers' and 'handlers' are incompatible.
|
|
41
|
+
Type 'H<Env, any, any, any>' is not assignable to type 'H<unknown, any, any, any>'.
|
|
42
|
+
Type 'Handler<Env, any, any, any>' is not assignable to type 'H<unknown, any, any, any>'.
|
|
43
|
+
Type 'Handler<Env, any, any, any>' is not assignable to type 'Handler<unknown, any, any, any>'.
|
|
44
|
+
Types of parameters 'c' and 'c' are incompatible.
|
|
45
|
+
Type 'Context<unknown, any, any>' is not assignable to type 'Context<Env, any, any>'.
|
|
46
|
+
Types of property 'env' are incompatible.
|
|
47
|
+
Type 'unknown' is not assignable to type 'object | undefined'.
|
|
48
|
+
src/history/history-routes.ts(48,30): error TS18046: 'historyService' is of type 'unknown'.
|
|
49
|
+
src/history/history-routes.ts(87,36): error TS18046: 'historyService' is of type 'unknown'.
|
|
50
|
+
src/serve-spa.ts(38,36): error TS2344: Type 'unknown' does not satisfy the constraint 'Env'.
|
|
51
|
+
src/storage/LocalStorageController.ts(346,33): error TS2339: Property 'code' does not exist on type '{}'.
|
|
52
|
+
ELIFECYCLE Command failed with exit code 2.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class AstSchemaEditor {
|
|
2
|
+
private project;
|
|
3
|
+
private collectionsDir;
|
|
4
|
+
constructor(collectionsDir: string);
|
|
5
|
+
/**
|
|
6
|
+
* Sanitize collectionId to prevent path traversal attacks.
|
|
7
|
+
* Only allows alphanumeric characters, underscores, and hyphens.
|
|
8
|
+
*/
|
|
9
|
+
private sanitizeCollectionId;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a file path and ensure it falls within the collectionsDir.
|
|
12
|
+
*/
|
|
13
|
+
private safePath;
|
|
14
|
+
private getCollectionFile;
|
|
15
|
+
private getCollectionObject;
|
|
16
|
+
private convertJsonToAstString;
|
|
17
|
+
saveProperty(collectionId: string, propertyKey: string, propertyConfig: Record<string, unknown>): Promise<void>;
|
|
18
|
+
deleteProperty(collectionId: string, propertyKey: string): Promise<void>;
|
|
19
|
+
saveCollection(collectionId: string, collectionData: Record<string, unknown>): Promise<void>;
|
|
20
|
+
deleteCollection(collectionId: string): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ErrorHandler } from "hono";
|
|
2
|
+
import type { HonoEnv } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Standardized API error class.
|
|
5
|
+
* Throw this from any route handler — the errorHandler middleware
|
|
6
|
+
* will format it into `{ error: { message, code, details? } }`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ApiError extends Error {
|
|
9
|
+
readonly statusCode: number;
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly details?: unknown;
|
|
12
|
+
constructor(statusCode: number, code: string, message: string, details?: unknown);
|
|
13
|
+
static badRequest(message: string, code?: string, details?: unknown): ApiError;
|
|
14
|
+
static unauthorized(message: string, code?: string): ApiError;
|
|
15
|
+
static forbidden(message: string, code?: string): ApiError;
|
|
16
|
+
static notFound(message: string, code?: string): ApiError;
|
|
17
|
+
static conflict(message: string, code?: string): ApiError;
|
|
18
|
+
static internal(message: string, code?: string): ApiError;
|
|
19
|
+
static serviceUnavailable(message: string, code?: string): ApiError;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Canonical error response shape:
|
|
23
|
+
* `{ error: { message: string, code: string, details?: unknown } }`
|
|
24
|
+
*/
|
|
25
|
+
export interface ErrorResponse {
|
|
26
|
+
error: {
|
|
27
|
+
message: string;
|
|
28
|
+
code: string;
|
|
29
|
+
details?: unknown;
|
|
30
|
+
/** Request correlation ID for tracing (echoes X-Request-ID). */
|
|
31
|
+
requestId?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* General shape of errors that flow through the API error handler.
|
|
36
|
+
* Extends Error with optional HTTP status, error code, and details.
|
|
37
|
+
*/
|
|
38
|
+
export interface RebaseApiError extends Error {
|
|
39
|
+
statusCode?: number;
|
|
40
|
+
code?: string;
|
|
41
|
+
details?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Type guard for errors that carry optional API metadata (statusCode, code, details).
|
|
45
|
+
* Returns true for any Error instance — the optional properties are then
|
|
46
|
+
* checked via normal property access.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isRebaseApiError(error: unknown): error is RebaseApiError;
|
|
49
|
+
/**
|
|
50
|
+
* Hono error-handling middleware (`app.onError`).
|
|
51
|
+
* Converts any error into the canonical `{ error: { message, code } }` shape.
|
|
52
|
+
*/
|
|
53
|
+
export declare const errorHandler: ErrorHandler<HonoEnv>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GraphQLSchema } from "graphql";
|
|
2
|
+
import { DataDriver, EntityCollection } from "@rebasepro/types";
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight GraphQL schema generator that leverages existing DataDriver
|
|
5
|
+
* No duplication - uses your existing data layer and services
|
|
6
|
+
*/
|
|
7
|
+
export declare class GraphQLSchemaGenerator {
|
|
8
|
+
private collections;
|
|
9
|
+
private driver;
|
|
10
|
+
private typeRegistry;
|
|
11
|
+
private inputTypeRegistry;
|
|
12
|
+
constructor(collections: EntityCollection[], driver: DataDriver);
|
|
13
|
+
/**
|
|
14
|
+
* Enforce API key permission scoping for a GraphQL resolver.
|
|
15
|
+
*
|
|
16
|
+
* Extracts the `apiKey` from the Hono context passed by `@hono/graphql-server`.
|
|
17
|
+
* If the request was made with an API key and the key does not have the
|
|
18
|
+
* required permission for the target collection/operation, an error is thrown.
|
|
19
|
+
* Non-API-key requests (e.g. session auth) are allowed through.
|
|
20
|
+
*/
|
|
21
|
+
private enforceApiKeyPermission;
|
|
22
|
+
/**
|
|
23
|
+
* Generate complete GraphQL schema using existing DataDriver
|
|
24
|
+
*/
|
|
25
|
+
generateSchema(): GraphQLSchema;
|
|
26
|
+
/**
|
|
27
|
+
* Create GraphQL type for an entity collection
|
|
28
|
+
*/
|
|
29
|
+
private createEntityType;
|
|
30
|
+
private convertPropertyToField;
|
|
31
|
+
private createInputType;
|
|
32
|
+
private convertPropertyToInputType;
|
|
33
|
+
/**
|
|
34
|
+
* Create Query type using existing DataDriver methods
|
|
35
|
+
*/
|
|
36
|
+
private createQueryType;
|
|
37
|
+
/**
|
|
38
|
+
* Create Mutation type using existing DataDriver methods
|
|
39
|
+
*/
|
|
40
|
+
private createMutationType;
|
|
41
|
+
private getTypeName;
|
|
42
|
+
private getSingleQueryName;
|
|
43
|
+
private getListQueryName;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./graphql-schema-generator";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API generation infrastructure for Rebase
|
|
3
|
+
* Automatically generates GraphQL and REST APIs from EntityCollection definitions
|
|
4
|
+
*/
|
|
5
|
+
export * from "./graphql";
|
|
6
|
+
export * from "./rest";
|
|
7
|
+
export * from "./types";
|
|
8
|
+
export * from "./errors";
|
|
9
|
+
export * from "./server";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { MiddlewareHandler } from "hono";
|
|
3
|
+
import type { HonoEnv } from "./types";
|
|
4
|
+
export interface LogEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
level: "debug" | "info" | "warn" | "error";
|
|
8
|
+
source: "api" | "auth" | "storage" | "realtime" | "system";
|
|
9
|
+
message: string;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
declare class LogRingBuffer {
|
|
13
|
+
private buffer;
|
|
14
|
+
private maxSize;
|
|
15
|
+
private idCounter;
|
|
16
|
+
constructor(maxSize?: number);
|
|
17
|
+
push(entry: Omit<LogEntry, "id">): void;
|
|
18
|
+
query(options: {
|
|
19
|
+
level?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
search?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
since?: string;
|
|
25
|
+
}): {
|
|
26
|
+
entries: LogEntry[];
|
|
27
|
+
total: number;
|
|
28
|
+
};
|
|
29
|
+
getLatest(count?: number): LogEntry[];
|
|
30
|
+
}
|
|
31
|
+
export declare const logBuffer: LogRingBuffer;
|
|
32
|
+
/** Add a log entry */
|
|
33
|
+
export declare function addLog(level: LogEntry["level"], source: LogEntry["source"], message: string, metadata?: Record<string, unknown>): void;
|
|
34
|
+
/** Hono middleware to log API requests */
|
|
35
|
+
export declare function logMiddleware(): MiddlewareHandler<HonoEnv>;
|
|
36
|
+
declare const app: Hono<HonoEnv, import("hono/types").BlankSchema, "/">;
|
|
37
|
+
export default app;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EntityCollection } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAPI 3.0.3 specification generator.
|
|
4
|
+
*
|
|
5
|
+
* Produces a spec that exactly mirrors the REST API consumed by the
|
|
6
|
+
* Rebase SDK client (`@rebasepro/client`).
|
|
7
|
+
*
|
|
8
|
+
* Routes are mounted at `{basePath}/data/{slug}` by `initializeRebaseBackend`.
|
|
9
|
+
*/
|
|
10
|
+
export interface OpenApiGeneratorOptions {
|
|
11
|
+
/** Base path for the API (e.g. "/api"). Defaults to "/api". */
|
|
12
|
+
basePath?: string;
|
|
13
|
+
/** Whether auth is enabled on data routes. Defaults to true. */
|
|
14
|
+
requireAuth?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function generateOpenApiSpec(collections: EntityCollection[], options?: OpenApiGeneratorOptions): Record<string, unknown>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { AuthAdapter, DataDriver, EntityCollection } from "@rebasepro/types";
|
|
3
|
+
import { HonoEnv } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight REST API generator that leverages existing Rebase DataDriver.
|
|
6
|
+
* Supports `include` query parameter for eager-loading relations via Drizzle.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RestApiGenerator {
|
|
9
|
+
private collections;
|
|
10
|
+
private router;
|
|
11
|
+
private driver;
|
|
12
|
+
private authAdapter?;
|
|
13
|
+
constructor(collections: EntityCollection[], driver: DataDriver, authAdapter?: AuthAdapter);
|
|
14
|
+
/**
|
|
15
|
+
* Generate REST routes using existing DataDriver
|
|
16
|
+
*/
|
|
17
|
+
generateRoutes(): Hono<HonoEnv>;
|
|
18
|
+
/**
|
|
19
|
+
* Check API key permissions for a collection operation.
|
|
20
|
+
* Throws 403 if the key doesn't have the required permission.
|
|
21
|
+
* No-ops if the request is not authenticated via an API key.
|
|
22
|
+
*/
|
|
23
|
+
private enforceApiKeyPermission;
|
|
24
|
+
/**
|
|
25
|
+
* Get the request-scoped driver. Throws if none is set — never falls
|
|
26
|
+
* back to the unscoped `this.driver` to avoid bypassing RLS/auth.
|
|
27
|
+
*/
|
|
28
|
+
private getScopedDriver;
|
|
29
|
+
/**
|
|
30
|
+
* Get the typed RestFetchService from a driver if it exposes one (for include support).
|
|
31
|
+
*/
|
|
32
|
+
private getFetchService;
|
|
33
|
+
/**
|
|
34
|
+
* Create REST routes for a collection using existing Rebase patterns
|
|
35
|
+
*/
|
|
36
|
+
private createCollectionRoutes;
|
|
37
|
+
/**
|
|
38
|
+
* Catch-all routes for subcollection paths.
|
|
39
|
+
*
|
|
40
|
+
* Matches URL patterns like:
|
|
41
|
+
* GET /authors/111094/posts → list child collection
|
|
42
|
+
* GET /authors/111094/posts/43 → get child entity
|
|
43
|
+
* POST /authors/111094/posts → create child entity
|
|
44
|
+
* PUT /authors/111094/posts/43 → update child entity
|
|
45
|
+
* DELETE /authors/111094/posts/43 → delete child entity
|
|
46
|
+
*
|
|
47
|
+
* The `:rest{.+}` regex param captures the full remainder of the URL
|
|
48
|
+
* path (Hono v4 `*` wildcard does not populate `c.req.param("*")`).
|
|
49
|
+
* We split it into segments and reconstruct the `collectionPath`
|
|
50
|
+
* (e.g. "authors/111094/posts") and optional `entityId` (e.g. "43").
|
|
51
|
+
*
|
|
52
|
+
* The DataDriver.saveEntity / fetchCollection / etc. already know how to
|
|
53
|
+
* resolve multi-segment relation paths, so we just forward to them.
|
|
54
|
+
*/
|
|
55
|
+
private createSubcollectionRoutes;
|
|
56
|
+
/**
|
|
57
|
+
* Format successful API response - flattened for traditional REST API
|
|
58
|
+
*/
|
|
59
|
+
private formatResponse;
|
|
60
|
+
/**
|
|
61
|
+
* Flatten Rebase entity structure to traditional REST format
|
|
62
|
+
*/
|
|
63
|
+
private flattenEntity;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch raw collection data without Entity wrapper (fallback for non-Postgres)
|
|
66
|
+
*/
|
|
67
|
+
private fetchRawCollection;
|
|
68
|
+
/**
|
|
69
|
+
* Count raw entities for a collection
|
|
70
|
+
*/
|
|
71
|
+
private countRawEntities;
|
|
72
|
+
/**
|
|
73
|
+
* Fetch single entity raw data without Entity wrapper (fallback)
|
|
74
|
+
*/
|
|
75
|
+
private fetchRawEntity;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./api-generator";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LogicalCondition, FilterCondition, WhereFilterOp } from "@rebasepro/types";
|
|
2
|
+
export declare const mapOperator: (op: string) => WhereFilterOp | null;
|
|
3
|
+
import { QueryOptions } from "../types";
|
|
4
|
+
export declare function parseLogicalString(str: string): FilterCondition | LogicalCondition;
|
|
5
|
+
/**
|
|
6
|
+
* Parse query parameters into QueryOptions
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseQueryOptions(query: Record<string, unknown>): QueryOptions;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { DataDriver } from "@rebasepro/types";
|
|
3
|
+
import { ApiConfig, HonoEnv } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Simplified API server that leverages existing Rebase infrastructure
|
|
6
|
+
* Can be used standalone or mounted on existing Hono app
|
|
7
|
+
*/
|
|
8
|
+
export declare class RebaseApiServer {
|
|
9
|
+
private app;
|
|
10
|
+
private router;
|
|
11
|
+
private config;
|
|
12
|
+
private driver;
|
|
13
|
+
private constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Factory method to create an asynchronously initialized ApiServer instance
|
|
16
|
+
*/
|
|
17
|
+
static create(config: ApiConfig & {
|
|
18
|
+
driver: DataDriver;
|
|
19
|
+
}): Promise<RebaseApiServer>;
|
|
20
|
+
/**
|
|
21
|
+
* Setup Hono middleware
|
|
22
|
+
*/
|
|
23
|
+
private setupMiddleware;
|
|
24
|
+
/**
|
|
25
|
+
* Setup API routes using existing services
|
|
26
|
+
*/
|
|
27
|
+
private setupRoutes;
|
|
28
|
+
/**
|
|
29
|
+
* Get the Hono router with all API routes
|
|
30
|
+
*/
|
|
31
|
+
getRouter(): Hono<HonoEnv>;
|
|
32
|
+
/**
|
|
33
|
+
* Get the standalone Hono app
|
|
34
|
+
*/
|
|
35
|
+
getApp(): Hono<HonoEnv>;
|
|
36
|
+
/**
|
|
37
|
+
* Start the server (standalone mode) via @hono/node-server
|
|
38
|
+
*/
|
|
39
|
+
listen(port?: number, callback?: () => void): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { EntityCollection, VectorSearchParams, LogicalCondition, FilterValues } from "@rebasepro/types";
|
|
2
|
+
import { AuthResult } from "../auth/middleware";
|
|
3
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
4
|
+
import { DataDriver } from "@rebasepro/types";
|
|
5
|
+
import type { ApiKeyMasked } from "../auth/api-keys/api-key-types";
|
|
6
|
+
/**
|
|
7
|
+
* Hono Environment Variables
|
|
8
|
+
* Passed to generic Hono<HonoEnv> to type `c.get()`
|
|
9
|
+
*/
|
|
10
|
+
export type HonoEnv = {
|
|
11
|
+
Variables: {
|
|
12
|
+
user?: AuthResult | {
|
|
13
|
+
userId?: string;
|
|
14
|
+
roles?: string[];
|
|
15
|
+
};
|
|
16
|
+
driver?: DataDriver;
|
|
17
|
+
/** Set when the request is authenticated via a Service API Key. */
|
|
18
|
+
apiKey?: ApiKeyMasked;
|
|
19
|
+
/** Unique request correlation ID (generated or propagated from X-Request-ID header). */
|
|
20
|
+
requestId?: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Configuration for API generation
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Configuration for API generation
|
|
28
|
+
*/
|
|
29
|
+
export interface ApiConfig {
|
|
30
|
+
collections?: EntityCollection[];
|
|
31
|
+
collectionsDir?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Declared data sources. When provided, collections on a `direct`/`custom`
|
|
34
|
+
* transport are treated as client-only and no server routes are generated
|
|
35
|
+
* for them.
|
|
36
|
+
*/
|
|
37
|
+
dataSources?: import("@rebasepro/types").DataSourceDefinition[];
|
|
38
|
+
basePath?: string;
|
|
39
|
+
enableGraphQL?: boolean;
|
|
40
|
+
enableREST?: boolean;
|
|
41
|
+
cors?: {
|
|
42
|
+
origin?: string | string[] | boolean;
|
|
43
|
+
credentials?: boolean;
|
|
44
|
+
};
|
|
45
|
+
/** Whether auth is required for API endpoints (default: true) */
|
|
46
|
+
requireAuth?: boolean;
|
|
47
|
+
/** Optional custom validator for authentication */
|
|
48
|
+
authValidator?: (c: import("hono").Context<import("./types").HonoEnv>) => Promise<AuthResult>;
|
|
49
|
+
pagination?: {
|
|
50
|
+
defaultLimit: number;
|
|
51
|
+
maxLimit: number;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Context passed to resolvers and handlers
|
|
56
|
+
*/
|
|
57
|
+
export interface ApiContext {
|
|
58
|
+
user?: AuthResult;
|
|
59
|
+
collections: Map<string, EntityCollection>;
|
|
60
|
+
db: NodePgDatabase;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Standard API response format
|
|
64
|
+
*/
|
|
65
|
+
export interface ApiResponse<T = unknown> {
|
|
66
|
+
data?: T;
|
|
67
|
+
error?: {
|
|
68
|
+
message: string;
|
|
69
|
+
code?: string;
|
|
70
|
+
details?: unknown;
|
|
71
|
+
};
|
|
72
|
+
meta?: {
|
|
73
|
+
total?: number;
|
|
74
|
+
page?: number;
|
|
75
|
+
limit?: number;
|
|
76
|
+
hasMore?: boolean;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Query options for API endpoints
|
|
81
|
+
*/
|
|
82
|
+
export interface QueryOptions {
|
|
83
|
+
limit?: number;
|
|
84
|
+
offset?: number;
|
|
85
|
+
where?: FilterValues<string>;
|
|
86
|
+
logical?: LogicalCondition;
|
|
87
|
+
orderBy?: Array<{
|
|
88
|
+
field: string;
|
|
89
|
+
direction: "asc" | "desc";
|
|
90
|
+
}>;
|
|
91
|
+
include?: string[];
|
|
92
|
+
/** Columns to return in the response (field-level selection) */
|
|
93
|
+
fields?: string[];
|
|
94
|
+
/** Vector similarity search configuration */
|
|
95
|
+
vectorSearch?: VectorSearchParams;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Relation resolution configuration
|
|
99
|
+
*/
|
|
100
|
+
export interface RelationConfig {
|
|
101
|
+
relationName: string;
|
|
102
|
+
depth?: number;
|
|
103
|
+
include?: string[];
|
|
104
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter Auth Middleware
|
|
3
|
+
*
|
|
4
|
+
* Creates a Hono middleware that delegates authentication to an `AuthAdapter`
|
|
5
|
+
* instead of hardcoded JWT verification. This is used when the user passes
|
|
6
|
+
* an `AuthAdapter` to `initializeRebaseBackend()`.
|
|
7
|
+
*
|
|
8
|
+
* The middleware:
|
|
9
|
+
* 1. Checks for API key tokens (`rk_` prefix) first — these are Rebase-level
|
|
10
|
+
* 2. Falls back to `adapter.verifyRequest(request)` to resolve the user
|
|
11
|
+
* 3. Scopes the DataDriver via `withAuth()` for RLS
|
|
12
|
+
* 4. Enforces auth (401) when `requireAuth` is true and no user is found
|
|
13
|
+
*
|
|
14
|
+
* The behavior is identical to `createAuthMiddleware()` — only the
|
|
15
|
+
* token verification strategy is pluggable.
|
|
16
|
+
*/
|
|
17
|
+
import type { MiddlewareHandler, Context } from "hono";
|
|
18
|
+
import type { DataDriver, AuthAdapter } from "@rebasepro/types";
|
|
19
|
+
import type { HonoEnv } from "../api/types";
|
|
20
|
+
import type { ApiKeyStore } from "./api-keys/api-key-store";
|
|
21
|
+
export interface AdapterAuthMiddlewareOptions {
|
|
22
|
+
/** The auth adapter to delegate verification to. */
|
|
23
|
+
adapter: AuthAdapter;
|
|
24
|
+
/** The DataDriver to scope via withAuth() for RLS. */
|
|
25
|
+
driver: DataDriver;
|
|
26
|
+
/**
|
|
27
|
+
* Optional per-request driver resolver for multi-data-source backends.
|
|
28
|
+
* Returns the unscoped delegate to use for this request (e.g. Postgres vs
|
|
29
|
+
* Mongo). When omitted, `driver` is used for every request.
|
|
30
|
+
*/
|
|
31
|
+
resolveDriver?: (c: Context<HonoEnv>) => DataDriver;
|
|
32
|
+
/**
|
|
33
|
+
* If true, return 401 when no valid user is resolved.
|
|
34
|
+
* Defaults to `true` (secure by default).
|
|
35
|
+
*/
|
|
36
|
+
requireAuth?: boolean;
|
|
37
|
+
/** Optional API key store — when provided, `rk_` bearer tokens are accepted. */
|
|
38
|
+
apiKeyStore?: ApiKeyStore;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a Hono middleware that uses an `AuthAdapter` for request verification.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createAdapterAuthMiddleware(options: AdapterAuthMiddlewareOptions): MiddlewareHandler<HonoEnv>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin endpoint for listing all roles.
|
|
3
|
+
*
|
|
4
|
+
* Mounts: GET /roles
|
|
5
|
+
*/
|
|
6
|
+
import { Hono } from "hono";
|
|
7
|
+
import type { AuthRepository } from "./interfaces";
|
|
8
|
+
import type { HonoEnv } from "../api/types";
|
|
9
|
+
export interface AdminRolesRouteConfig {
|
|
10
|
+
authRepo: AuthRepository;
|
|
11
|
+
serviceKey?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a standalone admin route for listing roles.
|
|
15
|
+
*
|
|
16
|
+
* Mounts: GET /roles
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAdminRolesRoute(config: AdminRolesRouteConfig): Hono<HonoEnv>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin User Operations
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities and orchestration for admin-initiated user management
|
|
5
|
+
* (user creation via REST API, password reset via admin panel).
|
|
6
|
+
*
|
|
7
|
+
* Hook resolution order:
|
|
8
|
+
* 1. Collection-level hook (`auth.onCreateUser` on the collection) — closest to the data
|
|
9
|
+
* 2. Backend-level hook (`AuthHooks.onAdminCreateUser`) — global override
|
|
10
|
+
* 3. Built-in default — framework fallback
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthRepository } from "./interfaces";
|
|
13
|
+
import type { EmailService, EmailConfig } from "../email";
|
|
14
|
+
import type { ResolvedAuthHooks } from "./auth-hooks";
|
|
15
|
+
import type { AuthCollectionConfig } from "@rebasepro/types";
|
|
16
|
+
/**
|
|
17
|
+
* Generate a cryptographically secure random password that meets strength requirements.
|
|
18
|
+
*
|
|
19
|
+
* 16 characters, guaranteed at least one uppercase, one lowercase, one digit.
|
|
20
|
+
* Ambiguous characters (0, O, 1, l, I) are excluded.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateSecurePassword(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Generate a cryptographically secure random token (80 hex characters).
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateSecureToken(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Hash a token for database storage using SHA-256.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hashToken(token: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Context needed by admin user creation / password reset operations.
|
|
33
|
+
*/
|
|
34
|
+
export interface AdminUserContext {
|
|
35
|
+
authRepo: AuthRepository;
|
|
36
|
+
emailService?: EmailService;
|
|
37
|
+
emailConfig?: EmailConfig;
|
|
38
|
+
resolvedHooks: ResolvedAuthHooks;
|
|
39
|
+
/** The parsed auth config from the collection (if `auth` is an object, not just `true`). */
|
|
40
|
+
collectionAuthConfig?: AuthCollectionConfig;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Result of preparing user values for admin-initiated creation.
|
|
44
|
+
*/
|
|
45
|
+
export interface AdminUserPrepareResult {
|
|
46
|
+
/** Values ready for `driver.saveEntity()`. */
|
|
47
|
+
values: Record<string, unknown>;
|
|
48
|
+
/** The cleartext password (for returning to admin or sending via email). */
|
|
49
|
+
clearPassword?: string;
|
|
50
|
+
/** Whether the hook already handled the invitation email. */
|
|
51
|
+
hookHandledEmail: boolean;
|
|
52
|
+
/** Whether an invitation was sent (only relevant when hookHandledEmail is true). */
|
|
53
|
+
invitationSent: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Prepare user values for an admin-initiated user creation.
|
|
57
|
+
*
|
|
58
|
+
* Resolution order:
|
|
59
|
+
* 1. Collection-level `auth.onCreateUser` — closest to the data
|
|
60
|
+
* 2. Backend-level `AuthHooks.onAdminCreateUser` — global override
|
|
61
|
+
* 3. Built-in default — generate password → hash → normalize email
|
|
62
|
+
*
|
|
63
|
+
* The caller is responsible for persisting (via `driver.saveEntity()`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function prepareAdminUserValues(body: Record<string, unknown>, ctx: AdminUserContext): Promise<AdminUserPrepareResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Handle post-creation work for admin-created users.
|
|
68
|
+
*
|
|
69
|
+
* Sends an invitation email (password-reset link) if email is configured
|
|
70
|
+
* and no explicit password was provided. Falls back to returning the
|
|
71
|
+
* temporary password if email fails or is not configured.
|
|
72
|
+
*/
|
|
73
|
+
export declare function finalizeAdminUserCreation(entity: {
|
|
74
|
+
id: string;
|
|
75
|
+
values: Record<string, unknown>;
|
|
76
|
+
}, clearPassword: string | undefined, ctx: AdminUserContext): Promise<{
|
|
77
|
+
temporaryPassword?: string;
|
|
78
|
+
invitationSent: boolean;
|
|
79
|
+
}>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone admin endpoint for user management.
|
|
3
|
+
*
|
|
4
|
+
* Mounts:
|
|
5
|
+
* GET /users
|
|
6
|
+
* GET /users/:userId
|
|
7
|
+
* POST /users
|
|
8
|
+
* PUT /users/:userId
|
|
9
|
+
* DELETE /users/:userId
|
|
10
|
+
* POST /bootstrap
|
|
11
|
+
*/
|
|
12
|
+
import { Hono } from "hono";
|
|
13
|
+
import type { AuthRepository } from "./interfaces";
|
|
14
|
+
import type { AuthHooks } from "./auth-hooks";
|
|
15
|
+
import type { EmailService, EmailConfig } from "../email";
|
|
16
|
+
import type { HonoEnv } from "../api/types";
|
|
17
|
+
import type { AuthCollectionConfig } from "@rebasepro/types";
|
|
18
|
+
export interface AdminUsersRouteConfig {
|
|
19
|
+
authRepo: AuthRepository;
|
|
20
|
+
emailService?: EmailService;
|
|
21
|
+
emailConfig?: EmailConfig;
|
|
22
|
+
serviceKey?: string;
|
|
23
|
+
authHooks?: AuthHooks;
|
|
24
|
+
collectionAuthConfig?: AuthCollectionConfig;
|
|
25
|
+
isBootstrapCompleted?: () => Promise<boolean>;
|
|
26
|
+
setBootstrapCompleted?: () => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare function createAdminUsersRoute(config: AdminUsersRouteConfig): Hono<HonoEnv>;
|