@gzl10/nexus-backend 0.11.0 → 0.12.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/dist/cli.js CHANGED
@@ -1,12 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/cli.ts
3
+ // src/env-loader.ts
4
4
  import { existsSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ import { config } from "dotenv";
7
+ var dir = process.cwd();
8
+ console.log("[env-loader] Starting search from cwd:", dir);
9
+ for (let i = 0; i < 5; i++) {
10
+ const envPath = join(dir, ".env");
11
+ const exists = existsSync(envPath);
12
+ console.log(`[env-loader] Checking: ${envPath}`, exists ? "\u2713 FOUND" : "\u2717 not found");
13
+ if (exists) {
14
+ config({ path: envPath });
15
+ console.log("[env-loader] Loaded:", envPath);
16
+ break;
17
+ }
18
+ const parent = dirname(dir);
19
+ if (parent === dir) break;
20
+ dir = parent;
21
+ }
22
+
23
+ // src/cli.ts
5
24
  import { Command } from "commander";
6
25
  import { consola } from "consola";
7
- if (existsSync(".env")) {
8
- process.loadEnvFile(".env");
9
- }
10
26
  var program = new Command();
11
27
  program.name("nexus").description("Nexus Backend CLI").version("0.1.0");
12
28
  program.command("ui").description("Open UI in browser").option("-p, --port <port>", "Nexus backend port").action(async (options) => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync } from 'fs'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\n\n// Cargar .env si existe (Node 20+)\nif (existsSync('.env')) {\n process.loadEnvFile('.env')\n}\n\nconst program = new Command()\n\nprogram\n .name('nexus')\n .description('Nexus Backend CLI')\n .version('0.1.0')\n\nprogram\n .command('ui')\n .description('Open UI in browser')\n .option('-p, --port <port>', 'Nexus backend port')\n .action(async (options) => {\n const port = parseInt(options.port || process.env['PORT'] || '3000', 10)\n const baseUrl = (process.env['BACKEND_URL'] || `http://localhost:${port}`).replace(/\\/$/, '')\n const url = `${baseUrl}/ui`\n\n // Verificar que Nexus está corriendo\n try {\n const res = await fetch(`${baseUrl}/health`)\n if (!res.ok) throw new Error()\n } catch {\n consola.error(`Nexus no está corriendo en ${baseUrl}`)\n consola.info('Inicia el servidor primero con: pnpm dev')\n process.exit(1)\n }\n\n // Abrir navegador\n const { exec } = await import('child_process')\n const cmd = process.platform === 'darwin' ? 'open'\n : process.platform === 'win32' ? 'start'\n : 'xdg-open'\n\n exec(`${cmd} ${url}`)\n consola.success(`Abriendo: ${url}`)\n })\n\nprogram.parse()\n"],"mappings":";;;AACA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,eAAe;AAGxB,IAAI,WAAW,MAAM,GAAG;AACtB,UAAQ,YAAY,MAAM;AAC5B;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,mBAAmB,EAC/B,QAAQ,OAAO;AAElB,QACG,QAAQ,IAAI,EACZ,YAAY,oBAAoB,EAChC,OAAO,qBAAqB,oBAAoB,EAChD,OAAO,OAAO,YAAY;AACzB,QAAM,OAAO,SAAS,QAAQ,QAAQ,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE;AACvE,QAAM,WAAW,QAAQ,IAAI,aAAa,KAAK,oBAAoB,IAAI,IAAI,QAAQ,OAAO,EAAE;AAC5F,QAAM,MAAM,GAAG,OAAO;AAGtB,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,OAAO,SAAS;AAC3C,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM;AAAA,EAC/B,QAAQ;AACN,YAAQ,MAAM,iCAA8B,OAAO,EAAE;AACrD,YAAQ,KAAK,0CAA0C;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,eAAe;AAC7C,QAAM,MAAM,QAAQ,aAAa,WAAW,SAChC,QAAQ,aAAa,UAAU,UAC/B;AAEZ,OAAK,GAAG,GAAG,IAAI,GAAG,EAAE;AACpB,UAAQ,QAAQ,aAAa,GAAG,EAAE;AACpC,CAAC;AAEH,QAAQ,MAAM;","names":[]}
1
+ {"version":3,"sources":["../src/env-loader.ts","../src/cli.ts"],"sourcesContent":["/**\n * Carga .env antes de cualquier otro import del proyecto\n * Este archivo SOLO importa de node/npm, nunca de archivos locales\n */\nimport { existsSync } from 'fs'\nimport { join, dirname } from 'path'\nimport { config } from 'dotenv'\n\nlet dir = process.cwd()\nconsole.log('[env-loader] Starting search from cwd:', dir)\n\nfor (let i = 0; i < 5; i++) {\n const envPath = join(dir, '.env')\n const exists = existsSync(envPath)\n console.log(`[env-loader] Checking: ${envPath}`, exists ? '✓ FOUND' : '✗ not found')\n if (exists) {\n config({ path: envPath })\n console.log('[env-loader] Loaded:', envPath)\n break\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n}\n","#!/usr/bin/env node\nimport './env-loader.js'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\n\nconst program = new Command()\n\nprogram\n .name('nexus')\n .description('Nexus Backend CLI')\n .version('0.1.0')\n\nprogram\n .command('ui')\n .description('Open UI in browser')\n .option('-p, --port <port>', 'Nexus backend port')\n .action(async (options) => {\n const port = parseInt(options.port || process.env['PORT'] || '3000', 10)\n const baseUrl = (process.env['BACKEND_URL'] || `http://localhost:${port}`).replace(/\\/$/, '')\n const url = `${baseUrl}/ui`\n\n // Verificar que Nexus está corriendo\n try {\n const res = await fetch(`${baseUrl}/health`)\n if (!res.ok) throw new Error()\n } catch {\n consola.error(`Nexus no está corriendo en ${baseUrl}`)\n consola.info('Inicia el servidor primero con: pnpm dev')\n process.exit(1)\n }\n\n // Abrir navegador\n const { exec } = await import('child_process')\n const cmd = process.platform === 'darwin' ? 'open'\n : process.platform === 'win32' ? 'start'\n : 'xdg-open'\n\n exec(`${cmd} ${url}`)\n consola.success(`Abriendo: ${url}`)\n })\n\nprogram.parse()\n"],"mappings":";;;AAIA,SAAS,kBAAkB;AAC3B,SAAS,MAAM,eAAe;AAC9B,SAAS,cAAc;AAEvB,IAAI,MAAM,QAAQ,IAAI;AACtB,QAAQ,IAAI,0CAA0C,GAAG;AAEzD,SAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAM,UAAU,KAAK,KAAK,MAAM;AAChC,QAAM,SAAS,WAAW,OAAO;AACjC,UAAQ,IAAI,0BAA0B,OAAO,IAAI,SAAS,iBAAY,kBAAa;AACnF,MAAI,QAAQ;AACV,WAAO,EAAE,MAAM,QAAQ,CAAC;AACxB,YAAQ,IAAI,wBAAwB,OAAO;AAC3C;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,GAAG;AAC1B,MAAI,WAAW,IAAK;AACpB,QAAM;AACR;;;ACrBA,SAAS,eAAe;AACxB,SAAS,eAAe;AAExB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,mBAAmB,EAC/B,QAAQ,OAAO;AAElB,QACG,QAAQ,IAAI,EACZ,YAAY,oBAAoB,EAChC,OAAO,qBAAqB,oBAAoB,EAChD,OAAO,OAAO,YAAY;AACzB,QAAM,OAAO,SAAS,QAAQ,QAAQ,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE;AACvE,QAAM,WAAW,QAAQ,IAAI,aAAa,KAAK,oBAAoB,IAAI,IAAI,QAAQ,OAAO,EAAE;AAC5F,QAAM,MAAM,GAAG,OAAO;AAGtB,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,OAAO,SAAS;AAC3C,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM;AAAA,EAC/B,QAAQ;AACN,YAAQ,MAAM,iCAA8B,OAAO,EAAE;AACrD,YAAQ,KAAK,0CAA0C;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,eAAe;AAC7C,QAAM,MAAM,QAAQ,aAAa,WAAW,SAChC,QAAQ,aAAa,UAAU,UAC/B;AAEZ,OAAK,GAAG,GAAG,IAAI,GAAG,EAAE;AACpB,UAAQ,QAAQ,aAAa,GAAG,EAAE;AACpC,CAAC;AAEH,QAAQ,MAAM;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import http from 'node:http';
2
2
  import * as express_serve_static_core from 'express-serve-static-core';
3
3
  import knex, { Knex } from 'knex';
4
- import { ModuleManifest, PluginManifest, EntityQuery, PaginatedResult as PaginatedResult$1, EntityDefinition, ModuleContext, EntityServiceHooks, CollectionEntityDefinition, SingleEntityDefinition, ReferenceEntityDefinition, EventEntityDefinition, ConfigEntityDefinition, TempEntityDefinition, ViewEntityDefinition, ExternalEntityDefinition, VirtualEntityDefinition, ComputedEntityDefinition, ActionEntityDefinition, AuthRequest as AuthRequest$1 } from '@gzl10/nexus-sdk';
4
+ import { ModuleManifest, PluginManifest, EntityQuery, PaginatedResult as PaginatedResult$1, EntityDefinition, ModuleContext, EntityServiceHooks, CollectionEntityDefinition, SingleEntityDefinition, ReferenceEntityDefinition, EventEntityDefinition, ConfigEntityDefinition, TempEntityDefinition, ViewEntityDefinition, ExternalEntityDefinition, VirtualEntityDefinition, ComputedEntityDefinition, ActionEntityDefinition, Request as Request$1, Response as Response$1, AuthRequest as AuthRequest$1 } from '@gzl10/nexus-sdk';
5
5
  export { Category, ContextHelpers, CookieOptions, EntityDefinition, EntityQuery, ModuleAbilities, ModuleContext, ModuleManifest, ModuleMiddlewares, ModuleRequirements, NextFunction, PluginManifest, Request, RequestHandler, Response, Router, ValidateSchemas } from '@gzl10/nexus-sdk';
6
6
  import { Request, Response, Router } from 'express';
7
7
  import pino from 'pino';
@@ -357,6 +357,27 @@ declare abstract class BaseEntityService<T = unknown> implements EntityService<T
357
357
  * Exclude sensitive fields from array of entities
358
358
  */
359
359
  protected excludeSensitiveFieldsFromArray<D extends Record<string, unknown>>(items: D[]): Partial<D>[];
360
+ /**
361
+ * Execute an action defined in this entity programmatically
362
+ *
363
+ * Allows invoking EntityActions from other services without HTTP context.
364
+ * NOTE: Does NOT verify CASL permissions - caller is responsible for authorization.
365
+ *
366
+ * @param actionKey - Key of the action to execute
367
+ * @param input - Input for the handler (without _record if recordId is provided)
368
+ * @param recordId - ID of the record (optional, loads automatically)
369
+ * @param options - Additional options
370
+ * @returns Result from the action handler
371
+ *
372
+ * @example
373
+ * // From another service
374
+ * const storageService = ctx.services['storage_files'] as CollectionService
375
+ * const result = await storageService.executeAction('thumbnail', { width: 200 }, fileId)
376
+ */
377
+ executeAction(actionKey: string, input?: Record<string, unknown>, recordId?: string, options?: {
378
+ userId?: string;
379
+ skipValidation?: boolean;
380
+ }): Promise<unknown>;
360
381
  }
361
382
 
362
383
  /**
@@ -583,6 +604,15 @@ declare class ConfigService<T extends Record<string, unknown> = Record<string, u
583
604
  * Reset config to defaults
584
605
  */
585
606
  resetToDefaults(id: string): Promise<T | null>;
607
+ /**
608
+ * Set a config as the default (only one can be default at a time)
609
+ */
610
+ setAsDefault(id: string): Promise<void>;
611
+ /**
612
+ * Get the default config record
613
+ * Fallback: first record ordered by created_at if no is_default: true
614
+ */
615
+ getDefault(): Promise<T | null>;
586
616
  /**
587
617
  * Merge entity with defaults
588
618
  */
@@ -854,8 +884,12 @@ declare class ActionService<T extends Record<string, unknown> = Record<string, u
854
884
  findById(_id: string): Promise<T | null>;
855
885
  /**
856
886
  * Execute the action
887
+ * @param input - Body data
888
+ * @param req - Express request (optional, for accessing files, params, etc.)
889
+ * @param res - Express response (optional, for streaming, custom headers, etc.)
890
+ * @returns Result to be sent as JSON, or undefined if handler controlled response
857
891
  */
858
- execute(input: unknown): Promise<unknown>;
892
+ execute(input: unknown, req?: Request$1, res?: Response$1): Promise<unknown>;
859
893
  /**
860
894
  * Get action metadata
861
895
  */
@@ -921,7 +955,6 @@ interface Permission {
921
955
  created_by: string | null;
922
956
  updated_by: string | null;
923
957
  }
924
-
925
958
  /** User sin password para respuestas API */
926
959
  type UserWithoutPassword = Omit<User, 'password'>;
927
960
  /** Presencia del usuario (Socket.IO) */
@@ -988,9 +1021,6 @@ interface PaginatedResult<T> {
988
1021
  hasNext: boolean;
989
1022
  }
990
1023
 
991
- /**
992
- * Tipos del módulo Auth
993
- */
994
1024
  /**
995
1025
  * Token de refresco para rotación de JWT
996
1026
  */
@@ -999,6 +1029,8 @@ interface RefreshToken {
999
1029
  token: string;
1000
1030
  user_id: string;
1001
1031
  expires_at: Date;
1032
+ device_id?: string | null;
1033
+ device_name?: string | null;
1002
1034
  created_at?: Date;
1003
1035
  }
1004
1036
  /**
@@ -1013,7 +1045,6 @@ interface AuthAudit {
1013
1045
  user_agent?: string | null;
1014
1046
  details?: Record<string, unknown> | null;
1015
1047
  created_at: Date;
1016
- updated_at: Date;
1017
1048
  }
1018
1049
 
1019
1050
  interface JwtPayload {
@@ -1161,14 +1192,14 @@ declare const sendNotificationInputSchema: z.ZodObject<{
1161
1192
  type: "error" | "info" | "warning" | "success";
1162
1193
  priority: "high" | "normal" | "low" | "urgent";
1163
1194
  title: string;
1164
- target_type: "all" | "user" | "authenticated" | "users" | "role";
1195
+ target_type: "all" | "user" | "users" | "authenticated" | "role";
1165
1196
  link?: string | undefined;
1166
1197
  expires_at?: string | undefined;
1167
1198
  target_value?: string | undefined;
1168
1199
  }, {
1169
1200
  message: string;
1170
1201
  title: string;
1171
- target_type: "all" | "user" | "authenticated" | "users" | "role";
1202
+ target_type: "all" | "user" | "users" | "authenticated" | "role";
1172
1203
  type?: "error" | "info" | "warning" | "success" | undefined;
1173
1204
  link?: string | undefined;
1174
1205
  expires_at?: string | undefined;
@@ -1211,6 +1242,11 @@ interface NotificationPayload {
1211
1242
  declare class NotificationService {
1212
1243
  private db;
1213
1244
  private logger;
1245
+ private generateId;
1246
+ private nowTimestamp;
1247
+ private formatTimestamp;
1248
+ private socket;
1249
+ private events;
1214
1250
  constructor(ctx: ModuleContext);
1215
1251
  /**
1216
1252
  * Envía una notificación
@@ -1265,5 +1301,10 @@ declare function getLibPath(): string;
1265
1301
  * - Lib: /proyecto-usuario/
1266
1302
  */
1267
1303
  declare function getProjectPath(): string;
1304
+ /**
1305
+ * Busca .env subiendo desde cwd hasta encontrarlo (máx 5 niveles)
1306
+ * Útil para monorepos donde el .env está en la raíz
1307
+ */
1308
+ declare function findEnvFile(): string | null;
1268
1309
 
1269
- export { ActionService, type Actions, type AppAbility, type AuthAudit, type AuthRequest, BaseEntityService, CollectionService, ComputedService, ConfigService, type DbEventPayload, type EntityController, type EntityHandler, type EntityRuntime, type EntityService, EventService, type ExternalAdapter, ExternalService, type JwtPayload, type NexusConfig, type NexusEventName, type NexusEventPayload, type NexusEvents, type Notification, type NotificationPayload, type NotificationPriority, NotificationService, type NotificationTarget, type NotificationType, type PaginatedResult, type PaginationParams, type Permission, ReferenceService, type RefreshToken, type ResolvedConfig, type Role, type RoleWithCounts, type RoleWithPermissions, type SendNotificationInput, SingleService, type SubjectRegistry, type SubjectStrings, type Subjects, TempService, type TokenPair, type User, type UserPresence, type UserWithRole, type UserWithoutPassword, ViewService, VirtualService, closeSocketIO, createApp, createEntityRuntime, createEntityService, createModuleRouters, createModuleServices, db, defineAbilityFor, destroyDb, getAdapter, getConfig, getConnectedUsers, getDatabaseType, getDb, getIO, getLibPath, getModule, getModules, getNotificationService, getOrderedModules, getPlugin, getPlugins, getProjectPath, getRegisteredSubjects, getServiceKey, getUserSocketCount, initNotificationService, initSocketIO, isRunning, isSocketIOInitialized, isUserConnected, isValidSubject, loadCoreModules, nexusEvents, packRules, registerAdapter, registerModule, registerPlugin, restart, start, stop, unpackRules };
1310
+ export { ActionService, type Actions, type AppAbility, type AuthAudit, type AuthRequest, BaseEntityService, CollectionService, ComputedService, ConfigService, type DbEventPayload, type EntityController, type EntityHandler, type EntityRuntime, type EntityService, EventService, type ExternalAdapter, ExternalService, type JwtPayload, type NexusConfig, type NexusEventName, type NexusEventPayload, type NexusEvents, type Notification, type NotificationPayload, type NotificationPriority, NotificationService, type NotificationTarget, type NotificationType, type PaginatedResult, type PaginationParams, type Permission, ReferenceService, type RefreshToken, type ResolvedConfig, type Role, type RoleWithCounts, type RoleWithPermissions, type SendNotificationInput, SingleService, type SubjectRegistry, type SubjectStrings, type Subjects, TempService, type TokenPair, type User, type UserPresence, type UserWithRole, type UserWithoutPassword, ViewService, VirtualService, closeSocketIO, createApp, createEntityRuntime, createEntityService, createModuleRouters, createModuleServices, db, defineAbilityFor, destroyDb, findEnvFile, getAdapter, getConfig, getConnectedUsers, getDatabaseType, getDb, getIO, getLibPath, getModule, getModules, getNotificationService, getOrderedModules, getPlugin, getPlugins, getProjectPath, getRegisteredSubjects, getServiceKey, getUserSocketCount, initNotificationService, initSocketIO, isRunning, isSocketIOInitialized, isUserConnected, isValidSubject, loadCoreModules, nexusEvents, packRules, registerAdapter, registerModule, registerPlugin, restart, start, stop, unpackRules };