mirror of
https://github.com/immich-app/immich.git
synced 2025-12-07 13:21:02 -08:00
Compare commits
69 Commits
feat/backg
...
feat/unass
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e36b7240c7 | ||
|
|
fec3a04123 | ||
|
|
4c7347d653 | ||
|
|
dca420ef70 | ||
|
|
21bd20fd75 | ||
|
|
351dd647a9 | ||
|
|
298370b7be | ||
|
|
e3d39837d0 | ||
|
|
38f4a02a14 | ||
|
|
fc5615eff6 | ||
|
|
6879bcb7a4 | ||
|
|
11152f9b3d | ||
|
|
75830a4878 | ||
|
|
e7c8501930 | ||
|
|
50f9b2d44e | ||
|
|
9628ea2d24 | ||
|
|
d919d2c975 | ||
|
|
7ac9c1bb78 | ||
|
|
4d4bb8b6a7 | ||
|
|
99f0aa868a | ||
|
|
459fee9ee4 | ||
|
|
871f3ea468 | ||
|
|
98c4c683ae | ||
|
|
8a7b0f66a4 | ||
|
|
9e71256191 | ||
|
|
d5cf8e4bfe | ||
|
|
95012dc19b | ||
|
|
f197f5d530 | ||
|
|
7168707395 | ||
|
|
847cb90038 | ||
|
|
602f0a3499 | ||
|
|
fdaa0e5413 | ||
|
|
39d2c4f37b | ||
|
|
1f5d82e9d9 | ||
|
|
e98744f222 | ||
|
|
56ea07bcba | ||
|
|
b3b258f32f | ||
|
|
69b5eb005f | ||
|
|
3f44a33eac | ||
|
|
b2a0422efb | ||
|
|
562c43b6f5 | ||
|
|
4f21f6a2e1 | ||
|
|
76fdcc9863 | ||
|
|
57d94bce68 | ||
|
|
832d728940 | ||
|
|
8bfa6769a5 | ||
|
|
e7aa50425c | ||
|
|
a5e8b451b2 | ||
|
|
13cbdf6851 | ||
|
|
967d195a05 | ||
|
|
8f37784eae | ||
|
|
ecd018a826 | ||
|
|
202745f14b | ||
|
|
6a4c2e97c0 | ||
|
|
f6f82a5662 | ||
|
|
ae21781442 | ||
|
|
06ce8247cc | ||
|
|
a4887bfa7e | ||
|
|
27a02c75dc | ||
|
|
f8ee977b9e | ||
|
|
a3e7e8cc31 | ||
|
|
a341ab0050 | ||
|
|
61b850f0ce | ||
|
|
0f6e665d99 | ||
|
|
7ced61e67d | ||
|
|
ac26d2f45f | ||
|
|
782d02a5e2 | ||
|
|
22c42dd8ff | ||
|
|
7e9dcaacff |
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: PR Conventional Commit Validation
|
||||
uses: ytanikin/PRConventionalCommits@1.1.0
|
||||
uses: ytanikin/PRConventionalCommits@1.2.0
|
||||
with:
|
||||
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]'
|
||||
add_label: 'false'
|
||||
|
||||
15
.github/workflows/test.yml
vendored
15
.github/workflows/test.yml
vendored
@@ -260,9 +260,18 @@ jobs:
|
||||
name: OpenAPI Clients
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install server dependencies
|
||||
run: npm --prefix=server ci
|
||||
|
||||
- name: Build the app
|
||||
run: npm --prefix=server run build
|
||||
|
||||
- name: Run API generation
|
||||
run: make open-api
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@v20
|
||||
id: verify-changed-files
|
||||
@@ -270,6 +279,8 @@ jobs:
|
||||
files: |
|
||||
mobile/openapi
|
||||
open-api/typescript-sdk
|
||||
open-api/immich-openapi-specs.json
|
||||
|
||||
- name: Verify files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
run: |
|
||||
@@ -332,7 +343,7 @@ jobs:
|
||||
exit 1
|
||||
|
||||
- name: Run SQL generation
|
||||
run: npm run sql:generate
|
||||
run: npm run sync:sql
|
||||
env:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -37,7 +37,7 @@ open-api-typescript:
|
||||
cd ./open-api && bash ./bin/generate-open-api.sh typescript
|
||||
|
||||
sql:
|
||||
npm --prefix server run sql:generate
|
||||
npm --prefix server run sync:sql
|
||||
|
||||
attach-server:
|
||||
docker exec -it docker_immich-server_1 sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getMyUserInfo } from '@immich/sdk';
|
||||
import { getMyUser } from '@immich/sdk';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { mkdir, unlink } from 'node:fs/promises';
|
||||
import { BaseOptions, connect, getAuthFilePath, logError, withError, writeAuthFile } from 'src/utils';
|
||||
@@ -10,13 +10,13 @@ export const login = async (url: string, key: string, options: BaseOptions) => {
|
||||
|
||||
await connect(url, key);
|
||||
|
||||
const [error, userInfo] = await withError(getMyUserInfo());
|
||||
const [error, user] = await withError(getMyUser());
|
||||
if (error) {
|
||||
logError(error, 'Failed to load user info');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Logged in as ${userInfo.email}`);
|
||||
console.log(`Logged in as ${user.email}`);
|
||||
|
||||
if (!existsSync(configDir)) {
|
||||
// Create config folder if it doesn't exist
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getAssetStatistics, getMyUserInfo, getServerVersion, getSupportedMediaTypes } from '@immich/sdk';
|
||||
import { getAssetStatistics, getMyUser, getServerVersion, getSupportedMediaTypes } from '@immich/sdk';
|
||||
import { BaseOptions, authenticate } from 'src/utils';
|
||||
|
||||
export const serverInfo = async (options: BaseOptions) => {
|
||||
@@ -8,7 +8,7 @@ export const serverInfo = async (options: BaseOptions) => {
|
||||
getServerVersion(),
|
||||
getSupportedMediaTypes(),
|
||||
getAssetStatistics({}),
|
||||
getMyUserInfo(),
|
||||
getMyUser(),
|
||||
]);
|
||||
|
||||
console.log(`Server Info (via ${userInfo.email})`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getMyUserInfo, init, isHttpError } from '@immich/sdk';
|
||||
import { getMyUser, init, isHttpError } from '@immich/sdk';
|
||||
import { glob } from 'fast-glob';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { createReadStream } from 'node:fs';
|
||||
@@ -48,7 +48,7 @@ export const connect = async (url: string, key: string) => {
|
||||
|
||||
init({ baseUrl: url, apiKey: key });
|
||||
|
||||
const [error] = await withError(getMyUserInfo());
|
||||
const [error] = await withError(getMyUser());
|
||||
if (isHttpError(error)) {
|
||||
logError(error, 'Failed to connect to server');
|
||||
process.exit(1);
|
||||
|
||||
@@ -9,6 +9,9 @@ services:
|
||||
container_name: immich_server
|
||||
command: ['/usr/src/app/bin/immich-dev']
|
||||
image: immich-server-dev:latest
|
||||
# extends:
|
||||
# file: hwaccel.transcoding.yml
|
||||
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: server/Dockerfile
|
||||
@@ -81,7 +84,9 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: redis:6.2-alpine@sha256:c0634a08e74a4bb576d02d1ee993dc05dba10e8b7b9492dfa28a7af100d46c01
|
||||
image: redis:6.2-alpine@sha256:e31ca60b18f7e9b78b573d156702471d4eda038803c0b8e6f01559f350031e93
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
@@ -97,6 +102,11 @@ services:
|
||||
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
healthcheck:
|
||||
test: pg_isready --dbname='${DB_DATABASE_NAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT SUM(checksum_failures) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
|
||||
interval: 5m
|
||||
start_interval: 30s
|
||||
start_period: 5m
|
||||
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
||||
|
||||
# set IMMICH_METRICS=true in .env to enable metrics
|
||||
|
||||
@@ -4,6 +4,9 @@ services:
|
||||
immich-server:
|
||||
container_name: immich_server
|
||||
image: immich-server:latest
|
||||
# extends:
|
||||
# file: hwaccel.transcoding.yml
|
||||
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: server/Dockerfile
|
||||
@@ -12,12 +15,12 @@ services:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
env_file:
|
||||
- .env
|
||||
restart: always
|
||||
ports:
|
||||
- 2283:3001
|
||||
depends_on:
|
||||
- redis
|
||||
- database
|
||||
restart: always
|
||||
|
||||
immich-machine-learning:
|
||||
container_name: immich_machine_learning
|
||||
@@ -38,7 +41,9 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: redis:6.2-alpine@sha256:c0634a08e74a4bb576d02d1ee993dc05dba10e8b7b9492dfa28a7af100d46c01
|
||||
image: redis:6.2-alpine@sha256:e31ca60b18f7e9b78b573d156702471d4eda038803c0b8e6f01559f350031e93
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
|
||||
database:
|
||||
@@ -55,7 +60,13 @@ services:
|
||||
- ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
healthcheck:
|
||||
test: pg_isready --dbname='${DB_DATABASE_NAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT SUM(checksum_failures) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
|
||||
interval: 5m
|
||||
start_interval: 30s
|
||||
start_period: 5m
|
||||
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
||||
restart: always
|
||||
|
||||
# set IMMICH_METRICS=true in .env to enable metrics
|
||||
immich-prometheus:
|
||||
|
||||
@@ -12,6 +12,9 @@ services:
|
||||
immich-server:
|
||||
container_name: immich_server
|
||||
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||
# extends:
|
||||
# file: hwaccel.transcoding.yml
|
||||
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
||||
volumes:
|
||||
- ${UPLOAD_LOCATION}:/usr/src/app/upload
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
@@ -40,7 +43,9 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: immich_redis
|
||||
image: docker.io/redis:6.2-alpine@sha256:c0634a08e74a4bb576d02d1ee993dc05dba10e8b7b9492dfa28a7af100d46c01
|
||||
image: docker.io/redis:6.2-alpine@sha256:e31ca60b18f7e9b78b573d156702471d4eda038803c0b8e6f01559f350031e93
|
||||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
|
||||
database:
|
||||
@@ -53,8 +58,13 @@ services:
|
||||
POSTGRES_INITDB_ARGS: '--data-checksums'
|
||||
volumes:
|
||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
restart: always
|
||||
healthcheck:
|
||||
test: pg_isready --dbname='${DB_DATABASE_NAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT SUM(checksum_failures) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
|
||||
interval: 5m
|
||||
start_interval: 30s
|
||||
start_period: 5m
|
||||
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
model-cache:
|
||||
|
||||
BIN
docs/docs/administration/img/google-example.webp
Normal file
BIN
docs/docs/administration/img/google-example.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/docs/administration/img/immich-google-example.webp
Normal file
BIN
docs/docs/administration/img/immich-google-example.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
@@ -110,8 +110,44 @@ Immich has a route (`/api/oauth/mobile-redirect`) that is already configured to
|
||||
|
||||
## Example Configuration
|
||||
|
||||
<details>
|
||||
<summary>Authentik Example</summary>
|
||||
|
||||
### Authentik Example
|
||||
|
||||
Here's an example of OAuth configured for Authentik:
|
||||
|
||||

|
||||
<img src={require('./img/oauth-settings.png').default} title="OAuth settings" />
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Google Example</summary>
|
||||
|
||||
### Google Example
|
||||
|
||||
Configuration of Authorised redirect URIs (Google Console)
|
||||
|
||||
<img src={require('./img/google-example.webp').default} width='50%' title="Authorised redirect URIs" />
|
||||
|
||||
Configuration of OAuth in System Settings
|
||||
|
||||
| Setting | Value |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| Issuer URL | [https://accounts.google.com](https://accounts.google.com) |
|
||||
| Client ID | 7\***\*\*\*\*\*\*\***\*\*\***\*\*\*\*\*\*\***vuls.apps.googleusercontent.com |
|
||||
| Client Secret | G\***\*\*\*\*\*\*\***\*\*\***\*\*\*\*\*\*\***OO |
|
||||
| Scope | openid email profile |
|
||||
| Signing Algorithm | RS256 |
|
||||
| Storage Label Claim | preferred_username |
|
||||
| Storage Quota Claim | immich_quota |
|
||||
| Default Storage Quota (GiB) | 0 (0 for unlimited quota) |
|
||||
| Button Text | Sign in with Google (optional) |
|
||||
| Auto Register | Enabled (optional) |
|
||||
| Auto Launch | Enabled |
|
||||
| Mobile Redirect URI Override | Enabled (required) |
|
||||
| Mobile Redirect URI | [https://demo.immich.app/api/oauth/mobile-redirect](https://demo.immich.app/api/oauth/mobile-redirect) |
|
||||
|
||||
</details>
|
||||
|
||||
[oidc]: https://openid.net/connect/
|
||||
|
||||
@@ -15,7 +15,7 @@ The [hwaccel.ml.yml](https://github.com/immich-app/immich/releases/latest/downlo
|
||||
:::
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
name: immich_remote_ml
|
||||
|
||||
services:
|
||||
immich-machine-learning:
|
||||
|
||||
@@ -157,9 +157,6 @@ The default configuration looks like this:
|
||||
"server": {
|
||||
"externalDomain": "",
|
||||
"loginPageMessage": ""
|
||||
},
|
||||
"user": {
|
||||
"deleteDelay": 7
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ services:
|
||||
- 2283:3001
|
||||
|
||||
redis:
|
||||
image: redis:6.2-alpine@sha256:c0634a08e74a4bb576d02d1ee993dc05dba10e8b7b9492dfa28a7af100d46c01
|
||||
image: redis:6.2-alpine@sha256:e31ca60b18f7e9b78b573d156702471d4eda038803c0b8e6f01559f350031e93
|
||||
|
||||
database:
|
||||
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
|
||||
|
||||
26
e2e/package-lock.json
generated
26
e2e/package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"devDependencies": {
|
||||
"@immich/cli": "file:../cli",
|
||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.41.2",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^20.11.17",
|
||||
"@types/pg": "^8.11.0",
|
||||
@@ -88,7 +88,7 @@
|
||||
"@oazapfts/runtime": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.12",
|
||||
"@types/node": "^20.11.0",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
},
|
||||
@@ -971,12 +971,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.0.tgz",
|
||||
"integrity": "sha512-rNX5lbNidamSUorBhB4XZ9SQTjAqfe5M+p37Z8ic0jPFBMo5iCtQz1kRWkEMg+rYOKSlVycpQmpqjSFq7LXOfg==",
|
||||
"version": "1.44.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz",
|
||||
"integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright": "1.44.0"
|
||||
"playwright": "1.44.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -4252,12 +4252,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz",
|
||||
"integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==",
|
||||
"version": "1.44.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
|
||||
"integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright-core": "1.44.0"
|
||||
"playwright-core": "1.44.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -4270,9 +4270,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz",
|
||||
"integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==",
|
||||
"version": "1.44.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
|
||||
"integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@immich/cli": "file:../cli",
|
||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||
"@playwright/test": "^1.41.2",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@types/luxon": "^3.4.2",
|
||||
"@types/node": "^20.11.17",
|
||||
"@types/pg": "^8.11.0",
|
||||
|
||||
@@ -14,7 +14,7 @@ import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/activity', () => {
|
||||
describe('/activities', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let nonOwner: LoginResponseDto;
|
||||
let asset: AssetFileUploadResponseDto;
|
||||
@@ -45,22 +45,24 @@ describe('/activity', () => {
|
||||
await utils.resetDatabase(['activity']);
|
||||
});
|
||||
|
||||
describe('GET /activity', () => {
|
||||
describe('GET /activities', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/activity');
|
||||
const { status, body } = await request(app).get('/activities');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require an albumId', async () => {
|
||||
const { status, body } = await request(app).get('/activity').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
const { status, body } = await request(app)
|
||||
.get('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(400);
|
||||
expect(body).toEqual(errorDto.badRequest(expect.arrayContaining(['albumId must be a UUID'])));
|
||||
});
|
||||
|
||||
it('should reject an invalid albumId', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: uuidDto.invalid })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(400);
|
||||
@@ -69,7 +71,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should reject an invalid assetId', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: uuidDto.notFound, assetId: uuidDto.invalid })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(400);
|
||||
@@ -78,7 +80,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should start off empty', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(body).toEqual([]);
|
||||
@@ -102,7 +104,7 @@ describe('/activity', () => {
|
||||
]);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
@@ -121,7 +123,7 @@ describe('/activity', () => {
|
||||
]);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id, type: 'comment' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
@@ -140,7 +142,7 @@ describe('/activity', () => {
|
||||
]);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id, type: 'like' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
@@ -152,7 +154,7 @@ describe('/activity', () => {
|
||||
const reaction = await createActivity({ albumId: album.id, type: ReactionType.Like });
|
||||
|
||||
const response1 = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id, userId: uuidDto.notFound })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
@@ -160,7 +162,7 @@ describe('/activity', () => {
|
||||
expect(response1.body.length).toBe(0);
|
||||
|
||||
const response2 = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id, userId: admin.userId })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
@@ -180,7 +182,7 @@ describe('/activity', () => {
|
||||
]);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/activity')
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id, assetId: asset.id })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
@@ -189,16 +191,16 @@ describe('/activity', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /activity', () => {
|
||||
describe('POST /activities', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post('/activity');
|
||||
const { status, body } = await request(app).post('/activities');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require an albumId', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: uuidDto.invalid });
|
||||
expect(status).toEqual(400);
|
||||
@@ -207,7 +209,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should require a comment when type is comment', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: uuidDto.notFound, type: 'comment', comment: null });
|
||||
expect(status).toEqual(400);
|
||||
@@ -216,7 +218,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should add a comment to an album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
albumId: album.id,
|
||||
@@ -236,7 +238,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should add a like to an album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: album.id, type: 'like' });
|
||||
expect(status).toEqual(201);
|
||||
@@ -253,7 +255,7 @@ describe('/activity', () => {
|
||||
it('should return a 200 for a duplicate like on the album', async () => {
|
||||
const reaction = await createActivity({ albumId: album.id, type: ReactionType.Like });
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: album.id, type: 'like' });
|
||||
expect(status).toEqual(200);
|
||||
@@ -267,7 +269,7 @@ describe('/activity', () => {
|
||||
type: ReactionType.Like,
|
||||
});
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: album.id, type: 'like' });
|
||||
expect(status).toEqual(201);
|
||||
@@ -276,7 +278,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should add a comment to an asset', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
albumId: album.id,
|
||||
@@ -297,7 +299,7 @@ describe('/activity', () => {
|
||||
|
||||
it('should add a like to an asset', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: album.id, assetId: asset.id, type: 'like' });
|
||||
expect(status).toEqual(201);
|
||||
@@ -319,7 +321,7 @@ describe('/activity', () => {
|
||||
});
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.post('/activity')
|
||||
.post('/activities')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ albumId: album.id, assetId: asset.id, type: 'like' });
|
||||
expect(status).toEqual(200);
|
||||
@@ -327,16 +329,16 @@ describe('/activity', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /activity/:id', () => {
|
||||
describe('DELETE /activities/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/activity/${uuidDto.notFound}`);
|
||||
const { status, body } = await request(app).delete(`/activities/${uuidDto.notFound}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require a valid uuid', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/activity/${uuidDto.invalid}`)
|
||||
.delete(`/activities/${uuidDto.invalid}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(['id must be a UUID']));
|
||||
@@ -349,7 +351,7 @@ describe('/activity', () => {
|
||||
comment: 'This is a test comment',
|
||||
});
|
||||
const { status } = await request(app)
|
||||
.delete(`/activity/${reaction.id}`)
|
||||
.delete(`/activities/${reaction.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(204);
|
||||
});
|
||||
@@ -360,7 +362,7 @@ describe('/activity', () => {
|
||||
type: ReactionType.Like,
|
||||
});
|
||||
const { status } = await request(app)
|
||||
.delete(`/activity/${reaction.id}`)
|
||||
.delete(`/activities/${reaction.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(204);
|
||||
});
|
||||
@@ -373,7 +375,7 @@ describe('/activity', () => {
|
||||
});
|
||||
|
||||
const { status } = await request(app)
|
||||
.delete(`/activity/${reaction.id}`)
|
||||
.delete(`/activities/${reaction.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toEqual(204);
|
||||
@@ -387,7 +389,7 @@ describe('/activity', () => {
|
||||
});
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/activity/${reaction.id}`)
|
||||
.delete(`/activities/${reaction.id}`)
|
||||
.set('Authorization', `Bearer ${nonOwner.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -405,7 +407,7 @@ describe('/activity', () => {
|
||||
);
|
||||
|
||||
const { status } = await request(app)
|
||||
.delete(`/activity/${reaction.id}`)
|
||||
.delete(`/activities/${reaction.id}`)
|
||||
.set('Authorization', `Bearer ${nonOwner.accessToken}`);
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
AlbumUserRole,
|
||||
AssetFileUploadResponseDto,
|
||||
AssetOrder,
|
||||
deleteUser,
|
||||
deleteUserAdmin,
|
||||
getAlbumInfo,
|
||||
LoginResponseDto,
|
||||
SharedLinkType,
|
||||
@@ -23,7 +23,7 @@ const user2SharedUser = 'user2SharedUser';
|
||||
const user2SharedLink = 'user2SharedLink';
|
||||
const user2NotShared = 'user2NotShared';
|
||||
|
||||
describe('/album', () => {
|
||||
describe('/albums', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let user1: LoginResponseDto;
|
||||
let user1Asset1: AssetFileUploadResponseDto;
|
||||
@@ -107,19 +107,19 @@ describe('/album', () => {
|
||||
}),
|
||||
]);
|
||||
|
||||
await deleteUser({ id: user3.userId, deleteUserDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
await deleteUserAdmin({ id: user3.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
});
|
||||
|
||||
describe('GET /album', () => {
|
||||
describe('GET /albums', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/album');
|
||||
const { status, body } = await request(app).get('/albums');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should reject an invalid shared param', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album?shared=invalid')
|
||||
.get('/albums?shared=invalid')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toEqual(400);
|
||||
expect(body).toEqual(errorDto.badRequest(['shared must be a boolean value']));
|
||||
@@ -127,7 +127,7 @@ describe('/album', () => {
|
||||
|
||||
it('should reject an invalid assetId param', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album?assetId=invalid')
|
||||
.get('/albums?assetId=invalid')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toEqual(400);
|
||||
expect(body).toEqual(errorDto.badRequest(['assetId must be a UUID']));
|
||||
@@ -135,7 +135,7 @@ describe('/album', () => {
|
||||
|
||||
it("should not show other users' favorites", async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user1Albums[0].id}?withoutAssets=false`)
|
||||
.get(`/albums/${user1Albums[0].id}?withoutAssets=false`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
expect(body).toEqual({
|
||||
@@ -146,7 +146,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not return shared albums with a deleted owner', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album?shared=true')
|
||||
.get('/albums?shared=true')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -178,7 +178,7 @@ describe('/album', () => {
|
||||
});
|
||||
|
||||
it('should return the album collection including owned and shared', async () => {
|
||||
const { status, body } = await request(app).get('/album').set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
const { status, body } = await request(app).get('/albums').set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(4);
|
||||
expect(body).toEqual(
|
||||
@@ -209,7 +209,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return the album collection filtered by shared', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album?shared=true')
|
||||
.get('/albums?shared=true')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(4);
|
||||
@@ -241,7 +241,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return the album collection filtered by NOT shared', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album?shared=false')
|
||||
.get('/albums?shared=false')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(1);
|
||||
@@ -258,7 +258,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return the album collection filtered by assetId', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album?assetId=${user1Asset2.id}`)
|
||||
.get(`/albums?assetId=${user1Asset2.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(1);
|
||||
@@ -266,7 +266,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return the album collection filtered by assetId and ignores shared=true', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album?shared=true&assetId=${user1Asset1.id}`)
|
||||
.get(`/albums?shared=true&assetId=${user1Asset1.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(5);
|
||||
@@ -274,23 +274,23 @@ describe('/album', () => {
|
||||
|
||||
it('should return the album collection filtered by assetId and ignores shared=false', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album?shared=false&assetId=${user1Asset1.id}`)
|
||||
.get(`/albums?shared=false&assetId=${user1Asset1.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /album/:id', () => {
|
||||
describe('GET /albums/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/album/${user1Albums[0].id}`);
|
||||
const { status, body } = await request(app).get(`/albums/${user1Albums[0].id}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should return album info for own album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user1Albums[0].id}?withoutAssets=false`)
|
||||
.get(`/albums/${user1Albums[0].id}?withoutAssets=false`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -302,7 +302,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return album info for shared album (editor)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user2Albums[0].id}?withoutAssets=false`)
|
||||
.get(`/albums/${user2Albums[0].id}?withoutAssets=false`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -311,7 +311,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return album info for shared album (viewer)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user1Albums[3].id}?withoutAssets=false`)
|
||||
.get(`/albums/${user1Albums[3].id}?withoutAssets=false`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -320,7 +320,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return album info with assets when withoutAssets is undefined', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user1Albums[0].id}`)
|
||||
.get(`/albums/${user1Albums[0].id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -332,7 +332,7 @@ describe('/album', () => {
|
||||
|
||||
it('should return album info without assets when withoutAssets is true', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/album/${user1Albums[0].id}?withoutAssets=true`)
|
||||
.get(`/albums/${user1Albums[0].id}?withoutAssets=true`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -344,16 +344,16 @@ describe('/album', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /album/count', () => {
|
||||
describe('GET /albums/count', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/album/count');
|
||||
const { status, body } = await request(app).get('/albums/count');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should return total count of albums the user has access to', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/album/count')
|
||||
.get('/albums/count')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -361,16 +361,16 @@ describe('/album', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /album', () => {
|
||||
describe('POST /albums', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post('/album').send({ albumName: 'New album' });
|
||||
const { status, body } = await request(app).post('/albums').send({ albumName: 'New album' });
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should create an album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/album')
|
||||
.post('/albums')
|
||||
.send({ albumName: 'New album' })
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(status).toBe(201);
|
||||
@@ -383,7 +383,6 @@ describe('/album', () => {
|
||||
description: '',
|
||||
albumThumbnailAssetId: null,
|
||||
shared: false,
|
||||
sharedUsers: [],
|
||||
albumUsers: [],
|
||||
hasSharedLink: false,
|
||||
assets: [],
|
||||
@@ -395,9 +394,9 @@ describe('/album', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /album/:id/assets', () => {
|
||||
describe('PUT /albums/:id/assets', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/album/${user1Albums[0].id}/assets`);
|
||||
const { status, body } = await request(app).put(`/albums/${user1Albums[0].id}/assets`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
@@ -405,7 +404,7 @@ describe('/album', () => {
|
||||
it('should be able to add own asset to own album', async () => {
|
||||
const asset = await utils.createAsset(user1.accessToken);
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${user1Albums[0].id}/assets`)
|
||||
.put(`/albums/${user1Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [asset.id] });
|
||||
|
||||
@@ -416,7 +415,7 @@ describe('/album', () => {
|
||||
it('should be able to add own asset to shared album', async () => {
|
||||
const asset = await utils.createAsset(user1.accessToken);
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${user2Albums[0].id}/assets`)
|
||||
.put(`/albums/${user2Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [asset.id] });
|
||||
|
||||
@@ -427,7 +426,7 @@ describe('/album', () => {
|
||||
it('should not be able to add assets to album as a viewer', async () => {
|
||||
const asset = await utils.createAsset(user2.accessToken);
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${user1Albums[3].id}/assets`)
|
||||
.put(`/albums/${user1Albums[3].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ ids: [asset.id] });
|
||||
|
||||
@@ -438,7 +437,7 @@ describe('/album', () => {
|
||||
it('should add duplicate assets only once', async () => {
|
||||
const asset = await utils.createAsset(user1.accessToken);
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${user1Albums[0].id}/assets`)
|
||||
.put(`/albums/${user1Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [asset.id, asset.id] });
|
||||
|
||||
@@ -450,10 +449,10 @@ describe('/album', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PATCH /album/:id', () => {
|
||||
describe('PATCH /albums/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/album/${uuidDto.notFound}`)
|
||||
.patch(`/albums/${uuidDto.notFound}`)
|
||||
.send({ albumName: 'New album name' });
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -464,7 +463,7 @@ describe('/album', () => {
|
||||
albumName: 'New album',
|
||||
});
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/album/${album.id}`)
|
||||
.patch(`/albums/${album.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({
|
||||
albumName: 'New album name',
|
||||
@@ -481,7 +480,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to update as a viewer', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/album/${user1Albums[3].id}`)
|
||||
.patch(`/albums/${user1Albums[3].id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ albumName: 'New album name' });
|
||||
|
||||
@@ -491,7 +490,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to update as an editor', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/album/${user1Albums[0].id}`)
|
||||
.patch(`/albums/${user1Albums[0].id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ albumName: 'New album name' });
|
||||
|
||||
@@ -500,10 +499,10 @@ describe('/album', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /album/:id/assets', () => {
|
||||
describe('DELETE /albums/:id/assets', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user1Albums[0].id}/assets`)
|
||||
.delete(`/albums/${user1Albums[0].id}/assets`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
expect(status).toBe(401);
|
||||
@@ -512,7 +511,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to remove foreign asset from own album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user2Albums[0].id}/assets`)
|
||||
.delete(`/albums/${user2Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
@@ -528,7 +527,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to remove foreign asset from foreign album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user1Albums[0].id}/assets`)
|
||||
.delete(`/albums/${user1Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
@@ -544,7 +543,7 @@ describe('/album', () => {
|
||||
|
||||
it('should be able to remove own asset from own album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user1Albums[0].id}/assets`)
|
||||
.delete(`/albums/${user1Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
@@ -554,7 +553,7 @@ describe('/album', () => {
|
||||
|
||||
it('should be able to remove own asset from shared album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user2Albums[0].id}/assets`)
|
||||
.delete(`/albums/${user2Albums[0].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
@@ -564,7 +563,7 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to remove assets from album as a viewer', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user1Albums[3].id}/assets`)
|
||||
.delete(`/albums/${user1Albums[3].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id] });
|
||||
|
||||
@@ -574,7 +573,7 @@ describe('/album', () => {
|
||||
|
||||
it('should remove duplicate assets only once', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/album/${user1Albums[1].id}/assets`)
|
||||
.delete(`/albums/${user1Albums[1].id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ ids: [user1Asset1.id, user1Asset1.id] });
|
||||
|
||||
@@ -596,7 +595,7 @@ describe('/album', () => {
|
||||
});
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/album/${user1Albums[0].id}/users`).send({ sharedUserIds: [] });
|
||||
const { status, body } = await request(app).put(`/albums/${user1Albums[0].id}/users`).send({ sharedUserIds: [] });
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -604,21 +603,25 @@ describe('/album', () => {
|
||||
|
||||
it('should be able to add user to own album', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${album.id}/users`)
|
||||
.put(`/albums/${album.id}/users`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }] });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
sharedUsers: [expect.objectContaining({ id: user2.userId })],
|
||||
albumUsers: [
|
||||
expect.objectContaining({
|
||||
user: expect.objectContaining({ id: user2.userId }),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not be able to share album with owner', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${album.id}/users`)
|
||||
.put(`/albums/${album.id}/users`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ albumUsers: [{ userId: user1.userId, role: AlbumUserRole.Editor }] });
|
||||
|
||||
@@ -628,12 +631,12 @@ describe('/album', () => {
|
||||
|
||||
it('should not be able to add existing user to shared album', async () => {
|
||||
await request(app)
|
||||
.put(`/album/${album.id}/users`)
|
||||
.put(`/albums/${album.id}/users`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }] });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${album.id}/users`)
|
||||
.put(`/albums/${album.id}/users`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }] });
|
||||
|
||||
@@ -652,14 +655,16 @@ describe('/album', () => {
|
||||
expect(album.albumUsers[0].role).toEqual(AlbumUserRole.Viewer);
|
||||
|
||||
const { status } = await request(app)
|
||||
.put(`/album/${album.id}/user/${user2.userId}`)
|
||||
.put(`/albums/${album.id}/user/${user2.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ role: AlbumUserRole.Editor });
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
// Get album to verify the role change
|
||||
const { body } = await request(app).get(`/album/${album.id}`).set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
const { body } = await request(app)
|
||||
.get(`/albums/${album.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
albumUsers: [expect.objectContaining({ role: AlbumUserRole.Editor })],
|
||||
@@ -676,7 +681,7 @@ describe('/album', () => {
|
||||
expect(album.albumUsers[0].role).toEqual(AlbumUserRole.Viewer);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/album/${album.id}/user/${user2.userId}`)
|
||||
.put(`/albums/${album.id}/user/${user2.userId}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ role: AlbumUserRole.Editor });
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
LoginResponseDto,
|
||||
SharedLinkType,
|
||||
getAssetInfo,
|
||||
getMyUser,
|
||||
updateAssets,
|
||||
} from '@immich/sdk';
|
||||
import { exiftool } from 'exiftool-vendored';
|
||||
@@ -71,7 +72,7 @@ describe('/asset', () => {
|
||||
let stackAssets: AssetFileUploadResponseDto[];
|
||||
let locationAsset: AssetFileUploadResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTests = async () => {
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup({ onboarding: false });
|
||||
|
||||
@@ -85,6 +86,8 @@ describe('/asset', () => {
|
||||
utils.userSetup(admin.accessToken, createUserDto.create('stack')),
|
||||
]);
|
||||
|
||||
await utils.createPartner(user1.accessToken, user2.userId);
|
||||
|
||||
// asset location
|
||||
locationAsset = await utils.createAsset(admin.accessToken, {
|
||||
assetData: {
|
||||
@@ -154,7 +157,8 @@ describe('/asset', () => {
|
||||
assetId: user1Assets[0].id,
|
||||
personId: person1.id,
|
||||
});
|
||||
}, 30_000);
|
||||
};
|
||||
beforeAll(setupTests, 30_000);
|
||||
|
||||
afterAll(() => {
|
||||
utils.disconnectWebsocket(websocket);
|
||||
@@ -211,15 +215,18 @@ describe('/asset', () => {
|
||||
expect(body).toMatchObject({
|
||||
id: user1Assets[0].id,
|
||||
isFavorite: false,
|
||||
people: [
|
||||
{
|
||||
birthDate: null,
|
||||
id: expect.any(String),
|
||||
isHidden: false,
|
||||
name: 'Test Person',
|
||||
thumbnailPath: '/my/awesome/thumbnail.jpg',
|
||||
},
|
||||
],
|
||||
people: {
|
||||
visiblePeople: [
|
||||
{
|
||||
birthDate: null,
|
||||
id: expect.any(String),
|
||||
isHidden: false,
|
||||
name: 'Test Person',
|
||||
thumbnailPath: '/my/awesome/thumbnail.jpg',
|
||||
},
|
||||
],
|
||||
numberOfFaces: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const sharedLink = await utils.createSharedLink(user1.accessToken, {
|
||||
@@ -229,7 +236,36 @@ describe('/asset', () => {
|
||||
|
||||
const data = await request(app).get(`/asset/${user1Assets[0].id}?key=${sharedLink.key}`);
|
||||
expect(data.status).toBe(200);
|
||||
expect(data.body).toMatchObject({ people: [] });
|
||||
expect(data.body).not.toHaveProperty('people');
|
||||
});
|
||||
|
||||
describe('partner assets', () => {
|
||||
it('should get the asset info', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/asset/${user1Assets[0].id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ id: user1Assets[0].id });
|
||||
});
|
||||
|
||||
it('disallows viewing archived assets', async () => {
|
||||
const asset = await utils.createAsset(user1.accessToken, { isArchived: true });
|
||||
|
||||
const { status } = await request(app)
|
||||
.get(`/asset/${asset.id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`);
|
||||
expect(status).toBe(400);
|
||||
});
|
||||
|
||||
it('disallows viewing trashed assets', async () => {
|
||||
const asset = await utils.createAsset(user1.accessToken);
|
||||
await utils.deleteAssets(user1.accessToken, [asset.id]);
|
||||
|
||||
const { status } = await request(app)
|
||||
.get(`/asset/${asset.id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`);
|
||||
expect(status).toBe(400);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -478,15 +514,18 @@ describe('/asset', () => {
|
||||
expect(body).toMatchObject({
|
||||
id: user1Assets[0].id,
|
||||
isFavorite: true,
|
||||
people: [
|
||||
{
|
||||
birthDate: null,
|
||||
id: expect.any(String),
|
||||
isHidden: false,
|
||||
name: 'Test Person',
|
||||
thumbnailPath: '/my/awesome/thumbnail.jpg',
|
||||
},
|
||||
],
|
||||
people: {
|
||||
visiblePeople: [
|
||||
{
|
||||
birthDate: null,
|
||||
id: expect.any(String),
|
||||
isHidden: false,
|
||||
name: 'Test Person',
|
||||
thumbnailPath: '/my/awesome/thumbnail.jpg',
|
||||
},
|
||||
],
|
||||
numberOfFaces: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -538,14 +577,321 @@ describe('/asset', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset/thumbnail/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/asset/thumbnail/${locationAsset.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should not include gps data for webp thumbnails', async () => {
|
||||
await utils.waitForWebsocketEvent({
|
||||
event: 'assetUpload',
|
||||
id: locationAsset.id,
|
||||
});
|
||||
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/thumbnail/${locationAsset.id}?format=WEBP`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/webp');
|
||||
|
||||
const exifData = await readTags(body, 'thumbnail.webp');
|
||||
expect(exifData).not.toHaveProperty('GPSLongitude');
|
||||
expect(exifData).not.toHaveProperty('GPSLatitude');
|
||||
});
|
||||
|
||||
it('should not include gps data for jpeg thumbnails', async () => {
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/thumbnail/${locationAsset.id}?format=JPEG`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/jpeg');
|
||||
|
||||
const exifData = await readTags(body, 'thumbnail.jpg');
|
||||
expect(exifData).not.toHaveProperty('GPSLongitude');
|
||||
expect(exifData).not.toHaveProperty('GPSLatitude');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset/file/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/asset/thumbnail/${locationAsset.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should download the original', async () => {
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/file/${locationAsset.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/jpeg');
|
||||
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, locationAsset.id);
|
||||
|
||||
const original = await readFile(locationAssetFilepath);
|
||||
const originalChecksum = utils.sha1(original);
|
||||
const downloadChecksum = utils.sha1(body);
|
||||
|
||||
expect(originalChecksum).toBe(downloadChecksum);
|
||||
expect(downloadChecksum).toBe(asset.checksum);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset/map-marker', () => {
|
||||
beforeAll(async () => {
|
||||
const files = [
|
||||
'formats/avif/8bit-sRGB.avif',
|
||||
'formats/jpg/el_torcal_rocks.jpg',
|
||||
'formats/jxl/8bit-sRGB.jxl',
|
||||
'formats/heic/IMG_2682.heic',
|
||||
'formats/png/density_plot.png',
|
||||
'formats/raw/Nikon/D80/glarus.nef',
|
||||
'formats/raw/Nikon/D700/philadelphia.nef',
|
||||
'formats/raw/Panasonic/DMC-GH4/4_3.rw2',
|
||||
'formats/raw/Sony/ILCE-6300/12bit-compressed-(3_2).arw',
|
||||
'formats/raw/Sony/ILCE-7M2/14bit-uncompressed-(3_2).arw',
|
||||
];
|
||||
utils.resetEvents();
|
||||
const uploadFile = async (input: string) => {
|
||||
const filepath = join(testAssetDir, input);
|
||||
const { id } = await utils.createAsset(admin.accessToken, {
|
||||
assetData: { bytes: await readFile(filepath), filename: basename(filepath) },
|
||||
});
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id });
|
||||
};
|
||||
const uploads = files.map((f) => uploadFile(f));
|
||||
await Promise.all(uploads);
|
||||
}, 30_000);
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/asset/map-marker');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
// TODO archive one of these assets
|
||||
it('should get map markers for all non-archived assets', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/asset/map-marker')
|
||||
.query({ isArchived: false })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(2);
|
||||
expect(body).toEqual([
|
||||
{
|
||||
city: 'Palisade',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(39.115),
|
||||
lon: expect.closeTo(-108.400_968),
|
||||
state: 'Colorado',
|
||||
},
|
||||
{
|
||||
city: 'Ralston',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(41.2203),
|
||||
lon: expect.closeTo(-96.071_625),
|
||||
state: 'Nebraska',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
// TODO archive one of these assets
|
||||
it('should get all map markers', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/asset/map-marker')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual([
|
||||
{
|
||||
city: 'Palisade',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(39.115),
|
||||
lon: expect.closeTo(-108.400_968),
|
||||
state: 'Colorado',
|
||||
},
|
||||
{
|
||||
city: 'Ralston',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(41.2203),
|
||||
lon: expect.closeTo(-96.071_625),
|
||||
state: 'Nebraska',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /asset', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/asset');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require a valid parent id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ stackParentId: uuidDto.invalid, ids: [stackAssets[0].id] });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(['stackParentId must be a UUID']));
|
||||
});
|
||||
|
||||
it('should require access to the parent', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[3].id, ids: [user1Assets[0].id] });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.noPermission);
|
||||
});
|
||||
|
||||
it('should add stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[0].id, ids: [stackAssets[3].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(expect.arrayContaining([expect.objectContaining({ id: stackAssets[3].id })]));
|
||||
});
|
||||
|
||||
it('should remove stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ removeParent: true, ids: [stackAssets[1].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
expect.objectContaining({ id: stackAssets[3].id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove all stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ removeParent: true, ids: [stackAssets[2].id, stackAssets[3].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should merge stack children', async () => {
|
||||
// create stack after previous test removed stack children
|
||||
await updateAssets(
|
||||
{ assetBulkUpdateDto: { stackParentId: stackAssets[0].id, ids: [stackAssets[1].id, stackAssets[2].id] } },
|
||||
{ headers: asBearerAuth(stackUser.accessToken) },
|
||||
);
|
||||
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[3].id, ids: [stackAssets[0].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[3].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[0].id }),
|
||||
expect.objectContaining({ id: stackAssets[1].id }),
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /asset/stack/parent', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/asset/stack/parent');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require a valid id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ oldParentId: uuidDto.invalid, newParentId: uuidDto.invalid });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
|
||||
it('should require access', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ oldParentId: stackAssets[3].id, newParentId: stackAssets[0].id });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.noPermission);
|
||||
});
|
||||
|
||||
it('should make old parent child of new parent', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ oldParentId: stackAssets[3].id, newParentId: stackAssets[0].id });
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
|
||||
// new parent
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[1].id }),
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
expect.objectContaining({ id: stackAssets[3].id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('POST /asset/upload', () => {
|
||||
beforeAll(setupTests, 30_000);
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/asset/upload`);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
expect(status).toBe(401);
|
||||
});
|
||||
|
||||
const invalid = [
|
||||
it.each([
|
||||
{ should: 'require `deviceAssetId`', dto: { ...makeUploadDto({ omit: 'deviceAssetId' }) } },
|
||||
{ should: 'require `deviceId`', dto: { ...makeUploadDto({ omit: 'deviceId' }) } },
|
||||
{ should: 'require `fileCreatedAt`', dto: { ...makeUploadDto({ omit: 'fileCreatedAt' }) } },
|
||||
@@ -554,21 +900,17 @@ describe('/asset', () => {
|
||||
{ should: 'throw if `isFavorite` is not a boolean', dto: { ...makeUploadDto(), isFavorite: 'not-a-boolean' } },
|
||||
{ should: 'throw if `isVisible` is not a boolean', dto: { ...makeUploadDto(), isVisible: 'not-a-boolean' } },
|
||||
{ should: 'throw if `isArchived` is not a boolean', dto: { ...makeUploadDto(), isArchived: 'not-a-boolean' } },
|
||||
];
|
||||
])('should $should', async ({ dto }) => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/asset/upload')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.attach('assetData', makeRandomImage(), 'example.png')
|
||||
.field(dto);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
|
||||
for (const { should, dto } of invalid) {
|
||||
it(`should ${should}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/asset/upload')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.attach('assetData', makeRandomImage(), 'example.png')
|
||||
.field(dto);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
const tests = [
|
||||
it.each([
|
||||
{
|
||||
input: 'formats/avif/8bit-sRGB.avif',
|
||||
expected: {
|
||||
@@ -784,26 +1126,22 @@ describe('/asset', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for (const { input, expected } of tests) {
|
||||
it(`should upload and generate a thumbnail for ${input}`, async () => {
|
||||
const filepath = join(testAssetDir, input);
|
||||
const { id, duplicate } = await utils.createAsset(admin.accessToken, {
|
||||
assetData: { bytes: await readFile(filepath), filename: basename(filepath) },
|
||||
});
|
||||
|
||||
expect(duplicate).toBe(false);
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: id });
|
||||
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, id);
|
||||
|
||||
expect(asset.exifInfo).toBeDefined();
|
||||
expect(asset.exifInfo).toMatchObject(expected.exifInfo);
|
||||
expect(asset).toMatchObject(expected);
|
||||
])(`should upload and generate a thumbnail for $input`, async ({ input, expected }) => {
|
||||
const filepath = join(testAssetDir, input);
|
||||
const { id, duplicate } = await utils.createAsset(admin.accessToken, {
|
||||
assetData: { bytes: await readFile(filepath), filename: basename(filepath) },
|
||||
});
|
||||
}
|
||||
|
||||
expect(duplicate).toBe(false);
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: id });
|
||||
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, id);
|
||||
|
||||
expect(asset.exifInfo).toBeDefined();
|
||||
expect(asset.exifInfo).toMatchObject(expected.exifInfo);
|
||||
expect(asset).toMatchObject(expected);
|
||||
});
|
||||
|
||||
it('should handle a duplicate', async () => {
|
||||
const filepath = 'formats/jpeg/el_torcal_rocks.jpeg';
|
||||
@@ -830,7 +1168,7 @@ describe('/asset', () => {
|
||||
expect(body).toEqual({ id: expect.any(String), duplicate: false });
|
||||
expect(status).toBe(201);
|
||||
|
||||
const { body: user } = await request(app).get('/user/me').set('Authorization', `Bearer ${quotaUser.accessToken}`);
|
||||
const user = await getMyUser({ headers: asBearerAuth(quotaUser.accessToken) });
|
||||
|
||||
expect(user).toEqual(expect.objectContaining({ quotaUsageInBytes: 70 }));
|
||||
});
|
||||
@@ -854,7 +1192,7 @@ describe('/asset', () => {
|
||||
// This ensures that immich+exiftool are extracting the videos the same way Samsung does.
|
||||
// DO NOT assume immich+exiftool are doing things correctly and just copy whatever hash it gives
|
||||
// into the test here.
|
||||
const motionTests = [
|
||||
it.each([
|
||||
{
|
||||
filepath: 'formats/motionphoto/Samsung One UI 5.jpg',
|
||||
checksum: 'fr14niqCq6N20HB8rJYEvpsUVtI=',
|
||||
@@ -867,329 +1205,23 @@ describe('/asset', () => {
|
||||
filepath: 'formats/motionphoto/Samsung One UI 6.heic',
|
||||
checksum: '/ejgzywvgvzvVhUYVfvkLzFBAF0=',
|
||||
},
|
||||
];
|
||||
|
||||
for (const { filepath, checksum } of motionTests) {
|
||||
it(`should extract motionphoto video from ${filepath}`, async () => {
|
||||
const response = await utils.createAsset(admin.accessToken, {
|
||||
assetData: {
|
||||
bytes: await readFile(join(testAssetDir, filepath)),
|
||||
filename: basename(filepath),
|
||||
},
|
||||
});
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: response.id });
|
||||
|
||||
expect(response.duplicate).toBe(false);
|
||||
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, response.id);
|
||||
expect(asset.livePhotoVideoId).toBeDefined();
|
||||
|
||||
const video = await utils.getAssetInfo(admin.accessToken, asset.livePhotoVideoId as string);
|
||||
expect(video.checksum).toStrictEqual(checksum);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('GET /asset/thumbnail/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/asset/thumbnail/${locationAsset.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should not include gps data for webp thumbnails', async () => {
|
||||
await utils.waitForWebsocketEvent({
|
||||
event: 'assetUpload',
|
||||
id: locationAsset.id,
|
||||
])(`should extract motionphoto video from $filepath`, async ({ filepath, checksum }) => {
|
||||
const response = await utils.createAsset(admin.accessToken, {
|
||||
assetData: {
|
||||
bytes: await readFile(join(testAssetDir, filepath)),
|
||||
filename: basename(filepath),
|
||||
},
|
||||
});
|
||||
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/thumbnail/${locationAsset.id}?format=WEBP`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: response.id });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/webp');
|
||||
expect(response.duplicate).toBe(false);
|
||||
|
||||
const exifData = await readTags(body, 'thumbnail.webp');
|
||||
expect(exifData).not.toHaveProperty('GPSLongitude');
|
||||
expect(exifData).not.toHaveProperty('GPSLatitude');
|
||||
});
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, response.id);
|
||||
expect(asset.livePhotoVideoId).toBeDefined();
|
||||
|
||||
it('should not include gps data for jpeg thumbnails', async () => {
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/thumbnail/${locationAsset.id}?format=JPEG`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/jpeg');
|
||||
|
||||
const exifData = await readTags(body, 'thumbnail.jpg');
|
||||
expect(exifData).not.toHaveProperty('GPSLongitude');
|
||||
expect(exifData).not.toHaveProperty('GPSLatitude');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset/file/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/asset/thumbnail/${locationAsset.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should download the original', async () => {
|
||||
const { status, body, type } = await request(app)
|
||||
.get(`/asset/file/${locationAsset.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toBeDefined();
|
||||
expect(type).toBe('image/jpeg');
|
||||
|
||||
const asset = await utils.getAssetInfo(admin.accessToken, locationAsset.id);
|
||||
|
||||
const original = await readFile(locationAssetFilepath);
|
||||
const originalChecksum = utils.sha1(original);
|
||||
const downloadChecksum = utils.sha1(body);
|
||||
|
||||
expect(originalChecksum).toBe(downloadChecksum);
|
||||
expect(downloadChecksum).toBe(asset.checksum);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset/map-marker', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/asset/map-marker');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
// TODO archive one of these assets
|
||||
it('should get map markers for all non-archived assets', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/asset/map-marker')
|
||||
.query({ isArchived: false })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(2);
|
||||
expect(body).toEqual([
|
||||
{
|
||||
city: 'Palisade',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(39.115),
|
||||
lon: expect.closeTo(-108.400_968),
|
||||
state: 'Colorado',
|
||||
},
|
||||
{
|
||||
city: 'Ralston',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(41.2203),
|
||||
lon: expect.closeTo(-96.071_625),
|
||||
state: 'Nebraska',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
// TODO archive one of these assets
|
||||
it('should get all map markers', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/asset/map-marker')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual([
|
||||
{
|
||||
city: 'Palisade',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(39.115),
|
||||
lon: expect.closeTo(-108.400_968),
|
||||
state: 'Colorado',
|
||||
},
|
||||
{
|
||||
city: 'Ralston',
|
||||
country: 'United States of America',
|
||||
id: expect.any(String),
|
||||
lat: expect.closeTo(41.2203),
|
||||
lon: expect.closeTo(-96.071_625),
|
||||
state: 'Nebraska',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /asset', () => {
|
||||
it('should return stack data', async () => {
|
||||
const { status, body } = await request(app).get('/asset').set('Authorization', `Bearer ${stackUser.accessToken}`);
|
||||
|
||||
const stack = body.find((asset: AssetResponseDto) => asset.id === stackAssets[0].id);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(stack).toEqual(
|
||||
expect.objectContaining({
|
||||
stackCount: 3,
|
||||
stack:
|
||||
// Response includes children at the root level
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[1].id }),
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /asset', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/asset');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require a valid parent id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ stackParentId: uuidDto.invalid, ids: [stackAssets[0].id] });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(['stackParentId must be a UUID']));
|
||||
});
|
||||
|
||||
it('should require access to the parent', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[3].id, ids: [user1Assets[0].id] });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.noPermission);
|
||||
});
|
||||
|
||||
it('should add stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[0].id, ids: [stackAssets[3].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(expect.arrayContaining([expect.objectContaining({ id: stackAssets[3].id })]));
|
||||
});
|
||||
|
||||
it('should remove stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ removeParent: true, ids: [stackAssets[1].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
expect.objectContaining({ id: stackAssets[3].id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove all stack children', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ removeParent: true, ids: [stackAssets[2].id, stackAssets[3].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should merge stack children', async () => {
|
||||
// create stack after previous test removed stack children
|
||||
await updateAssets(
|
||||
{ assetBulkUpdateDto: { stackParentId: stackAssets[0].id, ids: [stackAssets[1].id, stackAssets[2].id] } },
|
||||
{ headers: asBearerAuth(stackUser.accessToken) },
|
||||
);
|
||||
|
||||
const { status } = await request(app)
|
||||
.put('/asset')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ stackParentId: stackAssets[3].id, ids: [stackAssets[0].id] });
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[3].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[0].id }),
|
||||
expect.objectContaining({ id: stackAssets[1].id }),
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /asset/stack/parent', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/asset/stack/parent');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require a valid id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ oldParentId: uuidDto.invalid, newParentId: uuidDto.invalid });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
|
||||
it('should require access', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ oldParentId: stackAssets[3].id, newParentId: stackAssets[0].id });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.noPermission);
|
||||
});
|
||||
|
||||
it('should make old parent child of new parent', async () => {
|
||||
const { status } = await request(app)
|
||||
.put('/asset/stack/parent')
|
||||
.set('Authorization', `Bearer ${stackUser.accessToken}`)
|
||||
.send({ oldParentId: stackAssets[3].id, newParentId: stackAssets[0].id });
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
const asset = await getAssetInfo({ id: stackAssets[0].id }, { headers: asBearerAuth(stackUser.accessToken) });
|
||||
|
||||
// new parent
|
||||
expect(asset.stack).not.toBeUndefined();
|
||||
expect(asset.stack).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ id: stackAssets[1].id }),
|
||||
expect.objectContaining({ id: stackAssets[2].id }),
|
||||
expect.objectContaining({ id: stackAssets[3].id }),
|
||||
]),
|
||||
);
|
||||
const video = await utils.getAssetInfo(admin.accessToken, asset.livePhotoVideoId as string);
|
||||
expect(video.checksum).toStrictEqual(checksum);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { deleteAssets, getAuditFiles, updateAsset, type LoginResponseDto } from
|
||||
import { asBearerAuth, utils } from 'src/utils';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/audit', () => {
|
||||
describe('/audits', () => {
|
||||
let admin: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
const scan = async (accessToken: string, id: string, dto: ScanLibraryDto = {}) =>
|
||||
scanLibrary({ id, scanLibraryDto: dto }, { headers: asBearerAuth(accessToken) });
|
||||
|
||||
describe('/library', () => {
|
||||
describe('/libraries', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let user: LoginResponseDto;
|
||||
let library: LibraryResponseDto;
|
||||
@@ -37,24 +37,24 @@ describe('/library', () => {
|
||||
utils.resetEvents();
|
||||
});
|
||||
|
||||
describe('GET /library', () => {
|
||||
describe('GET /libraries', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/library');
|
||||
const { status, body } = await request(app).get('/libraries');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /library', () => {
|
||||
describe('POST /libraries', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post('/library').send({});
|
||||
const { status, body } = await request(app).post('/libraries').send({});
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require admin authentication', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/library')
|
||||
.post('/libraries')
|
||||
.set('Authorization', `Bearer ${user.accessToken}`)
|
||||
.send({ ownerId: admin.userId });
|
||||
|
||||
@@ -64,7 +64,7 @@ describe('/library', () => {
|
||||
|
||||
it('should create an external library with defaults', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/library')
|
||||
.post('/libraries')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ownerId: admin.userId });
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('/library', () => {
|
||||
|
||||
it('should create an external library with options', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/library')
|
||||
.post('/libraries')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
ownerId: admin.userId,
|
||||
@@ -103,7 +103,7 @@ describe('/library', () => {
|
||||
|
||||
it('should not create an external library with duplicate import paths', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/library')
|
||||
.post('/libraries')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
ownerId: admin.userId,
|
||||
@@ -118,7 +118,7 @@ describe('/library', () => {
|
||||
|
||||
it('should not create an external library with duplicate exclusion patterns', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/library')
|
||||
.post('/libraries')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
ownerId: admin.userId,
|
||||
@@ -132,16 +132,16 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /library/:id', () => {
|
||||
describe('PUT /libraries/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/library/${uuidDto.notFound}`).send({});
|
||||
const { status, body } = await request(app).put(`/libraries/${uuidDto.notFound}`).send({});
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should change the library name', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ name: 'New Library Name' });
|
||||
|
||||
@@ -155,7 +155,7 @@ describe('/library', () => {
|
||||
|
||||
it('should not set an empty name', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ name: '' });
|
||||
|
||||
@@ -165,7 +165,7 @@ describe('/library', () => {
|
||||
|
||||
it('should change the import paths', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ importPaths: [testAssetDirInternal] });
|
||||
|
||||
@@ -179,7 +179,7 @@ describe('/library', () => {
|
||||
|
||||
it('should reject an empty import path', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ importPaths: [''] });
|
||||
|
||||
@@ -189,7 +189,7 @@ describe('/library', () => {
|
||||
|
||||
it('should reject duplicate import paths', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ importPaths: ['/path', '/path'] });
|
||||
|
||||
@@ -199,7 +199,7 @@ describe('/library', () => {
|
||||
|
||||
it('should change the exclusion pattern', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ exclusionPatterns: ['**/Raw/**'] });
|
||||
|
||||
@@ -213,7 +213,7 @@ describe('/library', () => {
|
||||
|
||||
it('should reject duplicate exclusion patterns', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ exclusionPatterns: ['**/*.jpg', '**/*.jpg'] });
|
||||
|
||||
@@ -223,7 +223,7 @@ describe('/library', () => {
|
||||
|
||||
it('should reject an empty exclusion pattern', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/library/${library.id}`)
|
||||
.put(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ exclusionPatterns: [''] });
|
||||
|
||||
@@ -232,9 +232,9 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /library/:id', () => {
|
||||
describe('GET /libraries/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/library/${uuidDto.notFound}`);
|
||||
const { status, body } = await request(app).get(`/libraries/${uuidDto.notFound}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -242,7 +242,7 @@ describe('/library', () => {
|
||||
|
||||
it('should require admin access', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/library/${uuidDto.notFound}`)
|
||||
.get(`/libraries/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${user.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
@@ -252,7 +252,7 @@ describe('/library', () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, { ownerId: admin.userId });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get(`/library/${library.id}`)
|
||||
.get(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -269,18 +269,18 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /library/:id/statistics', () => {
|
||||
describe('GET /libraries/:id/statistics', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/library/${uuidDto.notFound}/statistics`);
|
||||
const { status, body } = await request(app).get(`/libraries/${uuidDto.notFound}/statistics`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /library/:id/scan', () => {
|
||||
describe('POST /libraries/:id/scan', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/library/${uuidDto.notFound}/scan`).send({});
|
||||
const { status, body } = await request(app).post(`/libraries/${uuidDto.notFound}/scan`).send({});
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -496,9 +496,9 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /library/:id/removeOffline', () => {
|
||||
describe('POST /libraries/:id/removeOffline', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/library/${uuidDto.notFound}/removeOffline`).send({});
|
||||
const { status, body } = await request(app).post(`/libraries/${uuidDto.notFound}/removeOffline`).send({});
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -532,7 +532,7 @@ describe('/library', () => {
|
||||
expect(offlineAssets.count).toBe(1);
|
||||
|
||||
const { status } = await request(app)
|
||||
.post(`/library/${library.id}/removeOffline`)
|
||||
.post(`/libraries/${library.id}/removeOffline`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
expect(status).toBe(204);
|
||||
@@ -557,7 +557,7 @@ describe('/library', () => {
|
||||
expect(assetsBefore.count).toBeGreaterThan(1);
|
||||
|
||||
const { status } = await request(app)
|
||||
.post(`/library/${library.id}/removeOffline`)
|
||||
.post(`/libraries/${library.id}/removeOffline`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send();
|
||||
expect(status).toBe(204);
|
||||
@@ -569,9 +569,9 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /library/:id/validate', () => {
|
||||
describe('POST /libraries/:id/validate', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/library/${uuidDto.notFound}/validate`).send({});
|
||||
const { status, body } = await request(app).post(`/libraries/${uuidDto.notFound}/validate`).send({});
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -617,9 +617,9 @@ describe('/library', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /library/:id', () => {
|
||||
describe('DELETE /libraries/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/library/${uuidDto.notFound}`);
|
||||
const { status, body } = await request(app).delete(`/libraries/${uuidDto.notFound}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -629,7 +629,7 @@ describe('/library', () => {
|
||||
const library = await utils.createLibrary(admin.accessToken, { ownerId: admin.userId });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/library/${library.id}`)
|
||||
.delete(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(204);
|
||||
@@ -655,7 +655,7 @@ describe('/library', () => {
|
||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', total: 2 });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/library/${library.id}`)
|
||||
.delete(`/libraries/${library.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(204);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/partner', () => {
|
||||
describe('/partners', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let user1: LoginResponseDto;
|
||||
let user2: LoginResponseDto;
|
||||
@@ -28,9 +28,9 @@ describe('/partner', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
describe('GET /partner', () => {
|
||||
describe('GET /partners', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/partner');
|
||||
const { status, body } = await request(app).get('/partners');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -38,7 +38,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should get all partners shared by user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/partner')
|
||||
.get('/partners')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.query({ direction: 'shared-by' });
|
||||
|
||||
@@ -48,7 +48,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should get all partners that share with user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/partner')
|
||||
.get('/partners')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.query({ direction: 'shared-with' });
|
||||
|
||||
@@ -57,9 +57,9 @@ describe('/partner', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /partner/:id', () => {
|
||||
describe('POST /partners/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/partner/${user3.userId}`);
|
||||
const { status, body } = await request(app).post(`/partners/${user3.userId}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -67,7 +67,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should share with new partner', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/partner/${user3.userId}`)
|
||||
.post(`/partners/${user3.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(201);
|
||||
@@ -76,7 +76,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should not share with new partner if already sharing with this partner', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/partner/${user2.userId}`)
|
||||
.post(`/partners/${user2.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -84,9 +84,9 @@ describe('/partner', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /partner/:id', () => {
|
||||
describe('PUT /partners/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/partner/${user2.userId}`);
|
||||
const { status, body } = await request(app).put(`/partners/${user2.userId}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -94,7 +94,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should update partner', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/partner/${user2.userId}`)
|
||||
.put(`/partners/${user2.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ inTimeline: false });
|
||||
|
||||
@@ -103,9 +103,9 @@ describe('/partner', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /partner/:id', () => {
|
||||
describe('DELETE /partners/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/partner/${user3.userId}`);
|
||||
const { status, body } = await request(app).delete(`/partners/${user3.userId}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -113,7 +113,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should delete partner', async () => {
|
||||
const { status } = await request(app)
|
||||
.delete(`/partner/${user3.userId}`)
|
||||
.delete(`/partners/${user3.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -121,7 +121,7 @@ describe('/partner', () => {
|
||||
|
||||
it('should throw a bad request if partner not found', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/partner/${user3.userId}`)
|
||||
.delete(`/partners/${user3.userId}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
|
||||
@@ -12,7 +12,7 @@ const invalidBirthday = [
|
||||
{ birthDate: new Date(9999, 0, 0).toISOString(), response: ['Birth date cannot be in the future'] },
|
||||
];
|
||||
|
||||
describe('/person', () => {
|
||||
describe('/people', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let visiblePerson: PersonResponseDto;
|
||||
let hiddenPerson: PersonResponseDto;
|
||||
@@ -47,11 +47,11 @@ describe('/person', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
describe('GET /person', () => {
|
||||
describe('GET /people', () => {
|
||||
beforeEach(async () => {});
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/person');
|
||||
const { status, body } = await request(app).get('/people');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -59,7 +59,7 @@ describe('/person', () => {
|
||||
|
||||
it('should return all people (including hidden)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/person')
|
||||
.get('/people')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.query({ withHidden: true });
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('/person', () => {
|
||||
});
|
||||
|
||||
it('should return only visible people', async () => {
|
||||
const { status, body } = await request(app).get('/person').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
const { status, body } = await request(app).get('/people').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
@@ -90,9 +90,9 @@ describe('/person', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /person/:id', () => {
|
||||
describe('GET /people/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/person/${uuidDto.notFound}`);
|
||||
const { status, body } = await request(app).get(`/people/${uuidDto.notFound}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -100,7 +100,7 @@ describe('/person', () => {
|
||||
|
||||
it('should throw error if person with id does not exist', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/person/${uuidDto.notFound}`)
|
||||
.get(`/people/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -109,7 +109,7 @@ describe('/person', () => {
|
||||
|
||||
it('should return person information', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/person/${visiblePerson.id}`)
|
||||
.get(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -117,9 +117,9 @@ describe('/person', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /person/:id/statistics', () => {
|
||||
describe('GET /people/:id/statistics', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/person/${multipleAssetsPerson.id}/statistics`);
|
||||
const { status, body } = await request(app).get(`/people/${multipleAssetsPerson.id}/statistics`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -127,7 +127,7 @@ describe('/person', () => {
|
||||
|
||||
it('should throw error if person with id does not exist', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/person/${uuidDto.notFound}/statistics`)
|
||||
.get(`/people/${uuidDto.notFound}/statistics`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -136,7 +136,7 @@ describe('/person', () => {
|
||||
|
||||
it('should return the correct number of assets', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/person/${multipleAssetsPerson.id}/statistics`)
|
||||
.get(`/people/${multipleAssetsPerson.id}/statistics`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -144,9 +144,9 @@ describe('/person', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /person', () => {
|
||||
describe('POST /people', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/person`);
|
||||
const { status, body } = await request(app).post(`/people`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
@@ -154,7 +154,7 @@ describe('/person', () => {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
it(`should not accept an invalid birth date [${birthDate}]`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/person`)
|
||||
.post(`/people`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate });
|
||||
expect(status).toBe(400);
|
||||
@@ -164,7 +164,7 @@ describe('/person', () => {
|
||||
|
||||
it('should create a person', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/person`)
|
||||
.post(`/people`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
name: 'New Person',
|
||||
@@ -179,9 +179,9 @@ describe('/person', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /person/:id', () => {
|
||||
describe('PUT /people/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/person/${uuidDto.notFound}`);
|
||||
const { status, body } = await request(app).put(`/people/${uuidDto.notFound}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
@@ -193,7 +193,7 @@ describe('/person', () => {
|
||||
]) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/person/${visiblePerson.id}`)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ [key]: null });
|
||||
expect(status).toBe(400);
|
||||
@@ -204,7 +204,7 @@ describe('/person', () => {
|
||||
for (const { birthDate, response } of invalidBirthday) {
|
||||
it(`should not accept an invalid birth date [${birthDate}]`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/person/${visiblePerson.id}`)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate });
|
||||
expect(status).toBe(400);
|
||||
@@ -214,7 +214,7 @@ describe('/person', () => {
|
||||
|
||||
it('should update a date of birth', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/person/${visiblePerson.id}`)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate: '1990-01-01T05:00:00.000Z' });
|
||||
expect(status).toBe(200);
|
||||
@@ -223,7 +223,7 @@ describe('/person', () => {
|
||||
|
||||
it('should clear a date of birth', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/person/${visiblePerson.id}`)
|
||||
.put(`/people/${visiblePerson.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ birthDate: null });
|
||||
expect(status).toBe(200);
|
||||
|
||||
@@ -15,16 +15,16 @@ describe('/server-info', () => {
|
||||
nonAdmin = await utils.userSetup(admin.accessToken, createUserDto.user1);
|
||||
});
|
||||
|
||||
describe('GET /server-info', () => {
|
||||
describe('GET /server-info/storage', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/server-info');
|
||||
const { status, body } = await request(app).get('/server-info/storage');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should return the disk information', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/server-info')
|
||||
.get('/server-info/storage')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
SharedLinkResponseDto,
|
||||
SharedLinkType,
|
||||
createAlbum,
|
||||
deleteUser,
|
||||
deleteUserAdmin,
|
||||
} from '@immich/sdk';
|
||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
@@ -13,7 +13,7 @@ import { app, asBearerAuth, shareUrl, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/shared-link', () => {
|
||||
describe('/shared-links', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let asset1: AssetFileUploadResponseDto;
|
||||
let asset2: AssetFileUploadResponseDto;
|
||||
@@ -86,7 +86,7 @@ describe('/shared-link', () => {
|
||||
}),
|
||||
]);
|
||||
|
||||
await deleteUser({ id: user2.userId, deleteUserDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
await deleteUserAdmin({ id: user2.userId, userAdminDeleteDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
});
|
||||
|
||||
describe('GET /share/${key}', () => {
|
||||
@@ -114,9 +114,9 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /shared-link', () => {
|
||||
describe('GET /shared-links', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link');
|
||||
const { status, body } = await request(app).get('/shared-links');
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -124,7 +124,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should get all shared links created by user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/shared-link')
|
||||
.get('/shared-links')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -142,7 +142,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should not get shared links created by other users', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/shared-link')
|
||||
.get('/shared-links')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -150,15 +150,15 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /shared-link/me', () => {
|
||||
describe('GET /shared-links/me', () => {
|
||||
it('should not require admin authentication', async () => {
|
||||
const { status } = await request(app).get('/shared-link/me').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
const { status } = await request(app).get('/shared-links/me').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(403);
|
||||
});
|
||||
|
||||
it('should get data for correct shared link', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link/me').query({ key: linkWithAlbum.key });
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithAlbum.key });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
@@ -172,7 +172,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should return unauthorized for incorrect shared link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/shared-link/me')
|
||||
.get('/shared-links/me')
|
||||
.query({ key: linkWithAlbum.key + 'foo' });
|
||||
|
||||
expect(status).toBe(401);
|
||||
@@ -180,14 +180,14 @@ describe('/shared-link', () => {
|
||||
});
|
||||
|
||||
it('should return unauthorized if target has been soft deleted', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link/me').query({ key: linkWithDeletedAlbum.key });
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithDeletedAlbum.key });
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.invalidShareKey);
|
||||
});
|
||||
|
||||
it('should return unauthorized for password protected link', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link/me').query({ key: linkWithPassword.key });
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithPassword.key });
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.invalidSharePassword);
|
||||
@@ -195,7 +195,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should get data for correct password protected link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/shared-link/me')
|
||||
.get('/shared-links/me')
|
||||
.query({ key: linkWithPassword.key, password: 'foo' });
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -209,7 +209,7 @@ describe('/shared-link', () => {
|
||||
});
|
||||
|
||||
it('should return metadata for album shared link', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link/me').query({ key: linkWithMetadata.key });
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithMetadata.key });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body.assets).toHaveLength(1);
|
||||
@@ -225,7 +225,7 @@ describe('/shared-link', () => {
|
||||
});
|
||||
|
||||
it('should not return metadata for album shared link without metadata', async () => {
|
||||
const { status, body } = await request(app).get('/shared-link/me').query({ key: linkWithoutMetadata.key });
|
||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithoutMetadata.key });
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body.assets).toHaveLength(1);
|
||||
@@ -239,9 +239,9 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /shared-link/:id', () => {
|
||||
describe('GET /shared-links/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/shared-link/${linkWithAlbum.id}`);
|
||||
const { status, body } = await request(app).get(`/shared-links/${linkWithAlbum.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -249,7 +249,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should get shared link by id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/shared-link/${linkWithAlbum.id}`)
|
||||
.get(`/shared-links/${linkWithAlbum.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -264,7 +264,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should not get shared link by id if user has not created the link or it does not exist', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/shared-link/${linkWithAlbum.id}`)
|
||||
.get(`/shared-links/${linkWithAlbum.id}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -272,10 +272,10 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /shared-link', () => {
|
||||
describe('POST /shared-links', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/shared-link')
|
||||
.post('/shared-links')
|
||||
.send({ type: SharedLinkType.Album, albumId: uuidDto.notFound });
|
||||
|
||||
expect(status).toBe(401);
|
||||
@@ -284,7 +284,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should require a type and the correspondent asset/album id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/shared-link')
|
||||
.post('/shared-links')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -293,7 +293,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should require an asset/album id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/shared-link')
|
||||
.post('/shared-links')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ type: SharedLinkType.Album });
|
||||
|
||||
@@ -303,7 +303,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should require a valid asset id', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/shared-link')
|
||||
.post('/shared-links')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ type: SharedLinkType.Individual, assetId: uuidDto.notFound });
|
||||
|
||||
@@ -313,7 +313,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should create a shared link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post('/shared-link')
|
||||
.post('/shared-links')
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ type: SharedLinkType.Album, albumId: album.id });
|
||||
|
||||
@@ -327,10 +327,10 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PATCH /shared-link/:id', () => {
|
||||
describe('PATCH /shared-links/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/shared-link/${linkWithAlbum.id}`)
|
||||
.patch(`/shared-links/${linkWithAlbum.id}`)
|
||||
.send({ description: 'foo' });
|
||||
|
||||
expect(status).toBe(401);
|
||||
@@ -339,7 +339,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should fail if invalid link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/shared-link/${uuidDto.notFound}`)
|
||||
.patch(`/shared-links/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ description: 'foo' });
|
||||
|
||||
@@ -349,7 +349,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should update shared link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/shared-link/${linkWithAlbum.id}`)
|
||||
.patch(`/shared-links/${linkWithAlbum.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ description: 'foo' });
|
||||
|
||||
@@ -364,10 +364,10 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /shared-link/:id/assets', () => {
|
||||
describe('PUT /shared-links/:id/assets', () => {
|
||||
it('should not add assets to shared link (album)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/shared-link/${linkWithAlbum.id}/assets`)
|
||||
.put(`/shared-links/${linkWithAlbum.id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ assetIds: [asset2.id] });
|
||||
|
||||
@@ -377,7 +377,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should add an assets to a shared link (individual)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/shared-link/${linkWithAssets.id}/assets`)
|
||||
.put(`/shared-links/${linkWithAssets.id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ assetIds: [asset2.id] });
|
||||
|
||||
@@ -386,10 +386,10 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /shared-link/:id/assets', () => {
|
||||
describe('DELETE /shared-links/:id/assets', () => {
|
||||
it('should not remove assets from a shared link (album)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/shared-link/${linkWithAlbum.id}/assets`)
|
||||
.delete(`/shared-links/${linkWithAlbum.id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ assetIds: [asset2.id] });
|
||||
|
||||
@@ -399,7 +399,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should remove assets from a shared link (individual)', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/shared-link/${linkWithAssets.id}/assets`)
|
||||
.delete(`/shared-links/${linkWithAssets.id}/assets`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
||||
.send({ assetIds: [asset2.id] });
|
||||
|
||||
@@ -408,9 +408,9 @@ describe('/shared-link', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /shared-link/:id', () => {
|
||||
describe('DELETE /shared-links/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/shared-link/${linkWithAlbum.id}`);
|
||||
const { status, body } = await request(app).delete(`/shared-links/${linkWithAlbum.id}`);
|
||||
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
@@ -418,7 +418,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should fail if invalid link', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/shared-link/${uuidDto.notFound}`)
|
||||
.delete(`/shared-links/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
@@ -427,7 +427,7 @@ describe('/shared-link', () => {
|
||||
|
||||
it('should delete a shared link', async () => {
|
||||
const { status } = await request(app)
|
||||
.delete(`/shared-link/${linkWithAlbum.id}`)
|
||||
.delete(`/shared-links/${linkWithAlbum.id}`)
|
||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LoginResponseDto, getAllAssets } from '@immich/sdk';
|
||||
import { LoginResponseDto, getAssetInfo, getAssetStatistics } from '@immich/sdk';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, utils } from 'src/utils';
|
||||
@@ -31,16 +31,16 @@ describe('/trash', () => {
|
||||
const { id: assetId } = await utils.createAsset(admin.accessToken);
|
||||
await utils.deleteAssets(admin.accessToken, [assetId]);
|
||||
|
||||
const before = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(before).toStrictEqual([expect.objectContaining({ id: assetId, isTrashed: true })]);
|
||||
const before = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(before).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: true }));
|
||||
|
||||
const { status } = await request(app).post('/trash/empty').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(204);
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'assetDelete', id: assetId });
|
||||
|
||||
const after = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after.length).toBe(0);
|
||||
const after = await getAssetStatistics({ isTrashed: true }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after.total).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,14 +56,14 @@ describe('/trash', () => {
|
||||
const { id: assetId } = await utils.createAsset(admin.accessToken);
|
||||
await utils.deleteAssets(admin.accessToken, [assetId]);
|
||||
|
||||
const before = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(before).toStrictEqual([expect.objectContaining({ id: assetId, isTrashed: true })]);
|
||||
const before = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(before).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: true }));
|
||||
|
||||
const { status } = await request(app).post('/trash/restore').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(204);
|
||||
|
||||
const after = await getAllAssets({}, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toStrictEqual([expect.objectContaining({ id: assetId, isTrashed: false })]);
|
||||
const after = await getAssetInfo({ id: assetId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after).toStrictEqual(expect.objectContaining({ id: assetId, isTrashed: false }));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
317
e2e/src/api/specs/user-admin.e2e-spec.ts
Normal file
317
e2e/src/api/specs/user-admin.e2e-spec.ts
Normal file
@@ -0,0 +1,317 @@
|
||||
import { LoginResponseDto, deleteUserAdmin, getMyUser, getUserAdmin, login } from '@immich/sdk';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/admin/users', () => {
|
||||
let websocket: Socket;
|
||||
|
||||
let admin: LoginResponseDto;
|
||||
let nonAdmin: LoginResponseDto;
|
||||
let deletedUser: LoginResponseDto;
|
||||
let userToDelete: LoginResponseDto;
|
||||
let userToHardDelete: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup({ onboarding: false });
|
||||
|
||||
[websocket, nonAdmin, deletedUser, userToDelete, userToHardDelete] = await Promise.all([
|
||||
utils.connectWebsocket(admin.accessToken),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user1),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user2),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user3),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user4),
|
||||
]);
|
||||
|
||||
await deleteUserAdmin(
|
||||
{ id: deletedUser.userId, userAdminDeleteDto: {} },
|
||||
{ headers: asBearerAuth(admin.accessToken) },
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
utils.disconnectWebsocket(websocket);
|
||||
});
|
||||
|
||||
describe('GET /admin/users', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/admin/users`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require authorization', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/admin/users`)
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should hide deleted users by default', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/admin/users`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(4);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: admin.userEmail }),
|
||||
expect.objectContaining({ email: nonAdmin.userEmail }),
|
||||
expect.objectContaining({ email: userToDelete.userEmail }),
|
||||
expect.objectContaining({ email: userToHardDelete.userEmail }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should include deleted users', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/admin/users?withDeleted=true`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(5);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: admin.userEmail }),
|
||||
expect.objectContaining({ email: nonAdmin.userEmail }),
|
||||
expect.objectContaining({ email: userToDelete.userEmail }),
|
||||
expect.objectContaining({ email: userToHardDelete.userEmail }),
|
||||
expect.objectContaining({ email: deletedUser.userEmail }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /admin/users', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/admin/users`).send(createUserDto.user1);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require authorization', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users`)
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`)
|
||||
.send(createUserDto.user1);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
for (const key of [
|
||||
'password',
|
||||
'email',
|
||||
'name',
|
||||
'quotaSizeInBytes',
|
||||
'shouldChangePassword',
|
||||
'memoriesEnabled',
|
||||
'notify',
|
||||
]) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ...createUserDto.user1, [key]: null });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it('should ignore `isAdmin`', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users`)
|
||||
.send({
|
||||
isAdmin: true,
|
||||
email: 'user5@immich.cloud',
|
||||
password: 'password123',
|
||||
name: 'Immich',
|
||||
})
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(body).toMatchObject({
|
||||
email: 'user5@immich.cloud',
|
||||
isAdmin: false,
|
||||
shouldChangePassword: true,
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
});
|
||||
|
||||
it('should create a user without memories enabled', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users`)
|
||||
.send({
|
||||
email: 'no-memories@immich.cloud',
|
||||
password: 'Password123',
|
||||
name: 'No Memories',
|
||||
memoriesEnabled: false,
|
||||
})
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(body).toMatchObject({
|
||||
email: 'no-memories@immich.cloud',
|
||||
memoriesEnabled: false,
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /admin/users/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/admin/users/${uuidDto.notFound}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require authorization', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
for (const key of ['password', 'email', 'name', 'shouldChangePassword', 'memoriesEnabled']) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${uuidDto.notFound}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ [key]: null });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it('should not allow a non-admin to become an admin', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${nonAdmin.userId}`)
|
||||
.send({ isAdmin: true })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ isAdmin: false });
|
||||
});
|
||||
|
||||
it('ignores updates to profileImagePath', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}`)
|
||||
.send({ profileImagePath: 'invalid.jpg' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ id: admin.userId, profileImagePath: '' });
|
||||
});
|
||||
|
||||
it('should update first and last name', async () => {
|
||||
const before = await getUserAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}`)
|
||||
.send({ name: 'Name' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
...before,
|
||||
updatedAt: expect.any(String),
|
||||
name: 'Name',
|
||||
});
|
||||
expect(before.updatedAt).not.toEqual(body.updatedAt);
|
||||
});
|
||||
|
||||
it('should update memories enabled', async () => {
|
||||
const before = await getUserAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${admin.userId}`)
|
||||
.send({ memoriesEnabled: false })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
...before,
|
||||
updatedAt: expect.anything(),
|
||||
memoriesEnabled: false,
|
||||
});
|
||||
expect(before.updatedAt).not.toEqual(body.updatedAt);
|
||||
});
|
||||
|
||||
it('should update password', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/admin/users/${nonAdmin.userId}`)
|
||||
.send({ password: 'super-secret' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ email: nonAdmin.userEmail });
|
||||
|
||||
const token = await login({ loginCredentialDto: { email: nonAdmin.userEmail, password: 'super-secret' } });
|
||||
expect(token.accessToken).toBeDefined();
|
||||
|
||||
const user = await getMyUser({ headers: asBearerAuth(token.accessToken) });
|
||||
expect(user).toMatchObject({ email: nonAdmin.userEmail });
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /admin/users/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/admin/users/${userToDelete.userId}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require authorization', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/admin/users/${userToDelete.userId}`)
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should delete user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/admin/users/${userToDelete.userId}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: userToDelete.userId,
|
||||
updatedAt: expect.any(String),
|
||||
deletedAt: expect.any(String),
|
||||
});
|
||||
});
|
||||
|
||||
it('should hard delete a user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/admin/users/${userToHardDelete.userId}`)
|
||||
.send({ force: true })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: userToHardDelete.userId,
|
||||
updatedAt: expect.any(String),
|
||||
deletedAt: expect.any(String),
|
||||
});
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'userDelete', id: userToHardDelete.userId, timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /admin/users/:id/restore', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/admin/users/${userToDelete.userId}/restore`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should require authorization', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/admin/users/${userToDelete.userId}/restore`)
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,288 +1,105 @@
|
||||
import { LoginResponseDto, deleteUser, getUserById } from '@immich/sdk';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { createUserDto, userDto } from 'src/fixtures';
|
||||
import { LoginResponseDto, SharedLinkType, deleteUserAdmin, getMyUser, login } from '@immich/sdk';
|
||||
import { createUserDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/user', () => {
|
||||
let websocket: Socket;
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
describe('/users', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let deletedUser: LoginResponseDto;
|
||||
let userToDelete: LoginResponseDto;
|
||||
let userToHardDelete: LoginResponseDto;
|
||||
let nonAdmin: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup({ onboarding: false });
|
||||
|
||||
[websocket, deletedUser, nonAdmin, userToDelete, userToHardDelete] = await Promise.all([
|
||||
utils.connectWebsocket(admin.accessToken),
|
||||
[deletedUser, nonAdmin] = await Promise.all([
|
||||
utils.userSetup(admin.accessToken, createUserDto.user1),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user2),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user3),
|
||||
utils.userSetup(admin.accessToken, createUserDto.user4),
|
||||
]);
|
||||
|
||||
await deleteUser({ id: deletedUser.userId, deleteUserDto: {} }, { headers: asBearerAuth(admin.accessToken) });
|
||||
await deleteUserAdmin(
|
||||
{ id: deletedUser.userId, userAdminDeleteDto: {} },
|
||||
{ headers: asBearerAuth(admin.accessToken) },
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
utils.disconnectWebsocket(websocket);
|
||||
});
|
||||
|
||||
describe('GET /user', () => {
|
||||
describe('GET /users', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/user');
|
||||
const { status, body } = await request(app).get('/users');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should get users', async () => {
|
||||
const { status, body } = await request(app).get('/user').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
const { status, body } = await request(app).get('/users').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
expect(body).toHaveLength(5);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: 'admin@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user1@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user2@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user3@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user4@immich.cloud' }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should hide deleted users', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/user`)
|
||||
.query({ isAll: true })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(4);
|
||||
expect(body).toHaveLength(2);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: 'admin@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user2@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user3@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user4@immich.cloud' }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should include deleted users', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/user`)
|
||||
.query({ isAll: false })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toHaveLength(5);
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ email: 'admin@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user1@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user2@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user3@immich.cloud' }),
|
||||
expect.objectContaining({ email: 'user4@immich.cloud' }),
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /user/info/:id', () => {
|
||||
describe('GET /users/me', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status } = await request(app).get(`/user/info/${admin.userId}`);
|
||||
expect(status).toEqual(401);
|
||||
const { status, body } = await request(app).get(`/users/me`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should get the user info', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/user/info/${admin.userId}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
it('should not work for shared links', async () => {
|
||||
const album = await utils.createAlbum(admin.accessToken, { albumName: 'Album' });
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Album,
|
||||
albumId: album.id,
|
||||
});
|
||||
const { status, body } = await request(app).get(`/users/me?key=${sharedLink.key}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should get my user', async () => {
|
||||
const { status, body } = await request(app).get(`/users/me`).set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: admin.userId,
|
||||
email: 'admin@immich.cloud',
|
||||
memoriesEnabled: true,
|
||||
quotaUsageInBytes: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /user/me', () => {
|
||||
describe('PUT /users/me', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get(`/user/me`);
|
||||
const { status, body } = await request(app).put(`/users/me`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should get my info', async () => {
|
||||
const { status, body } = await request(app).get(`/user/me`).set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: admin.userId,
|
||||
email: 'admin@immich.cloud',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /user', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).post(`/user`).send(createUserDto.user1);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
for (const key of Object.keys(createUserDto.user1)) {
|
||||
for (const key of ['email', 'name', 'memoriesEnabled', 'avatarColor']) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const dto = { [key]: null };
|
||||
const { status, body } = await request(app)
|
||||
.post(`/user`)
|
||||
.put(`/users/me`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ...createUserDto.user1, [key]: null });
|
||||
.send(dto);
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it('should ignore `isAdmin`', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/user`)
|
||||
.send({
|
||||
isAdmin: true,
|
||||
email: 'user5@immich.cloud',
|
||||
password: 'password123',
|
||||
name: 'Immich',
|
||||
})
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(body).toMatchObject({
|
||||
email: 'user5@immich.cloud',
|
||||
isAdmin: false,
|
||||
shouldChangePassword: true,
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
});
|
||||
|
||||
it('should create a user without memories enabled', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.post(`/user`)
|
||||
.send({
|
||||
email: 'no-memories@immich.cloud',
|
||||
password: 'Password123',
|
||||
name: 'No Memories',
|
||||
memoriesEnabled: false,
|
||||
})
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(body).toMatchObject({
|
||||
email: 'no-memories@immich.cloud',
|
||||
memoriesEnabled: false,
|
||||
});
|
||||
expect(status).toBe(201);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /user/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete(`/user/${userToDelete.userId}`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should delete user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/user/${userToDelete.userId}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: userToDelete.userId,
|
||||
updatedAt: expect.any(String),
|
||||
deletedAt: expect.any(String),
|
||||
});
|
||||
});
|
||||
|
||||
it('should hard delete user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete(`/user/${userToHardDelete.userId}`)
|
||||
.send({ force: true })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: userToHardDelete.userId,
|
||||
updatedAt: expect.any(String),
|
||||
deletedAt: expect.any(String),
|
||||
});
|
||||
|
||||
await utils.waitForWebsocketEvent({ event: 'userDelete', id: userToHardDelete.userId, timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /user', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put(`/user`);
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
for (const key of Object.keys(userDto.admin)) {
|
||||
it(`should not allow null ${key}`, async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ ...userDto.admin, [key]: null });
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest());
|
||||
});
|
||||
}
|
||||
|
||||
it('should not allow a non-admin to become an admin', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.send({ isAdmin: true, id: nonAdmin.userId })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.alreadyHasAdmin);
|
||||
});
|
||||
|
||||
it('ignores updates to profileImagePath', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.send({ id: admin.userId, profileImagePath: 'invalid.jpg' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({ id: admin.userId, profileImagePath: '' });
|
||||
});
|
||||
|
||||
it('should ignore updates to createdAt, updatedAt and deletedAt', async () => {
|
||||
const before = await getUserById({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.send({
|
||||
id: admin.userId,
|
||||
createdAt: '2023-01-01T00:00:00.000Z',
|
||||
updatedAt: '2023-01-01T00:00:00.000Z',
|
||||
deletedAt: '2023-01-01T00:00:00.000Z',
|
||||
})
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toStrictEqual(before);
|
||||
});
|
||||
|
||||
it('should update first and last name', async () => {
|
||||
const before = await getUserById({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
const before = await getMyUser({ headers: asBearerAuth(admin.accessToken) });
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.send({
|
||||
id: admin.userId,
|
||||
name: 'Name',
|
||||
})
|
||||
.put(`/users/me`)
|
||||
.send({ name: 'Name' })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -291,17 +108,13 @@ describe('/user', () => {
|
||||
updatedAt: expect.any(String),
|
||||
name: 'Name',
|
||||
});
|
||||
expect(before.updatedAt).not.toEqual(body.updatedAt);
|
||||
});
|
||||
|
||||
it('should update memories enabled', async () => {
|
||||
const before = await getUserById({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||
const before = await getMyUser({ headers: asBearerAuth(admin.accessToken) });
|
||||
const { status, body } = await request(app)
|
||||
.put(`/user`)
|
||||
.send({
|
||||
id: admin.userId,
|
||||
memoriesEnabled: false,
|
||||
})
|
||||
.put(`/users/me`)
|
||||
.send({ memoriesEnabled: false })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
@@ -310,7 +123,80 @@ describe('/user', () => {
|
||||
updatedAt: expect.anything(),
|
||||
memoriesEnabled: false,
|
||||
});
|
||||
expect(before.updatedAt).not.toEqual(body.updatedAt);
|
||||
|
||||
const after = await getMyUser({ headers: asBearerAuth(admin.accessToken) });
|
||||
expect(after.memoriesEnabled).toBe(false);
|
||||
});
|
||||
|
||||
/** @deprecated */
|
||||
it('should allow a user to change their password (deprecated)', async () => {
|
||||
const user = await getMyUser({ headers: asBearerAuth(nonAdmin.accessToken) });
|
||||
|
||||
expect(user.shouldChangePassword).toBe(true);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me`)
|
||||
.send({ password: 'super-secret' })
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
email: nonAdmin.userEmail,
|
||||
shouldChangePassword: false,
|
||||
});
|
||||
|
||||
const token = await login({ loginCredentialDto: { email: nonAdmin.userEmail, password: 'super-secret' } });
|
||||
|
||||
expect(token.accessToken).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not allow user to change to a taken email', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me`)
|
||||
.send({ email: 'admin@immich.cloud' })
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toMatchObject(errorDto.badRequest('Email already in use by another account'));
|
||||
});
|
||||
|
||||
it('should update my email', async () => {
|
||||
const before = await getMyUser({ headers: asBearerAuth(nonAdmin.accessToken) });
|
||||
const { status, body } = await request(app)
|
||||
.put(`/users/me`)
|
||||
.send({ email: 'non-admin@immich.cloud' })
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
...before,
|
||||
email: 'non-admin@immich.cloud',
|
||||
updatedAt: expect.anything(),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /users/:id', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status } = await request(app).get(`/users/${admin.userId}`);
|
||||
expect(status).toEqual(401);
|
||||
});
|
||||
|
||||
it('should get the user', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get(`/users/${admin.userId}`)
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toMatchObject({
|
||||
id: admin.userId,
|
||||
email: 'admin@immich.cloud',
|
||||
});
|
||||
|
||||
expect(body).not.toMatchObject({
|
||||
shouldChangePassword: expect.anything(),
|
||||
memoriesEnabled: expect.anything(),
|
||||
storageLabel: expect.anything(),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LoginResponseDto, getAllAlbums, getAllAssets } from '@immich/sdk';
|
||||
import { LoginResponseDto, getAllAlbums, getAssetStatistics } from '@immich/sdk';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { mkdir, readdir, rm, symlink } from 'node:fs/promises';
|
||||
import { asKeyAuth, immichCli, testAssetDir, utils } from 'src/utils';
|
||||
@@ -28,8 +28,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(1);
|
||||
});
|
||||
|
||||
it('should skip a duplicate file', async () => {
|
||||
@@ -40,8 +40,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(first.exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(1);
|
||||
|
||||
const second = await immichCli(['upload', `${testAssetDir}/albums/nature/silver_fir.jpg`]);
|
||||
expect(second.stderr).toBe('');
|
||||
@@ -60,8 +60,8 @@ describe(`immich upload`, () => {
|
||||
expect(stdout.split('\n')).toEqual(expect.arrayContaining([expect.stringContaining('No files found, exiting')]));
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
});
|
||||
|
||||
it('should have accurate dry run', async () => {
|
||||
@@ -76,8 +76,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
});
|
||||
|
||||
it('dry run should handle duplicates', async () => {
|
||||
@@ -88,8 +88,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(first.exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(1);
|
||||
|
||||
const second = await immichCli(['upload', `${testAssetDir}/albums/nature/`, '--dry-run']);
|
||||
expect(second.stderr).toBe('');
|
||||
@@ -112,8 +112,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(9);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(9);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -135,8 +135,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(9);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(9);
|
||||
|
||||
const albums = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums.length).toBe(1);
|
||||
@@ -151,8 +151,8 @@ describe(`immich upload`, () => {
|
||||
expect(response1.stderr).toBe('');
|
||||
expect(response1.exitCode).toBe(0);
|
||||
|
||||
const assets1 = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets1.length).toBe(9);
|
||||
const assets1 = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets1.total).toBe(9);
|
||||
|
||||
const albums1 = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums1.length).toBe(0);
|
||||
@@ -167,8 +167,8 @@ describe(`immich upload`, () => {
|
||||
expect(response2.stderr).toBe('');
|
||||
expect(response2.exitCode).toBe(0);
|
||||
|
||||
const assets2 = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets2.length).toBe(9);
|
||||
const assets2 = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets2.total).toBe(9);
|
||||
|
||||
const albums2 = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums2.length).toBe(1);
|
||||
@@ -193,8 +193,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
|
||||
const albums = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums.length).toBe(0);
|
||||
@@ -219,8 +219,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(9);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(9);
|
||||
|
||||
const albums = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums.length).toBe(1);
|
||||
@@ -245,8 +245,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
|
||||
const albums = await getAllAlbums({}, { headers: asKeyAuth(key) });
|
||||
expect(albums.length).toBe(0);
|
||||
@@ -276,8 +276,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(9);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(9);
|
||||
});
|
||||
|
||||
it('should have accurate dry run', async () => {
|
||||
@@ -302,8 +302,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toBe('');
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -328,8 +328,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(1);
|
||||
});
|
||||
|
||||
it('should throw an error if attempting dry run', async () => {
|
||||
@@ -344,8 +344,8 @@ describe(`immich upload`, () => {
|
||||
expect(stderr).toEqual(`error: option '-n, --dry-run' cannot be used with option '-h, --skip-hash'`);
|
||||
expect(exitCode).not.toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -367,8 +367,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(9);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(9);
|
||||
});
|
||||
|
||||
it('should reject string argument', async () => {
|
||||
@@ -408,8 +408,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(8);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(8);
|
||||
});
|
||||
|
||||
it('should ignore assets matching glob pattern', async () => {
|
||||
@@ -429,8 +429,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(1);
|
||||
});
|
||||
|
||||
it('should have accurate dry run', async () => {
|
||||
@@ -451,8 +451,8 @@ describe(`immich upload`, () => {
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
const assets = await getAssetStatistics({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.total).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,19 +5,19 @@ import {
|
||||
CreateAlbumDto,
|
||||
CreateAssetDto,
|
||||
CreateLibraryDto,
|
||||
CreateUserDto,
|
||||
MetadataSearchDto,
|
||||
PersonCreateDto,
|
||||
SharedLinkCreateDto,
|
||||
UserAdminCreateDto,
|
||||
ValidateLibraryDto,
|
||||
createAlbum,
|
||||
createApiKey,
|
||||
createLibrary,
|
||||
createPartner,
|
||||
createPerson,
|
||||
createSharedLink,
|
||||
createUser,
|
||||
createUserAdmin,
|
||||
deleteAssets,
|
||||
getAllAssets,
|
||||
getAllJobsStatus,
|
||||
getAssetInfo,
|
||||
getConfigDefaults,
|
||||
@@ -273,8 +273,8 @@ export const utils = {
|
||||
return response;
|
||||
},
|
||||
|
||||
userSetup: async (accessToken: string, dto: CreateUserDto) => {
|
||||
await createUser({ createUserDto: dto }, { headers: asBearerAuth(accessToken) });
|
||||
userSetup: async (accessToken: string, dto: UserAdminCreateDto) => {
|
||||
await createUserAdmin({ userAdminCreateDto: dto }, { headers: asBearerAuth(accessToken) });
|
||||
return login({
|
||||
loginCredentialDto: { email: dto.email, password: dto.password },
|
||||
});
|
||||
@@ -340,8 +340,6 @@ export const utils = {
|
||||
|
||||
getAssetInfo: (accessToken: string, id: string) => getAssetInfo({ id }, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
getAllAssets: (accessToken: string) => getAllAssets({}, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
metadataSearch: async (accessToken: string, dto: MetadataSearchDto) => {
|
||||
return searchMetadata({ metadataSearchDto: dto }, { headers: asBearerAuth(accessToken) });
|
||||
},
|
||||
@@ -388,6 +386,8 @@ export const utils = {
|
||||
validateLibrary: (accessToken: string, id: string, dto: ValidateLibraryDto) =>
|
||||
validate({ id, validateLibraryDto: dto }, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
createPartner: (accessToken: string, id: string) => createPartner({ id }, { headers: asBearerAuth(accessToken) }),
|
||||
|
||||
setAuthCookies: async (context: BrowserContext, accessToken: string) =>
|
||||
await context.addCookies([
|
||||
{
|
||||
|
||||
60
e2e/src/web/specs/asset-viewer/detail-panel.e2e-spec.ts
Normal file
60
e2e/src/web/specs/asset-viewer/detail-panel.e2e-spec.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { AssetFileUploadResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { utils } from 'src/utils';
|
||||
|
||||
test.describe('Detail Panel', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let asset: AssetFileUploadResponseDto;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
utils.initSdk();
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup();
|
||||
asset = await utils.createAsset(admin.accessToken);
|
||||
});
|
||||
|
||||
test('can be opened for shared links', async ({ page }) => {
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
assetIds: [asset.id],
|
||||
});
|
||||
await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`);
|
||||
await page.waitForSelector('#immich-asset-viewer');
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Info' })).toBeVisible();
|
||||
await page.keyboard.press('i');
|
||||
await expect(page.locator('#detail-panel')).toBeVisible();
|
||||
await page.keyboard.press('i');
|
||||
await expect(page.locator('#detail-panel')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('cannot be opened for shared links with hidden metadata', async ({ page }) => {
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
assetIds: [asset.id],
|
||||
showMetadata: false,
|
||||
});
|
||||
await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`);
|
||||
await page.waitForSelector('#immich-asset-viewer');
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Info' })).toHaveCount(0);
|
||||
await page.keyboard.press('i');
|
||||
await expect(page.locator('#detail-panel')).toHaveCount(0);
|
||||
await page.keyboard.press('i');
|
||||
await expect(page.locator('#detail-panel')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('description is visible for owner on shared links', async ({ context, page }) => {
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
assetIds: [asset.id],
|
||||
});
|
||||
await utils.setAuthCookies(context, admin.accessToken);
|
||||
await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`);
|
||||
|
||||
const textarea = page.getByRole('textbox', { name: 'Add a description' });
|
||||
await page.getByRole('button', { name: 'Info' }).click();
|
||||
await expect(textarea).toBeVisible();
|
||||
await expect(textarea).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
52
e2e/src/web/specs/asset-viewer/navbar.e2e-spec.ts
Normal file
52
e2e/src/web/specs/asset-viewer/navbar.e2e-spec.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { AssetFileUploadResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { utils } from 'src/utils';
|
||||
|
||||
test.describe('Asset Viewer Navbar', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let asset: AssetFileUploadResponseDto;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
utils.initSdk();
|
||||
await utils.resetDatabase();
|
||||
admin = await utils.adminSetup();
|
||||
asset = await utils.createAsset(admin.accessToken);
|
||||
});
|
||||
|
||||
test.describe('shared link without metadata', () => {
|
||||
test('visible guest actions', async ({ page }) => {
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
assetIds: [asset.id],
|
||||
showMetadata: false,
|
||||
});
|
||||
await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`);
|
||||
await page.waitForSelector('#immich-asset-viewer');
|
||||
|
||||
const expected = ['Zoom Image', 'Copy Image', 'Download'];
|
||||
const buttons = await page.getByTestId('asset-viewer-navbar-actions').getByRole('button').all();
|
||||
|
||||
for (const [i, button] of buttons.entries()) {
|
||||
await expect(button).toHaveAccessibleName(expected[i]);
|
||||
}
|
||||
});
|
||||
|
||||
test('visible owner actions', async ({ context, page }) => {
|
||||
const sharedLink = await utils.createSharedLink(admin.accessToken, {
|
||||
type: SharedLinkType.Individual,
|
||||
assetIds: [asset.id],
|
||||
showMetadata: false,
|
||||
});
|
||||
await utils.setAuthCookies(context, admin.accessToken);
|
||||
await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`);
|
||||
await page.waitForSelector('#immich-asset-viewer');
|
||||
|
||||
const expected = ['Share', 'Zoom Image', 'Copy Image', 'Download'];
|
||||
const buttons = await page.getByTestId('asset-viewer-navbar-actions').getByRole('button').all();
|
||||
|
||||
for (const [i, button] of buttons.entries()) {
|
||||
await expect(button).toHaveAccessibleName(expected[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -95,3 +95,5 @@ COPY start.sh log_conf.json ./
|
||||
COPY app .
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
CMD ["./start.sh"]
|
||||
|
||||
HEALTHCHECK CMD python3 healthcheck.py
|
||||
|
||||
14
machine-learning/app/healthcheck.py
Normal file
14
machine-learning/app/healthcheck.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import requests
|
||||
|
||||
port = os.getenv("IMMICH_PORT", 3003)
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://localhost:{port}/ping", timeout=2)
|
||||
if response.status_code == 200:
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
except requests.RequestException:
|
||||
sys.exit(1)
|
||||
@@ -62,6 +62,8 @@ fi
|
||||
if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
|
||||
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
|
||||
npm --prefix server version "$SERVER_PUMP"
|
||||
npm --prefix server ci
|
||||
npm --prefix server run build
|
||||
make open-api
|
||||
npm --prefix open-api/typescript-sdk version "$SERVER_PUMP"
|
||||
npm --prefix web version "$SERVER_PUMP"
|
||||
|
||||
@@ -10,7 +10,7 @@ GEM
|
||||
artifactory (3.0.17)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.931.0)
|
||||
aws-partitions (1.932.0)
|
||||
aws-sdk-core (3.196.1)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
|
||||
@@ -10,7 +10,7 @@ GEM
|
||||
artifactory (3.0.17)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.931.0)
|
||||
aws-partitions (1.932.0)
|
||||
aws-sdk-core (3.196.1)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
|
||||
@@ -145,9 +145,10 @@ class Album {
|
||||
.remoteIdEqualTo(dto.albumThumbnailAssetId)
|
||||
.findFirst();
|
||||
}
|
||||
if (dto.sharedUsers.isNotEmpty) {
|
||||
final users = await db.users
|
||||
.getAllById(dto.sharedUsers.map((e) => e.id).toList(growable: false));
|
||||
if (dto.albumUsers.isNotEmpty) {
|
||||
final users = await db.users.getAllById(
|
||||
dto.albumUsers.map((e) => e.user.id).toList(growable: false),
|
||||
);
|
||||
a.sharedUsers.addAll(users.cast());
|
||||
}
|
||||
if (dto.assets.isNotEmpty) {
|
||||
|
||||
@@ -27,7 +27,7 @@ class User {
|
||||
|
||||
Id get isarId => fastHash(id);
|
||||
|
||||
User.fromUserDto(UserResponseDto dto)
|
||||
User.fromUserDto(UserAdminResponseDto dto)
|
||||
: id = dto.id,
|
||||
updatedAt = dto.updatedAt,
|
||||
email = dto.email,
|
||||
@@ -44,21 +44,21 @@ class User {
|
||||
|
||||
User.fromPartnerDto(PartnerResponseDto dto)
|
||||
: id = dto.id,
|
||||
updatedAt = dto.updatedAt,
|
||||
updatedAt = DateTime.now(),
|
||||
email = dto.email,
|
||||
name = dto.name,
|
||||
isPartnerSharedBy = false,
|
||||
isPartnerSharedWith = false,
|
||||
profileImagePath = dto.profileImagePath,
|
||||
isAdmin = dto.isAdmin,
|
||||
memoryEnabled = dto.memoriesEnabled ?? false,
|
||||
isAdmin = false,
|
||||
memoryEnabled = false,
|
||||
avatarColor = dto.avatarColor.toAvatarColor(),
|
||||
inTimeline = dto.inTimeline ?? false,
|
||||
quotaUsageInBytes = dto.quotaUsageInBytes ?? 0,
|
||||
quotaSizeInBytes = dto.quotaSizeInBytes ?? 0;
|
||||
quotaUsageInBytes = 0,
|
||||
quotaSizeInBytes = 0;
|
||||
|
||||
/// Base user dto used where the complete user object is not required
|
||||
User.fromSimpleUserDto(UserDto dto)
|
||||
User.fromSimpleUserDto(UserResponseDto dto)
|
||||
: id = dto.id,
|
||||
email = dto.email,
|
||||
name = dto.name,
|
||||
|
||||
@@ -32,7 +32,7 @@ class ServerDiskInfo {
|
||||
return 'ServerDiskInfo(diskAvailable: $diskAvailable, diskSize: $diskSize, diskUse: $diskUse, diskUsagePercentage: $diskUsagePercentage)';
|
||||
}
|
||||
|
||||
ServerDiskInfo.fromDto(ServerInfoResponseDto dto)
|
||||
ServerDiskInfo.fromDto(ServerStorageResponseDto dto)
|
||||
: diskAvailable = dto.diskAvailable,
|
||||
diskSize = dto.diskSize,
|
||||
diskUse = dto.diskUse,
|
||||
|
||||
@@ -133,7 +133,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
|
||||
Widget buildTitle(Album album) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 24),
|
||||
padding: const EdgeInsets.only(left: 8, right: 8),
|
||||
child: userId == album.ownerId && album.isRemote
|
||||
? AlbumViewerEditableTitle(
|
||||
album: album,
|
||||
@@ -228,9 +228,30 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: ref.watch(multiselectProvider)
|
||||
? null
|
||||
: album.when(
|
||||
body: Stack(
|
||||
children: [
|
||||
album.widgetWhen(
|
||||
onData: (data) => MultiselectGrid(
|
||||
renderListProvider: albumRenderlistProvider(albumId),
|
||||
topWidget: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildHeader(data),
|
||||
if (data.isRemote) buildControlButton(data),
|
||||
],
|
||||
),
|
||||
onRemoveFromAlbum: onRemoveFromAlbumPressed,
|
||||
editEnabled: data.ownerId == userId,
|
||||
),
|
||||
),
|
||||
AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
top: ref.watch(multiselectProvider)
|
||||
? -(kToolbarHeight + MediaQuery.of(context).padding.top)
|
||||
: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: album.when(
|
||||
data: (data) => AlbumViewerAppbar(
|
||||
titleFocusNode: titleFocusNode,
|
||||
album: data,
|
||||
@@ -242,19 +263,8 @@ class AlbumViewerPage extends HookConsumerWidget {
|
||||
error: (error, stackTrace) => AppBar(title: const Text("Error")),
|
||||
loading: () => AppBar(),
|
||||
),
|
||||
body: album.widgetWhen(
|
||||
onData: (data) => MultiselectGrid(
|
||||
renderListProvider: albumRenderlistProvider(albumId),
|
||||
topWidget: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildHeader(data),
|
||||
if (data.isRemote) buildControlButton(data),
|
||||
],
|
||||
),
|
||||
onRemoveFromAlbum: onRemoveFromAlbumPressed,
|
||||
editEnabled: data.ownerId == userId,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,11 +138,9 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
||||
|
||||
Future<bool> changePassword(String newPassword) async {
|
||||
try {
|
||||
await _apiService.userApi.updateUser(
|
||||
UpdateUserDto(
|
||||
id: state.userId,
|
||||
await _apiService.userApi.updateMyUser(
|
||||
UserUpdateMeDto(
|
||||
password: newPassword,
|
||||
shouldChangePassword: false,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -178,9 +176,9 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
||||
user = offlineUser;
|
||||
retResult = false;
|
||||
} else {
|
||||
UserResponseDto? userResponseDto;
|
||||
UserAdminResponseDto? userResponseDto;
|
||||
try {
|
||||
userResponseDto = await _apiService.userApi.getMyUserInfo();
|
||||
userResponseDto = await _apiService.userApi.getMyUser();
|
||||
} on ApiException catch (error, stackTrace) {
|
||||
_log.severe(
|
||||
"Error getting user information from the server [API EXCEPTION]",
|
||||
|
||||
@@ -374,7 +374,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
|
||||
if (state.backupProgress != BackUpProgressEnum.inBackground) {
|
||||
await _getBackupAlbumsInfo();
|
||||
await updateServerInfo();
|
||||
await updateDiskInfo();
|
||||
await _updateBackupAssetCount();
|
||||
} else {
|
||||
log.warning("cannot get backup info - background backup is in progress!");
|
||||
@@ -542,7 +542,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
_updatePersistentAlbumsSelection();
|
||||
}
|
||||
|
||||
updateServerInfo();
|
||||
updateDiskInfo();
|
||||
}
|
||||
|
||||
void _onUploadProgress(int sent, int total) {
|
||||
@@ -579,13 +579,13 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updateServerInfo() async {
|
||||
final serverInfo = await _serverInfoService.getServerInfo();
|
||||
Future<void> updateDiskInfo() async {
|
||||
final diskInfo = await _serverInfoService.getDiskInfo();
|
||||
|
||||
// Update server info
|
||||
if (serverInfo != null) {
|
||||
if (diskInfo != null) {
|
||||
state = state.copyWith(
|
||||
serverInfo: serverInfo,
|
||||
serverInfo: diskInfo,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
bool isDuplicated,
|
||||
) {
|
||||
state = state.copyWith(successfulUploads: state.successfulUploads + 1);
|
||||
_backupProvider.updateServerInfo();
|
||||
_backupProvider.updateDiskInfo();
|
||||
}
|
||||
|
||||
void _onAssetUploadError(ErrorUploadAsset errorAssetInfo) {
|
||||
|
||||
@@ -20,7 +20,7 @@ class CurrentUserProvider extends StateNotifier<User?> {
|
||||
|
||||
refresh() async {
|
||||
try {
|
||||
final user = await _apiService.userApi.getMyUserInfo();
|
||||
final user = await _apiService.userApi.getMyUser();
|
||||
if (user != null) {
|
||||
Store.put(
|
||||
StoreKey.currentUser,
|
||||
|
||||
@@ -57,7 +57,7 @@ class TabNavigationObserver extends AutoRouterObserver {
|
||||
// Update user info
|
||||
try {
|
||||
final userResponseDto =
|
||||
await ref.read(apiServiceProvider).userApi.getMyUserInfo();
|
||||
await ref.read(apiServiceProvider).userApi.getMyUser();
|
||||
|
||||
if (userResponseDto == null) {
|
||||
return;
|
||||
|
||||
@@ -180,7 +180,14 @@ class AlbumService {
|
||||
CreateAlbumDto(
|
||||
albumName: albumName,
|
||||
assetIds: assets.map((asset) => asset.remoteId!).toList(),
|
||||
sharedWithUserIds: sharedUsers.map((e) => e.id).toList(),
|
||||
albumUsers: sharedUsers
|
||||
.map(
|
||||
(e) => AlbumUserCreateDto(
|
||||
userId: e.id,
|
||||
role: AlbumUserRole.editor,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
if (remote != null) {
|
||||
|
||||
@@ -84,7 +84,7 @@ class AssetService {
|
||||
final AssetResponseDto? dto =
|
||||
await _apiService.assetApi.getAssetInfo(remoteId);
|
||||
|
||||
return dto?.people;
|
||||
return dto?.people?.visiblePeople;
|
||||
} catch (error, stack) {
|
||||
log.severe(
|
||||
'Error while getting remote asset info: ${error.toString()}',
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
import 'package:immich_mobile/utils/backup_progress.dart';
|
||||
import 'package:immich_mobile/utils/diff.dart';
|
||||
import 'package:immich_mobile/utils/http_ssl_cert_override.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:path_provider_ios/path_provider_ios.dart';
|
||||
import 'package:photo_manager/photo_manager.dart';
|
||||
@@ -590,6 +591,7 @@ enum IosBackgroundTask { fetch, processing }
|
||||
/// entry point called by Kotlin/Java code; needs to be a top-level function
|
||||
@pragma('vm:entry-point')
|
||||
void _nativeEntry() {
|
||||
HttpOverrides.global = HttpSSLCertOverride();
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
DartPluginRegistrant.ensureInitialized();
|
||||
BackgroundService backgroundService = BackgroundService();
|
||||
|
||||
@@ -8,6 +8,8 @@ import 'package:isar/isar.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
import '../utils/string_helper.dart';
|
||||
|
||||
final memoryServiceProvider = StateProvider<MemoryService>((ref) {
|
||||
return MemoryService(
|
||||
ref.watch(apiServiceProvider),
|
||||
@@ -36,13 +38,13 @@ class MemoryService {
|
||||
}
|
||||
|
||||
List<Memory> memories = [];
|
||||
for (final MemoryLaneResponseDto(:title, :assets) in data) {
|
||||
for (final MemoryLaneResponseDto(:yearsAgo, :assets) in data) {
|
||||
final dbAssets =
|
||||
await _db.assets.getAllByRemoteId(assets.map((e) => e.id));
|
||||
if (dbAssets.isNotEmpty) {
|
||||
memories.add(
|
||||
Memory(
|
||||
title: title,
|
||||
title: '$yearsAgo year${s(yearsAgo)} ago',
|
||||
assets: dbAssets,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -18,14 +18,14 @@ class ServerInfoService {
|
||||
|
||||
ServerInfoService(this._apiService);
|
||||
|
||||
Future<ServerDiskInfo?> getServerInfo() async {
|
||||
Future<ServerDiskInfo?> getDiskInfo() async {
|
||||
try {
|
||||
final dto = await _apiService.serverInfoApi.getServerInfo();
|
||||
final dto = await _apiService.serverInfoApi.getStorage();
|
||||
if (dto != null) {
|
||||
return ServerDiskInfo.fromDto(dto);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint("Error [getServerInfo] ${e.toString()}");
|
||||
debugPrint("Error [getDiskInfo] ${e.toString()}");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -362,15 +362,15 @@ class SyncService {
|
||||
// update shared users
|
||||
final List<User> sharedUsers = album.sharedUsers.toList(growable: false);
|
||||
sharedUsers.sort((a, b) => a.id.compareTo(b.id));
|
||||
dto.sharedUsers.sort((a, b) => a.id.compareTo(b.id));
|
||||
dto.albumUsers.sort((a, b) => a.user.id.compareTo(b.user.id));
|
||||
final List<String> userIdsToAdd = [];
|
||||
final List<User> usersToUnlink = [];
|
||||
diffSortedListsSync(
|
||||
dto.sharedUsers,
|
||||
dto.albumUsers,
|
||||
sharedUsers,
|
||||
compare: (UserResponseDto a, User b) => a.id.compareTo(b.id),
|
||||
compare: (AlbumUserResponseDto a, User b) => a.user.id.compareTo(b.id),
|
||||
both: (a, b) => false,
|
||||
onlyFirst: (UserResponseDto a) => userIdsToAdd.add(a.id),
|
||||
onlyFirst: (AlbumUserResponseDto a) => userIdsToAdd.add(a.user.id),
|
||||
onlySecond: (User a) => usersToUnlink.add(a),
|
||||
);
|
||||
|
||||
@@ -905,7 +905,7 @@ bool _hasAlbumResponseDtoChanged(AlbumResponseDto dto, Album a) {
|
||||
dto.albumName != a.name ||
|
||||
dto.albumThumbnailAssetId != a.thumbnail.value?.remoteId ||
|
||||
dto.shared != a.shared ||
|
||||
dto.sharedUsers.length != a.sharedUsers.length ||
|
||||
dto.albumUsers.length != a.sharedUsers.length ||
|
||||
!dto.updatedAt.isAtSameMomentAs(a.modifiedAt) ||
|
||||
!isAtSameMomentAs(dto.startDate, a.startDate) ||
|
||||
!isAtSameMomentAs(dto.endDate, a.endDate) ||
|
||||
|
||||
@@ -37,10 +37,10 @@ class UserService {
|
||||
this._partnerService,
|
||||
);
|
||||
|
||||
Future<List<User>?> _getAllUsers({required bool isAll}) async {
|
||||
Future<List<User>?> _getAllUsers() async {
|
||||
try {
|
||||
final dto = await _apiService.userApi.getAllUsers(isAll);
|
||||
return dto?.map(User.fromUserDto).toList();
|
||||
final dto = await _apiService.userApi.searchUsers();
|
||||
return dto?.map(User.fromSimpleUserDto).toList();
|
||||
} catch (e) {
|
||||
_log.warning("Failed get all users", e);
|
||||
return null;
|
||||
@@ -71,7 +71,7 @@ class UserService {
|
||||
}
|
||||
|
||||
Future<List<User>?> getUsersFromServer() async {
|
||||
final List<User>? users = await _getAllUsers(isAll: true);
|
||||
final List<User>? users = await _getAllUsers();
|
||||
final List<User>? sharedBy =
|
||||
await _partnerService.getPartners(PartnerDirection.sharedBy);
|
||||
final List<User>? sharedWith =
|
||||
|
||||
@@ -77,5 +77,5 @@ String getThumbnailUrlForRemoteId(
|
||||
}
|
||||
|
||||
String getFaceThumbnailUrl(final String personId) {
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/person/$personId/thumbnail';
|
||||
return '${Store.get(StoreKey.serverEndpoint)}/people/$personId/thumbnail';
|
||||
}
|
||||
|
||||
@@ -3,3 +3,5 @@ extension StringExtension on String {
|
||||
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
|
||||
}
|
||||
}
|
||||
|
||||
String s(num count) => (count == 1 ? '' : 's');
|
||||
@@ -36,58 +36,62 @@ class AlbumViewerEditableTitle extends HookConsumerWidget {
|
||||
[],
|
||||
);
|
||||
|
||||
return TextField(
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty) {
|
||||
} else {
|
||||
ref.watch(albumViewerProvider.notifier).setEditTitleText(value);
|
||||
}
|
||||
},
|
||||
focusNode: titleFocusNode,
|
||||
style: context.textTheme.headlineMedium,
|
||||
controller: titleTextEditController,
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(titleFocusNode);
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: TextField(
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty) {
|
||||
} else {
|
||||
ref.watch(albumViewerProvider.notifier).setEditTitleText(value);
|
||||
}
|
||||
},
|
||||
focusNode: titleFocusNode,
|
||||
style: context.textTheme.headlineMedium,
|
||||
controller: titleTextEditController,
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(titleFocusNode);
|
||||
|
||||
ref.watch(albumViewerProvider.notifier).setEditTitleText(album.name);
|
||||
ref.watch(albumViewerProvider.notifier).enableEditAlbum();
|
||||
ref.watch(albumViewerProvider.notifier).setEditTitleText(album.name);
|
||||
ref.watch(albumViewerProvider.notifier).enableEditAlbum();
|
||||
|
||||
if (titleTextEditController.text == 'Untitled') {
|
||||
titleTextEditController.clear();
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
suffixIcon: titleFocusNode.hasFocus
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
titleTextEditController.clear();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.cancel_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
splashRadius: 10,
|
||||
)
|
||||
: null,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusColor: Colors.grey[300],
|
||||
fillColor: context.isDarkTheme
|
||||
? const Color.fromARGB(255, 32, 33, 35)
|
||||
: Colors.grey[200],
|
||||
filled: titleFocusNode.hasFocus,
|
||||
hintText: 'share_add_title'.tr(),
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 28,
|
||||
color: context.isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
||||
fontWeight: FontWeight.bold,
|
||||
if (titleTextEditController.text == 'Untitled') {
|
||||
titleTextEditController.clear();
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
suffixIcon: titleFocusNode.hasFocus
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
titleTextEditController.clear();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.cancel_rounded,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
splashRadius: 10,
|
||||
)
|
||||
: null,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
focusColor: Colors.grey[300],
|
||||
fillColor: context.isDarkTheme
|
||||
? const Color.fromARGB(255, 32, 33, 35)
|
||||
: Colors.grey[200],
|
||||
filled: titleFocusNode.hasFocus,
|
||||
hintText: 'share_add_title'.tr(),
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 28,
|
||||
color: context.isDarkTheme ? Colors.grey[300] : Colors.grey[700],
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -238,8 +238,10 @@ class ImmichAssetGridViewState extends ConsumerState<ImmichAssetGridView> {
|
||||
}
|
||||
|
||||
bool appBarOffset() {
|
||||
return ref.watch(tabProvider).index == 0 &&
|
||||
ModalRoute.of(context)?.settings.name == TabControllerRoute.name;
|
||||
return (ref.watch(tabProvider).index == 0 &&
|
||||
ModalRoute.of(context)?.settings.name ==
|
||||
TabControllerRoute.name) ||
|
||||
(ModalRoute.of(context)?.settings.name == AlbumViewerRoute.name);
|
||||
}
|
||||
|
||||
final listWidget = ScrollablePositionedList.builder(
|
||||
|
||||
@@ -31,7 +31,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
|
||||
|
||||
useEffect(
|
||||
() {
|
||||
ref.read(backupProvider.notifier).updateServerInfo();
|
||||
ref.read(backupProvider.notifier).updateDiskInfo();
|
||||
ref.read(currentUserProvider.notifier).refresh();
|
||||
return null;
|
||||
},
|
||||
|
||||
@@ -215,7 +215,7 @@ class _ManualPicker extends HookWidget {
|
||||
decorationText: "location_picker_longitude",
|
||||
hintText: "location_picker_longitude_hint",
|
||||
errorText: "location_picker_longitude_error",
|
||||
focusNode: latitiudeFocusNode,
|
||||
focusNode: longitudeFocusNode,
|
||||
validator: _validateLong,
|
||||
onUpdated: onLongitudeEditingCompleted,
|
||||
),
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:immich_mobile/entities/user.entity.dart';
|
||||
|
||||
Widget userAvatar(BuildContext context, User u, {double? radius}) {
|
||||
final url =
|
||||
"${Store.get(StoreKey.serverEndpoint)}/user/profile-image/${u.id}";
|
||||
"${Store.get(StoreKey.serverEndpoint)}/users/${u.id}/profile-image";
|
||||
final nameFirstLetter = u.name.isNotEmpty ? u.name[0] : "";
|
||||
return CircleAvatar(
|
||||
radius: radius,
|
||||
|
||||
@@ -24,7 +24,7 @@ class UserCircleAvatar extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
bool isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
||||
final profileImageUrl =
|
||||
'${Store.get(StoreKey.serverEndpoint)}/user/profile-image/${user.id}?d=${Random().nextInt(1024)}';
|
||||
'${Store.get(StoreKey.serverEndpoint)}/users/${user.id}/profile-image?d=${Random().nextInt(1024)}';
|
||||
|
||||
final textIcon = Text(
|
||||
user.name[0].toUpperCase(),
|
||||
|
||||
171
mobile/openapi/README.md
generated
171
mobile/openapi/README.md
generated
@@ -73,30 +73,29 @@ All URIs are relative to */api*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*APIKeyApi* | [**createApiKey**](doc//APIKeyApi.md#createapikey) | **POST** /api-key |
|
||||
*APIKeyApi* | [**deleteApiKey**](doc//APIKeyApi.md#deleteapikey) | **DELETE** /api-key/{id} |
|
||||
*APIKeyApi* | [**getApiKey**](doc//APIKeyApi.md#getapikey) | **GET** /api-key/{id} |
|
||||
*APIKeyApi* | [**getApiKeys**](doc//APIKeyApi.md#getapikeys) | **GET** /api-key |
|
||||
*APIKeyApi* | [**updateApiKey**](doc//APIKeyApi.md#updateapikey) | **PUT** /api-key/{id} |
|
||||
*ActivityApi* | [**createActivity**](doc//ActivityApi.md#createactivity) | **POST** /activity |
|
||||
*ActivityApi* | [**deleteActivity**](doc//ActivityApi.md#deleteactivity) | **DELETE** /activity/{id} |
|
||||
*ActivityApi* | [**getActivities**](doc//ActivityApi.md#getactivities) | **GET** /activity |
|
||||
*ActivityApi* | [**getActivityStatistics**](doc//ActivityApi.md#getactivitystatistics) | **GET** /activity/statistics |
|
||||
*AlbumApi* | [**addAssetsToAlbum**](doc//AlbumApi.md#addassetstoalbum) | **PUT** /album/{id}/assets |
|
||||
*AlbumApi* | [**addUsersToAlbum**](doc//AlbumApi.md#adduserstoalbum) | **PUT** /album/{id}/users |
|
||||
*AlbumApi* | [**createAlbum**](doc//AlbumApi.md#createalbum) | **POST** /album |
|
||||
*AlbumApi* | [**deleteAlbum**](doc//AlbumApi.md#deletealbum) | **DELETE** /album/{id} |
|
||||
*AlbumApi* | [**getAlbumCount**](doc//AlbumApi.md#getalbumcount) | **GET** /album/count |
|
||||
*AlbumApi* | [**getAlbumInfo**](doc//AlbumApi.md#getalbuminfo) | **GET** /album/{id} |
|
||||
*AlbumApi* | [**getAllAlbums**](doc//AlbumApi.md#getallalbums) | **GET** /album |
|
||||
*AlbumApi* | [**removeAssetFromAlbum**](doc//AlbumApi.md#removeassetfromalbum) | **DELETE** /album/{id}/assets |
|
||||
*AlbumApi* | [**removeUserFromAlbum**](doc//AlbumApi.md#removeuserfromalbum) | **DELETE** /album/{id}/user/{userId} |
|
||||
*AlbumApi* | [**updateAlbumInfo**](doc//AlbumApi.md#updatealbuminfo) | **PATCH** /album/{id} |
|
||||
*AlbumApi* | [**updateAlbumUser**](doc//AlbumApi.md#updatealbumuser) | **PUT** /album/{id}/user/{userId} |
|
||||
*APIKeyApi* | [**createApiKey**](doc//APIKeyApi.md#createapikey) | **POST** /api-keys |
|
||||
*APIKeyApi* | [**deleteApiKey**](doc//APIKeyApi.md#deleteapikey) | **DELETE** /api-keys/{id} |
|
||||
*APIKeyApi* | [**getApiKey**](doc//APIKeyApi.md#getapikey) | **GET** /api-keys/{id} |
|
||||
*APIKeyApi* | [**getApiKeys**](doc//APIKeyApi.md#getapikeys) | **GET** /api-keys |
|
||||
*APIKeyApi* | [**updateApiKey**](doc//APIKeyApi.md#updateapikey) | **PUT** /api-keys/{id} |
|
||||
*ActivityApi* | [**createActivity**](doc//ActivityApi.md#createactivity) | **POST** /activities |
|
||||
*ActivityApi* | [**deleteActivity**](doc//ActivityApi.md#deleteactivity) | **DELETE** /activities/{id} |
|
||||
*ActivityApi* | [**getActivities**](doc//ActivityApi.md#getactivities) | **GET** /activities |
|
||||
*ActivityApi* | [**getActivityStatistics**](doc//ActivityApi.md#getactivitystatistics) | **GET** /activities/statistics |
|
||||
*AlbumApi* | [**addAssetsToAlbum**](doc//AlbumApi.md#addassetstoalbum) | **PUT** /albums/{id}/assets |
|
||||
*AlbumApi* | [**addUsersToAlbum**](doc//AlbumApi.md#adduserstoalbum) | **PUT** /albums/{id}/users |
|
||||
*AlbumApi* | [**createAlbum**](doc//AlbumApi.md#createalbum) | **POST** /albums |
|
||||
*AlbumApi* | [**deleteAlbum**](doc//AlbumApi.md#deletealbum) | **DELETE** /albums/{id} |
|
||||
*AlbumApi* | [**getAlbumCount**](doc//AlbumApi.md#getalbumcount) | **GET** /albums/count |
|
||||
*AlbumApi* | [**getAlbumInfo**](doc//AlbumApi.md#getalbuminfo) | **GET** /albums/{id} |
|
||||
*AlbumApi* | [**getAllAlbums**](doc//AlbumApi.md#getallalbums) | **GET** /albums |
|
||||
*AlbumApi* | [**removeAssetFromAlbum**](doc//AlbumApi.md#removeassetfromalbum) | **DELETE** /albums/{id}/assets |
|
||||
*AlbumApi* | [**removeUserFromAlbum**](doc//AlbumApi.md#removeuserfromalbum) | **DELETE** /albums/{id}/user/{userId} |
|
||||
*AlbumApi* | [**updateAlbumInfo**](doc//AlbumApi.md#updatealbuminfo) | **PATCH** /albums/{id} |
|
||||
*AlbumApi* | [**updateAlbumUser**](doc//AlbumApi.md#updatealbumuser) | **PUT** /albums/{id}/user/{userId} |
|
||||
*AssetApi* | [**checkBulkUpload**](doc//AssetApi.md#checkbulkupload) | **POST** /asset/bulk-upload-check |
|
||||
*AssetApi* | [**checkExistingAssets**](doc//AssetApi.md#checkexistingassets) | **POST** /asset/exist |
|
||||
*AssetApi* | [**deleteAssets**](doc//AssetApi.md#deleteassets) | **DELETE** /asset |
|
||||
*AssetApi* | [**getAllAssets**](doc//AssetApi.md#getallassets) | **GET** /asset |
|
||||
*AssetApi* | [**getAllUserAssetsByDeviceId**](doc//AssetApi.md#getalluserassetsbydeviceid) | **GET** /asset/device/{deviceId} |
|
||||
*AssetApi* | [**getAssetInfo**](doc//AssetApi.md#getassetinfo) | **GET** /asset/{id} |
|
||||
*AssetApi* | [**getAssetStatistics**](doc//AssetApi.md#getassetstatistics) | **GET** /asset/statistics |
|
||||
@@ -104,6 +103,7 @@ Class | Method | HTTP request | Description
|
||||
*AssetApi* | [**getMapMarkers**](doc//AssetApi.md#getmapmarkers) | **GET** /asset/map-marker |
|
||||
*AssetApi* | [**getMemoryLane**](doc//AssetApi.md#getmemorylane) | **GET** /asset/memory-lane |
|
||||
*AssetApi* | [**getRandom**](doc//AssetApi.md#getrandom) | **GET** /asset/random |
|
||||
*AssetApi* | [**replaceAsset**](doc//AssetApi.md#replaceasset) | **PUT** /asset/{id}/file |
|
||||
*AssetApi* | [**runAssetJobs**](doc//AssetApi.md#runassetjobs) | **POST** /asset/jobs |
|
||||
*AssetApi* | [**serveFile**](doc//AssetApi.md#servefile) | **GET** /asset/file/{id} |
|
||||
*AssetApi* | [**updateAsset**](doc//AssetApi.md#updateasset) | **PUT** /asset/{id} |
|
||||
@@ -120,22 +120,23 @@ Class | Method | HTTP request | Description
|
||||
*DownloadApi* | [**downloadFile**](doc//DownloadApi.md#downloadfile) | **POST** /download/asset/{id} |
|
||||
*DownloadApi* | [**getDownloadInfo**](doc//DownloadApi.md#getdownloadinfo) | **POST** /download/info |
|
||||
*DuplicateApi* | [**getAssetDuplicates**](doc//DuplicateApi.md#getassetduplicates) | **GET** /duplicates |
|
||||
*FaceApi* | [**getFaces**](doc//FaceApi.md#getfaces) | **GET** /face |
|
||||
*FaceApi* | [**reassignFacesById**](doc//FaceApi.md#reassignfacesbyid) | **PUT** /face/{id} |
|
||||
*FileReportApi* | [**fixAuditFiles**](doc//FileReportApi.md#fixauditfiles) | **POST** /report/fix |
|
||||
*FileReportApi* | [**getAuditFiles**](doc//FileReportApi.md#getauditfiles) | **GET** /report |
|
||||
*FileReportApi* | [**getFileChecksums**](doc//FileReportApi.md#getfilechecksums) | **POST** /report/checksum |
|
||||
*FaceApi* | [**getFaces**](doc//FaceApi.md#getfaces) | **GET** /faces |
|
||||
*FaceApi* | [**reassignFacesById**](doc//FaceApi.md#reassignfacesbyid) | **PUT** /faces/{id} |
|
||||
*FaceApi* | [**unassignFace**](doc//FaceApi.md#unassignface) | **DELETE** /faces/{id} |
|
||||
*FileReportApi* | [**fixAuditFiles**](doc//FileReportApi.md#fixauditfiles) | **POST** /reports/fix |
|
||||
*FileReportApi* | [**getAuditFiles**](doc//FileReportApi.md#getauditfiles) | **GET** /reports |
|
||||
*FileReportApi* | [**getFileChecksums**](doc//FileReportApi.md#getfilechecksums) | **POST** /reports/checksum |
|
||||
*JobApi* | [**getAllJobsStatus**](doc//JobApi.md#getalljobsstatus) | **GET** /jobs |
|
||||
*JobApi* | [**sendJobCommand**](doc//JobApi.md#sendjobcommand) | **PUT** /jobs/{id} |
|
||||
*LibraryApi* | [**createLibrary**](doc//LibraryApi.md#createlibrary) | **POST** /library |
|
||||
*LibraryApi* | [**deleteLibrary**](doc//LibraryApi.md#deletelibrary) | **DELETE** /library/{id} |
|
||||
*LibraryApi* | [**getAllLibraries**](doc//LibraryApi.md#getalllibraries) | **GET** /library |
|
||||
*LibraryApi* | [**getLibrary**](doc//LibraryApi.md#getlibrary) | **GET** /library/{id} |
|
||||
*LibraryApi* | [**getLibraryStatistics**](doc//LibraryApi.md#getlibrarystatistics) | **GET** /library/{id}/statistics |
|
||||
*LibraryApi* | [**removeOfflineFiles**](doc//LibraryApi.md#removeofflinefiles) | **POST** /library/{id}/removeOffline |
|
||||
*LibraryApi* | [**scanLibrary**](doc//LibraryApi.md#scanlibrary) | **POST** /library/{id}/scan |
|
||||
*LibraryApi* | [**updateLibrary**](doc//LibraryApi.md#updatelibrary) | **PUT** /library/{id} |
|
||||
*LibraryApi* | [**validate**](doc//LibraryApi.md#validate) | **POST** /library/{id}/validate |
|
||||
*LibraryApi* | [**createLibrary**](doc//LibraryApi.md#createlibrary) | **POST** /libraries |
|
||||
*LibraryApi* | [**deleteLibrary**](doc//LibraryApi.md#deletelibrary) | **DELETE** /libraries/{id} |
|
||||
*LibraryApi* | [**getAllLibraries**](doc//LibraryApi.md#getalllibraries) | **GET** /libraries |
|
||||
*LibraryApi* | [**getLibrary**](doc//LibraryApi.md#getlibrary) | **GET** /libraries/{id} |
|
||||
*LibraryApi* | [**getLibraryStatistics**](doc//LibraryApi.md#getlibrarystatistics) | **GET** /libraries/{id}/statistics |
|
||||
*LibraryApi* | [**removeOfflineFiles**](doc//LibraryApi.md#removeofflinefiles) | **POST** /libraries/{id}/removeOffline |
|
||||
*LibraryApi* | [**scanLibrary**](doc//LibraryApi.md#scanlibrary) | **POST** /libraries/{id}/scan |
|
||||
*LibraryApi* | [**updateLibrary**](doc//LibraryApi.md#updatelibrary) | **PUT** /libraries/{id} |
|
||||
*LibraryApi* | [**validate**](doc//LibraryApi.md#validate) | **POST** /libraries/{id}/validate |
|
||||
*MemoryApi* | [**addMemoryAssets**](doc//MemoryApi.md#addmemoryassets) | **PUT** /memories/{id}/assets |
|
||||
*MemoryApi* | [**createMemory**](doc//MemoryApi.md#creatememory) | **POST** /memories |
|
||||
*MemoryApi* | [**deleteMemory**](doc//MemoryApi.md#deletememory) | **DELETE** /memories/{id} |
|
||||
@@ -148,20 +149,21 @@ Class | Method | HTTP request | Description
|
||||
*OAuthApi* | [**redirectOAuthToMobile**](doc//OAuthApi.md#redirectoauthtomobile) | **GET** /oauth/mobile-redirect |
|
||||
*OAuthApi* | [**startOAuth**](doc//OAuthApi.md#startoauth) | **POST** /oauth/authorize |
|
||||
*OAuthApi* | [**unlinkOAuthAccount**](doc//OAuthApi.md#unlinkoauthaccount) | **POST** /oauth/unlink |
|
||||
*PartnerApi* | [**createPartner**](doc//PartnerApi.md#createpartner) | **POST** /partner/{id} |
|
||||
*PartnerApi* | [**getPartners**](doc//PartnerApi.md#getpartners) | **GET** /partner |
|
||||
*PartnerApi* | [**removePartner**](doc//PartnerApi.md#removepartner) | **DELETE** /partner/{id} |
|
||||
*PartnerApi* | [**updatePartner**](doc//PartnerApi.md#updatepartner) | **PUT** /partner/{id} |
|
||||
*PersonApi* | [**createPerson**](doc//PersonApi.md#createperson) | **POST** /person |
|
||||
*PersonApi* | [**getAllPeople**](doc//PersonApi.md#getallpeople) | **GET** /person |
|
||||
*PersonApi* | [**getPerson**](doc//PersonApi.md#getperson) | **GET** /person/{id} |
|
||||
*PersonApi* | [**getPersonAssets**](doc//PersonApi.md#getpersonassets) | **GET** /person/{id}/assets |
|
||||
*PersonApi* | [**getPersonStatistics**](doc//PersonApi.md#getpersonstatistics) | **GET** /person/{id}/statistics |
|
||||
*PersonApi* | [**getPersonThumbnail**](doc//PersonApi.md#getpersonthumbnail) | **GET** /person/{id}/thumbnail |
|
||||
*PersonApi* | [**mergePerson**](doc//PersonApi.md#mergeperson) | **POST** /person/{id}/merge |
|
||||
*PersonApi* | [**reassignFaces**](doc//PersonApi.md#reassignfaces) | **PUT** /person/{id}/reassign |
|
||||
*PersonApi* | [**updatePeople**](doc//PersonApi.md#updatepeople) | **PUT** /person |
|
||||
*PersonApi* | [**updatePerson**](doc//PersonApi.md#updateperson) | **PUT** /person/{id} |
|
||||
*PartnerApi* | [**createPartner**](doc//PartnerApi.md#createpartner) | **POST** /partners/{id} |
|
||||
*PartnerApi* | [**getPartners**](doc//PartnerApi.md#getpartners) | **GET** /partners |
|
||||
*PartnerApi* | [**removePartner**](doc//PartnerApi.md#removepartner) | **DELETE** /partners/{id} |
|
||||
*PartnerApi* | [**updatePartner**](doc//PartnerApi.md#updatepartner) | **PUT** /partners/{id} |
|
||||
*PersonApi* | [**createPerson**](doc//PersonApi.md#createperson) | **POST** /people |
|
||||
*PersonApi* | [**getAllPeople**](doc//PersonApi.md#getallpeople) | **GET** /people |
|
||||
*PersonApi* | [**getPerson**](doc//PersonApi.md#getperson) | **GET** /people/{id} |
|
||||
*PersonApi* | [**getPersonAssets**](doc//PersonApi.md#getpersonassets) | **GET** /people/{id}/assets |
|
||||
*PersonApi* | [**getPersonStatistics**](doc//PersonApi.md#getpersonstatistics) | **GET** /people/{id}/statistics |
|
||||
*PersonApi* | [**getPersonThumbnail**](doc//PersonApi.md#getpersonthumbnail) | **GET** /people/{id}/thumbnail |
|
||||
*PersonApi* | [**mergePerson**](doc//PersonApi.md#mergeperson) | **POST** /people/{id}/merge |
|
||||
*PersonApi* | [**reassignFaces**](doc//PersonApi.md#reassignfaces) | **PUT** /people/{id}/reassign |
|
||||
*PersonApi* | [**unassignFaces**](doc//PersonApi.md#unassignfaces) | **DELETE** /people |
|
||||
*PersonApi* | [**updatePeople**](doc//PersonApi.md#updatepeople) | **PUT** /people |
|
||||
*PersonApi* | [**updatePerson**](doc//PersonApi.md#updateperson) | **PUT** /people/{id} |
|
||||
*SearchApi* | [**getAssetsByCity**](doc//SearchApi.md#getassetsbycity) | **GET** /search/cities |
|
||||
*SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore |
|
||||
*SearchApi* | [**getSearchSuggestions**](doc//SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions |
|
||||
@@ -171,23 +173,23 @@ Class | Method | HTTP request | Description
|
||||
*SearchApi* | [**searchSmart**](doc//SearchApi.md#searchsmart) | **POST** /search/smart |
|
||||
*ServerInfoApi* | [**getServerConfig**](doc//ServerInfoApi.md#getserverconfig) | **GET** /server-info/config |
|
||||
*ServerInfoApi* | [**getServerFeatures**](doc//ServerInfoApi.md#getserverfeatures) | **GET** /server-info/features |
|
||||
*ServerInfoApi* | [**getServerInfo**](doc//ServerInfoApi.md#getserverinfo) | **GET** /server-info |
|
||||
*ServerInfoApi* | [**getServerStatistics**](doc//ServerInfoApi.md#getserverstatistics) | **GET** /server-info/statistics |
|
||||
*ServerInfoApi* | [**getServerVersion**](doc//ServerInfoApi.md#getserverversion) | **GET** /server-info/version |
|
||||
*ServerInfoApi* | [**getStorage**](doc//ServerInfoApi.md#getstorage) | **GET** /server-info/storage |
|
||||
*ServerInfoApi* | [**getSupportedMediaTypes**](doc//ServerInfoApi.md#getsupportedmediatypes) | **GET** /server-info/media-types |
|
||||
*ServerInfoApi* | [**getTheme**](doc//ServerInfoApi.md#gettheme) | **GET** /server-info/theme |
|
||||
*ServerInfoApi* | [**pingServer**](doc//ServerInfoApi.md#pingserver) | **GET** /server-info/ping |
|
||||
*SessionsApi* | [**deleteAllSessions**](doc//SessionsApi.md#deleteallsessions) | **DELETE** /sessions |
|
||||
*SessionsApi* | [**deleteSession**](doc//SessionsApi.md#deletesession) | **DELETE** /sessions/{id} |
|
||||
*SessionsApi* | [**getSessions**](doc//SessionsApi.md#getsessions) | **GET** /sessions |
|
||||
*SharedLinkApi* | [**addSharedLinkAssets**](doc//SharedLinkApi.md#addsharedlinkassets) | **PUT** /shared-link/{id}/assets |
|
||||
*SharedLinkApi* | [**createSharedLink**](doc//SharedLinkApi.md#createsharedlink) | **POST** /shared-link |
|
||||
*SharedLinkApi* | [**getAllSharedLinks**](doc//SharedLinkApi.md#getallsharedlinks) | **GET** /shared-link |
|
||||
*SharedLinkApi* | [**getMySharedLink**](doc//SharedLinkApi.md#getmysharedlink) | **GET** /shared-link/me |
|
||||
*SharedLinkApi* | [**getSharedLinkById**](doc//SharedLinkApi.md#getsharedlinkbyid) | **GET** /shared-link/{id} |
|
||||
*SharedLinkApi* | [**removeSharedLink**](doc//SharedLinkApi.md#removesharedlink) | **DELETE** /shared-link/{id} |
|
||||
*SharedLinkApi* | [**removeSharedLinkAssets**](doc//SharedLinkApi.md#removesharedlinkassets) | **DELETE** /shared-link/{id}/assets |
|
||||
*SharedLinkApi* | [**updateSharedLink**](doc//SharedLinkApi.md#updatesharedlink) | **PATCH** /shared-link/{id} |
|
||||
*SharedLinkApi* | [**addSharedLinkAssets**](doc//SharedLinkApi.md#addsharedlinkassets) | **PUT** /shared-links/{id}/assets |
|
||||
*SharedLinkApi* | [**createSharedLink**](doc//SharedLinkApi.md#createsharedlink) | **POST** /shared-links |
|
||||
*SharedLinkApi* | [**getAllSharedLinks**](doc//SharedLinkApi.md#getallsharedlinks) | **GET** /shared-links |
|
||||
*SharedLinkApi* | [**getMySharedLink**](doc//SharedLinkApi.md#getmysharedlink) | **GET** /shared-links/me |
|
||||
*SharedLinkApi* | [**getSharedLinkById**](doc//SharedLinkApi.md#getsharedlinkbyid) | **GET** /shared-links/{id} |
|
||||
*SharedLinkApi* | [**removeSharedLink**](doc//SharedLinkApi.md#removesharedlink) | **DELETE** /shared-links/{id} |
|
||||
*SharedLinkApi* | [**removeSharedLinkAssets**](doc//SharedLinkApi.md#removesharedlinkassets) | **DELETE** /shared-links/{id}/assets |
|
||||
*SharedLinkApi* | [**updateSharedLink**](doc//SharedLinkApi.md#updatesharedlink) | **PATCH** /shared-links/{id} |
|
||||
*SyncApi* | [**getDeltaSync**](doc//SyncApi.md#getdeltasync) | **POST** /sync/delta-sync |
|
||||
*SyncApi* | [**getFullSyncForUser**](doc//SyncApi.md#getfullsyncforuser) | **POST** /sync/full-sync |
|
||||
*SystemConfigApi* | [**getConfig**](doc//SystemConfigApi.md#getconfig) | **GET** /system-config |
|
||||
@@ -198,29 +200,32 @@ Class | Method | HTTP request | Description
|
||||
*SystemMetadataApi* | [**getAdminOnboarding**](doc//SystemMetadataApi.md#getadminonboarding) | **GET** /system-metadata/admin-onboarding |
|
||||
*SystemMetadataApi* | [**getReverseGeocodingState**](doc//SystemMetadataApi.md#getreversegeocodingstate) | **GET** /system-metadata/reverse-geocoding-state |
|
||||
*SystemMetadataApi* | [**updateAdminOnboarding**](doc//SystemMetadataApi.md#updateadminonboarding) | **POST** /system-metadata/admin-onboarding |
|
||||
*TagApi* | [**createTag**](doc//TagApi.md#createtag) | **POST** /tag |
|
||||
*TagApi* | [**deleteTag**](doc//TagApi.md#deletetag) | **DELETE** /tag/{id} |
|
||||
*TagApi* | [**getAllTags**](doc//TagApi.md#getalltags) | **GET** /tag |
|
||||
*TagApi* | [**getTagAssets**](doc//TagApi.md#gettagassets) | **GET** /tag/{id}/assets |
|
||||
*TagApi* | [**getTagById**](doc//TagApi.md#gettagbyid) | **GET** /tag/{id} |
|
||||
*TagApi* | [**tagAssets**](doc//TagApi.md#tagassets) | **PUT** /tag/{id}/assets |
|
||||
*TagApi* | [**untagAssets**](doc//TagApi.md#untagassets) | **DELETE** /tag/{id}/assets |
|
||||
*TagApi* | [**updateTag**](doc//TagApi.md#updatetag) | **PATCH** /tag/{id} |
|
||||
*TagApi* | [**createTag**](doc//TagApi.md#createtag) | **POST** /tags |
|
||||
*TagApi* | [**deleteTag**](doc//TagApi.md#deletetag) | **DELETE** /tags/{id} |
|
||||
*TagApi* | [**getAllTags**](doc//TagApi.md#getalltags) | **GET** /tags |
|
||||
*TagApi* | [**getTagAssets**](doc//TagApi.md#gettagassets) | **GET** /tags/{id}/assets |
|
||||
*TagApi* | [**getTagById**](doc//TagApi.md#gettagbyid) | **GET** /tags/{id} |
|
||||
*TagApi* | [**tagAssets**](doc//TagApi.md#tagassets) | **PUT** /tags/{id}/assets |
|
||||
*TagApi* | [**untagAssets**](doc//TagApi.md#untagassets) | **DELETE** /tags/{id}/assets |
|
||||
*TagApi* | [**updateTag**](doc//TagApi.md#updatetag) | **PATCH** /tags/{id} |
|
||||
*TimelineApi* | [**getTimeBucket**](doc//TimelineApi.md#gettimebucket) | **GET** /timeline/bucket |
|
||||
*TimelineApi* | [**getTimeBuckets**](doc//TimelineApi.md#gettimebuckets) | **GET** /timeline/buckets |
|
||||
*TrashApi* | [**emptyTrash**](doc//TrashApi.md#emptytrash) | **POST** /trash/empty |
|
||||
*TrashApi* | [**restoreAssets**](doc//TrashApi.md#restoreassets) | **POST** /trash/restore/assets |
|
||||
*TrashApi* | [**restoreTrash**](doc//TrashApi.md#restoretrash) | **POST** /trash/restore |
|
||||
*UserApi* | [**createProfileImage**](doc//UserApi.md#createprofileimage) | **POST** /user/profile-image |
|
||||
*UserApi* | [**createUser**](doc//UserApi.md#createuser) | **POST** /user |
|
||||
*UserApi* | [**deleteProfileImage**](doc//UserApi.md#deleteprofileimage) | **DELETE** /user/profile-image |
|
||||
*UserApi* | [**deleteUser**](doc//UserApi.md#deleteuser) | **DELETE** /user/{id} |
|
||||
*UserApi* | [**getAllUsers**](doc//UserApi.md#getallusers) | **GET** /user |
|
||||
*UserApi* | [**getMyUserInfo**](doc//UserApi.md#getmyuserinfo) | **GET** /user/me |
|
||||
*UserApi* | [**getProfileImage**](doc//UserApi.md#getprofileimage) | **GET** /user/profile-image/{id} |
|
||||
*UserApi* | [**getUserById**](doc//UserApi.md#getuserbyid) | **GET** /user/info/{id} |
|
||||
*UserApi* | [**restoreUser**](doc//UserApi.md#restoreuser) | **POST** /user/{id}/restore |
|
||||
*UserApi* | [**updateUser**](doc//UserApi.md#updateuser) | **PUT** /user |
|
||||
*UserApi* | [**createProfileImage**](doc//UserApi.md#createprofileimage) | **POST** /users/profile-image |
|
||||
*UserApi* | [**createUserAdmin**](doc//UserApi.md#createuseradmin) | **POST** /admin/users |
|
||||
*UserApi* | [**deleteProfileImage**](doc//UserApi.md#deleteprofileimage) | **DELETE** /users/profile-image |
|
||||
*UserApi* | [**deleteUserAdmin**](doc//UserApi.md#deleteuseradmin) | **DELETE** /admin/users/{id} |
|
||||
*UserApi* | [**getMyUser**](doc//UserApi.md#getmyuser) | **GET** /users/me |
|
||||
*UserApi* | [**getProfileImage**](doc//UserApi.md#getprofileimage) | **GET** /users/{id}/profile-image |
|
||||
*UserApi* | [**getUser**](doc//UserApi.md#getuser) | **GET** /users/{id} |
|
||||
*UserApi* | [**getUserAdmin**](doc//UserApi.md#getuseradmin) | **GET** /admin/users/{id} |
|
||||
*UserApi* | [**restoreUserAdmin**](doc//UserApi.md#restoreuseradmin) | **POST** /admin/users/{id}/restore |
|
||||
*UserApi* | [**searchUsers**](doc//UserApi.md#searchusers) | **GET** /users |
|
||||
*UserApi* | [**searchUsersAdmin**](doc//UserApi.md#searchusersadmin) | **GET** /admin/users |
|
||||
*UserApi* | [**updateMyUser**](doc//UserApi.md#updatemyuser) | **PUT** /users/me |
|
||||
*UserApi* | [**updateUserAdmin**](doc//UserApi.md#updateuseradmin) | **PUT** /admin/users/{id} |
|
||||
|
||||
|
||||
## Documentation For Models
|
||||
@@ -259,6 +264,8 @@ Class | Method | HTTP request | Description
|
||||
- [AssetIdsResponseDto](doc//AssetIdsResponseDto.md)
|
||||
- [AssetJobName](doc//AssetJobName.md)
|
||||
- [AssetJobsDto](doc//AssetJobsDto.md)
|
||||
- [AssetMediaResponseDto](doc//AssetMediaResponseDto.md)
|
||||
- [AssetMediaStatus](doc//AssetMediaStatus.md)
|
||||
- [AssetOrder](doc//AssetOrder.md)
|
||||
- [AssetResponseDto](doc//AssetResponseDto.md)
|
||||
- [AssetStatsResponseDto](doc//AssetStatsResponseDto.md)
|
||||
@@ -278,8 +285,6 @@ Class | Method | HTTP request | Description
|
||||
- [CreateLibraryDto](doc//CreateLibraryDto.md)
|
||||
- [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md)
|
||||
- [CreateTagDto](doc//CreateTagDto.md)
|
||||
- [CreateUserDto](doc//CreateUserDto.md)
|
||||
- [DeleteUserDto](doc//DeleteUserDto.md)
|
||||
- [DownloadArchiveInfo](doc//DownloadArchiveInfo.md)
|
||||
- [DownloadInfoDto](doc//DownloadInfoDto.md)
|
||||
- [DownloadResponseDto](doc//DownloadResponseDto.md)
|
||||
@@ -326,6 +331,7 @@ Class | Method | HTTP request | Description
|
||||
- [PeopleResponseDto](doc//PeopleResponseDto.md)
|
||||
- [PeopleUpdateDto](doc//PeopleUpdateDto.md)
|
||||
- [PeopleUpdateItem](doc//PeopleUpdateItem.md)
|
||||
- [PeopleWithFacesResponseDto](doc//PeopleWithFacesResponseDto.md)
|
||||
- [PersonCreateDto](doc//PersonCreateDto.md)
|
||||
- [PersonResponseDto](doc//PersonResponseDto.md)
|
||||
- [PersonStatisticsResponseDto](doc//PersonStatisticsResponseDto.md)
|
||||
@@ -348,10 +354,10 @@ Class | Method | HTTP request | Description
|
||||
- [SearchSuggestionType](doc//SearchSuggestionType.md)
|
||||
- [ServerConfigDto](doc//ServerConfigDto.md)
|
||||
- [ServerFeaturesDto](doc//ServerFeaturesDto.md)
|
||||
- [ServerInfoResponseDto](doc//ServerInfoResponseDto.md)
|
||||
- [ServerMediaTypesResponseDto](doc//ServerMediaTypesResponseDto.md)
|
||||
- [ServerPingResponse](doc//ServerPingResponse.md)
|
||||
- [ServerStatsResponseDto](doc//ServerStatsResponseDto.md)
|
||||
- [ServerStorageResponseDto](doc//ServerStorageResponseDto.md)
|
||||
- [ServerThemeDto](doc//ServerThemeDto.md)
|
||||
- [ServerVersionResponseDto](doc//ServerVersionResponseDto.md)
|
||||
- [SessionResponseDto](doc//SessionResponseDto.md)
|
||||
@@ -400,12 +406,15 @@ Class | Method | HTTP request | Description
|
||||
- [UpdatePartnerDto](doc//UpdatePartnerDto.md)
|
||||
- [UpdateStackParentDto](doc//UpdateStackParentDto.md)
|
||||
- [UpdateTagDto](doc//UpdateTagDto.md)
|
||||
- [UpdateUserDto](doc//UpdateUserDto.md)
|
||||
- [UsageByUserDto](doc//UsageByUserDto.md)
|
||||
- [UserAdminCreateDto](doc//UserAdminCreateDto.md)
|
||||
- [UserAdminDeleteDto](doc//UserAdminDeleteDto.md)
|
||||
- [UserAdminResponseDto](doc//UserAdminResponseDto.md)
|
||||
- [UserAdminUpdateDto](doc//UserAdminUpdateDto.md)
|
||||
- [UserAvatarColor](doc//UserAvatarColor.md)
|
||||
- [UserDto](doc//UserDto.md)
|
||||
- [UserResponseDto](doc//UserResponseDto.md)
|
||||
- [UserStatus](doc//UserStatus.md)
|
||||
- [UserUpdateMeDto](doc//UserUpdateMeDto.md)
|
||||
- [ValidateAccessTokenResponseDto](doc//ValidateAccessTokenResponseDto.md)
|
||||
- [ValidateLibraryDto](doc//ValidateLibraryDto.md)
|
||||
- [ValidateLibraryImportPathResponseDto](doc//ValidateLibraryImportPathResponseDto.md)
|
||||
|
||||
16
mobile/openapi/doc/PeopleWithFacesResponseDto.md
generated
Normal file
16
mobile/openapi/doc/PeopleWithFacesResponseDto.md
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
# openapi.model.PeopleWithFacesResponseDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**numberOfFaces** | **int** | |
|
||||
**visiblePeople** | [**List<PersonWithFacesResponseDto>**](PersonWithFacesResponseDto.md) | | [default to const []]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
14
mobile/openapi/lib/api.dart
generated
14
mobile/openapi/lib/api.dart
generated
@@ -91,6 +91,8 @@ part 'model/asset_ids_dto.dart';
|
||||
part 'model/asset_ids_response_dto.dart';
|
||||
part 'model/asset_job_name.dart';
|
||||
part 'model/asset_jobs_dto.dart';
|
||||
part 'model/asset_media_response_dto.dart';
|
||||
part 'model/asset_media_status.dart';
|
||||
part 'model/asset_order.dart';
|
||||
part 'model/asset_response_dto.dart';
|
||||
part 'model/asset_stats_response_dto.dart';
|
||||
@@ -110,8 +112,6 @@ part 'model/create_album_dto.dart';
|
||||
part 'model/create_library_dto.dart';
|
||||
part 'model/create_profile_image_response_dto.dart';
|
||||
part 'model/create_tag_dto.dart';
|
||||
part 'model/create_user_dto.dart';
|
||||
part 'model/delete_user_dto.dart';
|
||||
part 'model/download_archive_info.dart';
|
||||
part 'model/download_info_dto.dart';
|
||||
part 'model/download_response_dto.dart';
|
||||
@@ -158,6 +158,7 @@ part 'model/path_type.dart';
|
||||
part 'model/people_response_dto.dart';
|
||||
part 'model/people_update_dto.dart';
|
||||
part 'model/people_update_item.dart';
|
||||
part 'model/people_with_faces_response_dto.dart';
|
||||
part 'model/person_create_dto.dart';
|
||||
part 'model/person_response_dto.dart';
|
||||
part 'model/person_statistics_response_dto.dart';
|
||||
@@ -180,10 +181,10 @@ part 'model/search_response_dto.dart';
|
||||
part 'model/search_suggestion_type.dart';
|
||||
part 'model/server_config_dto.dart';
|
||||
part 'model/server_features_dto.dart';
|
||||
part 'model/server_info_response_dto.dart';
|
||||
part 'model/server_media_types_response_dto.dart';
|
||||
part 'model/server_ping_response.dart';
|
||||
part 'model/server_stats_response_dto.dart';
|
||||
part 'model/server_storage_response_dto.dart';
|
||||
part 'model/server_theme_dto.dart';
|
||||
part 'model/server_version_response_dto.dart';
|
||||
part 'model/session_response_dto.dart';
|
||||
@@ -232,12 +233,15 @@ part 'model/update_library_dto.dart';
|
||||
part 'model/update_partner_dto.dart';
|
||||
part 'model/update_stack_parent_dto.dart';
|
||||
part 'model/update_tag_dto.dart';
|
||||
part 'model/update_user_dto.dart';
|
||||
part 'model/usage_by_user_dto.dart';
|
||||
part 'model/user_admin_create_dto.dart';
|
||||
part 'model/user_admin_delete_dto.dart';
|
||||
part 'model/user_admin_response_dto.dart';
|
||||
part 'model/user_admin_update_dto.dart';
|
||||
part 'model/user_avatar_color.dart';
|
||||
part 'model/user_dto.dart';
|
||||
part 'model/user_response_dto.dart';
|
||||
part 'model/user_status.dart';
|
||||
part 'model/user_update_me_dto.dart';
|
||||
part 'model/validate_access_token_response_dto.dart';
|
||||
part 'model/validate_library_dto.dart';
|
||||
part 'model/validate_library_import_path_response_dto.dart';
|
||||
|
||||
16
mobile/openapi/lib/api/activity_api.dart
generated
16
mobile/openapi/lib/api/activity_api.dart
generated
@@ -16,13 +16,13 @@ class ActivityApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /activity' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /activities' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [ActivityCreateDto] activityCreateDto (required):
|
||||
Future<Response> createActivityWithHttpInfo(ActivityCreateDto activityCreateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/activity';
|
||||
final path = r'/activities';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = activityCreateDto;
|
||||
@@ -63,13 +63,13 @@ class ActivityApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /activity/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /activities/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> deleteActivityWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/activity/{id}'
|
||||
final path = r'/activities/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -103,7 +103,7 @@ class ActivityApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /activity' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /activities' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] albumId (required):
|
||||
@@ -117,7 +117,7 @@ class ActivityApi {
|
||||
/// * [String] userId:
|
||||
Future<Response> getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/activity';
|
||||
final path = r'/activities';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -183,7 +183,7 @@ class ActivityApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /activity/statistics' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /activities/statistics' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] albumId (required):
|
||||
@@ -191,7 +191,7 @@ class ActivityApi {
|
||||
/// * [String] assetId:
|
||||
Future<Response> getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/activity/statistics';
|
||||
final path = r'/activities/statistics';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
44
mobile/openapi/lib/api/album_api.dart
generated
44
mobile/openapi/lib/api/album_api.dart
generated
@@ -16,7 +16,7 @@ class AlbumApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'PUT /album/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /albums/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -26,7 +26,7 @@ class AlbumApi {
|
||||
/// * [String] key:
|
||||
Future<Response> addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { String? key, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}/assets'
|
||||
final path = r'/albums/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -79,7 +79,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /album/{id}/users' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /albums/{id}/users' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -87,7 +87,7 @@ class AlbumApi {
|
||||
/// * [AddUsersDto] addUsersDto (required):
|
||||
Future<Response> addUsersToAlbumWithHttpInfo(String id, AddUsersDto addUsersDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}/users'
|
||||
final path = r'/albums/{id}/users'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -131,13 +131,13 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /album' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /albums' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [CreateAlbumDto] createAlbumDto (required):
|
||||
Future<Response> createAlbumWithHttpInfo(CreateAlbumDto createAlbumDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album';
|
||||
final path = r'/albums';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = createAlbumDto;
|
||||
@@ -178,13 +178,13 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /album/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /albums/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> deleteAlbumWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}'
|
||||
final path = r'/albums/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -218,10 +218,10 @@ class AlbumApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /album/count' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /albums/count' operation and returns the [Response].
|
||||
Future<Response> getAlbumCountWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/count';
|
||||
final path = r'/albums/count';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -259,7 +259,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /album/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /albums/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -269,7 +269,7 @@ class AlbumApi {
|
||||
/// * [bool] withoutAssets:
|
||||
Future<Response> getAlbumInfoWithHttpInfo(String id, { String? key, bool? withoutAssets, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}'
|
||||
final path = r'/albums/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -322,7 +322,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /album' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /albums' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] assetId:
|
||||
@@ -331,7 +331,7 @@ class AlbumApi {
|
||||
/// * [bool] shared:
|
||||
Future<Response> getAllAlbumsWithHttpInfo({ String? assetId, bool? shared, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album';
|
||||
final path = r'/albums';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -385,7 +385,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /album/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /albums/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -393,7 +393,7 @@ class AlbumApi {
|
||||
/// * [BulkIdsDto] bulkIdsDto (required):
|
||||
Future<Response> removeAssetFromAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}/assets'
|
||||
final path = r'/albums/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -440,7 +440,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /album/{id}/user/{userId}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /albums/{id}/user/{userId}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -448,7 +448,7 @@ class AlbumApi {
|
||||
/// * [String] userId (required):
|
||||
Future<Response> removeUserFromAlbumWithHttpInfo(String id, String userId,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}/user/{userId}'
|
||||
final path = r'/albums/{id}/user/{userId}'
|
||||
.replaceAll('{id}', id)
|
||||
.replaceAll('{userId}', userId);
|
||||
|
||||
@@ -485,7 +485,7 @@ class AlbumApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PATCH /album/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PATCH /albums/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -493,7 +493,7 @@ class AlbumApi {
|
||||
/// * [UpdateAlbumDto] updateAlbumDto (required):
|
||||
Future<Response> updateAlbumInfoWithHttpInfo(String id, UpdateAlbumDto updateAlbumDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}'
|
||||
final path = r'/albums/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -537,7 +537,7 @@ class AlbumApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /album/{id}/user/{userId}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /albums/{id}/user/{userId}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -547,7 +547,7 @@ class AlbumApi {
|
||||
/// * [UpdateAlbumUserDto] updateAlbumUserDto (required):
|
||||
Future<Response> updateAlbumUserWithHttpInfo(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/album/{id}/user/{userId}'
|
||||
final path = r'/albums/{id}/user/{userId}'
|
||||
.replaceAll('{id}', id)
|
||||
.replaceAll('{userId}', userId);
|
||||
|
||||
|
||||
20
mobile/openapi/lib/api/api_key_api.dart
generated
20
mobile/openapi/lib/api/api_key_api.dart
generated
@@ -16,13 +16,13 @@ class APIKeyApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /api-key' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /api-keys' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [APIKeyCreateDto] aPIKeyCreateDto (required):
|
||||
Future<Response> createApiKeyWithHttpInfo(APIKeyCreateDto aPIKeyCreateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/api-key';
|
||||
final path = r'/api-keys';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = aPIKeyCreateDto;
|
||||
@@ -63,13 +63,13 @@ class APIKeyApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /api-key/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /api-keys/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> deleteApiKeyWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/api-key/{id}'
|
||||
final path = r'/api-keys/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -103,13 +103,13 @@ class APIKeyApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /api-key/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /api-keys/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getApiKeyWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/api-key/{id}'
|
||||
final path = r'/api-keys/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -151,10 +151,10 @@ class APIKeyApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /api-key' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /api-keys' operation and returns the [Response].
|
||||
Future<Response> getApiKeysWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/api-key';
|
||||
final path = r'/api-keys';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -195,7 +195,7 @@ class APIKeyApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /api-key/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /api-keys/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -203,7 +203,7 @@ class APIKeyApi {
|
||||
/// * [APIKeyUpdateDto] aPIKeyUpdateDto (required):
|
||||
Future<Response> updateApiKeyWithHttpInfo(String id, APIKeyUpdateDto aPIKeyUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/api-key/{id}'
|
||||
final path = r'/api-keys/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
226
mobile/openapi/lib/api/asset_api.dart
generated
226
mobile/openapi/lib/api/asset_api.dart
generated
@@ -159,117 +159,6 @@ class AssetApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all AssetEntity belong to the user
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
///
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] ifNoneMatch:
|
||||
/// ETag of data already cached on the client
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [int] skip:
|
||||
///
|
||||
/// * [int] take:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [String] userId:
|
||||
Future<Response> getAllAssetsWithHttpInfo({ String? ifNoneMatch, bool? isArchived, bool? isFavorite, int? skip, int? take, DateTime? updatedAfter, DateTime? updatedBefore, String? userId, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
if (isArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'isArchived', isArchived));
|
||||
}
|
||||
if (isFavorite != null) {
|
||||
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
|
||||
}
|
||||
if (skip != null) {
|
||||
queryParams.addAll(_queryParams('', 'skip', skip));
|
||||
}
|
||||
if (take != null) {
|
||||
queryParams.addAll(_queryParams('', 'take', take));
|
||||
}
|
||||
if (updatedAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter));
|
||||
}
|
||||
if (updatedBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedBefore', updatedBefore));
|
||||
}
|
||||
if (userId != null) {
|
||||
queryParams.addAll(_queryParams('', 'userId', userId));
|
||||
}
|
||||
|
||||
if (ifNoneMatch != null) {
|
||||
headerParams[r'if-none-match'] = parameterToString(ifNoneMatch);
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Get all AssetEntity belong to the user
|
||||
///
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] ifNoneMatch:
|
||||
/// ETag of data already cached on the client
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [int] skip:
|
||||
///
|
||||
/// * [int] take:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [String] userId:
|
||||
Future<List<AssetResponseDto>?> getAllAssets({ String? ifNoneMatch, bool? isArchived, bool? isFavorite, int? skip, int? take, DateTime? updatedAfter, DateTime? updatedBefore, String? userId, }) async {
|
||||
final response = await getAllAssetsWithHttpInfo( ifNoneMatch: ifNoneMatch, isArchived: isArchived, isFavorite: isFavorite, skip: skip, take: take, updatedAfter: updatedAfter, updatedBefore: updatedBefore, userId: userId, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
final responseBody = await _decodeBodyBytes(response);
|
||||
return (await apiClient.deserializeAsync(responseBody, 'List<AssetResponseDto>') as List)
|
||||
.cast<AssetResponseDto>()
|
||||
.toList(growable: false);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get all asset of a device that are in the database, ID only.
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
@@ -710,6 +599,121 @@ class AssetApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
///
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [MultipartFile] assetData (required):
|
||||
///
|
||||
/// * [String] deviceAssetId (required):
|
||||
///
|
||||
/// * [String] deviceId (required):
|
||||
///
|
||||
/// * [DateTime] fileCreatedAt (required):
|
||||
///
|
||||
/// * [DateTime] fileModifiedAt (required):
|
||||
///
|
||||
/// * [String] key:
|
||||
///
|
||||
/// * [String] duration:
|
||||
Future<Response> replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? duration, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset/{id}/file'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
if (key != null) {
|
||||
queryParams.addAll(_queryParams('', 'key', key));
|
||||
}
|
||||
|
||||
const contentTypes = <String>['multipart/form-data'];
|
||||
|
||||
bool hasFields = false;
|
||||
final mp = MultipartRequest('PUT', Uri.parse(path));
|
||||
if (assetData != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'assetData'] = assetData.field;
|
||||
mp.files.add(assetData);
|
||||
}
|
||||
if (deviceAssetId != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'deviceAssetId'] = parameterToString(deviceAssetId);
|
||||
}
|
||||
if (deviceId != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'deviceId'] = parameterToString(deviceId);
|
||||
}
|
||||
if (duration != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'duration'] = parameterToString(duration);
|
||||
}
|
||||
if (fileCreatedAt != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'fileCreatedAt'] = parameterToString(fileCreatedAt);
|
||||
}
|
||||
if (fileModifiedAt != null) {
|
||||
hasFields = true;
|
||||
mp.fields[r'fileModifiedAt'] = parameterToString(fileModifiedAt);
|
||||
}
|
||||
if (hasFields) {
|
||||
postBody = mp;
|
||||
}
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'PUT',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Replace the asset with new file, without changing its id
|
||||
///
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [MultipartFile] assetData (required):
|
||||
///
|
||||
/// * [String] deviceAssetId (required):
|
||||
///
|
||||
/// * [String] deviceId (required):
|
||||
///
|
||||
/// * [DateTime] fileCreatedAt (required):
|
||||
///
|
||||
/// * [DateTime] fileModifiedAt (required):
|
||||
///
|
||||
/// * [String] key:
|
||||
///
|
||||
/// * [String] duration:
|
||||
Future<AssetMediaResponseDto?> replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? duration, }) async {
|
||||
final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, duration: duration, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetMediaResponseDto',) as AssetMediaResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /asset/jobs' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
|
||||
8
mobile/openapi/lib/api/authentication_api.dart
generated
8
mobile/openapi/lib/api/authentication_api.dart
generated
@@ -48,7 +48,7 @@ class AuthenticationApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [ChangePasswordDto] changePasswordDto (required):
|
||||
Future<UserResponseDto?> changePassword(ChangePasswordDto changePasswordDto,) async {
|
||||
Future<UserAdminResponseDto?> changePassword(ChangePasswordDto changePasswordDto,) async {
|
||||
final response = await changePasswordWithHttpInfo(changePasswordDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
@@ -57,7 +57,7 @@ class AuthenticationApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
@@ -183,7 +183,7 @@ class AuthenticationApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [SignUpDto] signUpDto (required):
|
||||
Future<UserResponseDto?> signUpAdmin(SignUpDto signUpDto,) async {
|
||||
Future<UserAdminResponseDto?> signUpAdmin(SignUpDto signUpDto,) async {
|
||||
final response = await signUpAdminWithHttpInfo(signUpDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
@@ -192,7 +192,7 @@ class AuthenticationApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
56
mobile/openapi/lib/api/face_api.dart
generated
56
mobile/openapi/lib/api/face_api.dart
generated
@@ -16,13 +16,13 @@ class FaceApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'GET /face' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /faces' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getFacesWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/face';
|
||||
final path = r'/faces';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -68,7 +68,7 @@ class FaceApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /face/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /faces/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -76,7 +76,7 @@ class FaceApi {
|
||||
/// * [FaceDto] faceDto (required):
|
||||
Future<Response> reassignFacesByIdWithHttpInfo(String id, FaceDto faceDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/face/{id}'
|
||||
final path = r'/faces/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -119,4 +119,52 @@ class FaceApi {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /faces/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> unassignFaceWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/faces/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'DELETE',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<AssetFaceResponseDto?> unassignFace(String id,) async {
|
||||
final response = await unassignFaceWithHttpInfo(id,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetFaceResponseDto',) as AssetFaceResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
12
mobile/openapi/lib/api/file_report_api.dart
generated
12
mobile/openapi/lib/api/file_report_api.dart
generated
@@ -16,13 +16,13 @@ class FileReportApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /report/fix' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /reports/fix' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [FileReportFixDto] fileReportFixDto (required):
|
||||
Future<Response> fixAuditFilesWithHttpInfo(FileReportFixDto fileReportFixDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/report/fix';
|
||||
final path = r'/reports/fix';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = fileReportFixDto;
|
||||
@@ -55,10 +55,10 @@ class FileReportApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /report' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /reports' operation and returns the [Response].
|
||||
Future<Response> getAuditFilesWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/report';
|
||||
final path = r'/reports';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -96,13 +96,13 @@ class FileReportApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /report/checksum' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /reports/checksum' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [FileChecksumDto] fileChecksumDto (required):
|
||||
Future<Response> getFileChecksumsWithHttpInfo(FileChecksumDto fileChecksumDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/report/checksum';
|
||||
final path = r'/reports/checksum';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = fileChecksumDto;
|
||||
|
||||
36
mobile/openapi/lib/api/library_api.dart
generated
36
mobile/openapi/lib/api/library_api.dart
generated
@@ -16,13 +16,13 @@ class LibraryApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /library' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /libraries' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [CreateLibraryDto] createLibraryDto (required):
|
||||
Future<Response> createLibraryWithHttpInfo(CreateLibraryDto createLibraryDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library';
|
||||
final path = r'/libraries';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = createLibraryDto;
|
||||
@@ -63,13 +63,13 @@ class LibraryApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /library/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /libraries/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> deleteLibraryWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}'
|
||||
final path = r'/libraries/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -103,10 +103,10 @@ class LibraryApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /library' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /libraries' operation and returns the [Response].
|
||||
Future<Response> getAllLibrariesWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library';
|
||||
final path = r'/libraries';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -147,13 +147,13 @@ class LibraryApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /library/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /libraries/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getLibraryWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}'
|
||||
final path = r'/libraries/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -195,13 +195,13 @@ class LibraryApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /library/{id}/statistics' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /libraries/{id}/statistics' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getLibraryStatisticsWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}/statistics'
|
||||
final path = r'/libraries/{id}/statistics'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -243,13 +243,13 @@ class LibraryApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /library/{id}/removeOffline' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /libraries/{id}/removeOffline' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> removeOfflineFilesWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}/removeOffline'
|
||||
final path = r'/libraries/{id}/removeOffline'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -283,7 +283,7 @@ class LibraryApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /library/{id}/scan' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /libraries/{id}/scan' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -291,7 +291,7 @@ class LibraryApi {
|
||||
/// * [ScanLibraryDto] scanLibraryDto (required):
|
||||
Future<Response> scanLibraryWithHttpInfo(String id, ScanLibraryDto scanLibraryDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}/scan'
|
||||
final path = r'/libraries/{id}/scan'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -327,7 +327,7 @@ class LibraryApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /library/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /libraries/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -335,7 +335,7 @@ class LibraryApi {
|
||||
/// * [UpdateLibraryDto] updateLibraryDto (required):
|
||||
Future<Response> updateLibraryWithHttpInfo(String id, UpdateLibraryDto updateLibraryDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}'
|
||||
final path = r'/libraries/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -379,7 +379,7 @@ class LibraryApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /library/{id}/validate' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /libraries/{id}/validate' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -387,7 +387,7 @@ class LibraryApi {
|
||||
/// * [ValidateLibraryDto] validateLibraryDto (required):
|
||||
Future<Response> validateWithHttpInfo(String id, ValidateLibraryDto validateLibraryDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/library/{id}/validate'
|
||||
final path = r'/libraries/{id}/validate'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
8
mobile/openapi/lib/api/o_auth_api.dart
generated
8
mobile/openapi/lib/api/o_auth_api.dart
generated
@@ -95,7 +95,7 @@ class OAuthApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [OAuthCallbackDto] oAuthCallbackDto (required):
|
||||
Future<UserResponseDto?> linkOAuthAccount(OAuthCallbackDto oAuthCallbackDto,) async {
|
||||
Future<UserAdminResponseDto?> linkOAuthAccount(OAuthCallbackDto oAuthCallbackDto,) async {
|
||||
final response = await linkOAuthAccountWithHttpInfo(oAuthCallbackDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
@@ -104,7 +104,7 @@ class OAuthApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
@@ -216,7 +216,7 @@ class OAuthApi {
|
||||
);
|
||||
}
|
||||
|
||||
Future<UserResponseDto?> unlinkOAuthAccount() async {
|
||||
Future<UserAdminResponseDto?> unlinkOAuthAccount() async {
|
||||
final response = await unlinkOAuthAccountWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
@@ -225,7 +225,7 @@ class OAuthApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
16
mobile/openapi/lib/api/partner_api.dart
generated
16
mobile/openapi/lib/api/partner_api.dart
generated
@@ -16,13 +16,13 @@ class PartnerApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /partner/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /partners/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> createPartnerWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/partner/{id}'
|
||||
final path = r'/partners/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -64,13 +64,13 @@ class PartnerApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /partner' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /partners' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] direction (required):
|
||||
Future<Response> getPartnersWithHttpInfo(String direction,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/partner';
|
||||
final path = r'/partners';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -116,13 +116,13 @@ class PartnerApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /partner/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /partners/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> removePartnerWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/partner/{id}'
|
||||
final path = r'/partners/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -156,7 +156,7 @@ class PartnerApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /partner/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /partners/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -164,7 +164,7 @@ class PartnerApi {
|
||||
/// * [UpdatePartnerDto] updatePartnerDto (required):
|
||||
Future<Response> updatePartnerWithHttpInfo(String id, UpdatePartnerDto updatePartnerDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/partner/{id}'
|
||||
final path = r'/partners/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
90
mobile/openapi/lib/api/person_api.dart
generated
90
mobile/openapi/lib/api/person_api.dart
generated
@@ -16,13 +16,13 @@ class PersonApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /person' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /people' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [PersonCreateDto] personCreateDto (required):
|
||||
Future<Response> createPersonWithHttpInfo(PersonCreateDto personCreateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person';
|
||||
final path = r'/people';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = personCreateDto;
|
||||
@@ -63,13 +63,13 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /person' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /people' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] withHidden:
|
||||
Future<Response> getAllPeopleWithHttpInfo({ bool? withHidden, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person';
|
||||
final path = r'/people';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -114,13 +114,13 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /person/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /people/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getPersonWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}'
|
||||
final path = r'/people/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -162,13 +162,13 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /person/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /people/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getPersonAssetsWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}/assets'
|
||||
final path = r'/people/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -213,13 +213,13 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /person/{id}/statistics' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /people/{id}/statistics' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getPersonStatisticsWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}/statistics'
|
||||
final path = r'/people/{id}/statistics'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -261,13 +261,13 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /person/{id}/thumbnail' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /people/{id}/thumbnail' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getPersonThumbnailWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}/thumbnail'
|
||||
final path = r'/people/{id}/thumbnail'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -309,7 +309,7 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /person/{id}/merge' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /people/{id}/merge' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -317,7 +317,7 @@ class PersonApi {
|
||||
/// * [MergePersonDto] mergePersonDto (required):
|
||||
Future<Response> mergePersonWithHttpInfo(String id, MergePersonDto mergePersonDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}/merge'
|
||||
final path = r'/people/{id}/merge'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -364,7 +364,7 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /person/{id}/reassign' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /people/{id}/reassign' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -372,7 +372,7 @@ class PersonApi {
|
||||
/// * [AssetFaceUpdateDto] assetFaceUpdateDto (required):
|
||||
Future<Response> reassignFacesWithHttpInfo(String id, AssetFaceUpdateDto assetFaceUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}/reassign'
|
||||
final path = r'/people/{id}/reassign'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -419,13 +419,63 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /person' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /people' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [AssetFaceUpdateDto] assetFaceUpdateDto (required):
|
||||
Future<Response> unassignFacesWithHttpInfo(AssetFaceUpdateDto assetFaceUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/people';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = assetFaceUpdateDto;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>['application/json'];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'DELETE',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [AssetFaceUpdateDto] assetFaceUpdateDto (required):
|
||||
Future<List<BulkIdResponseDto>?> unassignFaces(AssetFaceUpdateDto assetFaceUpdateDto,) async {
|
||||
final response = await unassignFacesWithHttpInfo(assetFaceUpdateDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
final responseBody = await _decodeBodyBytes(response);
|
||||
return (await apiClient.deserializeAsync(responseBody, 'List<BulkIdResponseDto>') as List)
|
||||
.cast<BulkIdResponseDto>()
|
||||
.toList(growable: false);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /people' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [PeopleUpdateDto] peopleUpdateDto (required):
|
||||
Future<Response> updatePeopleWithHttpInfo(PeopleUpdateDto peopleUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person';
|
||||
final path = r'/people';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = peopleUpdateDto;
|
||||
@@ -469,7 +519,7 @@ class PersonApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /person/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /people/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -477,7 +527,7 @@ class PersonApi {
|
||||
/// * [PersonUpdateDto] personUpdateDto (required):
|
||||
Future<Response> updatePersonWithHttpInfo(String id, PersonUpdateDto personUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/person/{id}'
|
||||
final path = r'/people/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
82
mobile/openapi/lib/api/server_info_api.dart
generated
82
mobile/openapi/lib/api/server_info_api.dart
generated
@@ -98,47 +98,6 @@ class ServerInfoApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /server-info' operation and returns the [Response].
|
||||
Future<Response> getServerInfoWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/server-info';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<ServerInfoResponseDto?> getServerInfo() async {
|
||||
final response = await getServerInfoWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerInfoResponseDto',) as ServerInfoResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /server-info/statistics' operation and returns the [Response].
|
||||
Future<Response> getServerStatisticsWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
@@ -221,6 +180,47 @@ class ServerInfoApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /server-info/storage' operation and returns the [Response].
|
||||
Future<Response> getStorageWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/server-info/storage';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<ServerStorageResponseDto?> getStorage() async {
|
||||
final response = await getStorageWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerStorageResponseDto',) as ServerStorageResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /server-info/media-types' operation and returns the [Response].
|
||||
Future<Response> getSupportedMediaTypesWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
|
||||
32
mobile/openapi/lib/api/shared_link_api.dart
generated
32
mobile/openapi/lib/api/shared_link_api.dart
generated
@@ -16,7 +16,7 @@ class SharedLinkApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'PUT /shared-link/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /shared-links/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -26,7 +26,7 @@ class SharedLinkApi {
|
||||
/// * [String] key:
|
||||
Future<Response> addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { String? key, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/{id}/assets'
|
||||
final path = r'/shared-links/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -79,13 +79,13 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /shared-link' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /shared-links' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [SharedLinkCreateDto] sharedLinkCreateDto (required):
|
||||
Future<Response> createSharedLinkWithHttpInfo(SharedLinkCreateDto sharedLinkCreateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link';
|
||||
final path = r'/shared-links';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = sharedLinkCreateDto;
|
||||
@@ -126,10 +126,10 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /shared-link' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /shared-links' operation and returns the [Response].
|
||||
Future<Response> getAllSharedLinksWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link';
|
||||
final path = r'/shared-links';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -170,7 +170,7 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /shared-link/me' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /shared-links/me' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] key:
|
||||
@@ -180,7 +180,7 @@ class SharedLinkApi {
|
||||
/// * [String] token:
|
||||
Future<Response> getMySharedLinkWithHttpInfo({ String? key, String? password, String? token, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/me';
|
||||
final path = r'/shared-links/me';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -235,13 +235,13 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /shared-link/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /shared-links/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getSharedLinkByIdWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/{id}'
|
||||
final path = r'/shared-links/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -283,13 +283,13 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /shared-link/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /shared-links/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> removeSharedLinkWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/{id}'
|
||||
final path = r'/shared-links/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -323,7 +323,7 @@ class SharedLinkApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /shared-link/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /shared-links/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -333,7 +333,7 @@ class SharedLinkApi {
|
||||
/// * [String] key:
|
||||
Future<Response> removeSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { String? key, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/{id}/assets'
|
||||
final path = r'/shared-links/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -386,7 +386,7 @@ class SharedLinkApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PATCH /shared-link/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PATCH /shared-links/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -394,7 +394,7 @@ class SharedLinkApi {
|
||||
/// * [SharedLinkEditDto] sharedLinkEditDto (required):
|
||||
Future<Response> updateSharedLinkWithHttpInfo(String id, SharedLinkEditDto sharedLinkEditDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/shared-link/{id}'
|
||||
final path = r'/shared-links/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
32
mobile/openapi/lib/api/tag_api.dart
generated
32
mobile/openapi/lib/api/tag_api.dart
generated
@@ -16,13 +16,13 @@ class TagApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /tag' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /tags' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [CreateTagDto] createTagDto (required):
|
||||
Future<Response> createTagWithHttpInfo(CreateTagDto createTagDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag';
|
||||
final path = r'/tags';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = createTagDto;
|
||||
@@ -63,13 +63,13 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /tag/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /tags/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> deleteTagWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}'
|
||||
final path = r'/tags/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -103,10 +103,10 @@ class TagApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /tag' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /tags' operation and returns the [Response].
|
||||
Future<Response> getAllTagsWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag';
|
||||
final path = r'/tags';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -147,13 +147,13 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /tag/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /tags/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getTagAssetsWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}/assets'
|
||||
final path = r'/tags/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -198,13 +198,13 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /tag/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /tags/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getTagByIdWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}'
|
||||
final path = r'/tags/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -246,7 +246,7 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /tag/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PUT /tags/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -254,7 +254,7 @@ class TagApi {
|
||||
/// * [AssetIdsDto] assetIdsDto (required):
|
||||
Future<Response> tagAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}/assets'
|
||||
final path = r'/tags/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -301,7 +301,7 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /tag/{id}/assets' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /tags/{id}/assets' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -309,7 +309,7 @@ class TagApi {
|
||||
/// * [AssetIdsDto] assetIdsDto (required):
|
||||
Future<Response> untagAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}/assets'
|
||||
final path = r'/tags/{id}/assets'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -356,7 +356,7 @@ class TagApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PATCH /tag/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'PATCH /tags/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
@@ -364,7 +364,7 @@ class TagApi {
|
||||
/// * [UpdateTagDto] updateTagDto (required):
|
||||
Future<Response> updateTagWithHttpInfo(String id, UpdateTagDto updateTagDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/tag/{id}'
|
||||
final path = r'/tags/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
|
||||
354
mobile/openapi/lib/api/user_api.dart
generated
354
mobile/openapi/lib/api/user_api.dart
generated
@@ -16,13 +16,13 @@ class UserApi {
|
||||
|
||||
final ApiClient apiClient;
|
||||
|
||||
/// Performs an HTTP 'POST /user/profile-image' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /users/profile-image' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [MultipartFile] file (required):
|
||||
Future<Response> createProfileImageWithHttpInfo(MultipartFile file,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/profile-image';
|
||||
final path = r'/users/profile-image';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -73,16 +73,16 @@ class UserApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /user' operation and returns the [Response].
|
||||
/// Performs an HTTP 'POST /admin/users' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [CreateUserDto] createUserDto (required):
|
||||
Future<Response> createUserWithHttpInfo(CreateUserDto createUserDto,) async {
|
||||
/// * [UserAdminCreateDto] userAdminCreateDto (required):
|
||||
Future<Response> createUserAdminWithHttpInfo(UserAdminCreateDto userAdminCreateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user';
|
||||
final path = r'/admin/users';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = createUserDto;
|
||||
Object? postBody = userAdminCreateDto;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
@@ -104,9 +104,9 @@ class UserApi {
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [CreateUserDto] createUserDto (required):
|
||||
Future<UserResponseDto?> createUser(CreateUserDto createUserDto,) async {
|
||||
final response = await createUserWithHttpInfo(createUserDto,);
|
||||
/// * [UserAdminCreateDto] userAdminCreateDto (required):
|
||||
Future<UserAdminResponseDto?> createUserAdmin(UserAdminCreateDto userAdminCreateDto,) async {
|
||||
final response = await createUserAdminWithHttpInfo(userAdminCreateDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -114,16 +114,16 @@ class UserApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /user/profile-image' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /users/profile-image' operation and returns the [Response].
|
||||
Future<Response> deleteProfileImageWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/profile-image';
|
||||
final path = r'/users/profile-image';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -153,19 +153,19 @@ class UserApi {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'DELETE /user/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'DELETE /admin/users/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [DeleteUserDto] deleteUserDto (required):
|
||||
Future<Response> deleteUserWithHttpInfo(String id, DeleteUserDto deleteUserDto,) async {
|
||||
/// * [UserAdminDeleteDto] userAdminDeleteDto (required):
|
||||
Future<Response> deleteUserAdminWithHttpInfo(String id, UserAdminDeleteDto userAdminDeleteDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/{id}'
|
||||
final path = r'/admin/users/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = deleteUserDto;
|
||||
Object? postBody = userAdminDeleteDto;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
@@ -189,9 +189,9 @@ class UserApi {
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [DeleteUserDto] deleteUserDto (required):
|
||||
Future<UserResponseDto?> deleteUser(String id, DeleteUserDto deleteUserDto,) async {
|
||||
final response = await deleteUserWithHttpInfo(id, deleteUserDto,);
|
||||
/// * [UserAdminDeleteDto] userAdminDeleteDto (required):
|
||||
Future<UserAdminResponseDto?> deleteUserAdmin(String id, UserAdminDeleteDto userAdminDeleteDto,) async {
|
||||
final response = await deleteUserAdminWithHttpInfo(id, userAdminDeleteDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -199,68 +199,16 @@ class UserApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /user' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] isAll (required):
|
||||
Future<Response> getAllUsersWithHttpInfo(bool isAll,) async {
|
||||
/// Performs an HTTP 'GET /users/me' operation and returns the [Response].
|
||||
Future<Response> getMyUserWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
queryParams.addAll(_queryParams('', 'isAll', isAll));
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] isAll (required):
|
||||
Future<List<UserResponseDto>?> getAllUsers(bool isAll,) async {
|
||||
final response = await getAllUsersWithHttpInfo(isAll,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
final responseBody = await _decodeBodyBytes(response);
|
||||
return (await apiClient.deserializeAsync(responseBody, 'List<UserResponseDto>') as List)
|
||||
.cast<UserResponseDto>()
|
||||
.toList(growable: false);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /user/me' operation and returns the [Response].
|
||||
Future<Response> getMyUserInfoWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/me';
|
||||
final path = r'/users/me';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
@@ -283,8 +231,8 @@ class UserApi {
|
||||
);
|
||||
}
|
||||
|
||||
Future<UserResponseDto?> getMyUserInfo() async {
|
||||
final response = await getMyUserInfoWithHttpInfo();
|
||||
Future<UserAdminResponseDto?> getMyUser() async {
|
||||
final response = await getMyUserWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -292,19 +240,19 @@ class UserApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /user/profile-image/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /users/{id}/profile-image' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getProfileImageWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/profile-image/{id}'
|
||||
final path = r'/users/{id}/profile-image'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -346,13 +294,13 @@ class UserApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /user/info/{id}' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /users/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> getUserByIdWithHttpInfo(String id,) async {
|
||||
Future<Response> getUserWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/info/{id}'
|
||||
final path = r'/users/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -379,8 +327,8 @@ class UserApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<UserResponseDto?> getUserById(String id,) async {
|
||||
final response = await getUserByIdWithHttpInfo(id,);
|
||||
Future<UserResponseDto?> getUser(String id,) async {
|
||||
final response = await getUserWithHttpInfo(id,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -394,13 +342,61 @@ class UserApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /user/{id}/restore' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /admin/users/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> restoreUserWithHttpInfo(String id,) async {
|
||||
Future<Response> getUserAdminWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user/{id}/restore'
|
||||
final path = r'/admin/users/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<UserAdminResponseDto?> getUserAdmin(String id,) async {
|
||||
final response = await getUserAdminWithHttpInfo(id,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /admin/users/{id}/restore' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<Response> restoreUserAdminWithHttpInfo(String id,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/admin/users/{id}/restore'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
@@ -427,8 +423,8 @@ class UserApi {
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
Future<UserResponseDto?> restoreUser(String id,) async {
|
||||
final response = await restoreUserWithHttpInfo(id,);
|
||||
Future<UserAdminResponseDto?> restoreUserAdmin(String id,) async {
|
||||
final response = await restoreUserAdminWithHttpInfo(id,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -436,22 +432,120 @@ class UserApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /user' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [UpdateUserDto] updateUserDto (required):
|
||||
Future<Response> updateUserWithHttpInfo(UpdateUserDto updateUserDto,) async {
|
||||
/// Performs an HTTP 'GET /users' operation and returns the [Response].
|
||||
Future<Response> searchUsersWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/user';
|
||||
final path = r'/users';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = updateUserDto;
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<UserResponseDto>?> searchUsers() async {
|
||||
final response = await searchUsersWithHttpInfo();
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
final responseBody = await _decodeBodyBytes(response);
|
||||
return (await apiClient.deserializeAsync(responseBody, 'List<UserResponseDto>') as List)
|
||||
.cast<UserResponseDto>()
|
||||
.toList(growable: false);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /admin/users' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
Future<Response> searchUsersAdminWithHttpInfo({ bool? withDeleted, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/admin/users';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
if (withDeleted != null) {
|
||||
queryParams.addAll(_queryParams('', 'withDeleted', withDeleted));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
Future<List<UserAdminResponseDto>?> searchUsersAdmin({ bool? withDeleted, }) async {
|
||||
final response = await searchUsersAdminWithHttpInfo( withDeleted: withDeleted, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
final responseBody = await _decodeBodyBytes(response);
|
||||
return (await apiClient.deserializeAsync(responseBody, 'List<UserAdminResponseDto>') as List)
|
||||
.cast<UserAdminResponseDto>()
|
||||
.toList(growable: false);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /users/me' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [UserUpdateMeDto] userUpdateMeDto (required):
|
||||
Future<Response> updateMyUserWithHttpInfo(UserUpdateMeDto userUpdateMeDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/users/me';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = userUpdateMeDto;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
@@ -473,9 +567,9 @@ class UserApi {
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [UpdateUserDto] updateUserDto (required):
|
||||
Future<UserResponseDto?> updateUser(UpdateUserDto updateUserDto,) async {
|
||||
final response = await updateUserWithHttpInfo(updateUserDto,);
|
||||
/// * [UserUpdateMeDto] userUpdateMeDto (required):
|
||||
Future<UserAdminResponseDto?> updateMyUser(UserUpdateMeDto userUpdateMeDto,) async {
|
||||
final response = await updateMyUserWithHttpInfo(userUpdateMeDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -483,7 +577,59 @@ class UserApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserResponseDto',) as UserResponseDto;
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'PUT /admin/users/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [UserAdminUpdateDto] userAdminUpdateDto (required):
|
||||
Future<Response> updateUserAdminWithHttpInfo(String id, UserAdminUpdateDto userAdminUpdateDto,) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/admin/users/{id}'
|
||||
.replaceAll('{id}', id);
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = userAdminUpdateDto;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>['application/json'];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'PUT',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [UserAdminUpdateDto] userAdminUpdateDto (required):
|
||||
Future<UserAdminResponseDto?> updateUserAdmin(String id, UserAdminUpdateDto userAdminUpdateDto,) async {
|
||||
final response = await updateUserAdminWithHttpInfo(id, userAdminUpdateDto,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
// When a remote server returns no body with a status of 204, we shall not decode it.
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'UserAdminResponseDto',) as UserAdminResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
28
mobile/openapi/lib/api_client.dart
generated
28
mobile/openapi/lib/api_client.dart
generated
@@ -250,6 +250,10 @@ class ApiClient {
|
||||
return AssetJobNameTypeTransformer().decode(value);
|
||||
case 'AssetJobsDto':
|
||||
return AssetJobsDto.fromJson(value);
|
||||
case 'AssetMediaResponseDto':
|
||||
return AssetMediaResponseDto.fromJson(value);
|
||||
case 'AssetMediaStatus':
|
||||
return AssetMediaStatusTypeTransformer().decode(value);
|
||||
case 'AssetOrder':
|
||||
return AssetOrderTypeTransformer().decode(value);
|
||||
case 'AssetResponseDto':
|
||||
@@ -288,10 +292,6 @@ class ApiClient {
|
||||
return CreateProfileImageResponseDto.fromJson(value);
|
||||
case 'CreateTagDto':
|
||||
return CreateTagDto.fromJson(value);
|
||||
case 'CreateUserDto':
|
||||
return CreateUserDto.fromJson(value);
|
||||
case 'DeleteUserDto':
|
||||
return DeleteUserDto.fromJson(value);
|
||||
case 'DownloadArchiveInfo':
|
||||
return DownloadArchiveInfo.fromJson(value);
|
||||
case 'DownloadInfoDto':
|
||||
@@ -384,6 +384,8 @@ class ApiClient {
|
||||
return PeopleUpdateDto.fromJson(value);
|
||||
case 'PeopleUpdateItem':
|
||||
return PeopleUpdateItem.fromJson(value);
|
||||
case 'PeopleWithFacesResponseDto':
|
||||
return PeopleWithFacesResponseDto.fromJson(value);
|
||||
case 'PersonCreateDto':
|
||||
return PersonCreateDto.fromJson(value);
|
||||
case 'PersonResponseDto':
|
||||
@@ -428,14 +430,14 @@ class ApiClient {
|
||||
return ServerConfigDto.fromJson(value);
|
||||
case 'ServerFeaturesDto':
|
||||
return ServerFeaturesDto.fromJson(value);
|
||||
case 'ServerInfoResponseDto':
|
||||
return ServerInfoResponseDto.fromJson(value);
|
||||
case 'ServerMediaTypesResponseDto':
|
||||
return ServerMediaTypesResponseDto.fromJson(value);
|
||||
case 'ServerPingResponse':
|
||||
return ServerPingResponse.fromJson(value);
|
||||
case 'ServerStatsResponseDto':
|
||||
return ServerStatsResponseDto.fromJson(value);
|
||||
case 'ServerStorageResponseDto':
|
||||
return ServerStorageResponseDto.fromJson(value);
|
||||
case 'ServerThemeDto':
|
||||
return ServerThemeDto.fromJson(value);
|
||||
case 'ServerVersionResponseDto':
|
||||
@@ -532,18 +534,24 @@ class ApiClient {
|
||||
return UpdateStackParentDto.fromJson(value);
|
||||
case 'UpdateTagDto':
|
||||
return UpdateTagDto.fromJson(value);
|
||||
case 'UpdateUserDto':
|
||||
return UpdateUserDto.fromJson(value);
|
||||
case 'UsageByUserDto':
|
||||
return UsageByUserDto.fromJson(value);
|
||||
case 'UserAdminCreateDto':
|
||||
return UserAdminCreateDto.fromJson(value);
|
||||
case 'UserAdminDeleteDto':
|
||||
return UserAdminDeleteDto.fromJson(value);
|
||||
case 'UserAdminResponseDto':
|
||||
return UserAdminResponseDto.fromJson(value);
|
||||
case 'UserAdminUpdateDto':
|
||||
return UserAdminUpdateDto.fromJson(value);
|
||||
case 'UserAvatarColor':
|
||||
return UserAvatarColorTypeTransformer().decode(value);
|
||||
case 'UserDto':
|
||||
return UserDto.fromJson(value);
|
||||
case 'UserResponseDto':
|
||||
return UserResponseDto.fromJson(value);
|
||||
case 'UserStatus':
|
||||
return UserStatusTypeTransformer().decode(value);
|
||||
case 'UserUpdateMeDto':
|
||||
return UserUpdateMeDto.fromJson(value);
|
||||
case 'ValidateAccessTokenResponseDto':
|
||||
return ValidateAccessTokenResponseDto.fromJson(value);
|
||||
case 'ValidateLibraryDto':
|
||||
|
||||
3
mobile/openapi/lib/api_helper.dart
generated
3
mobile/openapi/lib/api_helper.dart
generated
@@ -61,6 +61,9 @@ String parameterToString(dynamic value) {
|
||||
if (value is AssetJobName) {
|
||||
return AssetJobNameTypeTransformer().encode(value).toString();
|
||||
}
|
||||
if (value is AssetMediaStatus) {
|
||||
return AssetMediaStatusTypeTransformer().encode(value).toString();
|
||||
}
|
||||
if (value is AssetOrder) {
|
||||
return AssetOrderTypeTransformer().encode(value).toString();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ActivityResponseDto {
|
||||
|
||||
ActivityResponseDtoTypeEnum type;
|
||||
|
||||
UserDto user;
|
||||
UserResponseDto user;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is ActivityResponseDto &&
|
||||
@@ -87,7 +87,7 @@ class ActivityResponseDto {
|
||||
createdAt: mapDateTime(json, r'createdAt', r'')!,
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
type: ActivityResponseDtoTypeEnum.fromJson(json[r'type'])!,
|
||||
user: UserDto.fromJson(json[r'user'])!,
|
||||
user: UserResponseDto.fromJson(json[r'user'])!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
16
mobile/openapi/lib/model/add_users_dto.dart
generated
16
mobile/openapi/lib/model/add_users_dto.dart
generated
@@ -14,32 +14,25 @@ class AddUsersDto {
|
||||
/// Returns a new [AddUsersDto] instance.
|
||||
AddUsersDto({
|
||||
this.albumUsers = const [],
|
||||
this.sharedUserIds = const [],
|
||||
});
|
||||
|
||||
List<AlbumUserAddDto> albumUsers;
|
||||
|
||||
/// This property was deprecated in v1.102.0
|
||||
List<String> sharedUserIds;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AddUsersDto &&
|
||||
_deepEquality.equals(other.albumUsers, albumUsers) &&
|
||||
_deepEquality.equals(other.sharedUserIds, sharedUserIds);
|
||||
_deepEquality.equals(other.albumUsers, albumUsers);
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(albumUsers.hashCode) +
|
||||
(sharedUserIds.hashCode);
|
||||
(albumUsers.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AddUsersDto[albumUsers=$albumUsers, sharedUserIds=$sharedUserIds]';
|
||||
String toString() => 'AddUsersDto[albumUsers=$albumUsers]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'albumUsers'] = this.albumUsers;
|
||||
json[r'sharedUserIds'] = this.sharedUserIds;
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -52,9 +45,6 @@ class AddUsersDto {
|
||||
|
||||
return AddUsersDto(
|
||||
albumUsers: AlbumUserAddDto.listFromJson(json[r'albumUsers']),
|
||||
sharedUserIds: json[r'sharedUserIds'] is Iterable
|
||||
? (json[r'sharedUserIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
11
mobile/openapi/lib/model/album_response_dto.dart
generated
11
mobile/openapi/lib/model/album_response_dto.dart
generated
@@ -29,7 +29,6 @@ class AlbumResponseDto {
|
||||
required this.owner,
|
||||
required this.ownerId,
|
||||
required this.shared,
|
||||
this.sharedUsers = const [],
|
||||
this.startDate,
|
||||
required this.updatedAt,
|
||||
});
|
||||
@@ -84,9 +83,6 @@ class AlbumResponseDto {
|
||||
|
||||
bool shared;
|
||||
|
||||
/// This property was deprecated in v1.102.0
|
||||
List<UserResponseDto> sharedUsers;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -115,7 +111,6 @@ class AlbumResponseDto {
|
||||
other.owner == owner &&
|
||||
other.ownerId == ownerId &&
|
||||
other.shared == shared &&
|
||||
_deepEquality.equals(other.sharedUsers, sharedUsers) &&
|
||||
other.startDate == startDate &&
|
||||
other.updatedAt == updatedAt;
|
||||
|
||||
@@ -138,12 +133,11 @@ class AlbumResponseDto {
|
||||
(owner.hashCode) +
|
||||
(ownerId.hashCode) +
|
||||
(shared.hashCode) +
|
||||
(sharedUsers.hashCode) +
|
||||
(startDate == null ? 0 : startDate!.hashCode) +
|
||||
(updatedAt.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, albumUsers=$albumUsers, assetCount=$assetCount, assets=$assets, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, isActivityEnabled=$isActivityEnabled, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, order=$order, owner=$owner, ownerId=$ownerId, shared=$shared, sharedUsers=$sharedUsers, startDate=$startDate, updatedAt=$updatedAt]';
|
||||
String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, albumUsers=$albumUsers, assetCount=$assetCount, assets=$assets, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, isActivityEnabled=$isActivityEnabled, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, order=$order, owner=$owner, ownerId=$ownerId, shared=$shared, startDate=$startDate, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -179,7 +173,6 @@ class AlbumResponseDto {
|
||||
json[r'owner'] = this.owner;
|
||||
json[r'ownerId'] = this.ownerId;
|
||||
json[r'shared'] = this.shared;
|
||||
json[r'sharedUsers'] = this.sharedUsers;
|
||||
if (this.startDate != null) {
|
||||
json[r'startDate'] = this.startDate!.toUtc().toIso8601String();
|
||||
} else {
|
||||
@@ -213,7 +206,6 @@ class AlbumResponseDto {
|
||||
owner: UserResponseDto.fromJson(json[r'owner'])!,
|
||||
ownerId: mapValueOfType<String>(json, r'ownerId')!,
|
||||
shared: mapValueOfType<bool>(json, r'shared')!,
|
||||
sharedUsers: UserResponseDto.listFromJson(json[r'sharedUsers']),
|
||||
startDate: mapDateTime(json, r'startDate', r''),
|
||||
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
|
||||
);
|
||||
@@ -276,7 +268,6 @@ class AlbumResponseDto {
|
||||
'owner',
|
||||
'ownerId',
|
||||
'shared',
|
||||
'sharedUsers',
|
||||
'updatedAt',
|
||||
};
|
||||
}
|
||||
|
||||
13
mobile/openapi/lib/model/asset_bulk_update_dto.dart
generated
13
mobile/openapi/lib/model/asset_bulk_update_dto.dart
generated
@@ -14,6 +14,7 @@ class AssetBulkUpdateDto {
|
||||
/// Returns a new [AssetBulkUpdateDto] instance.
|
||||
AssetBulkUpdateDto({
|
||||
this.dateTimeOriginal,
|
||||
this.duplicateId,
|
||||
this.ids = const [],
|
||||
this.isArchived,
|
||||
this.isFavorite,
|
||||
@@ -31,6 +32,8 @@ class AssetBulkUpdateDto {
|
||||
///
|
||||
String? dateTimeOriginal;
|
||||
|
||||
String? duplicateId;
|
||||
|
||||
List<String> ids;
|
||||
|
||||
///
|
||||
@@ -84,6 +87,7 @@ class AssetBulkUpdateDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AssetBulkUpdateDto &&
|
||||
other.dateTimeOriginal == dateTimeOriginal &&
|
||||
other.duplicateId == duplicateId &&
|
||||
_deepEquality.equals(other.ids, ids) &&
|
||||
other.isArchived == isArchived &&
|
||||
other.isFavorite == isFavorite &&
|
||||
@@ -96,6 +100,7 @@ class AssetBulkUpdateDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(dateTimeOriginal == null ? 0 : dateTimeOriginal!.hashCode) +
|
||||
(duplicateId == null ? 0 : duplicateId!.hashCode) +
|
||||
(ids.hashCode) +
|
||||
(isArchived == null ? 0 : isArchived!.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
@@ -105,7 +110,7 @@ class AssetBulkUpdateDto {
|
||||
(stackParentId == null ? 0 : stackParentId!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, removeParent=$removeParent, stackParentId=$stackParentId]';
|
||||
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, duplicateId=$duplicateId, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, removeParent=$removeParent, stackParentId=$stackParentId]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -113,6 +118,11 @@ class AssetBulkUpdateDto {
|
||||
json[r'dateTimeOriginal'] = this.dateTimeOriginal;
|
||||
} else {
|
||||
// json[r'dateTimeOriginal'] = null;
|
||||
}
|
||||
if (this.duplicateId != null) {
|
||||
json[r'duplicateId'] = this.duplicateId;
|
||||
} else {
|
||||
// json[r'duplicateId'] = null;
|
||||
}
|
||||
json[r'ids'] = this.ids;
|
||||
if (this.isArchived != null) {
|
||||
@@ -157,6 +167,7 @@ class AssetBulkUpdateDto {
|
||||
|
||||
return AssetBulkUpdateDto(
|
||||
dateTimeOriginal: mapValueOfType<String>(json, r'dateTimeOriginal'),
|
||||
duplicateId: mapValueOfType<String>(json, r'duplicateId'),
|
||||
ids: json[r'ids'] is Iterable
|
||||
? (json[r'ids'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
|
||||
106
mobile/openapi/lib/model/asset_media_response_dto.dart
generated
Normal file
106
mobile/openapi/lib/model/asset_media_response_dto.dart
generated
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class AssetMediaResponseDto {
|
||||
/// Returns a new [AssetMediaResponseDto] instance.
|
||||
AssetMediaResponseDto({
|
||||
required this.id,
|
||||
required this.status,
|
||||
});
|
||||
|
||||
String id;
|
||||
|
||||
AssetMediaStatus status;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AssetMediaResponseDto &&
|
||||
other.id == id &&
|
||||
other.status == status;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(id.hashCode) +
|
||||
(status.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetMediaResponseDto[id=$id, status=$status]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'id'] = this.id;
|
||||
json[r'status'] = this.status;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [AssetMediaResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static AssetMediaResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return AssetMediaResponseDto(
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
status: AssetMediaStatus.fromJson(json[r'status'])!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<AssetMediaResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <AssetMediaResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = AssetMediaResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, AssetMediaResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, AssetMediaResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = AssetMediaResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of AssetMediaResponseDto-objects as value to a dart map
|
||||
static Map<String, List<AssetMediaResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<AssetMediaResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = AssetMediaResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'id',
|
||||
'status',
|
||||
};
|
||||
}
|
||||
|
||||
85
mobile/openapi/lib/model/asset_media_status.dart
generated
Normal file
85
mobile/openapi/lib/model/asset_media_status.dart
generated
Normal file
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
|
||||
class AssetMediaStatus {
|
||||
/// Instantiate a new enum with the provided [value].
|
||||
const AssetMediaStatus._(this.value);
|
||||
|
||||
/// The underlying value of this enum member.
|
||||
final String value;
|
||||
|
||||
@override
|
||||
String toString() => value;
|
||||
|
||||
String toJson() => value;
|
||||
|
||||
static const replaced = AssetMediaStatus._(r'replaced');
|
||||
static const duplicate = AssetMediaStatus._(r'duplicate');
|
||||
|
||||
/// List of all possible values in this [enum][AssetMediaStatus].
|
||||
static const values = <AssetMediaStatus>[
|
||||
replaced,
|
||||
duplicate,
|
||||
];
|
||||
|
||||
static AssetMediaStatus? fromJson(dynamic value) => AssetMediaStatusTypeTransformer().decode(value);
|
||||
|
||||
static List<AssetMediaStatus> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <AssetMediaStatus>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = AssetMediaStatus.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
}
|
||||
|
||||
/// Transformation class that can [encode] an instance of [AssetMediaStatus] to String,
|
||||
/// and [decode] dynamic data back to [AssetMediaStatus].
|
||||
class AssetMediaStatusTypeTransformer {
|
||||
factory AssetMediaStatusTypeTransformer() => _instance ??= const AssetMediaStatusTypeTransformer._();
|
||||
|
||||
const AssetMediaStatusTypeTransformer._();
|
||||
|
||||
String encode(AssetMediaStatus data) => data.value;
|
||||
|
||||
/// Decodes a [dynamic value][data] to a AssetMediaStatus.
|
||||
///
|
||||
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||
///
|
||||
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||
/// and users are still using an old app with the old code.
|
||||
AssetMediaStatus? decode(dynamic data, {bool allowNull = true}) {
|
||||
if (data != null) {
|
||||
switch (data) {
|
||||
case r'replaced': return AssetMediaStatus.replaced;
|
||||
case r'duplicate': return AssetMediaStatus.duplicate;
|
||||
default:
|
||||
if (!allowNull) {
|
||||
throw ArgumentError('Unknown enum value to decode: $data');
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Singleton [AssetMediaStatusTypeTransformer] instance.
|
||||
static AssetMediaStatusTypeTransformer? _instance;
|
||||
}
|
||||
|
||||
58
mobile/openapi/lib/model/asset_response_dto.dart
generated
58
mobile/openapi/lib/model/asset_response_dto.dart
generated
@@ -24,10 +24,8 @@ class AssetResponseDto {
|
||||
required this.hasMetadata,
|
||||
required this.id,
|
||||
required this.isArchived,
|
||||
this.isExternal,
|
||||
required this.isFavorite,
|
||||
required this.isOffline,
|
||||
this.isReadOnly,
|
||||
required this.isTrashed,
|
||||
this.libraryId,
|
||||
this.livePhotoVideoId,
|
||||
@@ -36,7 +34,7 @@ class AssetResponseDto {
|
||||
required this.originalPath,
|
||||
this.owner,
|
||||
required this.ownerId,
|
||||
this.people = const [],
|
||||
this.people,
|
||||
required this.resized,
|
||||
this.smartInfo,
|
||||
this.stack = const [],
|
||||
@@ -77,28 +75,10 @@ class AssetResponseDto {
|
||||
|
||||
bool isArchived;
|
||||
|
||||
/// This property was deprecated in v1.104.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isExternal;
|
||||
|
||||
bool isFavorite;
|
||||
|
||||
bool isOffline;
|
||||
|
||||
/// This property was deprecated in v1.104.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isReadOnly;
|
||||
|
||||
bool isTrashed;
|
||||
|
||||
/// This property was deprecated in v1.106.0
|
||||
@@ -122,7 +102,13 @@ class AssetResponseDto {
|
||||
|
||||
String ownerId;
|
||||
|
||||
List<PersonWithFacesResponseDto> people;
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
PeopleWithFacesResponseDto? people;
|
||||
|
||||
bool resized;
|
||||
|
||||
@@ -161,10 +147,8 @@ class AssetResponseDto {
|
||||
other.hasMetadata == hasMetadata &&
|
||||
other.id == id &&
|
||||
other.isArchived == isArchived &&
|
||||
other.isExternal == isExternal &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isOffline == isOffline &&
|
||||
other.isReadOnly == isReadOnly &&
|
||||
other.isTrashed == isTrashed &&
|
||||
other.libraryId == libraryId &&
|
||||
other.livePhotoVideoId == livePhotoVideoId &&
|
||||
@@ -173,7 +157,7 @@ class AssetResponseDto {
|
||||
other.originalPath == originalPath &&
|
||||
other.owner == owner &&
|
||||
other.ownerId == ownerId &&
|
||||
_deepEquality.equals(other.people, people) &&
|
||||
other.people == people &&
|
||||
other.resized == resized &&
|
||||
other.smartInfo == smartInfo &&
|
||||
_deepEquality.equals(other.stack, stack) &&
|
||||
@@ -198,10 +182,8 @@ class AssetResponseDto {
|
||||
(hasMetadata.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isArchived.hashCode) +
|
||||
(isExternal == null ? 0 : isExternal!.hashCode) +
|
||||
(isFavorite.hashCode) +
|
||||
(isOffline.hashCode) +
|
||||
(isReadOnly == null ? 0 : isReadOnly!.hashCode) +
|
||||
(isTrashed.hashCode) +
|
||||
(libraryId == null ? 0 : libraryId!.hashCode) +
|
||||
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode) +
|
||||
@@ -210,7 +192,7 @@ class AssetResponseDto {
|
||||
(originalPath.hashCode) +
|
||||
(owner == null ? 0 : owner!.hashCode) +
|
||||
(ownerId.hashCode) +
|
||||
(people.hashCode) +
|
||||
(people == null ? 0 : people!.hashCode) +
|
||||
(resized.hashCode) +
|
||||
(smartInfo == null ? 0 : smartInfo!.hashCode) +
|
||||
(stack.hashCode) +
|
||||
@@ -222,7 +204,7 @@ class AssetResponseDto {
|
||||
(updatedAt.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isExternal=$isExternal, isFavorite=$isFavorite, isOffline=$isOffline, isReadOnly=$isReadOnly, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, smartInfo=$smartInfo, stack=$stack, stackCount=$stackCount, stackParentId=$stackParentId, tags=$tags, thumbhash=$thumbhash, type=$type, updatedAt=$updatedAt]';
|
||||
String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isFavorite=$isFavorite, isOffline=$isOffline, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, smartInfo=$smartInfo, stack=$stack, stackCount=$stackCount, stackParentId=$stackParentId, tags=$tags, thumbhash=$thumbhash, type=$type, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -245,18 +227,8 @@ class AssetResponseDto {
|
||||
json[r'hasMetadata'] = this.hasMetadata;
|
||||
json[r'id'] = this.id;
|
||||
json[r'isArchived'] = this.isArchived;
|
||||
if (this.isExternal != null) {
|
||||
json[r'isExternal'] = this.isExternal;
|
||||
} else {
|
||||
// json[r'isExternal'] = null;
|
||||
}
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
json[r'isOffline'] = this.isOffline;
|
||||
if (this.isReadOnly != null) {
|
||||
json[r'isReadOnly'] = this.isReadOnly;
|
||||
} else {
|
||||
// json[r'isReadOnly'] = null;
|
||||
}
|
||||
json[r'isTrashed'] = this.isTrashed;
|
||||
if (this.libraryId != null) {
|
||||
json[r'libraryId'] = this.libraryId;
|
||||
@@ -277,7 +249,11 @@ class AssetResponseDto {
|
||||
// json[r'owner'] = null;
|
||||
}
|
||||
json[r'ownerId'] = this.ownerId;
|
||||
if (this.people != null) {
|
||||
json[r'people'] = this.people;
|
||||
} else {
|
||||
// json[r'people'] = null;
|
||||
}
|
||||
json[r'resized'] = this.resized;
|
||||
if (this.smartInfo != null) {
|
||||
json[r'smartInfo'] = this.smartInfo;
|
||||
@@ -325,10 +301,8 @@ class AssetResponseDto {
|
||||
hasMetadata: mapValueOfType<bool>(json, r'hasMetadata')!,
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isArchived: mapValueOfType<bool>(json, r'isArchived')!,
|
||||
isExternal: mapValueOfType<bool>(json, r'isExternal'),
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite')!,
|
||||
isOffline: mapValueOfType<bool>(json, r'isOffline')!,
|
||||
isReadOnly: mapValueOfType<bool>(json, r'isReadOnly'),
|
||||
isTrashed: mapValueOfType<bool>(json, r'isTrashed')!,
|
||||
libraryId: mapValueOfType<String>(json, r'libraryId'),
|
||||
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
|
||||
@@ -337,7 +311,7 @@ class AssetResponseDto {
|
||||
originalPath: mapValueOfType<String>(json, r'originalPath')!,
|
||||
owner: UserResponseDto.fromJson(json[r'owner']),
|
||||
ownerId: mapValueOfType<String>(json, r'ownerId')!,
|
||||
people: PersonWithFacesResponseDto.listFromJson(json[r'people']),
|
||||
people: PeopleWithFacesResponseDto.fromJson(json[r'people']),
|
||||
resized: mapValueOfType<bool>(json, r'resized')!,
|
||||
smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']),
|
||||
stack: AssetResponseDto.listFromJson(json[r'stack']),
|
||||
|
||||
17
mobile/openapi/lib/model/create_album_dto.dart
generated
17
mobile/openapi/lib/model/create_album_dto.dart
generated
@@ -17,12 +17,10 @@ class CreateAlbumDto {
|
||||
this.albumUsers = const [],
|
||||
this.assetIds = const [],
|
||||
this.description,
|
||||
this.sharedWithUserIds = const [],
|
||||
});
|
||||
|
||||
String albumName;
|
||||
|
||||
/// This property was added in v1.104.0
|
||||
List<AlbumUserCreateDto> albumUsers;
|
||||
|
||||
List<String> assetIds;
|
||||
@@ -35,16 +33,12 @@ class CreateAlbumDto {
|
||||
///
|
||||
String? description;
|
||||
|
||||
/// This property was deprecated in v1.104.0
|
||||
List<String> sharedWithUserIds;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is CreateAlbumDto &&
|
||||
other.albumName == albumName &&
|
||||
_deepEquality.equals(other.albumUsers, albumUsers) &&
|
||||
_deepEquality.equals(other.assetIds, assetIds) &&
|
||||
other.description == description &&
|
||||
_deepEquality.equals(other.sharedWithUserIds, sharedWithUserIds);
|
||||
other.description == description;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
@@ -52,11 +46,10 @@ class CreateAlbumDto {
|
||||
(albumName.hashCode) +
|
||||
(albumUsers.hashCode) +
|
||||
(assetIds.hashCode) +
|
||||
(description == null ? 0 : description!.hashCode) +
|
||||
(sharedWithUserIds.hashCode);
|
||||
(description == null ? 0 : description!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'CreateAlbumDto[albumName=$albumName, albumUsers=$albumUsers, assetIds=$assetIds, description=$description, sharedWithUserIds=$sharedWithUserIds]';
|
||||
String toString() => 'CreateAlbumDto[albumName=$albumName, albumUsers=$albumUsers, assetIds=$assetIds, description=$description]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -68,7 +61,6 @@ class CreateAlbumDto {
|
||||
} else {
|
||||
// json[r'description'] = null;
|
||||
}
|
||||
json[r'sharedWithUserIds'] = this.sharedWithUserIds;
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -86,9 +78,6 @@ class CreateAlbumDto {
|
||||
? (json[r'assetIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
description: mapValueOfType<String>(json, r'description'),
|
||||
sharedWithUserIds: json[r'sharedWithUserIds'] is Iterable
|
||||
? (json[r'sharedWithUserIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -14,37 +14,30 @@ class MemoryLaneResponseDto {
|
||||
/// Returns a new [MemoryLaneResponseDto] instance.
|
||||
MemoryLaneResponseDto({
|
||||
this.assets = const [],
|
||||
required this.title,
|
||||
required this.yearsAgo,
|
||||
});
|
||||
|
||||
List<AssetResponseDto> assets;
|
||||
|
||||
/// This property was deprecated in v1.100.0
|
||||
String title;
|
||||
|
||||
int yearsAgo;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is MemoryLaneResponseDto &&
|
||||
_deepEquality.equals(other.assets, assets) &&
|
||||
other.title == title &&
|
||||
other.yearsAgo == yearsAgo;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(assets.hashCode) +
|
||||
(title.hashCode) +
|
||||
(yearsAgo.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'MemoryLaneResponseDto[assets=$assets, title=$title, yearsAgo=$yearsAgo]';
|
||||
String toString() => 'MemoryLaneResponseDto[assets=$assets, yearsAgo=$yearsAgo]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'assets'] = this.assets;
|
||||
json[r'title'] = this.title;
|
||||
json[r'yearsAgo'] = this.yearsAgo;
|
||||
return json;
|
||||
}
|
||||
@@ -58,7 +51,6 @@ class MemoryLaneResponseDto {
|
||||
|
||||
return MemoryLaneResponseDto(
|
||||
assets: AssetResponseDto.listFromJson(json[r'assets']),
|
||||
title: mapValueOfType<String>(json, r'title')!,
|
||||
yearsAgo: mapValueOfType<int>(json, r'yearsAgo')!,
|
||||
);
|
||||
}
|
||||
@@ -108,7 +100,6 @@ class MemoryLaneResponseDto {
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'assets',
|
||||
'title',
|
||||
'yearsAgo',
|
||||
};
|
||||
}
|
||||
|
||||
38
mobile/openapi/lib/model/metadata_search_dto.dart
generated
38
mobile/openapi/lib/model/metadata_search_dto.dart
generated
@@ -39,7 +39,6 @@ class MetadataSearchDto {
|
||||
this.page,
|
||||
this.personIds = const [],
|
||||
this.previewPath,
|
||||
this.resizePath,
|
||||
this.size,
|
||||
this.state,
|
||||
this.takenAfter,
|
||||
@@ -50,7 +49,6 @@ class MetadataSearchDto {
|
||||
this.type,
|
||||
this.updatedAfter,
|
||||
this.updatedBefore,
|
||||
this.webpPath,
|
||||
this.withArchived = false,
|
||||
this.withDeleted,
|
||||
this.withExif,
|
||||
@@ -261,15 +259,6 @@ class MetadataSearchDto {
|
||||
///
|
||||
String? previewPath;
|
||||
|
||||
/// This property was deprecated in v1.100.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? resizePath;
|
||||
|
||||
/// Minimum value: 1
|
||||
/// Maximum value: 1000
|
||||
///
|
||||
@@ -352,15 +341,6 @@ class MetadataSearchDto {
|
||||
///
|
||||
DateTime? updatedBefore;
|
||||
|
||||
/// This property was deprecated in v1.100.0
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? webpPath;
|
||||
|
||||
bool withArchived;
|
||||
|
||||
///
|
||||
@@ -423,7 +403,6 @@ class MetadataSearchDto {
|
||||
other.page == page &&
|
||||
_deepEquality.equals(other.personIds, personIds) &&
|
||||
other.previewPath == previewPath &&
|
||||
other.resizePath == resizePath &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
other.takenAfter == takenAfter &&
|
||||
@@ -434,7 +413,6 @@ class MetadataSearchDto {
|
||||
other.type == type &&
|
||||
other.updatedAfter == updatedAfter &&
|
||||
other.updatedBefore == updatedBefore &&
|
||||
other.webpPath == webpPath &&
|
||||
other.withArchived == withArchived &&
|
||||
other.withDeleted == withDeleted &&
|
||||
other.withExif == withExif &&
|
||||
@@ -470,7 +448,6 @@ class MetadataSearchDto {
|
||||
(page == null ? 0 : page!.hashCode) +
|
||||
(personIds.hashCode) +
|
||||
(previewPath == null ? 0 : previewPath!.hashCode) +
|
||||
(resizePath == null ? 0 : resizePath!.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
@@ -481,7 +458,6 @@ class MetadataSearchDto {
|
||||
(type == null ? 0 : type!.hashCode) +
|
||||
(updatedAfter == null ? 0 : updatedAfter!.hashCode) +
|
||||
(updatedBefore == null ? 0 : updatedBefore!.hashCode) +
|
||||
(webpPath == null ? 0 : webpPath!.hashCode) +
|
||||
(withArchived.hashCode) +
|
||||
(withDeleted == null ? 0 : withDeleted!.hashCode) +
|
||||
(withExif == null ? 0 : withExif!.hashCode) +
|
||||
@@ -489,7 +465,7 @@ class MetadataSearchDto {
|
||||
(withStacked == null ? 0 : withStacked!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, resizePath=$resizePath, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, webpPath=$webpPath, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isArchived=$isArchived, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -619,11 +595,6 @@ class MetadataSearchDto {
|
||||
} else {
|
||||
// json[r'previewPath'] = null;
|
||||
}
|
||||
if (this.resizePath != null) {
|
||||
json[r'resizePath'] = this.resizePath;
|
||||
} else {
|
||||
// json[r'resizePath'] = null;
|
||||
}
|
||||
if (this.size != null) {
|
||||
json[r'size'] = this.size;
|
||||
} else {
|
||||
@@ -673,11 +644,6 @@ class MetadataSearchDto {
|
||||
json[r'updatedBefore'] = this.updatedBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'updatedBefore'] = null;
|
||||
}
|
||||
if (this.webpPath != null) {
|
||||
json[r'webpPath'] = this.webpPath;
|
||||
} else {
|
||||
// json[r'webpPath'] = null;
|
||||
}
|
||||
json[r'withArchived'] = this.withArchived;
|
||||
if (this.withDeleted != null) {
|
||||
@@ -739,7 +705,6 @@ class MetadataSearchDto {
|
||||
? (json[r'personIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
previewPath: mapValueOfType<String>(json, r'previewPath'),
|
||||
resizePath: mapValueOfType<String>(json, r'resizePath'),
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
@@ -750,7 +715,6 @@ class MetadataSearchDto {
|
||||
type: AssetTypeEnum.fromJson(json[r'type']),
|
||||
updatedAfter: mapDateTime(json, r'updatedAfter', r''),
|
||||
updatedBefore: mapDateTime(json, r'updatedBefore', r''),
|
||||
webpPath: mapValueOfType<String>(json, r'webpPath'),
|
||||
withArchived: mapValueOfType<bool>(json, r'withArchived') ?? false,
|
||||
withDeleted: mapValueOfType<bool>(json, r'withDeleted'),
|
||||
withExif: mapValueOfType<bool>(json, r'withExif'),
|
||||
|
||||
119
mobile/openapi/lib/model/partner_response_dto.dart
generated
119
mobile/openapi/lib/model/partner_response_dto.dart
generated
@@ -14,30 +14,15 @@ class PartnerResponseDto {
|
||||
/// Returns a new [PartnerResponseDto] instance.
|
||||
PartnerResponseDto({
|
||||
required this.avatarColor,
|
||||
required this.createdAt,
|
||||
required this.deletedAt,
|
||||
required this.email,
|
||||
required this.id,
|
||||
this.inTimeline,
|
||||
required this.isAdmin,
|
||||
this.memoriesEnabled,
|
||||
required this.name,
|
||||
required this.oauthId,
|
||||
required this.profileImagePath,
|
||||
required this.quotaSizeInBytes,
|
||||
required this.quotaUsageInBytes,
|
||||
required this.shouldChangePassword,
|
||||
required this.status,
|
||||
required this.storageLabel,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
UserAvatarColor avatarColor;
|
||||
|
||||
DateTime createdAt;
|
||||
|
||||
DateTime? deletedAt;
|
||||
|
||||
String email;
|
||||
|
||||
String id;
|
||||
@@ -50,121 +35,44 @@ class PartnerResponseDto {
|
||||
///
|
||||
bool? inTimeline;
|
||||
|
||||
bool isAdmin;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? memoriesEnabled;
|
||||
|
||||
String name;
|
||||
|
||||
String oauthId;
|
||||
|
||||
String profileImagePath;
|
||||
|
||||
int? quotaSizeInBytes;
|
||||
|
||||
int? quotaUsageInBytes;
|
||||
|
||||
bool shouldChangePassword;
|
||||
|
||||
UserStatus status;
|
||||
|
||||
String? storageLabel;
|
||||
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PartnerResponseDto &&
|
||||
other.avatarColor == avatarColor &&
|
||||
other.createdAt == createdAt &&
|
||||
other.deletedAt == deletedAt &&
|
||||
other.email == email &&
|
||||
other.id == id &&
|
||||
other.inTimeline == inTimeline &&
|
||||
other.isAdmin == isAdmin &&
|
||||
other.memoriesEnabled == memoriesEnabled &&
|
||||
other.name == name &&
|
||||
other.oauthId == oauthId &&
|
||||
other.profileImagePath == profileImagePath &&
|
||||
other.quotaSizeInBytes == quotaSizeInBytes &&
|
||||
other.quotaUsageInBytes == quotaUsageInBytes &&
|
||||
other.shouldChangePassword == shouldChangePassword &&
|
||||
other.status == status &&
|
||||
other.storageLabel == storageLabel &&
|
||||
other.updatedAt == updatedAt;
|
||||
other.profileImagePath == profileImagePath;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(avatarColor.hashCode) +
|
||||
(createdAt.hashCode) +
|
||||
(deletedAt == null ? 0 : deletedAt!.hashCode) +
|
||||
(email.hashCode) +
|
||||
(id.hashCode) +
|
||||
(inTimeline == null ? 0 : inTimeline!.hashCode) +
|
||||
(isAdmin.hashCode) +
|
||||
(memoriesEnabled == null ? 0 : memoriesEnabled!.hashCode) +
|
||||
(name.hashCode) +
|
||||
(oauthId.hashCode) +
|
||||
(profileImagePath.hashCode) +
|
||||
(quotaSizeInBytes == null ? 0 : quotaSizeInBytes!.hashCode) +
|
||||
(quotaUsageInBytes == null ? 0 : quotaUsageInBytes!.hashCode) +
|
||||
(shouldChangePassword.hashCode) +
|
||||
(status.hashCode) +
|
||||
(storageLabel == null ? 0 : storageLabel!.hashCode) +
|
||||
(updatedAt.hashCode);
|
||||
(profileImagePath.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PartnerResponseDto[avatarColor=$avatarColor, createdAt=$createdAt, deletedAt=$deletedAt, email=$email, id=$id, inTimeline=$inTimeline, isAdmin=$isAdmin, memoriesEnabled=$memoriesEnabled, name=$name, oauthId=$oauthId, profileImagePath=$profileImagePath, quotaSizeInBytes=$quotaSizeInBytes, quotaUsageInBytes=$quotaUsageInBytes, shouldChangePassword=$shouldChangePassword, status=$status, storageLabel=$storageLabel, updatedAt=$updatedAt]';
|
||||
String toString() => 'PartnerResponseDto[avatarColor=$avatarColor, email=$email, id=$id, inTimeline=$inTimeline, name=$name, profileImagePath=$profileImagePath]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'avatarColor'] = this.avatarColor;
|
||||
json[r'createdAt'] = this.createdAt.toUtc().toIso8601String();
|
||||
if (this.deletedAt != null) {
|
||||
json[r'deletedAt'] = this.deletedAt!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'deletedAt'] = null;
|
||||
}
|
||||
json[r'email'] = this.email;
|
||||
json[r'id'] = this.id;
|
||||
if (this.inTimeline != null) {
|
||||
json[r'inTimeline'] = this.inTimeline;
|
||||
} else {
|
||||
// json[r'inTimeline'] = null;
|
||||
}
|
||||
json[r'isAdmin'] = this.isAdmin;
|
||||
if (this.memoriesEnabled != null) {
|
||||
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||
} else {
|
||||
// json[r'memoriesEnabled'] = null;
|
||||
}
|
||||
json[r'name'] = this.name;
|
||||
json[r'oauthId'] = this.oauthId;
|
||||
json[r'profileImagePath'] = this.profileImagePath;
|
||||
if (this.quotaSizeInBytes != null) {
|
||||
json[r'quotaSizeInBytes'] = this.quotaSizeInBytes;
|
||||
} else {
|
||||
// json[r'quotaSizeInBytes'] = null;
|
||||
}
|
||||
if (this.quotaUsageInBytes != null) {
|
||||
json[r'quotaUsageInBytes'] = this.quotaUsageInBytes;
|
||||
} else {
|
||||
// json[r'quotaUsageInBytes'] = null;
|
||||
}
|
||||
json[r'shouldChangePassword'] = this.shouldChangePassword;
|
||||
json[r'status'] = this.status;
|
||||
if (this.storageLabel != null) {
|
||||
json[r'storageLabel'] = this.storageLabel;
|
||||
} else {
|
||||
// json[r'storageLabel'] = null;
|
||||
}
|
||||
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -177,22 +85,11 @@ class PartnerResponseDto {
|
||||
|
||||
return PartnerResponseDto(
|
||||
avatarColor: UserAvatarColor.fromJson(json[r'avatarColor'])!,
|
||||
createdAt: mapDateTime(json, r'createdAt', r'')!,
|
||||
deletedAt: mapDateTime(json, r'deletedAt', r''),
|
||||
email: mapValueOfType<String>(json, r'email')!,
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
inTimeline: mapValueOfType<bool>(json, r'inTimeline'),
|
||||
isAdmin: mapValueOfType<bool>(json, r'isAdmin')!,
|
||||
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
oauthId: mapValueOfType<String>(json, r'oauthId')!,
|
||||
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
|
||||
quotaSizeInBytes: mapValueOfType<int>(json, r'quotaSizeInBytes'),
|
||||
quotaUsageInBytes: mapValueOfType<int>(json, r'quotaUsageInBytes'),
|
||||
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword')!,
|
||||
status: UserStatus.fromJson(json[r'status'])!,
|
||||
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
||||
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
@@ -241,20 +138,10 @@ class PartnerResponseDto {
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'avatarColor',
|
||||
'createdAt',
|
||||
'deletedAt',
|
||||
'email',
|
||||
'id',
|
||||
'isAdmin',
|
||||
'name',
|
||||
'oauthId',
|
||||
'profileImagePath',
|
||||
'quotaSizeInBytes',
|
||||
'quotaUsageInBytes',
|
||||
'shouldChangePassword',
|
||||
'status',
|
||||
'storageLabel',
|
||||
'updatedAt',
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
106
mobile/openapi/lib/model/people_with_faces_response_dto.dart
generated
Normal file
106
mobile/openapi/lib/model/people_with_faces_response_dto.dart
generated
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class PeopleWithFacesResponseDto {
|
||||
/// Returns a new [PeopleWithFacesResponseDto] instance.
|
||||
PeopleWithFacesResponseDto({
|
||||
required this.numberOfFaces,
|
||||
this.visiblePeople = const [],
|
||||
});
|
||||
|
||||
int numberOfFaces;
|
||||
|
||||
List<PersonWithFacesResponseDto> visiblePeople;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is PeopleWithFacesResponseDto &&
|
||||
other.numberOfFaces == numberOfFaces &&
|
||||
_deepEquality.equals(other.visiblePeople, visiblePeople);
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(numberOfFaces.hashCode) +
|
||||
(visiblePeople.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'PeopleWithFacesResponseDto[numberOfFaces=$numberOfFaces, visiblePeople=$visiblePeople]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'numberOfFaces'] = this.numberOfFaces;
|
||||
json[r'visiblePeople'] = this.visiblePeople;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [PeopleWithFacesResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static PeopleWithFacesResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return PeopleWithFacesResponseDto(
|
||||
numberOfFaces: mapValueOfType<int>(json, r'numberOfFaces')!,
|
||||
visiblePeople: PersonWithFacesResponseDto.listFromJson(json[r'visiblePeople']),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<PeopleWithFacesResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <PeopleWithFacesResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = PeopleWithFacesResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, PeopleWithFacesResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, PeopleWithFacesResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = PeopleWithFacesResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of PeopleWithFacesResponseDto-objects as value to a dart map
|
||||
static Map<String, List<PeopleWithFacesResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<PeopleWithFacesResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = PeopleWithFacesResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'numberOfFaces',
|
||||
'visiblePeople',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class ServerInfoResponseDto {
|
||||
/// Returns a new [ServerInfoResponseDto] instance.
|
||||
ServerInfoResponseDto({
|
||||
class ServerStorageResponseDto {
|
||||
/// Returns a new [ServerStorageResponseDto] instance.
|
||||
ServerStorageResponseDto({
|
||||
required this.diskAvailable,
|
||||
required this.diskAvailableRaw,
|
||||
required this.diskSize,
|
||||
@@ -37,7 +37,7 @@ class ServerInfoResponseDto {
|
||||
int diskUseRaw;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is ServerInfoResponseDto &&
|
||||
bool operator ==(Object other) => identical(this, other) || other is ServerStorageResponseDto &&
|
||||
other.diskAvailable == diskAvailable &&
|
||||
other.diskAvailableRaw == diskAvailableRaw &&
|
||||
other.diskSize == diskSize &&
|
||||
@@ -58,7 +58,7 @@ class ServerInfoResponseDto {
|
||||
(diskUseRaw.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'ServerInfoResponseDto[diskAvailable=$diskAvailable, diskAvailableRaw=$diskAvailableRaw, diskSize=$diskSize, diskSizeRaw=$diskSizeRaw, diskUsagePercentage=$diskUsagePercentage, diskUse=$diskUse, diskUseRaw=$diskUseRaw]';
|
||||
String toString() => 'ServerStorageResponseDto[diskAvailable=$diskAvailable, diskAvailableRaw=$diskAvailableRaw, diskSize=$diskSize, diskSizeRaw=$diskSizeRaw, diskUsagePercentage=$diskUsagePercentage, diskUse=$diskUse, diskUseRaw=$diskUseRaw]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -72,14 +72,14 @@ class ServerInfoResponseDto {
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [ServerInfoResponseDto] instance and imports its values from
|
||||
/// Returns a new [ServerStorageResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static ServerInfoResponseDto? fromJson(dynamic value) {
|
||||
static ServerStorageResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return ServerInfoResponseDto(
|
||||
return ServerStorageResponseDto(
|
||||
diskAvailable: mapValueOfType<String>(json, r'diskAvailable')!,
|
||||
diskAvailableRaw: mapValueOfType<int>(json, r'diskAvailableRaw')!,
|
||||
diskSize: mapValueOfType<String>(json, r'diskSize')!,
|
||||
@@ -92,11 +92,11 @@ class ServerInfoResponseDto {
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<ServerInfoResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <ServerInfoResponseDto>[];
|
||||
static List<ServerStorageResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <ServerStorageResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = ServerInfoResponseDto.fromJson(row);
|
||||
final value = ServerStorageResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
@@ -105,12 +105,12 @@ class ServerInfoResponseDto {
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, ServerInfoResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, ServerInfoResponseDto>{};
|
||||
static Map<String, ServerStorageResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, ServerStorageResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = ServerInfoResponseDto.fromJson(entry.value);
|
||||
final value = ServerStorageResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
@@ -119,14 +119,14 @@ class ServerInfoResponseDto {
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of ServerInfoResponseDto-objects as value to a dart map
|
||||
static Map<String, List<ServerInfoResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<ServerInfoResponseDto>>{};
|
||||
// maps a json object with a list of ServerStorageResponseDto-objects as value to a dart map
|
||||
static Map<String, List<ServerStorageResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<ServerStorageResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = ServerInfoResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
map[entry.key] = ServerStorageResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class CreateUserDto {
|
||||
/// Returns a new [CreateUserDto] instance.
|
||||
CreateUserDto({
|
||||
class UserAdminCreateDto {
|
||||
/// Returns a new [UserAdminCreateDto] instance.
|
||||
UserAdminCreateDto({
|
||||
required this.email,
|
||||
this.memoriesEnabled,
|
||||
required this.name,
|
||||
@@ -59,7 +59,7 @@ class CreateUserDto {
|
||||
String? storageLabel;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is CreateUserDto &&
|
||||
bool operator ==(Object other) => identical(this, other) || other is UserAdminCreateDto &&
|
||||
other.email == email &&
|
||||
other.memoriesEnabled == memoriesEnabled &&
|
||||
other.name == name &&
|
||||
@@ -82,7 +82,7 @@ class CreateUserDto {
|
||||
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'CreateUserDto[email=$email, memoriesEnabled=$memoriesEnabled, name=$name, notify=$notify, password=$password, quotaSizeInBytes=$quotaSizeInBytes, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
||||
String toString() => 'UserAdminCreateDto[email=$email, memoriesEnabled=$memoriesEnabled, name=$name, notify=$notify, password=$password, quotaSizeInBytes=$quotaSizeInBytes, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -117,14 +117,14 @@ class CreateUserDto {
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [CreateUserDto] instance and imports its values from
|
||||
/// Returns a new [UserAdminCreateDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static CreateUserDto? fromJson(dynamic value) {
|
||||
static UserAdminCreateDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return CreateUserDto(
|
||||
return UserAdminCreateDto(
|
||||
email: mapValueOfType<String>(json, r'email')!,
|
||||
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
@@ -138,11 +138,11 @@ class CreateUserDto {
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<CreateUserDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <CreateUserDto>[];
|
||||
static List<UserAdminCreateDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UserAdminCreateDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = CreateUserDto.fromJson(row);
|
||||
final value = UserAdminCreateDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
@@ -151,12 +151,12 @@ class CreateUserDto {
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, CreateUserDto> mapFromJson(dynamic json) {
|
||||
final map = <String, CreateUserDto>{};
|
||||
static Map<String, UserAdminCreateDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UserAdminCreateDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = CreateUserDto.fromJson(entry.value);
|
||||
final value = UserAdminCreateDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
@@ -165,14 +165,14 @@ class CreateUserDto {
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of CreateUserDto-objects as value to a dart map
|
||||
static Map<String, List<CreateUserDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<CreateUserDto>>{};
|
||||
// maps a json object with a list of UserAdminCreateDto-objects as value to a dart map
|
||||
static Map<String, List<UserAdminCreateDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UserAdminCreateDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = CreateUserDto.listFromJson(entry.value, growable: growable,);
|
||||
map[entry.key] = UserAdminCreateDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class DeleteUserDto {
|
||||
/// Returns a new [DeleteUserDto] instance.
|
||||
DeleteUserDto({
|
||||
class UserAdminDeleteDto {
|
||||
/// Returns a new [UserAdminDeleteDto] instance.
|
||||
UserAdminDeleteDto({
|
||||
this.force,
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ class DeleteUserDto {
|
||||
bool? force;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is DeleteUserDto &&
|
||||
bool operator ==(Object other) => identical(this, other) || other is UserAdminDeleteDto &&
|
||||
other.force == force;
|
||||
|
||||
@override
|
||||
@@ -34,7 +34,7 @@ class DeleteUserDto {
|
||||
(force == null ? 0 : force!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'DeleteUserDto[force=$force]';
|
||||
String toString() => 'UserAdminDeleteDto[force=$force]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -46,25 +46,25 @@ class DeleteUserDto {
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [DeleteUserDto] instance and imports its values from
|
||||
/// Returns a new [UserAdminDeleteDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static DeleteUserDto? fromJson(dynamic value) {
|
||||
static UserAdminDeleteDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return DeleteUserDto(
|
||||
return UserAdminDeleteDto(
|
||||
force: mapValueOfType<bool>(json, r'force'),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<DeleteUserDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <DeleteUserDto>[];
|
||||
static List<UserAdminDeleteDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UserAdminDeleteDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = DeleteUserDto.fromJson(row);
|
||||
final value = UserAdminDeleteDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
@@ -73,12 +73,12 @@ class DeleteUserDto {
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, DeleteUserDto> mapFromJson(dynamic json) {
|
||||
final map = <String, DeleteUserDto>{};
|
||||
static Map<String, UserAdminDeleteDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UserAdminDeleteDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = DeleteUserDto.fromJson(entry.value);
|
||||
final value = UserAdminDeleteDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
@@ -87,14 +87,14 @@ class DeleteUserDto {
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of DeleteUserDto-objects as value to a dart map
|
||||
static Map<String, List<DeleteUserDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<DeleteUserDto>>{};
|
||||
// maps a json object with a list of UserAdminDeleteDto-objects as value to a dart map
|
||||
static Map<String, List<UserAdminDeleteDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UserAdminDeleteDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = DeleteUserDto.listFromJson(entry.value, growable: growable,);
|
||||
map[entry.key] = UserAdminDeleteDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
243
mobile/openapi/lib/model/user_admin_response_dto.dart
generated
Normal file
243
mobile/openapi/lib/model/user_admin_response_dto.dart
generated
Normal file
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class UserAdminResponseDto {
|
||||
/// Returns a new [UserAdminResponseDto] instance.
|
||||
UserAdminResponseDto({
|
||||
required this.avatarColor,
|
||||
required this.createdAt,
|
||||
required this.deletedAt,
|
||||
required this.email,
|
||||
required this.id,
|
||||
required this.isAdmin,
|
||||
this.memoriesEnabled,
|
||||
required this.name,
|
||||
required this.oauthId,
|
||||
required this.profileImagePath,
|
||||
required this.quotaSizeInBytes,
|
||||
required this.quotaUsageInBytes,
|
||||
required this.shouldChangePassword,
|
||||
required this.status,
|
||||
required this.storageLabel,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
UserAvatarColor avatarColor;
|
||||
|
||||
DateTime createdAt;
|
||||
|
||||
DateTime? deletedAt;
|
||||
|
||||
String email;
|
||||
|
||||
String id;
|
||||
|
||||
bool isAdmin;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? memoriesEnabled;
|
||||
|
||||
String name;
|
||||
|
||||
String oauthId;
|
||||
|
||||
String profileImagePath;
|
||||
|
||||
int? quotaSizeInBytes;
|
||||
|
||||
int? quotaUsageInBytes;
|
||||
|
||||
bool shouldChangePassword;
|
||||
|
||||
UserStatus status;
|
||||
|
||||
String? storageLabel;
|
||||
|
||||
DateTime updatedAt;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is UserAdminResponseDto &&
|
||||
other.avatarColor == avatarColor &&
|
||||
other.createdAt == createdAt &&
|
||||
other.deletedAt == deletedAt &&
|
||||
other.email == email &&
|
||||
other.id == id &&
|
||||
other.isAdmin == isAdmin &&
|
||||
other.memoriesEnabled == memoriesEnabled &&
|
||||
other.name == name &&
|
||||
other.oauthId == oauthId &&
|
||||
other.profileImagePath == profileImagePath &&
|
||||
other.quotaSizeInBytes == quotaSizeInBytes &&
|
||||
other.quotaUsageInBytes == quotaUsageInBytes &&
|
||||
other.shouldChangePassword == shouldChangePassword &&
|
||||
other.status == status &&
|
||||
other.storageLabel == storageLabel &&
|
||||
other.updatedAt == updatedAt;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(avatarColor.hashCode) +
|
||||
(createdAt.hashCode) +
|
||||
(deletedAt == null ? 0 : deletedAt!.hashCode) +
|
||||
(email.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isAdmin.hashCode) +
|
||||
(memoriesEnabled == null ? 0 : memoriesEnabled!.hashCode) +
|
||||
(name.hashCode) +
|
||||
(oauthId.hashCode) +
|
||||
(profileImagePath.hashCode) +
|
||||
(quotaSizeInBytes == null ? 0 : quotaSizeInBytes!.hashCode) +
|
||||
(quotaUsageInBytes == null ? 0 : quotaUsageInBytes!.hashCode) +
|
||||
(shouldChangePassword.hashCode) +
|
||||
(status.hashCode) +
|
||||
(storageLabel == null ? 0 : storageLabel!.hashCode) +
|
||||
(updatedAt.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'UserAdminResponseDto[avatarColor=$avatarColor, createdAt=$createdAt, deletedAt=$deletedAt, email=$email, id=$id, isAdmin=$isAdmin, memoriesEnabled=$memoriesEnabled, name=$name, oauthId=$oauthId, profileImagePath=$profileImagePath, quotaSizeInBytes=$quotaSizeInBytes, quotaUsageInBytes=$quotaUsageInBytes, shouldChangePassword=$shouldChangePassword, status=$status, storageLabel=$storageLabel, updatedAt=$updatedAt]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'avatarColor'] = this.avatarColor;
|
||||
json[r'createdAt'] = this.createdAt.toUtc().toIso8601String();
|
||||
if (this.deletedAt != null) {
|
||||
json[r'deletedAt'] = this.deletedAt!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'deletedAt'] = null;
|
||||
}
|
||||
json[r'email'] = this.email;
|
||||
json[r'id'] = this.id;
|
||||
json[r'isAdmin'] = this.isAdmin;
|
||||
if (this.memoriesEnabled != null) {
|
||||
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||
} else {
|
||||
// json[r'memoriesEnabled'] = null;
|
||||
}
|
||||
json[r'name'] = this.name;
|
||||
json[r'oauthId'] = this.oauthId;
|
||||
json[r'profileImagePath'] = this.profileImagePath;
|
||||
if (this.quotaSizeInBytes != null) {
|
||||
json[r'quotaSizeInBytes'] = this.quotaSizeInBytes;
|
||||
} else {
|
||||
// json[r'quotaSizeInBytes'] = null;
|
||||
}
|
||||
if (this.quotaUsageInBytes != null) {
|
||||
json[r'quotaUsageInBytes'] = this.quotaUsageInBytes;
|
||||
} else {
|
||||
// json[r'quotaUsageInBytes'] = null;
|
||||
}
|
||||
json[r'shouldChangePassword'] = this.shouldChangePassword;
|
||||
json[r'status'] = this.status;
|
||||
if (this.storageLabel != null) {
|
||||
json[r'storageLabel'] = this.storageLabel;
|
||||
} else {
|
||||
// json[r'storageLabel'] = null;
|
||||
}
|
||||
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [UserAdminResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static UserAdminResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return UserAdminResponseDto(
|
||||
avatarColor: UserAvatarColor.fromJson(json[r'avatarColor'])!,
|
||||
createdAt: mapDateTime(json, r'createdAt', r'')!,
|
||||
deletedAt: mapDateTime(json, r'deletedAt', r''),
|
||||
email: mapValueOfType<String>(json, r'email')!,
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isAdmin: mapValueOfType<bool>(json, r'isAdmin')!,
|
||||
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
oauthId: mapValueOfType<String>(json, r'oauthId')!,
|
||||
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
|
||||
quotaSizeInBytes: mapValueOfType<int>(json, r'quotaSizeInBytes'),
|
||||
quotaUsageInBytes: mapValueOfType<int>(json, r'quotaUsageInBytes'),
|
||||
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword')!,
|
||||
status: UserStatus.fromJson(json[r'status'])!,
|
||||
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
||||
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<UserAdminResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UserAdminResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = UserAdminResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, UserAdminResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UserAdminResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = UserAdminResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of UserAdminResponseDto-objects as value to a dart map
|
||||
static Map<String, List<UserAdminResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UserAdminResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = UserAdminResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'avatarColor',
|
||||
'createdAt',
|
||||
'deletedAt',
|
||||
'email',
|
||||
'id',
|
||||
'isAdmin',
|
||||
'name',
|
||||
'oauthId',
|
||||
'profileImagePath',
|
||||
'quotaSizeInBytes',
|
||||
'quotaUsageInBytes',
|
||||
'shouldChangePassword',
|
||||
'status',
|
||||
'storageLabel',
|
||||
'updatedAt',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class UpdateUserDto {
|
||||
/// Returns a new [UpdateUserDto] instance.
|
||||
UpdateUserDto({
|
||||
class UserAdminUpdateDto {
|
||||
/// Returns a new [UserAdminUpdateDto] instance.
|
||||
UserAdminUpdateDto({
|
||||
this.avatarColor,
|
||||
this.email,
|
||||
required this.id,
|
||||
this.isAdmin,
|
||||
this.memoriesEnabled,
|
||||
this.name,
|
||||
this.password,
|
||||
@@ -41,16 +39,6 @@ class UpdateUserDto {
|
||||
///
|
||||
String? email;
|
||||
|
||||
String id;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isAdmin;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
@@ -86,20 +74,12 @@ class UpdateUserDto {
|
||||
///
|
||||
bool? shouldChangePassword;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? storageLabel;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is UpdateUserDto &&
|
||||
bool operator ==(Object other) => identical(this, other) || other is UserAdminUpdateDto &&
|
||||
other.avatarColor == avatarColor &&
|
||||
other.email == email &&
|
||||
other.id == id &&
|
||||
other.isAdmin == isAdmin &&
|
||||
other.memoriesEnabled == memoriesEnabled &&
|
||||
other.name == name &&
|
||||
other.password == password &&
|
||||
@@ -112,8 +92,6 @@ class UpdateUserDto {
|
||||
// ignore: unnecessary_parenthesis
|
||||
(avatarColor == null ? 0 : avatarColor!.hashCode) +
|
||||
(email == null ? 0 : email!.hashCode) +
|
||||
(id.hashCode) +
|
||||
(isAdmin == null ? 0 : isAdmin!.hashCode) +
|
||||
(memoriesEnabled == null ? 0 : memoriesEnabled!.hashCode) +
|
||||
(name == null ? 0 : name!.hashCode) +
|
||||
(password == null ? 0 : password!.hashCode) +
|
||||
@@ -122,7 +100,7 @@ class UpdateUserDto {
|
||||
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'UpdateUserDto[avatarColor=$avatarColor, email=$email, id=$id, isAdmin=$isAdmin, memoriesEnabled=$memoriesEnabled, name=$name, password=$password, quotaSizeInBytes=$quotaSizeInBytes, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
||||
String toString() => 'UserAdminUpdateDto[avatarColor=$avatarColor, email=$email, memoriesEnabled=$memoriesEnabled, name=$name, password=$password, quotaSizeInBytes=$quotaSizeInBytes, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@@ -135,12 +113,6 @@ class UpdateUserDto {
|
||||
json[r'email'] = this.email;
|
||||
} else {
|
||||
// json[r'email'] = null;
|
||||
}
|
||||
json[r'id'] = this.id;
|
||||
if (this.isAdmin != null) {
|
||||
json[r'isAdmin'] = this.isAdmin;
|
||||
} else {
|
||||
// json[r'isAdmin'] = null;
|
||||
}
|
||||
if (this.memoriesEnabled != null) {
|
||||
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||
@@ -175,18 +147,16 @@ class UpdateUserDto {
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [UpdateUserDto] instance and imports its values from
|
||||
/// Returns a new [UserAdminUpdateDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static UpdateUserDto? fromJson(dynamic value) {
|
||||
static UserAdminUpdateDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return UpdateUserDto(
|
||||
return UserAdminUpdateDto(
|
||||
avatarColor: UserAvatarColor.fromJson(json[r'avatarColor']),
|
||||
email: mapValueOfType<String>(json, r'email'),
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
isAdmin: mapValueOfType<bool>(json, r'isAdmin'),
|
||||
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||
name: mapValueOfType<String>(json, r'name'),
|
||||
password: mapValueOfType<String>(json, r'password'),
|
||||
@@ -198,11 +168,11 @@ class UpdateUserDto {
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<UpdateUserDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UpdateUserDto>[];
|
||||
static List<UserAdminUpdateDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UserAdminUpdateDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = UpdateUserDto.fromJson(row);
|
||||
final value = UserAdminUpdateDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
@@ -211,12 +181,12 @@ class UpdateUserDto {
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, UpdateUserDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UpdateUserDto>{};
|
||||
static Map<String, UserAdminUpdateDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UserAdminUpdateDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = UpdateUserDto.fromJson(entry.value);
|
||||
final value = UserAdminUpdateDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
@@ -225,14 +195,14 @@ class UpdateUserDto {
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of UpdateUserDto-objects as value to a dart map
|
||||
static Map<String, List<UpdateUserDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UpdateUserDto>>{};
|
||||
// maps a json object with a list of UserAdminUpdateDto-objects as value to a dart map
|
||||
static Map<String, List<UserAdminUpdateDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UserAdminUpdateDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = UpdateUserDto.listFromJson(entry.value, growable: growable,);
|
||||
map[entry.key] = UserAdminUpdateDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
@@ -240,7 +210,6 @@ class UpdateUserDto {
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'id',
|
||||
};
|
||||
}
|
||||
|
||||
130
mobile/openapi/lib/model/user_dto.dart
generated
130
mobile/openapi/lib/model/user_dto.dart
generated
@@ -1,130 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.18
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class UserDto {
|
||||
/// Returns a new [UserDto] instance.
|
||||
UserDto({
|
||||
required this.avatarColor,
|
||||
required this.email,
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.profileImagePath,
|
||||
});
|
||||
|
||||
UserAvatarColor avatarColor;
|
||||
|
||||
String email;
|
||||
|
||||
String id;
|
||||
|
||||
String name;
|
||||
|
||||
String profileImagePath;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is UserDto &&
|
||||
other.avatarColor == avatarColor &&
|
||||
other.email == email &&
|
||||
other.id == id &&
|
||||
other.name == name &&
|
||||
other.profileImagePath == profileImagePath;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(avatarColor.hashCode) +
|
||||
(email.hashCode) +
|
||||
(id.hashCode) +
|
||||
(name.hashCode) +
|
||||
(profileImagePath.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'UserDto[avatarColor=$avatarColor, email=$email, id=$id, name=$name, profileImagePath=$profileImagePath]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'avatarColor'] = this.avatarColor;
|
||||
json[r'email'] = this.email;
|
||||
json[r'id'] = this.id;
|
||||
json[r'name'] = this.name;
|
||||
json[r'profileImagePath'] = this.profileImagePath;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [UserDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static UserDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return UserDto(
|
||||
avatarColor: UserAvatarColor.fromJson(json[r'avatarColor'])!,
|
||||
email: mapValueOfType<String>(json, r'email')!,
|
||||
id: mapValueOfType<String>(json, r'id')!,
|
||||
name: mapValueOfType<String>(json, r'name')!,
|
||||
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<UserDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <UserDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = UserDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, UserDto> mapFromJson(dynamic json) {
|
||||
final map = <String, UserDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = UserDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of UserDto-objects as value to a dart map
|
||||
static Map<String, List<UserDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<UserDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = UserDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'avatarColor',
|
||||
'email',
|
||||
'id',
|
||||
'name',
|
||||
'profileImagePath',
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user