@nilejs/nile 0.0.6 → 0.0.7

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/dist/index.d.cts CHANGED
@@ -1,8 +1,55 @@
1
- import { Context, Hono } from 'hono';
2
1
  import { Result, ErrType, ResultMethods } from 'slang-ts';
2
+ import { Context, Hono } from 'hono';
3
3
  import { Store } from 'hono-rate-limiter';
4
4
  import z, { ZodTypeAny } from 'zod';
5
5
 
6
+ /** Where to extract the JWT token from incoming requests */
7
+ type TokenSource = "header" | "cookie";
8
+ /**
9
+ * Server-level auth configuration.
10
+ * Kept intentionally lean — only JWT verification via hono/jwt.
11
+ * For custom auth logic (RBAC, API keys, sessions), use onBeforeActionHandler.
12
+ */
13
+ interface AuthConfig {
14
+ /** JWT secret used for token verification */
15
+ secret: string;
16
+ /** Where to look for the token (default: "header") */
17
+ method?: TokenSource;
18
+ /** Cookie name when method is "cookie" (default: "auth_token") */
19
+ cookieName?: string;
20
+ /** Header name when method is "header" (default: "authorization") */
21
+ headerName?: string;
22
+ }
23
+ /** Successful auth result populated on NileContext after verification */
24
+ interface AuthResult {
25
+ userId: string;
26
+ organizationId: string;
27
+ /** Raw decoded JWT claims for custom logic in hooks */
28
+ claims: Record<string, unknown>;
29
+ }
30
+ /**
31
+ * Auth context passed to the JWT handler — carries the raw
32
+ * request data needed for token extraction.
33
+ */
34
+ interface AuthContext {
35
+ headers?: Headers;
36
+ cookies?: Record<string, string>;
37
+ }
38
+ /**
39
+ * Auth handler function signature.
40
+ * Returns Ok(AuthResult) on success, Err(message) on failure.
41
+ */
42
+ type AuthHandler = (context: AuthContext, config: AuthConfig) => Promise<Result<AuthResult, string>>;
43
+
44
+ /**
45
+ * Lean JWT authentication handler.
46
+ * Extracts token from header or cookie, verifies via hono/jwt,
47
+ * and returns AuthResult with userId, organizationId, and raw claims.
48
+ *
49
+ * For anything beyond JWT (RBAC, API keys, sessions), use onBeforeActionHandler.
50
+ */
51
+ declare function verifyJWT(context: AuthContext, config: AuthConfig): Promise<Result<AuthResult, string>>;
52
+
6
53
  /**
7
54
  * CORS options compatible with Hono's cors middleware
8
55
  */
@@ -173,6 +220,16 @@ interface NileContext<TDB = unknown> {
173
220
  getSession: (name: keyof Sessions) => Record<string, unknown> | undefined;
174
221
  /** Store session data for a specific interface */
175
222
  setSession: (name: keyof Sessions, data: Record<string, unknown>) => void;
223
+ /** Auth result populated after successful JWT verification */
224
+ authResult?: AuthResult;
225
+ /** Get the raw auth result after JWT verification */
226
+ getAuth: () => AuthResult | undefined;
227
+ /** Get authenticated user identity (userId + organizationId) */
228
+ getUser: () => {
229
+ userId: string;
230
+ organizationId: string;
231
+ [key: string]: unknown;
232
+ } | undefined;
176
233
  hookContext: HookContext;
177
234
  updateHookState: (key: string, value: unknown) => void;
178
235
  addHookLog: (phase: "before" | "after", logEntry: {
@@ -205,6 +262,8 @@ interface ServerConfig {
205
262
  /** Print registered services table to console on boot (default: true) */
206
263
  logServices?: boolean;
207
264
  resources?: Resources<unknown>;
265
+ /** JWT auth configuration — enables built-in token verification for protected actions */
266
+ auth?: AuthConfig;
208
267
  rest?: RestConfig;
209
268
  websocket?: Record<string, unknown>;
210
269
  rpc?: Record<string, unknown>;
@@ -312,6 +371,8 @@ interface EngineOptions {
312
371
  info: (msg: string, data?: unknown) => void;
313
372
  } | NileLogger;
314
373
  services: Services;
374
+ /** JWT auth configuration — when provided, protected actions require valid tokens */
375
+ auth?: AuthConfig;
315
376
  onBeforeActionHandler?: BeforeActionHandler<unknown, unknown>;
316
377
  onAfterActionHandler?: AfterActionHandler<unknown, unknown>;
317
378
  }
@@ -320,7 +381,7 @@ interface Engine {
320
381
  getServices: () => Result<ServiceSummary[], string>;
321
382
  getServiceActions: (serviceName: string) => Result<ActionSummary[], string>;
322
383
  getAction: (serviceName: string, actionName: string) => Result<Action, string>;
323
- executeAction: (serviceName: string, actionName: string, payload: unknown, nileContext: NileContext<unknown>) => Promise<Result<unknown, string>>;
384
+ executeAction: (serviceName: string, actionName: string, payload: unknown, nileContext: NileContext<unknown>, authContext?: AuthContext) => Promise<Result<unknown, string>>;
324
385
  }
325
386
 
326
387
  /**
@@ -422,6 +483,95 @@ declare function getContext<TDB = unknown>(): NileContext<TDB>;
422
483
  */
423
484
  declare function createNileServer(config: ServerConfig): NileServer;
424
485
 
486
+ /** Structured payload separating string fields from File objects */
487
+ interface StructuredPayload {
488
+ fields: Record<string, string | string[]>;
489
+ files: Record<string, File | File[]>;
490
+ }
491
+ /**
492
+ * Internal validation result for the upload validation chain.
493
+ * Carries structured error data for rich client-facing error responses,
494
+ * unlike slang-ts Result which only carries a string error.
495
+ */
496
+ interface UploadValidationResult {
497
+ status: boolean;
498
+ message?: string;
499
+ data?: Record<string, unknown>;
500
+ /** HTTP status code override (e.g., 415 for content-type mismatch) */
501
+ statusCode?: number;
502
+ }
503
+ /**
504
+ * Result from form-data parsing functions.
505
+ * On success: carries a StructuredPayload with separated fields/files.
506
+ * On failure: carries error metadata in errorData (not data) to avoid type conflicts.
507
+ */
508
+ interface FormDataResult {
509
+ status: boolean;
510
+ message?: string;
511
+ /** Parsed structured payload — only present on success */
512
+ data?: StructuredPayload;
513
+ /** Error details — only present on failure */
514
+ errorData?: Record<string, unknown>;
515
+ /** HTTP status code override */
516
+ statusCode?: number;
517
+ }
518
+ /** Upload limits configuration — mirrors RestConfig.uploads.limits */
519
+ interface UploadLimits {
520
+ maxFiles?: number;
521
+ maxFileSize?: number;
522
+ minFileSize?: number;
523
+ maxTotalSize?: number;
524
+ maxFilenameLength?: number;
525
+ }
526
+ /** Allowlist for MIME types and file extensions */
527
+ interface UploadAllowlist {
528
+ mimeTypes?: string[];
529
+ extensions?: string[];
530
+ }
531
+ /** Full upload configuration — mirrors RestConfig.uploads */
532
+ interface UploadsConfig {
533
+ enforceContentType?: boolean;
534
+ limits?: UploadLimits;
535
+ allow?: UploadAllowlist;
536
+ diagnostics?: boolean;
537
+ }
538
+
539
+ /**
540
+ * Multipart form-data parsing and content-type enforcement.
541
+ * Two parsing modes:
542
+ * - "flat" (default): conflict detection — rejects same key used for both files and fields
543
+ * - "structured": simple separation of fields and files with array aggregation
544
+ *
545
+ * Uses Hono's parseBody({ all: true }) for robust multipart parsing across HTTP clients.
546
+ */
547
+
548
+ /**
549
+ * High-level upload handler: parses multipart form data, validates files,
550
+ * and returns the structured payload ready for the action handler.
551
+ *
552
+ * This is the single entry point called from the REST layer for form-data requests.
553
+ */
554
+ declare function handleFormDataRequest(c: {
555
+ req: {
556
+ parseBody: (opts: {
557
+ all: true;
558
+ }) => Promise<Record<string, unknown>>;
559
+ };
560
+ }, config: UploadsConfig, _uploadMode?: "flat" | "structured"): Promise<FormDataResult>;
561
+
562
+ /**
563
+ * File validation chain for multipart uploads.
564
+ * 7-step sequential validation: filename length -> zero-byte -> min size ->
565
+ * file count -> max file size -> total size -> MIME + extension allowlist.
566
+ * Fails fast on first validation error.
567
+ */
568
+
569
+ /**
570
+ * Run the full 7-step validation chain on an array of files.
571
+ * Fails fast on the first validation error. Returns { status: true } if all pass.
572
+ */
573
+ declare function validateFiles(files: File[], config: UploadsConfig): UploadValidationResult;
574
+
425
575
  /**
426
576
  * Database instance or transaction pointer type.
427
577
  * Accepts a root DB instance (with .transaction method) or a transaction pointer.
@@ -643,4 +793,4 @@ interface HandleErrorParams {
643
793
  */
644
794
  declare function handleError(params: HandleErrorParams): ErrType<string> & ResultMethods<never>;
645
795
 
646
- export { type Action, type ActionHandler, type ActionResultConfig, type ActionSummary, type Actions, type AfterActionHandler, type BaseContext, type BeforeActionHandler, type CorsConfig, type CorsOptions, type CorsResolver, type CorsRouteRule, type CursorPage, type CursorPaginationOptions, type DBParams, type DBX, type Engine, type EngineOptions, type ExternalRequest, type ExternalResponse, type HookContext, type HookDefinition, type HookLogEntry, type Log, type LogFilter, type LoggerConfig, type ModelOperations, type ModelOptions, type NileContext, type NileLogger, type NileServer, type OffsetPage, type OffsetPaginationOptions, type RPCContext, type RateLimitConfig, type Resources, type RestConfig, type ServerConfig, type ServerRuntime, type Service, type ServiceSummary, type Services, type Sessions, type WebSocketContext, createAction, createActions, createLog, createLogger, createModel, createNileServer, createService, createServices, createTransactionVariant, getContext, getLogs, getZodSchema, handleError };
796
+ export { type Action, type ActionHandler, type ActionResultConfig, type ActionSummary, type Actions, type AfterActionHandler, type AuthConfig, type AuthContext, type AuthHandler, type AuthResult, type BaseContext, type BeforeActionHandler, type CorsConfig, type CorsOptions, type CorsResolver, type CorsRouteRule, type CursorPage, type CursorPaginationOptions, type DBParams, type DBX, type Engine, type EngineOptions, type ExternalRequest, type ExternalResponse, type FormDataResult, type HookContext, type HookDefinition, type HookLogEntry, type Log, type LogFilter, type LoggerConfig, type ModelOperations, type ModelOptions, type NileContext, type NileLogger, type NileServer, type OffsetPage, type OffsetPaginationOptions, type RPCContext, type RateLimitConfig, type Resources, type RestConfig, type ServerConfig, type ServerRuntime, type Service, type ServiceSummary, type Services, type Sessions, type StructuredPayload, type TokenSource, type UploadAllowlist, type UploadLimits, type UploadValidationResult, type UploadsConfig, type WebSocketContext, createAction, createActions, createLog, createLogger, createModel, createNileServer, createService, createServices, createTransactionVariant, getContext, getLogs, getZodSchema, handleError, handleFormDataRequest, validateFiles, verifyJWT };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,55 @@
1
- import { Context, Hono } from 'hono';
2
1
  import { Result, ErrType, ResultMethods } from 'slang-ts';
2
+ import { Context, Hono } from 'hono';
3
3
  import { Store } from 'hono-rate-limiter';
4
4
  import z, { ZodTypeAny } from 'zod';
5
5
 
6
+ /** Where to extract the JWT token from incoming requests */
7
+ type TokenSource = "header" | "cookie";
8
+ /**
9
+ * Server-level auth configuration.
10
+ * Kept intentionally lean — only JWT verification via hono/jwt.
11
+ * For custom auth logic (RBAC, API keys, sessions), use onBeforeActionHandler.
12
+ */
13
+ interface AuthConfig {
14
+ /** JWT secret used for token verification */
15
+ secret: string;
16
+ /** Where to look for the token (default: "header") */
17
+ method?: TokenSource;
18
+ /** Cookie name when method is "cookie" (default: "auth_token") */
19
+ cookieName?: string;
20
+ /** Header name when method is "header" (default: "authorization") */
21
+ headerName?: string;
22
+ }
23
+ /** Successful auth result populated on NileContext after verification */
24
+ interface AuthResult {
25
+ userId: string;
26
+ organizationId: string;
27
+ /** Raw decoded JWT claims for custom logic in hooks */
28
+ claims: Record<string, unknown>;
29
+ }
30
+ /**
31
+ * Auth context passed to the JWT handler — carries the raw
32
+ * request data needed for token extraction.
33
+ */
34
+ interface AuthContext {
35
+ headers?: Headers;
36
+ cookies?: Record<string, string>;
37
+ }
38
+ /**
39
+ * Auth handler function signature.
40
+ * Returns Ok(AuthResult) on success, Err(message) on failure.
41
+ */
42
+ type AuthHandler = (context: AuthContext, config: AuthConfig) => Promise<Result<AuthResult, string>>;
43
+
44
+ /**
45
+ * Lean JWT authentication handler.
46
+ * Extracts token from header or cookie, verifies via hono/jwt,
47
+ * and returns AuthResult with userId, organizationId, and raw claims.
48
+ *
49
+ * For anything beyond JWT (RBAC, API keys, sessions), use onBeforeActionHandler.
50
+ */
51
+ declare function verifyJWT(context: AuthContext, config: AuthConfig): Promise<Result<AuthResult, string>>;
52
+
6
53
  /**
7
54
  * CORS options compatible with Hono's cors middleware
8
55
  */
@@ -173,6 +220,16 @@ interface NileContext<TDB = unknown> {
173
220
  getSession: (name: keyof Sessions) => Record<string, unknown> | undefined;
174
221
  /** Store session data for a specific interface */
175
222
  setSession: (name: keyof Sessions, data: Record<string, unknown>) => void;
223
+ /** Auth result populated after successful JWT verification */
224
+ authResult?: AuthResult;
225
+ /** Get the raw auth result after JWT verification */
226
+ getAuth: () => AuthResult | undefined;
227
+ /** Get authenticated user identity (userId + organizationId) */
228
+ getUser: () => {
229
+ userId: string;
230
+ organizationId: string;
231
+ [key: string]: unknown;
232
+ } | undefined;
176
233
  hookContext: HookContext;
177
234
  updateHookState: (key: string, value: unknown) => void;
178
235
  addHookLog: (phase: "before" | "after", logEntry: {
@@ -205,6 +262,8 @@ interface ServerConfig {
205
262
  /** Print registered services table to console on boot (default: true) */
206
263
  logServices?: boolean;
207
264
  resources?: Resources<unknown>;
265
+ /** JWT auth configuration — enables built-in token verification for protected actions */
266
+ auth?: AuthConfig;
208
267
  rest?: RestConfig;
209
268
  websocket?: Record<string, unknown>;
210
269
  rpc?: Record<string, unknown>;
@@ -312,6 +371,8 @@ interface EngineOptions {
312
371
  info: (msg: string, data?: unknown) => void;
313
372
  } | NileLogger;
314
373
  services: Services;
374
+ /** JWT auth configuration — when provided, protected actions require valid tokens */
375
+ auth?: AuthConfig;
315
376
  onBeforeActionHandler?: BeforeActionHandler<unknown, unknown>;
316
377
  onAfterActionHandler?: AfterActionHandler<unknown, unknown>;
317
378
  }
@@ -320,7 +381,7 @@ interface Engine {
320
381
  getServices: () => Result<ServiceSummary[], string>;
321
382
  getServiceActions: (serviceName: string) => Result<ActionSummary[], string>;
322
383
  getAction: (serviceName: string, actionName: string) => Result<Action, string>;
323
- executeAction: (serviceName: string, actionName: string, payload: unknown, nileContext: NileContext<unknown>) => Promise<Result<unknown, string>>;
384
+ executeAction: (serviceName: string, actionName: string, payload: unknown, nileContext: NileContext<unknown>, authContext?: AuthContext) => Promise<Result<unknown, string>>;
324
385
  }
325
386
 
326
387
  /**
@@ -422,6 +483,95 @@ declare function getContext<TDB = unknown>(): NileContext<TDB>;
422
483
  */
423
484
  declare function createNileServer(config: ServerConfig): NileServer;
424
485
 
486
+ /** Structured payload separating string fields from File objects */
487
+ interface StructuredPayload {
488
+ fields: Record<string, string | string[]>;
489
+ files: Record<string, File | File[]>;
490
+ }
491
+ /**
492
+ * Internal validation result for the upload validation chain.
493
+ * Carries structured error data for rich client-facing error responses,
494
+ * unlike slang-ts Result which only carries a string error.
495
+ */
496
+ interface UploadValidationResult {
497
+ status: boolean;
498
+ message?: string;
499
+ data?: Record<string, unknown>;
500
+ /** HTTP status code override (e.g., 415 for content-type mismatch) */
501
+ statusCode?: number;
502
+ }
503
+ /**
504
+ * Result from form-data parsing functions.
505
+ * On success: carries a StructuredPayload with separated fields/files.
506
+ * On failure: carries error metadata in errorData (not data) to avoid type conflicts.
507
+ */
508
+ interface FormDataResult {
509
+ status: boolean;
510
+ message?: string;
511
+ /** Parsed structured payload — only present on success */
512
+ data?: StructuredPayload;
513
+ /** Error details — only present on failure */
514
+ errorData?: Record<string, unknown>;
515
+ /** HTTP status code override */
516
+ statusCode?: number;
517
+ }
518
+ /** Upload limits configuration — mirrors RestConfig.uploads.limits */
519
+ interface UploadLimits {
520
+ maxFiles?: number;
521
+ maxFileSize?: number;
522
+ minFileSize?: number;
523
+ maxTotalSize?: number;
524
+ maxFilenameLength?: number;
525
+ }
526
+ /** Allowlist for MIME types and file extensions */
527
+ interface UploadAllowlist {
528
+ mimeTypes?: string[];
529
+ extensions?: string[];
530
+ }
531
+ /** Full upload configuration — mirrors RestConfig.uploads */
532
+ interface UploadsConfig {
533
+ enforceContentType?: boolean;
534
+ limits?: UploadLimits;
535
+ allow?: UploadAllowlist;
536
+ diagnostics?: boolean;
537
+ }
538
+
539
+ /**
540
+ * Multipart form-data parsing and content-type enforcement.
541
+ * Two parsing modes:
542
+ * - "flat" (default): conflict detection — rejects same key used for both files and fields
543
+ * - "structured": simple separation of fields and files with array aggregation
544
+ *
545
+ * Uses Hono's parseBody({ all: true }) for robust multipart parsing across HTTP clients.
546
+ */
547
+
548
+ /**
549
+ * High-level upload handler: parses multipart form data, validates files,
550
+ * and returns the structured payload ready for the action handler.
551
+ *
552
+ * This is the single entry point called from the REST layer for form-data requests.
553
+ */
554
+ declare function handleFormDataRequest(c: {
555
+ req: {
556
+ parseBody: (opts: {
557
+ all: true;
558
+ }) => Promise<Record<string, unknown>>;
559
+ };
560
+ }, config: UploadsConfig, _uploadMode?: "flat" | "structured"): Promise<FormDataResult>;
561
+
562
+ /**
563
+ * File validation chain for multipart uploads.
564
+ * 7-step sequential validation: filename length -> zero-byte -> min size ->
565
+ * file count -> max file size -> total size -> MIME + extension allowlist.
566
+ * Fails fast on first validation error.
567
+ */
568
+
569
+ /**
570
+ * Run the full 7-step validation chain on an array of files.
571
+ * Fails fast on the first validation error. Returns { status: true } if all pass.
572
+ */
573
+ declare function validateFiles(files: File[], config: UploadsConfig): UploadValidationResult;
574
+
425
575
  /**
426
576
  * Database instance or transaction pointer type.
427
577
  * Accepts a root DB instance (with .transaction method) or a transaction pointer.
@@ -643,4 +793,4 @@ interface HandleErrorParams {
643
793
  */
644
794
  declare function handleError(params: HandleErrorParams): ErrType<string> & ResultMethods<never>;
645
795
 
646
- export { type Action, type ActionHandler, type ActionResultConfig, type ActionSummary, type Actions, type AfterActionHandler, type BaseContext, type BeforeActionHandler, type CorsConfig, type CorsOptions, type CorsResolver, type CorsRouteRule, type CursorPage, type CursorPaginationOptions, type DBParams, type DBX, type Engine, type EngineOptions, type ExternalRequest, type ExternalResponse, type HookContext, type HookDefinition, type HookLogEntry, type Log, type LogFilter, type LoggerConfig, type ModelOperations, type ModelOptions, type NileContext, type NileLogger, type NileServer, type OffsetPage, type OffsetPaginationOptions, type RPCContext, type RateLimitConfig, type Resources, type RestConfig, type ServerConfig, type ServerRuntime, type Service, type ServiceSummary, type Services, type Sessions, type WebSocketContext, createAction, createActions, createLog, createLogger, createModel, createNileServer, createService, createServices, createTransactionVariant, getContext, getLogs, getZodSchema, handleError };
796
+ export { type Action, type ActionHandler, type ActionResultConfig, type ActionSummary, type Actions, type AfterActionHandler, type AuthConfig, type AuthContext, type AuthHandler, type AuthResult, type BaseContext, type BeforeActionHandler, type CorsConfig, type CorsOptions, type CorsResolver, type CorsRouteRule, type CursorPage, type CursorPaginationOptions, type DBParams, type DBX, type Engine, type EngineOptions, type ExternalRequest, type ExternalResponse, type FormDataResult, type HookContext, type HookDefinition, type HookLogEntry, type Log, type LogFilter, type LoggerConfig, type ModelOperations, type ModelOptions, type NileContext, type NileLogger, type NileServer, type OffsetPage, type OffsetPaginationOptions, type RPCContext, type RateLimitConfig, type Resources, type RestConfig, type ServerConfig, type ServerRuntime, type Service, type ServiceSummary, type Services, type Sessions, type StructuredPayload, type TokenSource, type UploadAllowlist, type UploadLimits, type UploadValidationResult, type UploadsConfig, type WebSocketContext, createAction, createActions, createLog, createLogger, createModel, createNileServer, createService, createServices, createTransactionVariant, getContext, getLogs, getZodSchema, handleError, handleFormDataRequest, validateFiles, verifyJWT };