@beeblock/svelar 0.4.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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +110 -0
  3. package/dist/actions/index.d.ts +101 -0
  4. package/dist/actions/index.js +1 -0
  5. package/dist/api-keys/index.d.ts +58 -0
  6. package/dist/api-keys/index.js +1 -0
  7. package/dist/audit/index.d.ts +52 -0
  8. package/dist/audit/index.js +1 -0
  9. package/dist/auth/Auth.d.ts +283 -0
  10. package/dist/auth/Gate.d.ts +166 -0
  11. package/dist/auth/index.d.ts +2 -0
  12. package/dist/auth/index.js +80 -0
  13. package/dist/broadcasting/client.d.ts +195 -0
  14. package/dist/broadcasting/client.js +1 -0
  15. package/dist/broadcasting/index.d.ts +318 -0
  16. package/dist/broadcasting/index.js +20 -0
  17. package/dist/cache/index.d.ts +77 -0
  18. package/dist/cache/index.js +1 -0
  19. package/dist/cli/Cli.d.ts +23 -0
  20. package/dist/cli/Command.d.ts +36 -0
  21. package/dist/cli/bin.d.ts +8 -0
  22. package/dist/cli/bin.js +5856 -0
  23. package/dist/cli/commands/KeyGenerateCommand.d.ts +16 -0
  24. package/dist/cli/commands/MakeActionCommand.d.ts +15 -0
  25. package/dist/cli/commands/MakeBroadcastingCommand.d.ts +29 -0
  26. package/dist/cli/commands/MakeChannelCommand.d.ts +18 -0
  27. package/dist/cli/commands/MakeCommandCommand.d.ts +16 -0
  28. package/dist/cli/commands/MakeConfigCommand.d.ts +13 -0
  29. package/dist/cli/commands/MakeControllerCommand.d.ts +28 -0
  30. package/dist/cli/commands/MakeDashboardCommand.d.ts +34 -0
  31. package/dist/cli/commands/MakeDockerCommand.d.ts +32 -0
  32. package/dist/cli/commands/MakeEventCommand.d.ts +11 -0
  33. package/dist/cli/commands/MakeJobCommand.d.ts +11 -0
  34. package/dist/cli/commands/MakeListenerCommand.d.ts +16 -0
  35. package/dist/cli/commands/MakeMiddlewareCommand.d.ts +11 -0
  36. package/dist/cli/commands/MakeMigrationCommand.d.ts +17 -0
  37. package/dist/cli/commands/MakeModelCommand.d.ts +25 -0
  38. package/dist/cli/commands/MakeObserverCommand.d.ts +23 -0
  39. package/dist/cli/commands/MakePluginCommand.d.ts +11 -0
  40. package/dist/cli/commands/MakeProviderCommand.d.ts +11 -0
  41. package/dist/cli/commands/MakeRepositoryCommand.d.ts +22 -0
  42. package/dist/cli/commands/MakeRequestCommand.d.ts +15 -0
  43. package/dist/cli/commands/MakeResourceCommand.d.ts +30 -0
  44. package/dist/cli/commands/MakeRouteCommand.d.ts +42 -0
  45. package/dist/cli/commands/MakeSchemaCommand.d.ts +20 -0
  46. package/dist/cli/commands/MakeSeederCommand.d.ts +11 -0
  47. package/dist/cli/commands/MakeServiceCommand.d.ts +28 -0
  48. package/dist/cli/commands/MakeTaskCommand.d.ts +12 -0
  49. package/dist/cli/commands/MigrateCommand.d.ts +26 -0
  50. package/dist/cli/commands/NewCommand.d.ts +21 -0
  51. package/dist/cli/commands/NewCommandTemplates.d.ts +123 -0
  52. package/dist/cli/commands/PluginInstallCommand.d.ts +16 -0
  53. package/dist/cli/commands/PluginListCommand.d.ts +11 -0
  54. package/dist/cli/commands/PluginPublishCommand.d.ts +22 -0
  55. package/dist/cli/commands/QueueFailedCommand.d.ts +9 -0
  56. package/dist/cli/commands/QueueFlushCommand.d.ts +9 -0
  57. package/dist/cli/commands/QueueRetryCommand.d.ts +16 -0
  58. package/dist/cli/commands/QueueWorkCommand.d.ts +25 -0
  59. package/dist/cli/commands/RoutesListCommand.d.ts +30 -0
  60. package/dist/cli/commands/ScheduleRunCommand.d.ts +15 -0
  61. package/dist/cli/commands/SeedCommand.d.ts +14 -0
  62. package/dist/cli/commands/TinkerCommand.d.ts +10 -0
  63. package/dist/cli/index.d.ts +36 -0
  64. package/dist/cli/index.js +1973 -0
  65. package/dist/cli/ts-resolve-hook.mjs +74 -0
  66. package/dist/cli/ts-resolver.mjs +8 -0
  67. package/dist/config/Config.d.ts +65 -0
  68. package/dist/config/index.d.ts +1 -0
  69. package/dist/config/index.js +1 -0
  70. package/dist/container/Application.d.ts +33 -0
  71. package/dist/container/Container.d.ts +70 -0
  72. package/dist/container/ServiceProvider.d.ts +21 -0
  73. package/dist/container/index.d.ts +3 -0
  74. package/dist/container/index.js +1 -0
  75. package/dist/dashboard/index.d.ts +123 -0
  76. package/dist/dashboard/index.js +5 -0
  77. package/dist/database/Connection.d.ts +80 -0
  78. package/dist/database/Migration.d.ts +76 -0
  79. package/dist/database/SchemaBuilder.d.ts +91 -0
  80. package/dist/database/Seeder.d.ts +9 -0
  81. package/dist/database/index.d.ts +4 -0
  82. package/dist/database/index.js +4 -0
  83. package/dist/email-templates/index.d.ts +51 -0
  84. package/dist/email-templates/index.js +57 -0
  85. package/dist/errors/Handler.d.ts +100 -0
  86. package/dist/errors/index.d.ts +1 -0
  87. package/dist/errors/index.js +5 -0
  88. package/dist/events/EventServiceProvider.d.ts +82 -0
  89. package/dist/events/Listener.d.ts +28 -0
  90. package/dist/events/index.d.ts +80 -0
  91. package/dist/events/index.js +1 -0
  92. package/dist/excel/index.d.ts +154 -0
  93. package/dist/excel/index.js +1 -0
  94. package/dist/feature-flags/index.d.ts +158 -0
  95. package/dist/feature-flags/index.js +59 -0
  96. package/dist/forms/index.d.ts +81 -0
  97. package/dist/forms/index.js +1 -0
  98. package/dist/hashing/Hash.d.ts +51 -0
  99. package/dist/hashing/index.d.ts +1 -0
  100. package/dist/hashing/index.js +1 -0
  101. package/dist/hooks/index.d.ts +135 -0
  102. package/dist/hooks/index.js +5 -0
  103. package/dist/http/index.d.ts +201 -0
  104. package/dist/http/index.js +2 -0
  105. package/dist/i18n/index.d.ts +81 -0
  106. package/dist/i18n/index.js +1 -0
  107. package/dist/index.d.ts +54 -0
  108. package/dist/index.js +127 -0
  109. package/dist/logging/LogViewer.d.ts +95 -0
  110. package/dist/logging/LogViewer.js +1 -0
  111. package/dist/logging/index.d.ts +83 -0
  112. package/dist/logging/index.js +3 -0
  113. package/dist/mail/index.d.ts +149 -0
  114. package/dist/mail/index.js +1 -0
  115. package/dist/middleware/Middleware.d.ts +208 -0
  116. package/dist/middleware/index.d.ts +1 -0
  117. package/dist/middleware/index.js +1 -0
  118. package/dist/notifications/index.d.ts +85 -0
  119. package/dist/notifications/index.js +2 -0
  120. package/dist/orm/Model.d.ts +123 -0
  121. package/dist/orm/Observer.d.ts +34 -0
  122. package/dist/orm/QueryBuilder.d.ts +119 -0
  123. package/dist/orm/Relationship.d.ts +58 -0
  124. package/dist/orm/index.d.ts +4 -0
  125. package/dist/orm/index.js +1 -0
  126. package/dist/pagination/index.d.ts +8 -0
  127. package/dist/pagination/index.js +0 -0
  128. package/dist/pdf/GeneratePdfJob.d.ts +99 -0
  129. package/dist/pdf/GeneratePdfJob.js +41 -0
  130. package/dist/pdf/index.d.ts +328 -0
  131. package/dist/pdf/index.js +41 -0
  132. package/dist/permissions/index.d.ts +161 -0
  133. package/dist/permissions/index.js +60 -0
  134. package/dist/plugins/BootstrapPlugins.d.ts +11 -0
  135. package/dist/plugins/PluginInstaller.d.ts +30 -0
  136. package/dist/plugins/PluginInstaller.js +1 -0
  137. package/dist/plugins/PluginPublisher.d.ts +32 -0
  138. package/dist/plugins/PluginPublisher.js +1 -0
  139. package/dist/plugins/PluginRegistry.d.ts +55 -0
  140. package/dist/plugins/PluginRegistry.js +1 -0
  141. package/dist/plugins/index.d.ts +206 -0
  142. package/dist/plugins/index.js +1 -0
  143. package/dist/queue/JobMonitor.d.ts +109 -0
  144. package/dist/queue/JobMonitor.js +5 -0
  145. package/dist/queue/index.d.ts +279 -0
  146. package/dist/queue/index.js +5 -0
  147. package/dist/repositories/index.d.ts +147 -0
  148. package/dist/repositories/index.js +1 -0
  149. package/dist/routing/Controller.d.ts +115 -0
  150. package/dist/routing/FormRequest.d.ts +94 -0
  151. package/dist/routing/Resource.d.ts +213 -0
  152. package/dist/routing/Response.d.ts +138 -0
  153. package/dist/routing/index.d.ts +4 -0
  154. package/dist/routing/index.js +5 -0
  155. package/dist/scheduler/ScheduleMonitor.d.ts +141 -0
  156. package/dist/scheduler/ScheduleMonitor.js +1 -0
  157. package/dist/scheduler/SchedulerLock.d.ts +33 -0
  158. package/dist/scheduler/index.d.ts +208 -0
  159. package/dist/scheduler/index.js +34 -0
  160. package/dist/services/index.d.ts +79 -0
  161. package/dist/services/index.js +1 -0
  162. package/dist/session/Session.d.ts +166 -0
  163. package/dist/session/index.d.ts +1 -0
  164. package/dist/session/index.js +16 -0
  165. package/dist/storage/index.d.ts +154 -0
  166. package/dist/storage/index.js +1 -0
  167. package/dist/support/Pipeline.d.ts +65 -0
  168. package/dist/support/date.d.ts +136 -0
  169. package/dist/support/date.js +1 -0
  170. package/dist/support/index.d.ts +8 -0
  171. package/dist/support/index.js +1 -0
  172. package/dist/support/singleton.d.ts +10 -0
  173. package/dist/support/uuid.d.ts +40 -0
  174. package/dist/teams/index.d.ts +91 -0
  175. package/dist/teams/index.js +78 -0
  176. package/dist/uploads/index.d.ts +63 -0
  177. package/dist/uploads/index.js +2 -0
  178. package/dist/validation/index.d.ts +46 -0
  179. package/dist/validation/index.js +1 -0
  180. package/dist/webhooks/index.d.ts +66 -0
  181. package/dist/webhooks/index.js +1 -0
  182. package/package.json +338 -0
  183. package/src/i18n/LanguageSwitcher.svelte +47 -0
  184. package/src/i18n/index.ts +113 -0
  185. package/src/ui/Alert.svelte +22 -0
  186. package/src/ui/Avatar.svelte +18 -0
  187. package/src/ui/AvatarFallback.svelte +18 -0
  188. package/src/ui/AvatarImage.svelte +12 -0
  189. package/src/ui/Badge.svelte +27 -0
  190. package/src/ui/Button.svelte +51 -0
  191. package/src/ui/Card.svelte +15 -0
  192. package/src/ui/CardContent.svelte +15 -0
  193. package/src/ui/CardDescription.svelte +15 -0
  194. package/src/ui/CardFooter.svelte +15 -0
  195. package/src/ui/CardHeader.svelte +15 -0
  196. package/src/ui/CardTitle.svelte +15 -0
  197. package/src/ui/Icon.svelte +81 -0
  198. package/src/ui/Input.svelte +40 -0
  199. package/src/ui/Label.svelte +20 -0
  200. package/src/ui/Separator.svelte +10 -0
  201. package/src/ui/Tabs.svelte +23 -0
  202. package/src/ui/TabsContent.svelte +27 -0
  203. package/src/ui/TabsList.svelte +19 -0
  204. package/src/ui/TabsTrigger.svelte +28 -0
  205. package/src/ui/Toaster.svelte +279 -0
  206. package/src/ui/index.ts +31 -0
  207. package/src/ui/toast.ts +212 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Svelar Model
3
+ *
4
+ * Eloquent-like base Model class. Extend this for each database table.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * class User extends Model {
9
+ * static table = 'users';
10
+ * static timestamps = true;
11
+ *
12
+ * declare id: number;
13
+ * declare email: string;
14
+ * declare name: string;
15
+ *
16
+ * posts() {
17
+ * return this.hasMany(Post, 'user_id');
18
+ * }
19
+ * }
20
+ *
21
+ * const user = await User.find(1);
22
+ * const posts = await user.posts().load(user);
23
+ * ```
24
+ */
25
+ import { QueryBuilder } from './QueryBuilder.js';
26
+ import { HasOne, HasMany, BelongsTo, BelongsToMany } from './Relationship.js';
27
+ import { type ModelObserver } from './Observer.js';
28
+ export type ModelAttributes = Record<string, any>;
29
+ export interface ModelHooks {
30
+ creating?: (model: Model) => Promise<void> | void;
31
+ created?: (model: Model) => Promise<void> | void;
32
+ updating?: (model: Model) => Promise<void> | void;
33
+ updated?: (model: Model) => Promise<void> | void;
34
+ saving?: (model: Model) => Promise<void> | void;
35
+ saved?: (model: Model) => Promise<void> | void;
36
+ deleting?: (model: Model) => Promise<void> | void;
37
+ deleted?: (model: Model) => Promise<void> | void;
38
+ }
39
+ export declare class Model {
40
+ /** The database table name */
41
+ static table: string;
42
+ /** Primary key column */
43
+ static primaryKey: string;
44
+ /** Whether the model uses auto-incrementing IDs */
45
+ static incrementing: boolean;
46
+ /** Whether the model manages created_at/updated_at */
47
+ static timestamps: boolean;
48
+ /** Column names for timestamps */
49
+ static createdAt: string;
50
+ static updatedAt: string;
51
+ /** Attribute casting definitions */
52
+ static casts: Record<string, 'string' | 'number' | 'boolean' | 'date' | 'json'>;
53
+ /** Columns that can be mass-assigned */
54
+ static fillable: string[];
55
+ /** Columns that are hidden from serialization */
56
+ static hidden: string[];
57
+ /** Database connection name (null = default) */
58
+ static connection: string | undefined;
59
+ /** Registered model hooks */
60
+ private static hooks;
61
+ /** Registered model observers */
62
+ private static observers;
63
+ /** Custom model events (e.g. ['published', 'archived']) */
64
+ static events: string[];
65
+ private attributes;
66
+ private originalAttributes;
67
+ private relations;
68
+ private exists;
69
+ constructor(attributes?: ModelAttributes);
70
+ static query<T extends Model>(this: new () => T): QueryBuilder<T>;
71
+ static find<T extends Model>(this: new () => T, id: any): Promise<T | null>;
72
+ static findOrFail<T extends Model>(this: new () => T, id: any): Promise<T>;
73
+ static all<T extends Model>(this: new () => T): Promise<T[]>;
74
+ static first<T extends Model>(this: new () => T): Promise<T | null>;
75
+ static firstOrFail<T extends Model>(this: new () => T): Promise<T>;
76
+ static where<T extends Model>(this: new () => T, column: string, operatorOrValue?: any, value?: any): QueryBuilder<T>;
77
+ static whereIn<T extends Model>(this: new () => T, column: string, values: any[]): QueryBuilder<T>;
78
+ static whereNull<T extends Model>(this: new () => T, column: string): QueryBuilder<T>;
79
+ static whereNotNull<T extends Model>(this: new () => T, column: string): QueryBuilder<T>;
80
+ static orderBy<T extends Model>(this: new () => T, column: string, direction?: 'asc' | 'desc'): QueryBuilder<T>;
81
+ static latest<T extends Model>(this: new () => T, column?: string): QueryBuilder<T>;
82
+ static oldest<T extends Model>(this: new () => T, column?: string): QueryBuilder<T>;
83
+ static with<T extends Model>(this: new () => T, ...relations: string[]): QueryBuilder<T>;
84
+ static count(this: typeof Model): Promise<number>;
85
+ static create<T extends Model>(this: new () => T, attributes: ModelAttributes): Promise<T>;
86
+ save(): Promise<void>;
87
+ update(attributes: ModelAttributes): Promise<void>;
88
+ delete(): Promise<void>;
89
+ refresh(): Promise<void>;
90
+ getAttribute(key: string): any;
91
+ setAttribute(key: string, value: any): void;
92
+ fill(attributes: ModelAttributes): void;
93
+ getAttributes(): ModelAttributes;
94
+ getOriginal(key?: string): any;
95
+ getDirty(): ModelAttributes;
96
+ isDirty(...keys: string[]): boolean;
97
+ isClean(...keys: string[]): boolean;
98
+ wasChanged(...keys: string[]): boolean;
99
+ protected hasOne(related: typeof Model, foreignKey: string, localKey?: string): HasOne;
100
+ protected hasMany(related: typeof Model, foreignKey: string, localKey?: string): HasMany;
101
+ protected belongsTo(related: typeof Model, foreignKey: string, ownerKey?: string): BelongsTo;
102
+ protected belongsToMany(related: typeof Model, pivotTable: string, foreignPivotKey: string, relatedPivotKey: string, parentKey?: string, relatedKey?: string): BelongsToMany;
103
+ setRelation(name: string, value: any): void;
104
+ getRelation(name: string): any;
105
+ relationLoaded(name: string): boolean;
106
+ toJSON(): ModelAttributes;
107
+ toObject(): ModelAttributes;
108
+ /** @internal Create a model instance from a database row */
109
+ static hydrate<T extends Model>(this: new () => T, row: Record<string, any>): T;
110
+ /** Register hooks for this model class */
111
+ static boot(hooks: ModelHooks): void;
112
+ /** Register an observer for this model class */
113
+ static observe(observer: ModelObserver): void;
114
+ /** Remove all observers for this model class */
115
+ static removeObservers(): void;
116
+ private fireHook;
117
+ /** Fire a custom model event */
118
+ fireEvent(eventName: string): Promise<void>;
119
+ private syncOriginal;
120
+ private getInsertableAttributes;
121
+ /** Getter-based table name accessor (for relationship classes) */
122
+ static get tableName(): string;
123
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Svelar Model Observer
3
+ *
4
+ * Observers encapsulate model lifecycle logic in a dedicated class.
5
+ * Each method corresponds to a model event and receives the model instance.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * class UserObserver extends ModelObserver {
10
+ * async created(user: User) {
11
+ * await sendWelcomeEmail(user);
12
+ * }
13
+ *
14
+ * async deleting(user: User) {
15
+ * await user.posts().query().delete();
16
+ * }
17
+ * }
18
+ *
19
+ * User.observe(new UserObserver());
20
+ * ```
21
+ */
22
+ import type { Model } from './Model.js';
23
+ export type ModelEventName = 'creating' | 'created' | 'updating' | 'updated' | 'saving' | 'saved' | 'deleting' | 'deleted';
24
+ export declare const MODEL_EVENTS: ModelEventName[];
25
+ export declare abstract class ModelObserver {
26
+ creating?(model: Model): Promise<void> | void;
27
+ created?(model: Model): Promise<void> | void;
28
+ updating?(model: Model): Promise<void> | void;
29
+ updated?(model: Model): Promise<void> | void;
30
+ saving?(model: Model): Promise<void> | void;
31
+ saved?(model: Model): Promise<void> | void;
32
+ deleting?(model: Model): Promise<void> | void;
33
+ deleted?(model: Model): Promise<void> | void;
34
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Svelar QueryBuilder
3
+ *
4
+ * Eloquent-like fluent query builder that compiles to raw SQL.
5
+ * Works across SQLite, PostgreSQL, and MySQL through the Connection manager.
6
+ */
7
+ export type WhereOperator = '=' | '!=' | '<>' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'IS' | 'IS NOT' | 'BETWEEN';
8
+ export type OrderDirection = 'asc' | 'desc';
9
+ export type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'CROSS';
10
+ interface PaginationResult<T> {
11
+ data: T[];
12
+ total: number;
13
+ page: number;
14
+ perPage: number;
15
+ lastPage: number;
16
+ hasMore: boolean;
17
+ }
18
+ export declare class QueryBuilder<TModel = any> {
19
+ private tableName;
20
+ private selectColumns;
21
+ private whereClauses;
22
+ private joinClauses;
23
+ private orderClauses;
24
+ private groupByColumns;
25
+ private havingClauses;
26
+ private limitValue;
27
+ private offsetValue;
28
+ private eagerLoads;
29
+ private isDistinct;
30
+ private connectionName?;
31
+ private cteClauses;
32
+ private unionClauses;
33
+ private modelClass?;
34
+ constructor(table: string, modelClass?: any, connectionName?: string);
35
+ select(...columns: string[]): this;
36
+ addSelect(...columns: string[]): this;
37
+ distinct(): this;
38
+ from(table: string): this;
39
+ where(column: string, operatorOrValue?: any, value?: any): this;
40
+ orWhere(column: string, operatorOrValue?: any, value?: any): this;
41
+ whereIn(column: string, values: any[]): this;
42
+ whereNotIn(column: string, values: any[]): this;
43
+ whereNull(column: string): this;
44
+ whereNotNull(column: string): this;
45
+ whereBetween(column: string, range: [any, any]): this;
46
+ whereRaw(sql: string, bindings?: any[]): this;
47
+ whereNested(callback: (query: QueryBuilder) => void, bool?: 'AND' | 'OR'): this;
48
+ orWhereNested(callback: (query: QueryBuilder) => void): this;
49
+ whereExists(callback: (query: QueryBuilder) => void): this;
50
+ whereNotExists(callback: (query: QueryBuilder) => void): this;
51
+ whereSub(column: string, operator: string, callback: (query: QueryBuilder) => void): this;
52
+ orWhereRaw(sql: string, bindings?: any[]): this;
53
+ orWhereIn(column: string, values: any[]): this;
54
+ orWhereNull(column: string): this;
55
+ orWhereNotNull(column: string): this;
56
+ withCTE(name: string, callback: (query: QueryBuilder) => void, recursive?: boolean): this;
57
+ withRecursiveCTE(name: string, callback: (query: QueryBuilder) => void): this;
58
+ withRawCTE(name: string, sql: string, bindings?: any[], recursive?: boolean): this;
59
+ union(callback: (query: QueryBuilder) => void): this;
60
+ unionAll(callback: (query: QueryBuilder) => void): this;
61
+ join(table: string, first: string, operator: string, second: string): this;
62
+ leftJoin(table: string, first: string, operator: string, second: string): this;
63
+ rightJoin(table: string, first: string, operator: string, second: string): this;
64
+ crossJoin(table: string): this;
65
+ orderBy(column: string, direction?: OrderDirection): this;
66
+ latest(column?: string): this;
67
+ oldest(column?: string): this;
68
+ groupBy(...columns: string[]): this;
69
+ having(column: string, operator: string, value: any): this;
70
+ limit(count: number): this;
71
+ offset(skip: number): this;
72
+ take(count: number): this;
73
+ skip(count: number): this;
74
+ with(...relations: string[]): this;
75
+ get(): Promise<TModel[]>;
76
+ first(): Promise<TModel | null>;
77
+ firstOrFail(): Promise<TModel>;
78
+ find(id: any, primaryKey?: string): Promise<TModel | null>;
79
+ findOrFail(id: any, primaryKey?: string): Promise<TModel>;
80
+ count(column?: string): Promise<number>;
81
+ sum(column: string): Promise<number>;
82
+ avg(column: string): Promise<number>;
83
+ max(column: string): Promise<any>;
84
+ min(column: string): Promise<any>;
85
+ exists(): Promise<boolean>;
86
+ doesntExist(): Promise<boolean>;
87
+ pluck(column: string): Promise<any[]>;
88
+ value(column: string): Promise<any>;
89
+ chunk(size: number, callback: (items: TModel[], page: number) => Promise<boolean | void>): Promise<void>;
90
+ when(condition: boolean | any, callback: (query: this) => this): this;
91
+ selectRaw(expression: string): this;
92
+ upsert(data: Record<string, any>, conflictColumns: string[], updateColumns?: string[]): Promise<any>;
93
+ insertMany(rows: Record<string, any>[]): Promise<any>;
94
+ firstOrCreate(search: Record<string, any>, create?: Record<string, any>): Promise<TModel>;
95
+ updateOrCreate(search: Record<string, any>, update: Record<string, any>): Promise<TModel>;
96
+ whereColumn(first: string, operatorOrSecond: string, second?: string): this;
97
+ havingRaw(sql: string, bindings?: any[]): this;
98
+ orderByRaw(sql: string): this;
99
+ selectSub(callback: (query: QueryBuilder) => void, alias: string): this;
100
+ private _selectBindings?;
101
+ truncate(): Promise<void>;
102
+ paginate(page?: number, perPage?: number): Promise<PaginationResult<TModel>>;
103
+ insert(data: Record<string, any>): Promise<any>;
104
+ insertGetId(data: Record<string, any>, primaryKey?: string): Promise<number>;
105
+ update(data: Record<string, any>): Promise<number>;
106
+ delete(): Promise<number>;
107
+ increment(column: string, amount?: number): Promise<void>;
108
+ decrement(column: string, amount?: number): Promise<void>;
109
+ toSQL(): {
110
+ sql: string;
111
+ bindings: any[];
112
+ };
113
+ clone(): QueryBuilder<TModel>;
114
+ private buildWhere;
115
+ private buildAggregate;
116
+ private hydrateMany;
117
+ private loadRelations;
118
+ }
119
+ export {};
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Svelar Relationships
3
+ *
4
+ * Eloquent-like relationship definitions:
5
+ * HasOne, HasMany, BelongsTo, BelongsToMany
6
+ */
7
+ import { QueryBuilder } from './QueryBuilder.js';
8
+ export declare abstract class Relation<TParent = any, TRelated = any> {
9
+ protected parentModel: any;
10
+ protected relatedModel: any;
11
+ constructor(parent: any, related: any);
12
+ /** Load related models for a single parent */
13
+ abstract load(parent: TParent): Promise<TRelated>;
14
+ /** Eager load related models for a collection of parents */
15
+ abstract eagerLoad(parents: TParent[], relationName: string): Promise<void>;
16
+ /** Get a query builder for the related model */
17
+ query(): QueryBuilder;
18
+ }
19
+ export declare class HasOne extends Relation {
20
+ private foreignKey;
21
+ private localKey;
22
+ constructor(parent: any, related: any, foreignKey: string, localKey?: string);
23
+ load(parent: any): Promise<any>;
24
+ eagerLoad(parents: any[], relationName: string): Promise<void>;
25
+ create(attributes: Record<string, any>): Promise<any>;
26
+ }
27
+ export declare class HasMany extends Relation {
28
+ private foreignKey;
29
+ private localKey;
30
+ constructor(parent: any, related: any, foreignKey: string, localKey?: string);
31
+ load(parent: any): Promise<any[]>;
32
+ eagerLoad(parents: any[], relationName: string): Promise<void>;
33
+ create(attributes: Record<string, any>): Promise<any>;
34
+ createMany(items: Record<string, any>[]): Promise<any[]>;
35
+ }
36
+ export declare class BelongsTo extends Relation {
37
+ private foreignKey;
38
+ private ownerKey;
39
+ constructor(parent: any, related: any, foreignKey: string, ownerKey?: string);
40
+ load(parent: any): Promise<any>;
41
+ eagerLoad(parents: any[], relationName: string): Promise<void>;
42
+ associate(model: any): any;
43
+ dissociate(): any;
44
+ }
45
+ export declare class BelongsToMany extends Relation {
46
+ private pivotTable;
47
+ private foreignPivotKey;
48
+ private relatedPivotKey;
49
+ private parentKey;
50
+ private relatedKey;
51
+ constructor(parent: any, related: any, pivotTable: string, foreignPivotKey: string, relatedPivotKey: string, parentKey?: string, relatedKey?: string);
52
+ load(parent: any): Promise<any[]>;
53
+ eagerLoad(parents: any[], relationName: string): Promise<void>;
54
+ attach(id: any, pivot?: Record<string, any>): Promise<void>;
55
+ detach(id?: any): Promise<void>;
56
+ sync(ids: any[]): Promise<void>;
57
+ toggle(ids: any[]): Promise<void>;
58
+ }
@@ -0,0 +1,4 @@
1
+ export { Model, type ModelAttributes, type ModelHooks } from './Model.js';
2
+ export { QueryBuilder, type WhereOperator, type OrderDirection, type JoinType } from './QueryBuilder.js';
3
+ export { Relation, HasOne, HasMany, BelongsTo, BelongsToMany } from './Relationship.js';
4
+ export { ModelObserver, type ModelEventName, MODEL_EVENTS } from './Observer.js';
@@ -0,0 +1 @@
1
+ function v(l,e){let t=Symbol.for(l),s=globalThis;return s[t]||(s[t]=e()),s[t]}var M=class{connections=new Map;config=null;defaultName="default";configure(e){this.config=e,this.defaultName=e.default}async connection(e){let t=e??this.defaultName;if(this.connections.has(t))return this.connections.get(t).drizzle;if(!this.config)throw new Error("Database not configured. Call Connection.configure() first, or register DatabaseServiceProvider.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined in configuration.`);let i=await this.createConnection(s);return this.connections.set(t,i),i.drizzle}async rawClient(e){let t=e??this.defaultName;return await this.connection(t),this.connections.get(t).rawClient}async raw(e,t=[],s){let i=await this.connection(s),n=this.getConfig(s);switch(n.driver){case"sqlite":{let r=await this.rawClient(s),o=t.map(u=>typeof u=="boolean"?u?1:0:u instanceof Date?u.toISOString():u),a=r.prepare(e),d=e.trimStart().toUpperCase();return d.startsWith("SELECT")||d.startsWith("PRAGMA")||d.startsWith("WITH")?a.all(...o):a.run(...o)}case"postgres":return(await this.rawClient(s))(e,...t);case"mysql":{let r=await this.rawClient(s),[o]=await r.execute(e,t);return o}default:throw new Error(`Unsupported driver: ${n.driver}`)}}getDriver(e){return this.getConfig(e).driver}getConfig(e){let t=e??this.defaultName;if(!this.config)throw new Error("Database not configured.");let s=this.config.connections[t];if(!s)throw new Error(`Database connection "${t}" is not defined.`);return s}async disconnect(e){if(e){let t=this.connections.get(e);t&&(await this.closeConnection(t),this.connections.delete(e))}else{for(let[t,s]of this.connections)await this.closeConnection(s);this.connections.clear()}}isConnected(e){return this.connections.has(e??this.defaultName)}async transaction(e,t){let s=this.getConfig(t),i=await this.rawClient(t);switch(s.driver){case"sqlite":{i.exec("BEGIN");try{let n=await e();return i.exec("COMMIT"),n}catch(n){throw i.exec("ROLLBACK"),n}}case"postgres":{await i`BEGIN`;try{let n=await e();return await i`COMMIT`,n}catch(n){throw await i`ROLLBACK`,n}}case"mysql":{let n=await i.getConnection();await n.beginTransaction();try{let r=await e();return await n.commit(),n.release(),r}catch(r){throw await n.rollback(),n.release(),r}}default:throw new Error(`Unsupported driver: ${s.driver}`)}}async createConnection(e){switch(e.driver){case"sqlite":return this.createSQLiteConnection(e);case"postgres":return this.createPostgresConnection(e);case"mysql":return this.createMySQLConnection(e);default:throw new Error(`Unsupported database driver: ${e.driver}`)}}async createSQLiteConnection(e){let t=e.filename??e.database??":memory:";try{let s=(await import("better-sqlite3")).default,{drizzle:i}=await import("drizzle-orm/better-sqlite3"),n=new s(t);return n.pragma("journal_mode = WAL"),n.pragma("foreign_keys = ON"),{drizzle:i(n),config:e,rawClient:n}}catch(s){let i;try{i=(await new Function("mod","return import(mod)")("node:sqlite")).DatabaseSync}catch{throw new Error(`No SQLite driver available. Install better-sqlite3 (npm install better-sqlite3) or use Node.js v22+ which includes built-in SQLite support. Original error: ${s instanceof Error?s.message:String(s)}`)}let n=new i(t);n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA foreign_keys = ON");let r={prepare(a){let d=n.prepare(a);return{all(...u){return d.all(...u)},run(...u){return d.run(...u)},get(...u){return d.get(...u)}}},exec(a){n.exec(a)},pragma(a){return n.prepare(`PRAGMA ${a}`).all()},close(){n.close()}},o;try{let{drizzle:a}=await import("drizzle-orm/better-sqlite3");o=a(r)}catch{o=r}return{drizzle:o,config:e,rawClient:r}}}async createPostgresConnection(e){let t=(await import("postgres")).default,{drizzle:s}=await import("drizzle-orm/postgres-js"),i=e.url??`postgres://${e.user}:${e.password}@${e.host??"localhost"}:${e.port??5432}/${e.database}`,n=t(i);return{drizzle:s(n),config:e,rawClient:n}}async createMySQLConnection(e){let t=await import("mysql2/promise"),{drizzle:s}=await import("drizzle-orm/mysql2"),i=t.createPool({host:e.host??"localhost",port:e.port??3306,database:e.database,user:e.user,password:e.password,uri:e.url});return{drizzle:s(i),config:e,rawClient:i}}async closeConnection(e){try{switch(e.config.driver){case"sqlite":e.rawClient.close();break;case"postgres":await e.rawClient.end();break;case"mysql":await e.rawClient.end();break}}catch{}}},c=v("svelar.connection",()=>new M);var y=class l{tableName;selectColumns=["*"];whereClauses=[];joinClauses=[];orderClauses=[];groupByColumns=[];havingClauses=[];limitValue=null;offsetValue=null;eagerLoads=[];isDistinct=!1;connectionName;cteClauses=[];unionClauses=[];modelClass;constructor(e,t,s){this.tableName=e,this.modelClass=t,this.connectionName=s}select(...e){return this.selectColumns=e.length>0?e:["*"],this}addSelect(...e){return this.selectColumns[0]==="*"?this.selectColumns=e:this.selectColumns.push(...e),this}distinct(){return this.isDistinct=!0,this}from(e){return this.tableName=e,this}where(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"AND"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}orWhere(e,t,s){return s===void 0?this.whereClauses.push({type:"basic",column:e,operator:"=",value:t,boolean:"OR"}):this.whereClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"OR"}),this}whereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"AND"}),this}whereNotIn(e,t){return this.whereClauses.push({type:"notIn",column:e,values:t,boolean:"AND"}),this}whereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"AND"}),this}whereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"AND"}),this}whereBetween(e,t){return this.whereClauses.push({type:"between",column:e,values:t,boolean:"AND"}),this}whereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}whereNested(e,t="AND"){let s=new l(this.tableName,this.modelClass,this.connectionName);if(e(s),s.whereClauses.length>0){let{whereSQL:i,whereBindings:n}=s.buildWhere(),r=i.replace(/^WHERE /,"");this.whereClauses.push({type:"raw",raw:`(${r})`,values:n,boolean:t})}return this}orWhereNested(e){return this.whereNested(e,"OR")}whereExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:i}=t.toSQL();return this.whereClauses.push({type:"exists",subSQL:s,subBindings:i,boolean:"AND"}),this}whereNotExists(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:i}=t.toSQL();return this.whereClauses.push({type:"notExists",subSQL:s,subBindings:i,boolean:"AND"}),this}whereSub(e,t,s){let i=new l("__placeholder__",void 0,this.connectionName);s(i);let{sql:n,bindings:r}=i.toSQL();return this.whereClauses.push({type:"sub",column:e,operator:t,subSQL:n,subBindings:r,boolean:"AND"}),this}orWhereRaw(e,t=[]){return this.whereClauses.push({type:"raw",raw:e,values:t,boolean:"OR"}),this}orWhereIn(e,t){return this.whereClauses.push({type:"in",column:e,values:t,boolean:"OR"}),this}orWhereNull(e){return this.whereClauses.push({type:"null",column:e,boolean:"OR"}),this}orWhereNotNull(e){return this.whereClauses.push({type:"notNull",column:e,boolean:"OR"}),this}withCTE(e,t,s=!1){let i=new l("__placeholder__",void 0,this.connectionName);t(i);let{sql:n,bindings:r}=i.toSQL();return this.cteClauses.push({name:e,sql:n,bindings:r,recursive:s}),this}withRecursiveCTE(e,t){return this.withCTE(e,t,!0)}withRawCTE(e,t,s=[],i=!1){return this.cteClauses.push({name:e,sql:t,bindings:s,recursive:i}),this}union(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:i}=t.toSQL();return this.unionClauses.push({sql:s,bindings:i,all:!1}),this}unionAll(e){let t=new l("__placeholder__",void 0,this.connectionName);e(t);let{sql:s,bindings:i}=t.toSQL();return this.unionClauses.push({sql:s,bindings:i,all:!0}),this}join(e,t,s,i){return this.joinClauses.push({type:"INNER",table:e,first:t,operator:s,second:i}),this}leftJoin(e,t,s,i){return this.joinClauses.push({type:"LEFT",table:e,first:t,operator:s,second:i}),this}rightJoin(e,t,s,i){return this.joinClauses.push({type:"RIGHT",table:e,first:t,operator:s,second:i}),this}crossJoin(e){return this.joinClauses.push({type:"CROSS",table:e,first:"",operator:"",second:""}),this}orderBy(e,t="asc"){return this.orderClauses.push({column:e,direction:t}),this}latest(e="created_at"){return this.orderBy(e,"desc")}oldest(e="created_at"){return this.orderBy(e,"asc")}groupBy(...e){return this.groupByColumns.push(...e),this}having(e,t,s){return this.havingClauses.push({type:"basic",column:e,operator:t,value:s,boolean:"AND"}),this}limit(e){return this.limitValue=e,this}offset(e){return this.offsetValue=e,this}take(e){return this.limit(e)}skip(e){return this.offset(e)}with(...e){return this.eagerLoads.push(...e),this}async get(){let{sql:e,bindings:t}=this.toSQL(),s=await c.raw(e,t,this.connectionName),i=this.hydrateMany(s);return this.eagerLoads.length>0&&this.modelClass&&await this.loadRelations(i),i}async first(){return this.limitValue=1,(await this.get())[0]??null}async firstOrFail(){let e=await this.first();if(!e)throw new Error(`No results found for query on "${this.tableName}".`);return e}async find(e,t="id"){return this.where(t,e).first()}async findOrFail(e,t="id"){return this.where(t,e).firstOrFail()}async count(e="*"){let{sql:t,bindings:s}=this.buildAggregate(`COUNT(${e})`),i=await c.raw(t,s,this.connectionName);return Number(i[0]?.aggregate??0)}async sum(e){let{sql:t,bindings:s}=this.buildAggregate(`SUM(${e})`),i=await c.raw(t,s,this.connectionName);return Number(i[0]?.aggregate??0)}async avg(e){let{sql:t,bindings:s}=this.buildAggregate(`AVG(${e})`),i=await c.raw(t,s,this.connectionName);return Number(i[0]?.aggregate??0)}async max(e){let{sql:t,bindings:s}=this.buildAggregate(`MAX(${e})`);return(await c.raw(t,s,this.connectionName))[0]?.aggregate??null}async min(e){let{sql:t,bindings:s}=this.buildAggregate(`MIN(${e})`);return(await c.raw(t,s,this.connectionName))[0]?.aggregate??null}async exists(){return await this.count()>0}async doesntExist(){return!await this.exists()}async pluck(e){return this.selectColumns=[e],(await c.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName)).map(s=>s[e])}async value(e){return this.selectColumns=[e],this.limitValue=1,(await c.raw(this.toSQL().sql,this.toSQL().bindings,this.connectionName))[0]?.[e]??null}async chunk(e,t){let s=1,i=!0;for(;i;){let n=this.clone();n.limitValue=e,n.offsetValue=(s-1)*e;let r=await n.get();if(r.length===0||await t(r,s)===!1||r.length<e)break;s++}}when(e,t){return e&&t(this),this}selectRaw(e){return this.selectColumns[0]==="*"?this.selectColumns=[e]:this.selectColumns.push(e),this}async upsert(e,t,s){let i=c.getDriver(this.connectionName),n=Object.keys(e),r=Object.values(e),o=r.map(()=>"?").join(", "),a=s??n.filter(u=>!t.includes(u)),d;if(i==="postgres"){let u=a.map(h=>`${h} = EXCLUDED.${h}`).join(", ");d=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}else if(i==="mysql"){let u=a.map(h=>`${h} = VALUES(${h})`).join(", ");d=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON DUPLICATE KEY UPDATE ${u}`}else{let u=a.map(h=>`${h} = excluded.${h}`).join(", ");d=`INSERT INTO ${this.tableName} (${n.join(", ")}) VALUES (${o}) ON CONFLICT (${t.join(", ")}) DO UPDATE SET ${u}`}return c.raw(d,r,this.connectionName)}async insertMany(e){if(e.length===0)return;let t=Object.keys(e[0]),s=[],i=[];for(let r of e){let o=t.map(a=>r[a]);s.push(...o),i.push(`(${o.map(()=>"?").join(", ")})`)}let n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES ${i.join(", ")}`;return c.raw(n,s,this.connectionName)}async firstOrCreate(e,t={}){for(let[r,o]of Object.entries(e))this.where(r,o);let s=await this.first();if(s)return s;let i={...e,...t},n=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(i);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(n)}async updateOrCreate(e,t){let s=new l(this.tableName,this.modelClass,this.connectionName);for(let[o,a]of Object.entries(e))s.where(o,a);let i=await s.first();if(i)return await new l(this.tableName,this.modelClass,this.connectionName).where(this.modelClass?.primaryKey??"id",i[this.modelClass?.primaryKey??"id"]).update(t),new l(this.tableName,this.modelClass,this.connectionName).findOrFail(i[this.modelClass?.primaryKey??"id"]);let n={...e,...t},r=await new l(this.tableName,this.modelClass,this.connectionName).insertGetId(n);return new l(this.tableName,this.modelClass,this.connectionName).findOrFail(r)}whereColumn(e,t,s){return s===void 0?this.whereClauses.push({type:"raw",raw:`${e} = ${t}`,values:[],boolean:"AND"}):this.whereClauses.push({type:"raw",raw:`${e} ${t} ${s}`,values:[],boolean:"AND"}),this}havingRaw(e,t=[]){return this.havingClauses.push({type:"raw",raw:e,values:t,boolean:"AND"}),this}orderByRaw(e){return this.orderClauses.push({column:e,direction:"asc"}),this.orderClauses[this.orderClauses.length-1].__raw=!0,this}selectSub(e,t){let s=new l("__placeholder__",void 0,this.connectionName);e(s);let{sql:i,bindings:n}=s.toSQL(),r=`(${i}) as ${t}`;return this.selectColumns[0]==="*"?this.selectColumns=[r]:this.selectColumns.push(r),this._selectBindings||(this._selectBindings=[]),this._selectBindings.push(...n),this}_selectBindings;async truncate(){c.getDriver(this.connectionName)==="sqlite"?(await c.raw(`DELETE FROM ${this.tableName}`,[],this.connectionName),await c.raw("DELETE FROM sqlite_sequence WHERE name = ?",[this.tableName],this.connectionName)):await c.raw(`TRUNCATE TABLE ${this.tableName}`,[],this.connectionName)}async paginate(e=1,t=15){let s=await this.clone().count(),i=Math.ceil(s/t);return this.limitValue=t,this.offsetValue=(e-1)*t,{data:await this.get(),total:s,page:e,perPage:t,lastPage:i,hasMore:e<i}}async insert(e){let t=Object.keys(e),s=Object.values(e),i=s.map(()=>"?").join(", "),n=`INSERT INTO ${this.tableName} (${t.join(", ")}) VALUES (${i})`;return c.raw(n,s,this.connectionName)}async insertGetId(e,t="id"){let s=c.getDriver(this.connectionName),i=Object.keys(e),n=Object.values(e),r=n.map(()=>"?").join(", "),o=`INSERT INTO ${this.tableName} (${i.join(", ")}) VALUES (${r})`;return s==="postgres"?(o+=` RETURNING ${t}`,(await c.raw(o,n,this.connectionName))[0]?.[t]):(await c.raw(o,n,this.connectionName),s==="sqlite"?(await c.raw("SELECT last_insert_rowid() as id",[],this.connectionName))[0]?.id:s==="mysql"?(await c.raw("SELECT LAST_INSERT_ID() as id",[],this.connectionName))[0]?.id:0)}async update(e){let t=Object.keys(e),s=Object.values(e),i=t.map(a=>`${a} = ?`).join(", "),{whereSQL:n,whereBindings:r}=this.buildWhere(),o=`UPDATE ${this.tableName} SET ${i}${n}`;return await c.raw(o,[...s,...r],this.connectionName),1}async delete(){let{whereSQL:e,whereBindings:t}=this.buildWhere(),s=`DELETE FROM ${this.tableName}${e}`;return await c.raw(s,t,this.connectionName),1}async increment(e,t=1){let{whereSQL:s,whereBindings:i}=this.buildWhere(),n=`UPDATE ${this.tableName} SET ${e} = ${e} + ?${s}`;await c.raw(n,[t,...i],this.connectionName)}async decrement(e,t=1){return this.increment(e,-t)}toSQL(){let e=[],t=[];if(this.cteClauses.length>0){let o=this.cteClauses.some(d=>d.recursive)?"WITH RECURSIVE":"WITH",a=this.cteClauses.map(d=>(t.push(...d.bindings),`${d.name} AS (${d.sql})`));e.push(`${o} ${a.join(", ")}`)}this._selectBindings?.length&&t.push(...this._selectBindings);let s=this.isDistinct?"DISTINCT ":"";e.push(`SELECT ${s}${this.selectColumns.join(", ")}`),e.push(`FROM ${this.tableName}`);for(let r of this.joinClauses)r.type==="CROSS"?e.push(`CROSS JOIN ${r.table}`):e.push(`${r.type} JOIN ${r.table} ON ${r.first} ${r.operator} ${r.second}`);let{whereSQL:i,whereBindings:n}=this.buildWhere();if(i&&(e.push(i.trim()),t.push(...n)),this.groupByColumns.length>0&&e.push(`GROUP BY ${this.groupByColumns.join(", ")}`),this.havingClauses.length>0){let r=[];for(let o of this.havingClauses)o.type==="raw"?(r.push(o.raw),o.values&&t.push(...o.values)):(r.push(`${o.column} ${o.operator} ?`),t.push(o.value));e.push(`HAVING ${r.join(" AND ")}`)}if(this.orderClauses.length>0){let r=this.orderClauses.map(o=>o.__raw?o.column:`${o.column} ${o.direction.toUpperCase()}`);e.push(`ORDER BY ${r.join(", ")}`)}if(this.limitValue!==null&&e.push(`LIMIT ${this.limitValue}`),this.offsetValue!==null&&e.push(`OFFSET ${this.offsetValue}`),this.unionClauses.length>0)for(let r of this.unionClauses)e.push(r.all?"UNION ALL":"UNION"),e.push(r.sql),t.push(...r.bindings);return{sql:e.join(" "),bindings:t}}clone(){let e=new l(this.tableName,this.modelClass,this.connectionName);return e.selectColumns=[...this.selectColumns],e.whereClauses=[...this.whereClauses],e.joinClauses=[...this.joinClauses],e.orderClauses=[...this.orderClauses],e.groupByColumns=[...this.groupByColumns],e.havingClauses=[...this.havingClauses],e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.eagerLoads=[...this.eagerLoads],e.isDistinct=this.isDistinct,e.cteClauses=[...this.cteClauses],e.unionClauses=[...this.unionClauses],e}buildWhere(){if(this.whereClauses.length===0)return{whereSQL:"",whereBindings:[]};let e=[],t=[];for(let s=0;s<this.whereClauses.length;s++){let i=this.whereClauses[s],n=s===0?"WHERE":i.boolean;switch(i.type){case"basic":if((i.operator==="IS"||i.operator==="IS NOT")&&i.value===null){let a=(i.operator==="IS","null");e.push(`${n} ${i.column} ${i.operator} ${a}`)}else e.push(`${n} ${i.column} ${i.operator} ?`),t.push(i.value);break;case"in":let r=i.values.map(()=>"?").join(", ");e.push(`${n} ${i.column} IN (${r})`),t.push(...i.values);break;case"notIn":let o=i.values.map(()=>"?").join(", ");e.push(`${n} ${i.column} NOT IN (${o})`),t.push(...i.values);break;case"null":e.push(`${n} ${i.column} IS NULL`);break;case"notNull":e.push(`${n} ${i.column} IS NOT NULL`);break;case"between":e.push(`${n} ${i.column} BETWEEN ? AND ?`),t.push(i.values[0],i.values[1]);break;case"raw":e.push(`${n} ${i.raw}`),i.values&&t.push(...i.values);break;case"exists":e.push(`${n} EXISTS (${i.subSQL})`),i.subBindings&&t.push(...i.subBindings);break;case"notExists":e.push(`${n} NOT EXISTS (${i.subSQL})`),i.subBindings&&t.push(...i.subBindings);break;case"sub":e.push(`${n} ${i.column} ${i.operator} (${i.subSQL})`),i.subBindings&&t.push(...i.subBindings);break}}return{whereSQL:e.join(" "),whereBindings:t}}buildAggregate(e){let t=this.selectColumns;this.selectColumns=[`${e} as aggregate`];let s=this.toSQL();return this.selectColumns=t,s}hydrateMany(e){return this.modelClass?e.map(t=>this.modelClass.hydrate(t)):e}async loadRelations(e){if(!(!this.modelClass||e.length===0))for(let t of this.eagerLoads){let i=new this.modelClass()[t]?.();i&&typeof i.eagerLoad=="function"&&await i.eagerLoad(e,t)}}};var g=class{parentModel;relatedModel;constructor(e,t){this.parentModel=e,this.relatedModel=t}query(){return this.relatedModel.query()}},m=class extends g{constructor(t,s,i,n="id"){super(t,s);this.foreignKey=i;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).first()}async eagerLoad(t,s){let i=t.map(o=>o.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,i).get(),r=new Map;for(let o of n)r.set(o.getAttribute(this.foreignKey),o);for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,r.get(a)??null)}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}},b=class extends g{constructor(t,s,i,n="id"){super(t,s);this.foreignKey=i;this.localKey=n}async load(t){let s=t.getAttribute(this.localKey);return this.relatedModel.query().where(this.foreignKey,s).get()}async eagerLoad(t,s){let i=t.map(o=>o.getAttribute(this.localKey)),n=await this.relatedModel.query().whereIn(this.foreignKey,i).get(),r=new Map;for(let o of n){let a=o.getAttribute(this.foreignKey);r.has(a)||r.set(a,[]),r.get(a).push(o)}for(let o of t){let a=o.getAttribute(this.localKey);o.setRelation(s,r.get(a)??[])}}async create(t){let s=this.parentModel.getAttribute(this.localKey);return this.relatedModel.create({...t,[this.foreignKey]:s})}async createMany(t){let s=[];for(let i of t)s.push(await this.create(i));return s}},f=class extends g{constructor(t,s,i,n="id"){super(t,s);this.foreignKey=i;this.ownerKey=n}async load(t){let s=t.getAttribute(this.foreignKey);return s==null?null:this.relatedModel.query().where(this.ownerKey,s).first()}async eagerLoad(t,s){let i=t.map(o=>o.getAttribute(this.foreignKey)).filter(o=>o!=null);if(i.length===0){for(let o of t)o.setRelation(s,null);return}let n=await this.relatedModel.query().whereIn(this.ownerKey,i).get(),r=new Map;for(let o of n)r.set(o.getAttribute(this.ownerKey),o);for(let o of t){let a=o.getAttribute(this.foreignKey);o.setRelation(s,r.get(a)??null)}}associate(t){return this.parentModel.setAttribute(this.foreignKey,t.getAttribute(this.ownerKey)),this.parentModel}dissociate(){return this.parentModel.setAttribute(this.foreignKey,null),this.parentModel}},w=class extends g{constructor(t,s,i,n,r,o="id",a="id"){super(t,s);this.pivotTable=i;this.foreignPivotKey=n;this.relatedPivotKey=r;this.parentKey=o;this.relatedKey=a}async load(t){let s=t.getAttribute(this.parentKey),i=this.relatedModel.tableName,r=(await c.raw(`SELECT ${this.relatedPivotKey} FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])).map(o=>o[this.relatedPivotKey]);return r.length===0?[]:this.relatedModel.query().whereIn(this.relatedKey,r).get()}async eagerLoad(t,s){let i=t.map(h=>h.getAttribute(this.parentKey));if(i.length===0){for(let h of t)h.setRelation(s,[]);return}let n=i.map(()=>"?").join(", "),r=await c.raw(`SELECT * FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} IN (${n})`,i),o=[...new Set(r.map(h=>h[this.relatedPivotKey]))],a=o.length>0?await this.relatedModel.query().whereIn(this.relatedKey,o).get():[],d=new Map;for(let h of a)d.set(h.getAttribute(this.relatedKey),h);let u=new Map;for(let h of r){let p=h[this.foreignPivotKey],A=h[this.relatedPivotKey],L=d.get(A);L&&(u.has(p)||u.set(p,[]),u.get(p).push(L))}for(let h of t){let p=h.getAttribute(this.parentKey);h.setRelation(s,u.get(p)??[])}}async attach(t,s){let i=this.parentModel.getAttribute(this.parentKey),n={[this.foreignPivotKey]:i,[this.relatedPivotKey]:t,...s},r=Object.keys(n),o=Object.values(n),a=o.map(()=>"?").join(", ");await c.raw(`INSERT INTO ${this.pivotTable} (${r.join(", ")}) VALUES (${a})`,o)}async detach(t){let s=this.parentModel.getAttribute(this.parentKey);t?await c.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ?`,[s,t]):await c.raw(`DELETE FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ?`,[s])}async sync(t){await this.detach();for(let s of t)await this.attach(s)}async toggle(t){let s=this.parentModel.getAttribute(this.parentKey);for(let i of t)(await c.raw(`SELECT 1 FROM ${this.pivotTable} WHERE ${this.foreignPivotKey} = ? AND ${this.relatedPivotKey} = ? LIMIT 1`,[s,i])).length>0?await this.detach(i):await this.attach(i)}};var T=class{listeners=new Map;wildcardListeners=[];onceListeners=new Map;listen(e,t){let s=typeof e=="string"?e:e.name;return this.listeners.has(s)||this.listeners.set(s,[]),this.listeners.get(s).push(t),()=>{let i=this.listeners.get(s);if(i){let n=i.indexOf(t);n>=0&&i.splice(n,1)}}}once(e,t){let s=typeof e=="string"?e:e.name;return this.onceListeners.has(s)||this.onceListeners.set(s,[]),this.onceListeners.get(s).push(t),()=>{let i=this.onceListeners.get(s);if(i){let n=i.indexOf(t);n>=0&&i.splice(n,1)}}}onAny(e){return this.wildcardListeners.push(e),()=>{let t=this.wildcardListeners.indexOf(e);t>=0&&this.wildcardListeners.splice(t,1)}}async dispatch(e){let t=e.constructor.name,s=this.listeners.get(t)??[];for(let n of s)await n(e);let i=this.onceListeners.get(t)??[];for(let n of i)await n(e);this.onceListeners.delete(t);for(let n of this.wildcardListeners)await n(t,e)}async emit(e,t){let s=this.listeners.get(e)??[];for(let n of s)await n(t);let i=this.onceListeners.get(e)??[];for(let n of i)await n(t);this.onceListeners.delete(e);for(let n of this.wildcardListeners)await n(e,t)}subscribe(e){e.subscribe(this)}forget(e){let t=typeof e=="string"?e:e.name;this.listeners.delete(t),this.onceListeners.delete(t)}flush(){this.listeners.clear(),this.onceListeners.clear(),this.wildcardListeners=[]}hasListeners(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)>0||(this.onceListeners.get(t)?.length??0)>0||this.wildcardListeners.length>0}listenerCount(e){let t=typeof e=="string"?e:e.name;return(this.listeners.get(t)?.length??0)+(this.onceListeners.get(t)?.length??0)}},C=v("svelar.event",()=>new T);var N=class l{static table;static primaryKey="id";static incrementing=!0;static timestamps=!0;static createdAt="created_at";static updatedAt="updated_at";static casts={};static fillable=[];static hidden=[];static connection=void 0;static hooks=new Map;static observers=new Map;static events=[];attributes={};originalAttributes={};relations={};exists=!1;constructor(e){return e&&this.fill(e),new Proxy(this,{get(t,s,i){return typeof s=="symbol"||s in t||typeof s!="string"||["table","primaryKey","incrementing","timestamps","casts","fillable","hidden","connection"].includes(s)?Reflect.get(t,s,i):typeof t[s]=="function"?t[s].bind(t):t.getAttribute(s)},set(t,s,i){return typeof s=="symbol"||s in t?Reflect.set(t,s,i):(t.setAttribute(s,i),!0)}})}static query(){let e=new this,t=this;return new y(t.table,this,t.connection)}static async find(e){let t=this;return this.query().find(e,t.primaryKey)}static async findOrFail(e){let t=this;return this.query().findOrFail(e,t.primaryKey)}static async all(){return this.query().get()}static async first(){return this.query().first()}static async firstOrFail(){return this.query().firstOrFail()}static where(e,t,s){return this.query().where(e,t,s)}static whereIn(e,t){return this.query().whereIn(e,t)}static whereNull(e){return this.query().whereNull(e)}static whereNotNull(e){return this.query().whereNotNull(e)}static orderBy(e,t){return this.query().orderBy(e,t)}static latest(e){return this.query().latest(e)}static oldest(e){return this.query().oldest(e)}static with(...e){return this.query().with(...e)}static async count(){return this.query().count()}static async create(e){let t=new this,s=this;if(t.fill(e),await t.fireHook("creating"),await t.fireHook("saving"),s.timestamps){let o=new Date().toISOString();t.setAttribute(s.createdAt,o),t.setAttribute(s.updatedAt,o)}let i=t.getInsertableAttributes(),r=await new y(s.table,this,s.connection).insertGetId(i,s.primaryKey);return s.incrementing&&r&&t.setAttribute(s.primaryKey,r),t.syncOriginal(),t.exists=!0,await t.fireHook("created"),await t.fireHook("saved"),t}async save(){let e=this.constructor;if(this.exists){await this.fireHook("updating"),await this.fireHook("saving"),e.timestamps&&this.setAttribute(e.updatedAt,new Date().toISOString());let t=this.getDirty();if(Object.keys(t).length>0){let s=this.getAttribute(e.primaryKey);await new y(e.table,this.constructor,e.connection).where(e.primaryKey,s).update(t)}this.syncOriginal(),await this.fireHook("updated"),await this.fireHook("saved")}else{if(await this.fireHook("creating"),await this.fireHook("saving"),e.timestamps){let n=new Date().toISOString();this.getAttribute(e.createdAt)||this.setAttribute(e.createdAt,n),this.setAttribute(e.updatedAt,n)}let t=this.getInsertableAttributes(),i=await new y(e.table,this.constructor,e.connection).insertGetId(t,e.primaryKey);e.incrementing&&i&&this.setAttribute(e.primaryKey,i),this.syncOriginal(),this.exists=!0,await this.fireHook("created"),await this.fireHook("saved")}}async update(e){this.fill(e),await this.save()}async delete(){let e=this.constructor;await this.fireHook("deleting");let t=this.getAttribute(e.primaryKey);await new y(e.table,this.constructor,e.connection).where(e.primaryKey,t).delete(),this.exists=!1,await this.fireHook("deleted")}async refresh(){let e=this.constructor,t=this.getAttribute(e.primaryKey),s=await this.constructor.find(t);s&&(this.attributes={...s.attributes},this.syncOriginal())}getAttribute(e){let t=this.constructor,s=this.attributes[e],i=t.casts[e];if(i&&s!==void 0&&s!==null)switch(i){case"number":return Number(s);case"boolean":return!!s;case"string":return String(s);case"date":return new Date(s);case"json":return typeof s=="string"?JSON.parse(s):s}return s}setAttribute(e,t){this.constructor.casts[e]==="json"&&typeof t!="string"?this.attributes[e]=JSON.stringify(t):this.attributes[e]=t}fill(e){let t=this.constructor;for(let[s,i]of Object.entries(e))t.fillable.length>0&&!t.fillable.includes(s)||this.setAttribute(s,i)}getAttributes(){return{...this.attributes}}getOriginal(e){return e?this.originalAttributes[e]:{...this.originalAttributes}}getDirty(){let e={};for(let[t,s]of Object.entries(this.attributes))s!==this.originalAttributes[t]&&(e[t]=s);return e}isDirty(...e){let t=this.getDirty();return e.length===0?Object.keys(t).length>0:e.some(s=>s in t)}isClean(...e){return!this.isDirty(...e)}wasChanged(...e){return this.isDirty(...e)}hasOne(e,t,s){return new m(this,e,t,s??this.constructor.primaryKey)}hasMany(e,t,s){return new b(this,e,t,s??this.constructor.primaryKey)}belongsTo(e,t,s){return new f(this,e,t,s??e.primaryKey)}belongsToMany(e,t,s,i,n,r){return new w(this,e,t,s,i,n??this.constructor.primaryKey,r??e.primaryKey)}setRelation(e,t){this.relations[e]=t}getRelation(e){return this.relations[e]}relationLoaded(e){return e in this.relations}toJSON(){let e=this.constructor,t={};for(let[s,i]of Object.entries(this.attributes))e.hidden.includes(s)||(t[s]=this.getAttribute(s));for(let[s,i]of Object.entries(this.relations))Array.isArray(i)?t[s]=i.map(n=>n instanceof l?n.toJSON():n):i instanceof l?t[s]=i.toJSON():t[s]=i;return t}toObject(){return this.toJSON()}static hydrate(e){let t=new this;return t.attributes={...e},t.syncOriginal(),t.exists=!0,t}static boot(e){this.hooks.set(this.name,e)}static observe(e){let t=this.observers.get(this.name)??[];t.push(e),this.observers.set(this.name,t)}static removeObservers(){this.observers.delete(this.name)}async fireHook(e){let t=this.constructor,s=l.hooks.get(t.name);s?.[e]&&await s[e](this),typeof this[e]=="function"&&await this[e]();let i=l.observers.get(t.name)??[];for(let r of i){let o=r[e];typeof o=="function"&&await o.call(r,this)}let n=t.name.toLowerCase();await C.emit(`${n}.${e}`,this)}async fireEvent(e){let t=this.constructor;if(!t.events.includes(e))throw new Error(`Event "${e}" is not declared in ${t.name}.events. Add it to: static events = ['${e}', ...];`);let s=l.observers.get(t.name)??[];for(let n of s){let r=n[e];typeof r=="function"&&await r.call(n,this)}let i=t.name.toLowerCase();await C.emit(`${i}.${e}`,this)}syncOriginal(){this.originalAttributes={...this.attributes}}getInsertableAttributes(){let e=this.constructor,t={...this.attributes};return e.incrementing&&t[e.primaryKey]===void 0&&delete t[e.primaryKey],t}static get tableName(){return this.table}};var $=["creating","created","updating","updated","saving","saved","deleting","deleted"],E=class{};export{f as BelongsTo,w as BelongsToMany,b as HasMany,m as HasOne,$ as MODEL_EVENTS,N as Model,E as ModelObserver,y as QueryBuilder,g as Relation};
@@ -0,0 +1,8 @@
1
+ export interface PaginationResult<T> {
2
+ data: T[];
3
+ total: number;
4
+ page: number;
5
+ perPage: number;
6
+ lastPage: number;
7
+ hasMore: boolean;
8
+ }
File without changes
@@ -0,0 +1,99 @@
1
+ /**
2
+ * GeneratePdfJob — Queue job for async PDF generation
3
+ *
4
+ * Dispatches PDF generation to a background worker instead of blocking
5
+ * the request. Works with any Svelar queue driver (sync, memory, database).
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Queue } from 'svelar/queue';
10
+ * import { GeneratePdfJob } from 'svelar/pdf/GeneratePdfJob';
11
+ *
12
+ * // Register once in src/app.ts
13
+ * Queue.register(GeneratePdfJob);
14
+ *
15
+ * // Dispatch from a controller
16
+ * await Queue.dispatch(new GeneratePdfJob({
17
+ * type: 'html',
18
+ * content: '<h1>Invoice</h1><p>Total: $99</p>',
19
+ * outputPath: 'storage/invoices/inv-001.pdf',
20
+ * options: { margins: { top: '1in', bottom: '1in' } },
21
+ * }));
22
+ *
23
+ * // With webhook (fires and forgets to Gotenberg)
24
+ * await Queue.dispatch(new GeneratePdfJob({
25
+ * type: 'url',
26
+ * content: 'https://example.com/report',
27
+ * webhook: {
28
+ * url: 'https://myapp.com/api/pdf/webhook',
29
+ * errorUrl: 'https://myapp.com/api/pdf/webhook-error',
30
+ * },
31
+ * }));
32
+ * ```
33
+ */
34
+ export interface PdfJobPayload {
35
+ /** Type of conversion */
36
+ type: 'html' | 'url' | 'markdown' | 'office';
37
+ /** The HTML string, URL, markdown string, or file path */
38
+ content: string;
39
+ /** Optional file path to save the result (sync mode) */
40
+ outputPath?: string;
41
+ /** PDF options */
42
+ options?: {
43
+ margins?: {
44
+ top?: string;
45
+ bottom?: string;
46
+ left?: string;
47
+ right?: string;
48
+ };
49
+ landscape?: boolean;
50
+ scale?: number;
51
+ headerHtml?: string;
52
+ footerHtml?: string;
53
+ printBackground?: boolean;
54
+ waitDelay?: string;
55
+ waitForExpression?: string;
56
+ pdfFormat?: string;
57
+ pageSize?: {
58
+ width?: string;
59
+ height?: string;
60
+ };
61
+ };
62
+ /** Webhook options for async Gotenberg processing */
63
+ webhook?: {
64
+ url: string;
65
+ errorUrl: string;
66
+ method?: 'POST' | 'PUT' | 'PATCH';
67
+ extraHeaders?: Record<string, string>;
68
+ };
69
+ /** Callback event name to broadcast on completion (optional) */
70
+ broadcastEvent?: string;
71
+ /** Broadcast channel for completion notification (optional) */
72
+ broadcastChannel?: string;
73
+ /** Arbitrary metadata to pass through to webhook/broadcast */
74
+ meta?: Record<string, any>;
75
+ }
76
+ /**
77
+ * A queue job that generates a PDF using the Svelar PDF module.
78
+ *
79
+ * Supports sync generation (with file storage) and async webhook mode.
80
+ * Optionally broadcasts a completion event so the client can react.
81
+ */
82
+ export declare class GeneratePdfJob {
83
+ payload: PdfJobPayload;
84
+ /** Queue job name for serialization */
85
+ static readonly jobName = "GeneratePdfJob";
86
+ /** Max retry attempts */
87
+ maxAttempts: number;
88
+ /** Retry delay in seconds */
89
+ retryDelay: number;
90
+ /** Queue name */
91
+ queue: string;
92
+ constructor(payload: PdfJobPayload);
93
+ handle(): Promise<void>;
94
+ failed(error: Error): void;
95
+ /** Serialize for database queue driver */
96
+ serialize(): Record<string, any>;
97
+ /** Restore from database queue driver */
98
+ restore(data: Record<string, any>): void;
99
+ }