1
0
mirror of https://github.com/immich-app/immich.git synced 2025-06-16 03:40:33 +02:00

feat(server,web) Semantic import path validation (#7076)

* add library validation api

* chore: open api

* show warning i UI

* add flex row

* fix e2e

* tests

* fix tests

* enforce path validation

* enforce validation on refresh

* return 400 on bad import path

* add limits to import paths

* set response code to 200

* fix e2e

* fix lint

* fix test

* restore e2e folder

* fix import

* use startsWith

* icon color

* notify user of failed validation

* add parent div to validation

* add docs to the import validation

* improve library troubleshooting docs

* fix button alignment

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Jonathan Jogenfors
2024-02-20 16:53:12 +01:00
committed by GitHub
parent e7a875eadd
commit b3c7bebbd4
32 changed files with 1472 additions and 75 deletions

View File

@ -5316,6 +5316,63 @@ export interface ValidateAccessTokenResponseDto {
*/
'authStatus': boolean;
}
/**
*
* @export
* @interface ValidateLibraryDto
*/
export interface ValidateLibraryDto {
/**
*
* @type {Array<string>}
* @memberof ValidateLibraryDto
*/
'exclusionPatterns'?: Array<string>;
/**
*
* @type {Array<string>}
* @memberof ValidateLibraryDto
*/
'importPaths'?: Array<string>;
}
/**
*
* @export
* @interface ValidateLibraryImportPathResponseDto
*/
export interface ValidateLibraryImportPathResponseDto {
/**
*
* @type {string}
* @memberof ValidateLibraryImportPathResponseDto
*/
'importPath': string;
/**
*
* @type {boolean}
* @memberof ValidateLibraryImportPathResponseDto
*/
'isValid'?: boolean;
/**
*
* @type {string}
* @memberof ValidateLibraryImportPathResponseDto
*/
'message'?: string;
}
/**
*
* @export
* @interface ValidateLibraryResponseDto
*/
export interface ValidateLibraryResponseDto {
/**
*
* @type {Array<ValidateLibraryImportPathResponseDto>}
* @memberof ValidateLibraryResponseDto
*/
'importPaths'?: Array<ValidateLibraryImportPathResponseDto>;
}
/**
*
* @export
@ -12813,6 +12870,54 @@ export const LibraryApiAxiosParamCreator = function (configuration?: Configurati
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(updateLibraryDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id
* @param {ValidateLibraryDto} validateLibraryDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
validate: async (id: string, validateLibraryDto: ValidateLibraryDto, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('validate', 'id', id)
// verify required parameter 'validateLibraryDto' is not null or undefined
assertParamExists('validate', 'validateLibraryDto', validateLibraryDto)
const localVarPath = `/library/{id}/validate`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication cookie required
// authentication api_key required
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(validateLibraryDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
@ -12925,6 +13030,19 @@ export const LibraryApiFp = function(configuration?: Configuration) {
const operationBasePath = operationServerMap['LibraryApi.updateLibrary']?.[index]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
},
/**
*
* @param {string} id
* @param {ValidateLibraryDto} validateLibraryDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async validate(id: string, validateLibraryDto: ValidateLibraryDto, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ValidateLibraryResponseDto>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.validate(id, validateLibraryDto, options);
const index = configuration?.serverIndex ?? 0;
const operationBasePath = operationServerMap['LibraryApi.validate']?.[index]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
},
}
};
@ -13006,6 +13124,15 @@ export const LibraryApiFactory = function (configuration?: Configuration, basePa
updateLibrary(requestParameters: LibraryApiUpdateLibraryRequest, options?: RawAxiosRequestConfig): AxiosPromise<LibraryResponseDto> {
return localVarFp.updateLibrary(requestParameters.id, requestParameters.updateLibraryDto, options).then((request) => request(axios, basePath));
},
/**
*
* @param {LibraryApiValidateRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
validate(requestParameters: LibraryApiValidateRequest, options?: RawAxiosRequestConfig): AxiosPromise<ValidateLibraryResponseDto> {
return localVarFp.validate(requestParameters.id, requestParameters.validateLibraryDto, options).then((request) => request(axios, basePath));
},
};
};
@ -13121,6 +13248,27 @@ export interface LibraryApiUpdateLibraryRequest {
readonly updateLibraryDto: UpdateLibraryDto
}
/**
* Request parameters for validate operation in LibraryApi.
* @export
* @interface LibraryApiValidateRequest
*/
export interface LibraryApiValidateRequest {
/**
*
* @type {string}
* @memberof LibraryApiValidate
*/
readonly id: string
/**
*
* @type {ValidateLibraryDto}
* @memberof LibraryApiValidate
*/
readonly validateLibraryDto: ValidateLibraryDto
}
/**
* LibraryApi - object-oriented interface
* @export
@ -13214,6 +13362,17 @@ export class LibraryApi extends BaseAPI {
public updateLibrary(requestParameters: LibraryApiUpdateLibraryRequest, options?: RawAxiosRequestConfig) {
return LibraryApiFp(this.configuration).updateLibrary(requestParameters.id, requestParameters.updateLibraryDto, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {LibraryApiValidateRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof LibraryApi
*/
public validate(requestParameters: LibraryApiValidateRequest, options?: RawAxiosRequestConfig) {
return LibraryApiFp(this.configuration).validate(requestParameters.id, requestParameters.validateLibraryDto, options).then((request) => request(this.axios, this.basePath));
}
}

View File

@ -480,6 +480,18 @@ export type LibraryStatsResponseDto = {
usage: number;
videos: number;
};
export type ValidateLibraryDto = {
exclusionPatterns?: string[];
importPaths?: string[];
};
export type ValidateLibraryImportPathResponseDto = {
importPath: string;
isValid?: boolean;
message?: string;
};
export type ValidateLibraryResponseDto = {
importPaths?: ValidateLibraryImportPathResponseDto[];
};
export type OAuthConfigDto = {
redirectUri: string;
};
@ -1901,6 +1913,19 @@ export function getLibraryStatistics({ id }: {
...opts
}));
}
export function validate({ id, validateLibraryDto }: {
id: string;
validateLibraryDto: ValidateLibraryDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: ValidateLibraryResponseDto;
}>(`/library/${encodeURIComponent(id)}/validate`, oazapfts.json({
...opts,
method: "POST",
body: validateLibraryDto
})));
}
export function startOAuth({ oAuthConfigDto }: {
oAuthConfigDto: OAuthConfigDto;
}, opts?: Oazapfts.RequestOpts) {