@appweaver/create-weaver-app 1.0.16 → 1.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appweaver/create-weaver-app",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "Appweaver - the backend framework for AI-first development (@create-weaver-app)",
5
5
  "author": "Luka Matosevic",
6
6
  "license": "MIT",
package/skill/SKILL.md CHANGED
@@ -212,7 +212,8 @@ export default createModel({
212
212
  files: {
213
213
  photo: {
214
214
  mimeType: 'image/*',
215
- maxSize: '2 MB'
215
+ maxSize: '2 MB',
216
+ image: { quality: 80, maxWidth: 1200 }
216
217
  }
217
218
  },
218
219
  create: {
@@ -333,7 +334,8 @@ export default createAuthModel({
333
334
  files: {
334
335
  avatar: {
335
336
  mimeType: 'image/(png|jpeg|gif)',
336
- maxSize: '2 MB'
337
+ maxSize: '2 MB',
338
+ image: { quality: 80, maxHeight: 800, fit: 'inside' }
337
339
  }
338
340
  }
339
341
  });
@@ -434,7 +434,13 @@ const config = {
434
434
  photo: {
435
435
  mimeType: 'image/*',
436
436
  namePattern: 'photos/{userId}-{name}-{hash}.{extension}',
437
- maxSize: '2 MB'
437
+ maxSize: '2 MB',
438
+ image: {
439
+ quality: 80,
440
+ maxWidth: 1200,
441
+ maxHeight: 1200,
442
+ fit: 'inside'
443
+ }
438
444
  },
439
445
  documents: {
440
446
  mimeType: 'application/pdf',
@@ -454,6 +460,7 @@ const config = {
454
460
  | `maxCount` | number | Maximum number of files (for array fields). |
455
461
  | `output` | RelationOutput | When to include file info in output. |
456
462
  | `onResourceDeleted` | `'delete'` \| `'keep'` | When the owning resource is deleted. `'delete'` (default) removes files from storage, `'keep'` leaves them. |
463
+ | `image` | ImageConfig | Image compression and resize settings. Only applies to image MIME types (excluding GIF). |
457
464
 
458
465
  #### Available namePattern variables
459
466
 
@@ -483,6 +490,49 @@ Default pattern is: `{name}-{hash}.{extension}`.
483
490
  | `uuid` | string | Generated random UUID. |
484
491
  | `hash` | string | Generated random hash (32 bytes). |
485
492
 
493
+ #### Image compression
494
+
495
+ Configure automatic image compression and resizing by adding the `image` property to a file field. Processing only
496
+ applies to supported image MIME types: `image/jpeg`, `image/png`, `image/webp`, `image/avif`, `image/tiff`. GIF files
497
+ are passed through unchanged.
498
+
499
+ | Property | Type | Description |
500
+ |-------------|----------|----------------------------------------------------------------------------------------------------------------|
501
+ | `quality` | number | Compression quality (1-100). Applies to JPEG, PNG, WebP, AVIF, and TIFF. |
502
+ | `width` | number | Exact resize width in pixels. |
503
+ | `height` | number | Exact resize height in pixels. |
504
+ | `maxWidth` | number | Maximum width. Only downscales if the image exceeds this dimension. |
505
+ | `maxHeight` | number | Maximum height. Only downscales if the image exceeds this dimension. |
506
+ | `fit` | ImageFit | How the image fits the target dimensions: `'inside'` (default), `'contain'`, `'cover'`, `'fill'`, `'outside'`. |
507
+
508
+ `width`/`height` take precedence over `maxWidth`/`maxHeight`. When using `maxWidth`/`maxHeight`, images smaller than
509
+ the specified dimensions are not enlarged.
510
+
511
+ ```ts
512
+ // Compress and limit dimensions
513
+ const config = {
514
+ files: {
515
+ avatar: {
516
+ mimeType: 'image/*',
517
+ maxSize: '5 MB',
518
+ image: { quality: 80, maxWidth: 800, maxHeight: 800 }
519
+ }
520
+ }
521
+ };
522
+ ```
523
+
524
+ ```ts
525
+ // Exact resize for thumbnails
526
+ const config = {
527
+ files: {
528
+ thumbnail: {
529
+ mimeType: 'image/jpeg',
530
+ image: { quality: 70, width: 200, height: 200, fit: 'inside' }
531
+ }
532
+ }
533
+ }
534
+ ```
535
+
486
536
  ### Virtual fields
487
537
 
488
538
  Virtual fields are computed values not stored in the database. They can appear in input DTOs (to receive data) and/or
@@ -35,6 +35,9 @@ RUN npm ci --omit=dev
35
35
  # Copy build files
36
36
  COPY --from=build /usr/app/dist /usr/app/dist
37
37
 
38
+ # Copy public static files
39
+ COPY --from=build /usr/app/public /usr/app/public
40
+
38
41
  # Copy Prisma config, database migrations, and schema file
39
42
  COPY --from=build /usr/app/prisma.config.ts /usr/app/prisma.config.ts
40
43
  COPY --from=build /usr/app/database/migrations /usr/app/database/migrations
@@ -35,6 +35,9 @@ RUN bun install --frozen-lockfile --production
35
35
  # Copy build files
36
36
  COPY --from=build /usr/app/dist /usr/app/dist
37
37
 
38
+ # Copy public static files
39
+ COPY --from=build /usr/app/public /usr/app/public
40
+
38
41
  # Copy Prisma config, database migrations, and schema file
39
42
  COPY --from=build /usr/app/prisma.config.ts /usr/app/prisma.config.ts
40
43
  COPY --from=build /usr/app/database/migrations /usr/app/database/migrations
@@ -0,0 +1,90 @@
1
+ services:
2
+ postgres:
3
+ image: postgres:18.4
4
+ container_name: {{LOWER_NAME}}-postgres
5
+ restart: unless-stopped
6
+ healthcheck:
7
+ test: "PGPASSWORD=$$POSTGRES_PASSWORD psql -U $$POSTGRES_USER -d $$POSTGRES_DB -c 'SELECT 1'"
8
+ interval: 30s
9
+ timeout: 10s
10
+ retries: 10
11
+ start_period: 5s
12
+ start_interval: 5s
13
+ ports:
14
+ - "127.0.0.1:54312:5432"
15
+ environment:
16
+ POSTGRES_DB: "${DB_NAME}"
17
+ POSTGRES_USER: "${DB_USER}"
18
+ POSTGRES_PASSWORD: "${DB_PASSWORD}"
19
+ volumes:
20
+ - postgres-data:/var/lib/postgresql/data
21
+ networks:
22
+ - {{LOWER_NAME}}
23
+
24
+ redis:
25
+ image: redis:7.4.9
26
+ container_name: {{LOWER_NAME}}-redis
27
+ restart: unless-stopped
28
+ healthcheck:
29
+ test: [ "CMD", "redis-cli", "ping" ]
30
+ interval: 30s
31
+ timeout: 10s
32
+ retries: 10
33
+ start_period: 5s
34
+ start_interval: 5s
35
+ ports:
36
+ - "127.0.0.1:6380:6379"
37
+ volumes:
38
+ - redis-data:/data
39
+ networks:
40
+ - {{LOWER_NAME}}
41
+
42
+ {{LOWER_NAME}}.migrations:
43
+ image: {{LOWER_NAME}}:latest
44
+ container_name: {{LOWER_NAME}}-migrations
45
+ restart: no
46
+ depends_on:
47
+ postgres:
48
+ condition: service_healthy
49
+ env_file:
50
+ - .env
51
+ command: [ "migrations" ]
52
+ networks:
53
+ - {{LOWER_NAME}}
54
+
55
+ {{LOWER_NAME}}:
56
+ image: {{LOWER_NAME}}:latest
57
+ container_name: {{LOWER_NAME}}
58
+ restart: unless-stopped
59
+ build:
60
+ context: .
61
+ healthcheck:
62
+ test: "wget -qO - http://127.0.0.1:3030/health/ready || exit 1"
63
+ interval: 30s
64
+ timeout: 10s
65
+ retries: 5
66
+ start_period: 5s
67
+ start_interval: 5s
68
+ depends_on:
69
+ redis:
70
+ condition: service_healthy
71
+ {{LOWER_NAME}}.migrations:
72
+ condition: service_completed_successfully
73
+ ports:
74
+ - "127.0.0.1:3030:3003"
75
+ volumes:
76
+ - ./storage:/usr/app/storage
77
+ - ./logs:/usr/app/logs
78
+ env_file:
79
+ - .env
80
+ networks:
81
+ - {{LOWER_NAME}}
82
+
83
+ networks:
84
+ {{LOWER_NAME}}:
85
+ driver: bridge
86
+ name: {{LOWER_NAME}}-network
87
+
88
+ volumes:
89
+ postgres-data:
90
+ redis-data: