bunsane 0.1.0 โ†’ 0.1.2

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 (82) hide show
  1. package/.github/workflows/deploy-docs.yml +57 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +2 -28
  4. package/TODO.md +8 -1
  5. package/bun.lock +3 -0
  6. package/config/upload.config.ts +135 -0
  7. package/core/App.ts +168 -4
  8. package/core/ArcheType.ts +122 -0
  9. package/core/BatchLoader.ts +100 -0
  10. package/core/ComponentRegistry.ts +4 -3
  11. package/core/Components.ts +2 -2
  12. package/core/Decorators.ts +15 -8
  13. package/core/Entity.ts +193 -14
  14. package/core/EntityCache.ts +15 -0
  15. package/core/EntityHookManager.ts +855 -0
  16. package/core/EntityManager.ts +12 -2
  17. package/core/ErrorHandler.ts +64 -7
  18. package/core/FileValidator.ts +284 -0
  19. package/core/Query.ts +503 -85
  20. package/core/RequestContext.ts +24 -0
  21. package/core/RequestLoaders.ts +89 -0
  22. package/core/SchedulerManager.ts +710 -0
  23. package/core/UploadManager.ts +261 -0
  24. package/core/components/UploadComponent.ts +206 -0
  25. package/core/decorators/EntityHooks.ts +190 -0
  26. package/core/decorators/ScheduledTask.ts +83 -0
  27. package/core/events/EntityLifecycleEvents.ts +177 -0
  28. package/core/processors/ImageProcessor.ts +423 -0
  29. package/core/storage/LocalStorageProvider.ts +290 -0
  30. package/core/storage/StorageProvider.ts +112 -0
  31. package/database/DatabaseHelper.ts +183 -58
  32. package/database/index.ts +5 -5
  33. package/database/sqlHelpers.ts +7 -0
  34. package/docs/README.md +149 -0
  35. package/docs/_coverpage.md +36 -0
  36. package/docs/_sidebar.md +23 -0
  37. package/docs/api/core.md +568 -0
  38. package/docs/api/hooks.md +554 -0
  39. package/docs/api/index.md +222 -0
  40. package/docs/api/query.md +678 -0
  41. package/docs/api/service.md +744 -0
  42. package/docs/core-concepts/archetypes.md +512 -0
  43. package/docs/core-concepts/components.md +498 -0
  44. package/docs/core-concepts/entity.md +314 -0
  45. package/docs/core-concepts/hooks.md +683 -0
  46. package/docs/core-concepts/query.md +588 -0
  47. package/docs/core-concepts/services.md +647 -0
  48. package/docs/examples/code-examples.md +425 -0
  49. package/docs/getting-started.md +337 -0
  50. package/docs/index.html +97 -0
  51. package/gql/Generator.ts +58 -35
  52. package/gql/decorators/Upload.ts +176 -0
  53. package/gql/helpers.ts +67 -0
  54. package/gql/index.ts +65 -31
  55. package/gql/types.ts +1 -1
  56. package/index.ts +79 -11
  57. package/package.json +19 -10
  58. package/rest/Generator.ts +3 -0
  59. package/rest/index.ts +22 -0
  60. package/service/Service.ts +1 -1
  61. package/service/ServiceRegistry.ts +10 -6
  62. package/service/index.ts +12 -1
  63. package/tests/bench/insert.bench.ts +59 -0
  64. package/tests/bench/relations.bench.ts +269 -0
  65. package/tests/bench/sorting.bench.ts +415 -0
  66. package/tests/component-hooks.test.ts +1409 -0
  67. package/tests/component.test.ts +338 -0
  68. package/tests/errorHandling.test.ts +155 -0
  69. package/tests/hooks.test.ts +666 -0
  70. package/tests/query-sorting.test.ts +101 -0
  71. package/tests/relations.test.ts +169 -0
  72. package/tests/scheduler.test.ts +724 -0
  73. package/tsconfig.json +35 -34
  74. package/types/graphql.types.ts +87 -0
  75. package/types/hooks.types.ts +141 -0
  76. package/types/scheduler.types.ts +165 -0
  77. package/types/upload.types.ts +184 -0
  78. package/upload/index.ts +140 -0
  79. package/utils/UploadHelper.ts +305 -0
  80. package/utils/cronParser.ts +366 -0
  81. package/utils/errorMessages.ts +151 -0
  82. package/core/Events.ts +0 -0
@@ -0,0 +1,425 @@
1
+ # Code Examples
2
+
3
+ This section contains practical, runnable examples that demonstrate BunSane's capabilities. Each example includes complete code that you can copy and run in your own project.
4
+
5
+ ## ๐Ÿš€ Quick Start Example
6
+
7
+ Here's a complete example showing how to create a user management system with BunSane:
8
+
9
+ ### Project Setup
10
+
11
+ ```bash
12
+ # Create a new project
13
+ mkdir bunsane-user-app
14
+ cd bunsane-user-app
15
+
16
+ # Initialize with Bun
17
+ bun init -y
18
+
19
+ # Install BunSane
20
+ bun add bunsane
21
+
22
+ # Create project structure
23
+ mkdir -p src/services
24
+ ```
25
+
26
+ ### 1. Define Components
27
+
28
+ ```typescript
29
+ // src/services/UserComponents.ts
30
+ import { Component, CompData, BaseComponent } from 'bunsane';
31
+
32
+ @Component
33
+ export class UserProfile extends BaseComponent {
34
+ @CompData()
35
+ name: string = '';
36
+
37
+ @CompData()
38
+ email: string = '';
39
+
40
+ @CompData({ indexed: true })
41
+ username: string = '';
42
+
43
+ @CompData()
44
+ bio: string = '';
45
+
46
+ @CompData()
47
+ avatarUrl: string = '';
48
+ }
49
+
50
+ @Component
51
+ export class UserPreferences extends BaseComponent {
52
+ @CompData()
53
+ theme: 'light' | 'dark' | 'auto' = 'light';
54
+
55
+ @CompData()
56
+ notifications: boolean = true;
57
+
58
+ @CompData()
59
+ language: string = 'en';
60
+
61
+ @CompData()
62
+ timezone: string = 'UTC';
63
+ }
64
+
65
+ @Component
66
+ export class UserStats extends BaseComponent {
67
+ @CompData()
68
+ loginCount: number = 0;
69
+
70
+ @CompData()
71
+ lastLogin: Date = new Date();
72
+
73
+ @CompData()
74
+ postsCount: number = 0;
75
+
76
+ @CompData()
77
+ followersCount: number = 0;
78
+
79
+ @CompData()
80
+ followingCount: number = 0;
81
+ }
82
+ ```
83
+
84
+ ### 2. Create ArcheType
85
+
86
+ ```typescript
87
+ // src/services/UserArcheType.ts
88
+ import { ArcheType } from 'bunsane';
89
+ import { UserProfile, UserPreferences, UserStats } from './UserComponents';
90
+
91
+ export const UserArcheType = new ArcheType([
92
+ UserProfile,
93
+ UserPreferences,
94
+ UserStats
95
+ ]);
96
+ ```
97
+
98
+ ### 3. Create Service
99
+
100
+ ```typescript
101
+ // src/services/UserService.ts
102
+ import { BaseService, GraphQLObjectType, GraphQLOperation, GraphQLField, GraphQLFieldTypes } from 'bunsane';
103
+ import { UserArcheType } from './UserArcheType';
104
+
105
+ const userFields = {
106
+ id: GraphQLFieldTypes.ID_REQUIRED,
107
+ name: GraphQLFieldTypes.STRING_OPTIONAL,
108
+ email: GraphQLFieldTypes.STRING_REQUIRED,
109
+ username: GraphQLFieldTypes.STRING_OPTIONAL,
110
+ bio: GraphQLFieldTypes.STRING_OPTIONAL,
111
+ avatarUrl: GraphQLFieldTypes.STRING_OPTIONAL,
112
+ theme: GraphQLFieldTypes.STRING_OPTIONAL,
113
+ notifications: GraphQLFieldTypes.BOOLEAN_OPTIONAL,
114
+ loginCount: GraphQLFieldTypes.INT_OPTIONAL,
115
+ lastLogin: GraphQLFieldTypes.STRING_OPTIONAL,
116
+ postsCount: GraphQLFieldTypes.INT_OPTIONAL,
117
+ followersCount: GraphQLFieldTypes.INT_OPTIONAL,
118
+ followingCount: GraphQLFieldTypes.INT_OPTIONAL
119
+ };
120
+
121
+ const userInputs = {
122
+ createUser: {
123
+ name: GraphQLFieldTypes.STRING_REQUIRED,
124
+ email: GraphQLFieldTypes.STRING_REQUIRED,
125
+ username: GraphQLFieldTypes.STRING_REQUIRED,
126
+ bio: GraphQLFieldTypes.STRING_OPTIONAL,
127
+ avatarUrl: GraphQLFieldTypes.STRING_OPTIONAL
128
+ },
129
+ getUser: {
130
+ id: GraphQLFieldTypes.ID_REQUIRED
131
+ },
132
+ updateUser: {
133
+ id: GraphQLFieldTypes.ID_REQUIRED,
134
+ name: GraphQLFieldTypes.STRING_OPTIONAL,
135
+ email: GraphQLFieldTypes.STRING_OPTIONAL,
136
+ bio: GraphQLFieldTypes.STRING_OPTIONAL,
137
+ avatarUrl: GraphQLFieldTypes.STRING_OPTIONAL
138
+ }
139
+ };
140
+
141
+ @GraphQLObjectType({
142
+ name: "User",
143
+ fields: userFields
144
+ })
145
+ export default class UserService extends BaseService {
146
+ @GraphQLOperation({
147
+ type: "Mutation",
148
+ input: userInputs.createUser,
149
+ output: "User"
150
+ })
151
+ async createUser(args: { name: string; email: string; username: string; bio?: string; avatarUrl?: string }) {
152
+ const userEntity = UserArcheType.fill({
153
+ userProfile: args,
154
+ userPreferences: { theme: 'light', notifications: true },
155
+ userStats: { loginCount: 0, lastLogin: new Date() }
156
+ }).createEntity();
157
+
158
+ await userEntity.save();
159
+ return await UserArcheType.Unwrap(userEntity);
160
+ }
161
+
162
+ @GraphQLOperation({
163
+ type: "Query",
164
+ input: userInputs.getUser,
165
+ output: "User"
166
+ })
167
+ async getUser(args: { id: string }) {
168
+ const entity = await Entity.FindById(args.id);
169
+ if (!entity) return null;
170
+ return await UserArcheType.Unwrap(entity);
171
+ }
172
+
173
+ async getUsers(args: { limit?: number; offset?: number }) {
174
+ const query = new Query()
175
+ .with(UserProfile)
176
+ .limit(args.limit || 10)
177
+ .offset(args.offset || 0);
178
+
179
+ const entities = await query.exec();
180
+ return await Promise.all(
181
+ entities.map(entity => UserArcheType.Unwrap(entity))
182
+ );
183
+ }
184
+
185
+ @GraphQLOperation({
186
+ type: "Mutation",
187
+ input: userInputs.updateUser,
188
+ output: "User"
189
+ })
190
+ async updateUser(args: { id: string; name?: string; email?: string; bio?: string; avatarUrl?: string }) {
191
+ const entity = await Entity.FindById(args.id);
192
+ if (!entity) throw new Error('User not found');
193
+
194
+ await UserArcheType.updateEntity(entity, {
195
+ userProfile: args
196
+ });
197
+
198
+ await entity.save();
199
+ return await UserArcheType.Unwrap(entity);
200
+ }
201
+
202
+ async deleteUser(args: { id: string }) {
203
+ const entity = await Entity.FindById(args.id);
204
+ if (!entity) throw new Error('User not found');
205
+
206
+ await entity.delete(true);
207
+ return { success: true, message: 'User deleted successfully' };
208
+ }
209
+
210
+ @GraphQLField({ type: "User", field: "id" })
211
+ idResolver(parent: Entity) {
212
+ return parent.id;
213
+ }
214
+
215
+ @GraphQLField({ type: "User", field: "name" })
216
+ async nameResolver(parent: Entity) {
217
+ const profile = await parent.get(UserProfile);
218
+ return profile?.name ?? "";
219
+ }
220
+
221
+ @GraphQLField({ type: "User", field: "email" })
222
+ async emailResolver(parent: Entity) {
223
+ const profile = await parent.get(UserProfile);
224
+ return profile?.email ?? "";
225
+ }
226
+ }
227
+ ```
228
+
229
+ ### 4. Set Up Application
230
+
231
+ ```typescript
232
+ // index.ts
233
+ import { App } from 'bunsane';
234
+ import UserService from './src/services/UserService';
235
+
236
+ async function main() {
237
+ // Services are automatically registered when imported
238
+ // No manual registration needed
239
+
240
+ // Create and start the application
241
+ const app = new App({
242
+ port: 3000,
243
+ databaseUrl: process.env.DATABASE_URL || 'postgresql://user:pass@localhost:5432/bunsane_db'
244
+ });
245
+
246
+ await app.start();
247
+
248
+ console.log('๐Ÿš€ BunSane server running on http://localhost:3000');
249
+ console.log('๐Ÿ“Š GraphQL Playground: http://localhost:3000/graphql');
250
+ }
251
+
252
+ main().catch(console.error);
253
+ ```
254
+
255
+ ### 5. Environment Configuration
256
+
257
+ ```env
258
+ # .env
259
+ DATABASE_URL=postgresql://username:password@localhost:5432/bunsane_db
260
+ NODE_ENV=development
261
+ PORT=3000
262
+ LOG_LEVEL=info
263
+ ```
264
+
265
+ ### 6. TypeScript Configuration
266
+
267
+ ```json
268
+ // tsconfig.json
269
+ {
270
+ "compilerOptions": {
271
+ "target": "ES2022",
272
+ "module": "ESNext",
273
+ "moduleResolution": "bundler",
274
+ "experimentalDecorators": true,
275
+ "emitDecoratorMetadata": true,
276
+ "strict": true,
277
+ "esModuleInterop": true,
278
+ "skipLibCheck": true,
279
+ "forceConsistentCasingInFileNames": true,
280
+ "allowSyntheticDefaultImports": true,
281
+ "resolveJsonModule": true,
282
+ "isolatedModules": true,
283
+ "noEmit": true,
284
+ "types": ["bun-types"]
285
+ },
286
+ "include": ["src/**/*", "index.ts"],
287
+ "exclude": ["node_modules"]
288
+ }
289
+ ```
290
+
291
+ ## ๐Ÿงช Testing the Example
292
+
293
+ ### Start the Server
294
+
295
+ ```bash
296
+ bun run index.ts
297
+ ```
298
+
299
+ ### GraphQL Queries
300
+
301
+ Visit `http://localhost:3000/graphql` and try these queries:
302
+
303
+ #### Create a User
304
+
305
+ ```graphql
306
+ mutation CreateUser($input: CreateUserInput!) {
307
+ createUser(input: $input) {
308
+ id
309
+ name
310
+ email
311
+ username
312
+ theme
313
+ notifications
314
+ loginCount
315
+ lastLogin
316
+ }
317
+ }
318
+ ```
319
+
320
+ Variables:
321
+ ```json
322
+ {
323
+ "input": {
324
+ "name": "John Doe",
325
+ "email": "john.doe@example.com",
326
+ "username": "johndoe",
327
+ "bio": "Software developer passionate about TypeScript",
328
+ "avatarUrl": "https://example.com/avatar.jpg"
329
+ }
330
+ }
331
+ ```
332
+
333
+ #### Get Users
334
+
335
+ ```graphql
336
+ query GetUsers {
337
+ getUsers(limit: 10, offset: 0) {
338
+ id
339
+ name
340
+ email
341
+ username
342
+ bio
343
+ postsCount
344
+ followersCount
345
+ }
346
+ }
347
+ ```
348
+
349
+ #### Update User
350
+
351
+ ```graphql
352
+ mutation UpdateUser($input: UpdateUserInput!) {
353
+ updateUser(input: $input) {
354
+ id
355
+ name
356
+ email
357
+ bio
358
+ }
359
+ }
360
+ ```
361
+
362
+ Variables:
363
+ ```json
364
+ {
365
+ "input": {
366
+ "id": "01HXXXXXXXXXXXXXXXXXXXXX",
367
+ "name": "John Smith",
368
+ "bio": "Full-stack developer specializing in modern web technologies"
369
+ }
370
+ }
371
+ ```
372
+
373
+ ## ๐Ÿ“š More Examples
374
+
375
+ - **[Blog Application](blog-tutorial.md)** - Complete blogging platform
376
+ - **[E-commerce System](ecommerce-tutorial.md)** - Online store with products and orders
377
+ - **[Social Media Platform](social-tutorial.md)** - User interactions and content sharing
378
+
379
+ ## ๐Ÿ”ง Running Examples
380
+
381
+ Each example includes:
382
+
383
+ 1. **Complete code** - Copy and run immediately
384
+ 2. **Database setup** - SQL scripts for schema creation
385
+ 3. **GraphQL queries** - Ready-to-use API calls
386
+ 4. **Testing instructions** - How to verify functionality
387
+
388
+ ### Local Development
389
+
390
+ ```bash
391
+ # Clone the example
392
+ git clone https://github.com/yaaruu/bunsane-examples.git
393
+ cd bunsane-examples/user-management
394
+
395
+ # Install dependencies
396
+ bun install
397
+
398
+ # Set up database
399
+ createdb bunsane_examples
400
+ psql bunsane_examples < schema.sql
401
+
402
+ # Start the server
403
+ bun run dev
404
+ ```
405
+
406
+ ### Docker Development
407
+
408
+ ```bash
409
+ # Use Docker Compose for full development environment
410
+ docker-compose up -d
411
+
412
+ # Run the example
413
+ bun run index.ts
414
+ ```
415
+
416
+ ## ๐ŸŽฏ Learning Path
417
+
418
+ 1. **Start Here** - User management system (you're here!)
419
+ 2. **Add Features** - Extend with posts, comments, likes
420
+ 3. **Go Advanced** - Add real-time updates, file uploads, caching
421
+ 4. **Production Ready** - Add authentication, rate limiting, monitoring
422
+
423
+ ---
424
+
425
+ *Ready to build something amazing? Try the [Blog Application](blog-tutorial.md) next!* ๐Ÿš€