outlet-orm 9.0.2 → 11.1.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.
Files changed (44) hide show
  1. package/README.md +103 -5
  2. package/bin/reverse.js +0 -1
  3. package/package.json +1 -1
  4. package/skills/outlet-orm/ADVANCED.md +29 -0
  5. package/skills/outlet-orm/AI.md +23 -23
  6. package/skills/outlet-orm/API.md +33 -3
  7. package/skills/outlet-orm/MODELS.md +144 -2
  8. package/skills/outlet-orm/QUERIES.md +136 -3
  9. package/skills/outlet-orm/RELATIONS.md +44 -0
  10. package/skills/outlet-orm/SEEDS.md +2 -2
  11. package/skills/outlet-orm/SKILL.md +8 -6
  12. package/skills/outlet-orm/TYPESCRIPT.md +98 -0
  13. package/src/AI/{AiBridgeManager.js → AIManager.js} +61 -61
  14. package/src/AI/AIPromptEnhancer.js +1 -1
  15. package/src/AI/AIQueryBuilder.js +4 -4
  16. package/src/AI/AIQueryOptimizer.js +3 -3
  17. package/src/AI/AISeeder.js +1 -1
  18. package/src/AI/Builders/TextBuilder.js +2 -2
  19. package/src/AI/Contracts/AudioProviderContract.js +2 -2
  20. package/src/AI/Contracts/ChatProviderContract.js +3 -2
  21. package/src/AI/Contracts/EmbeddingsProviderContract.js +1 -1
  22. package/src/AI/Contracts/ImageProviderContract.js +1 -1
  23. package/src/AI/Contracts/ModelsProviderContract.js +1 -1
  24. package/src/AI/Contracts/ToolContract.js +1 -1
  25. package/src/AI/Facades/{AiBridge.js → AI.js} +11 -11
  26. package/src/AI/MCPServer.js +16 -16
  27. package/src/AI/Providers/CustomOpenAIProvider.js +0 -2
  28. package/src/AI/Providers/GeminiProvider.js +2 -2
  29. package/src/AI/Providers/OpenAIProvider.js +0 -5
  30. package/src/AI/Support/DocumentAttachmentMapper.js +37 -37
  31. package/src/AI/Support/FileSecurity.js +1 -1
  32. package/src/AI/Support/ToolChatRunner.js +1 -1
  33. package/src/Backup/BackupManager.js +6 -6
  34. package/src/Backup/BackupScheduler.js +1 -1
  35. package/src/Backup/BackupSocketServer.js +2 -2
  36. package/src/DatabaseConnection.js +51 -0
  37. package/src/Model.js +245 -5
  38. package/src/QueryBuilder.js +191 -0
  39. package/src/Relations/HasOneRelation.js +114 -114
  40. package/src/Relations/HasOneThroughRelation.js +105 -105
  41. package/src/Relations/MorphOneRelation.js +4 -2
  42. package/src/Relations/Relation.js +35 -0
  43. package/src/index.js +6 -6
  44. package/types/index.d.ts +78 -12
package/types/index.d.ts CHANGED
@@ -88,6 +88,8 @@ declare module 'outlet-orm' {
88
88
  update(table: string, data: Record<string, any>, query: QueryObject): Promise<UpdateResult>;
89
89
  delete(table: string, query: QueryObject): Promise<DeleteResult>;
90
90
  count(table: string, query: QueryObject): Promise<number>;
91
+ /** Execute an aggregate function (SUM, AVG, MIN, MAX) */
92
+ aggregate(table: string, fn: 'SUM' | 'AVG' | 'MIN' | 'MAX', column: string, query: QueryObject): Promise<number>;
91
93
  executeRawQuery(sql: string, params?: any[]): Promise<any[]>;
92
94
  /** Execute raw SQL and return driver-native results (used by migrations) */
93
95
  execute(sql: string, params?: any[]): Promise<any>;
@@ -237,6 +239,37 @@ declare module 'outlet-orm' {
237
239
  /** Lazily iterate over matching records using an async generator */
238
240
  cursor(chunkSize?: number): AsyncGenerator<T, void, unknown>;
239
241
 
242
+ // Convenience query methods
243
+ /** Get an array of values for a single column, optionally keyed by another column */
244
+ pluck(column: string): Promise<any[]>;
245
+ pluck(column: string, keyColumn: string): Promise<Record<string, any>>;
246
+ /** Get the value of a single column from the first matching row */
247
+ value(column: string): Promise<any>;
248
+
249
+ // Aggregate methods
250
+ /** Get the sum of a column */
251
+ sum(column: string): Promise<number>;
252
+ /** Get the average of a column */
253
+ avg(column: string): Promise<number>;
254
+ /** Get the minimum value of a column */
255
+ min(column: string): Promise<number>;
256
+ /** Get the maximum value of a column */
257
+ max(column: string): Promise<number>;
258
+
259
+ // Batch & conditional methods
260
+ /** Process results in chunks */
261
+ chunk(size: number, callback: (chunk: T[], page: number) => void | false | Promise<void | false>): Promise<void>;
262
+ /** Conditionally apply a callback to the query */
263
+ when(condition: any, callback: (qb: this, value: any) => void, fallback?: (qb: this, value: any) => void): this;
264
+ /** Pass the query builder to a callback without modifying the chain */
265
+ tap(callback: (qb: this) => void): this;
266
+
267
+ // Debugging
268
+ /** Get the SQL representation of the current query */
269
+ toSQL(): { table: string } & QueryObject;
270
+ /** Dump the SQL and throw */
271
+ dd(): never;
272
+
240
273
  clone(): QueryBuilder<T>;
241
274
  }
242
275
 
@@ -279,10 +312,15 @@ declare module 'outlet-orm' {
279
312
  export type EventCallback<T extends Model = Model> = (model: T) => boolean | void | Promise<boolean | void>;
280
313
 
281
314
  /**
282
- * Base Model class with optional generic for typed attributes
315
+ * Base Model class with optional generic for typed attributes.
316
+ * Instances are wrapped in a Proxy so attributes can be accessed
317
+ * directly as properties: `user.name` / `user.name = 'Jean'`.
318
+ * Existing methods (getAttribute, setAttribute) remain available.
283
319
  * @template TAttributes - Type of model attributes (defaults to Record<string, any>)
284
320
  */
285
321
  export class Model<TAttributes extends Record<string, any> = Record<string, any>> {
322
+ /** Property-style attribute access via Proxy (read & write) */
323
+ [K: string]: any;
286
324
  static table: string;
287
325
  static primaryKey: string;
288
326
  static timestamps: boolean;
@@ -290,6 +328,8 @@ declare module 'outlet-orm' {
290
328
  static hidden: string[];
291
329
  static casts: Record<string, CastType>;
292
330
  static connection: DatabaseConnection | null;
331
+ /** Computed attributes to append in serialization */
332
+ static appends: string[];
293
333
 
294
334
  // Soft Deletes
295
335
  static softDeletes: boolean;
@@ -409,6 +449,30 @@ declare module 'outlet-orm' {
409
449
  /** Load relations on an existing instance. Supports dot-notation and arrays. */
410
450
  load(...relations: string[] | [string[]]): Promise<this>;
411
451
 
452
+ // Model instance utilities
453
+ /** Reload a fresh model instance from the database */
454
+ fresh(...relations: string[]): Promise<this | null>;
455
+ /** Reload attributes from DB into this instance */
456
+ refresh(): Promise<this>;
457
+ /** Clone the model without the primary key */
458
+ replicate(...except: string[]): this;
459
+ /** Check if two models have the same ID and table */
460
+ is(model: Model | null): boolean;
461
+ /** Check if two models are different */
462
+ isNot(model: Model | null): boolean;
463
+ /** Get a subset of attributes as a plain object */
464
+ only(...keys: (string | string[])[]): Partial<TAttributes>;
465
+ /** Get all attributes except specified keys */
466
+ except(...keys: (string | string[])[]): Partial<TAttributes>;
467
+ /** Make attributes visible on this instance */
468
+ makeVisible(...attrs: (string | string[])[]): this;
469
+ /** Make attributes hidden on this instance */
470
+ makeHidden(...attrs: (string | string[])[]): this;
471
+ /** Check if attribute was changed on last save */
472
+ wasChanged(attr?: string): boolean;
473
+ /** Get attributes changed on last save */
474
+ getChanges(): Partial<TAttributes>;
475
+
412
476
  // Soft delete instance methods
413
477
  trashed(): boolean;
414
478
  restore(): Promise<this>;
@@ -459,6 +523,8 @@ declare module 'outlet-orm' {
459
523
 
460
524
  export abstract class Relation<T extends Model> {
461
525
  constructor(parent: Model, related: new () => T, foreignKey: string, localKey: string);
526
+ /** Set a default value when the relation result is null */
527
+ withDefault(value?: Record<string, any> | (() => T) | boolean): this;
462
528
  abstract get(): Promise<T | T[] | null>;
463
529
  abstract eagerLoad(models: Model[], relationName: string, constraint?: (qb: QueryBuilder<T>) => void): Promise<void>;
464
530
  }
@@ -1154,7 +1220,7 @@ declare module 'outlet-orm' {
1154
1220
 
1155
1221
  /** Tool chat runner — executes tool loops */
1156
1222
  export class ToolChatRunner {
1157
- constructor(manager: AiBridgeManager, registry: ToolRegistry);
1223
+ constructor(manager: AIManager, registry: ToolRegistry);
1158
1224
  run(provider: string, messages: Array<{ role: string; content: string }>, options?: { maxToolIterations?: number; model?: string }): Promise<ChatResponse>;
1159
1225
  }
1160
1226
 
@@ -1243,8 +1309,8 @@ declare module 'outlet-orm' {
1243
1309
  listModels(): Promise<any[]>;
1244
1310
  }
1245
1311
 
1246
- /** AiBridge manager configuration */
1247
- export interface AiBridgeConfig {
1312
+ /** AI manager configuration */
1313
+ export interface AIConfig {
1248
1314
  default?: string;
1249
1315
  openai?: OpenAIProviderConfig;
1250
1316
  ollama?: { endpoint?: string; model?: string };
@@ -1261,7 +1327,7 @@ declare module 'outlet-orm' {
1261
1327
 
1262
1328
  /** TextBuilder — fluent API for building AI requests */
1263
1329
  export class TextBuilder {
1264
- constructor(manager: AiBridgeManager);
1330
+ constructor(manager: AIManager);
1265
1331
  using(provider: string, model?: string): this;
1266
1332
  withPrompt(text: string, attachments?: Document[]): this;
1267
1333
  withSystemPrompt(text: string): this;
@@ -1280,9 +1346,9 @@ declare module 'outlet-orm' {
1280
1346
  asStream(): AsyncGenerator<StreamChunk>;
1281
1347
  }
1282
1348
 
1283
- /** AiBridge Manager — central orchestrator for multi-provider AI */
1284
- export class AiBridgeManager {
1285
- constructor(config?: AiBridgeConfig);
1349
+ /** AIManager — central orchestrator for multi-provider AI */
1350
+ export class AIManager {
1351
+ constructor(config?: AIConfig);
1286
1352
  provider(name: string): ChatProviderContract;
1287
1353
  registerProvider(name: string, provider: ChatProviderContract): void;
1288
1354
  chat(provider: string, messages: Array<{ role: string; content: string }>, options?: Record<string, any>): Promise<ChatResponse>;
@@ -1315,7 +1381,7 @@ declare module 'outlet-orm' {
1315
1381
 
1316
1382
  /** AIQueryBuilder — natural language to SQL conversion */
1317
1383
  export class AIQueryBuilder {
1318
- constructor(manager: AiBridgeManager, connection: DatabaseConnection);
1384
+ constructor(manager: AIManager, connection: DatabaseConnection);
1319
1385
  using(provider: string, model: string): this;
1320
1386
  safeMode(safe: boolean): this;
1321
1387
  query(question: string, options?: { model?: string; max_tokens?: number; temperature?: number }): Promise<AIQueryResult>;
@@ -1330,7 +1396,7 @@ declare module 'outlet-orm' {
1330
1396
 
1331
1397
  /** AISeeder — AI-powered data seeding */
1332
1398
  export class AISeeder {
1333
- constructor(manager: AiBridgeManager, connection: DatabaseConnection);
1399
+ constructor(manager: AIManager, connection: DatabaseConnection);
1334
1400
  using(provider: string, model: string): this;
1335
1401
  seed(table: string, count?: number, context?: { description?: string; locale?: string; domain?: string }): Promise<AISeedResult>;
1336
1402
  generate(table: string, count?: number, context?: { description?: string; locale?: string; domain?: string }): Promise<Record<string, any>[]>;
@@ -1348,7 +1414,7 @@ declare module 'outlet-orm' {
1348
1414
 
1349
1415
  /** AIQueryOptimizer — AI-powered SQL query optimization */
1350
1416
  export class AIQueryOptimizer {
1351
- constructor(manager: AiBridgeManager, connection?: DatabaseConnection);
1417
+ constructor(manager: AIManager, connection?: DatabaseConnection);
1352
1418
  using(provider: string, model: string): this;
1353
1419
  optimize(sql: string, options?: { schema?: string; dialect?: string; model?: string }): Promise<OptimizationResult>;
1354
1420
  explain(sql: string): Promise<{ plan: any[]; analysis: string }>;
@@ -1363,7 +1429,7 @@ declare module 'outlet-orm' {
1363
1429
 
1364
1430
  /** AIPromptEnhancer — LLM-powered schema/code generation */
1365
1431
  export class AIPromptEnhancer {
1366
- constructor(manager: AiBridgeManager);
1432
+ constructor(manager: AIManager);
1367
1433
  using(provider: string, model: string): this;
1368
1434
  generateSchema(description: string, options?: { model?: string }): Promise<AISchema>;
1369
1435
  generateModelCode(tableName: string, tableSchema: { columns: string[] }, relations?: any[]): Promise<string>;