@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
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:
|