add userprefrerencedb
This commit is contained in:
parent
9469090614
commit
2bbe798097
|
@ -0,0 +1,111 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import {
|
||||
DecodedPref, PrefValueType,
|
||||
PrefValueTypeStrings
|
||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||
import {
|
||||
AsyncFailable,
|
||||
Fail,
|
||||
Failable,
|
||||
HasFailed
|
||||
} from 'picsur-shared/dist/types';
|
||||
|
||||
type Enum = Record<string, string>;
|
||||
type EnumValue<E> = E[keyof E];
|
||||
type PrefValueTypeType<E extends Enum> = {
|
||||
[key in EnumValue<E>]: PrefValueTypeStrings;
|
||||
};
|
||||
type KeyValuePref = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class PreferenceCommonService {
|
||||
private readonly logger = new Logger('PreferenceCommonService');
|
||||
|
||||
public validateAndUnpackPref<E extends Enum>(
|
||||
preference: KeyValuePref,
|
||||
prefType: E,
|
||||
prefValueTypes: PrefValueTypeType<E>,
|
||||
): Failable<DecodedPref> {
|
||||
const key = this.validatePrefKey(preference.key, prefType);
|
||||
if (HasFailed(key)) return key;
|
||||
|
||||
const type = prefValueTypes[key];
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value,
|
||||
type: 'string',
|
||||
};
|
||||
case 'number':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: parseInt(preference.value, 10),
|
||||
type: 'number',
|
||||
};
|
||||
case 'boolean':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value == 'true',
|
||||
type: 'boolean',
|
||||
};
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
|
||||
public async validatePref<E extends Enum>(
|
||||
key: string,
|
||||
value: PrefValueType,
|
||||
prefType: E,
|
||||
prefValueTypes: PrefValueTypeType<E>,
|
||||
): AsyncFailable<KeyValuePref> {
|
||||
const validatedKey = this.validatePrefKey(key, prefType);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
const valueType = prefValueTypes[validatedKey];
|
||||
const validatedValue = this.validateAndPackPrefValue(value, valueType);
|
||||
if (HasFailed(validatedValue)) return validatedValue;
|
||||
|
||||
return {
|
||||
key: validatedKey,
|
||||
value: validatedValue,
|
||||
};
|
||||
}
|
||||
|
||||
public validatePrefKey<E extends Enum, V extends EnumValue<E>>(
|
||||
key: string,
|
||||
prefType: E,
|
||||
): Failable<V> {
|
||||
const keysList = Object.values(prefType);
|
||||
if (!keysList.includes(key)) {
|
||||
return Fail('Invalid preference key');
|
||||
}
|
||||
|
||||
return key as V;
|
||||
}
|
||||
|
||||
public validateAndPackPrefValue(
|
||||
value: PrefValueType,
|
||||
expectedType: PrefValueTypeStrings,
|
||||
): Failable<string> {
|
||||
const type = typeof value;
|
||||
if (type != expectedType) {
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return value as string;
|
||||
case 'number':
|
||||
return value.toString();
|
||||
case 'boolean':
|
||||
return value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
|
|||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { EarlyConfigModule } from '../../config/early/earlyconfig.module';
|
||||
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
|
||||
import { PreferenceCommonService } from './preferencecommon.service';
|
||||
import { PreferenceDefaultsService } from './preferencedefaults.service';
|
||||
import { SysPreferenceService } from './syspreferencedb.service';
|
||||
|
||||
|
@ -10,7 +11,11 @@ import { SysPreferenceService } from './syspreferencedb.service';
|
|||
TypeOrmModule.forFeature([ESysPreferenceBackend]),
|
||||
EarlyConfigModule,
|
||||
],
|
||||
providers: [SysPreferenceService, PreferenceDefaultsService],
|
||||
providers: [
|
||||
SysPreferenceService,
|
||||
PreferenceDefaultsService,
|
||||
PreferenceCommonService,
|
||||
],
|
||||
exports: [SysPreferenceService],
|
||||
})
|
||||
export class SysPreferenceModule {}
|
||||
|
|
|
@ -6,19 +6,14 @@ import {
|
|||
PrefValueTypeStrings
|
||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||
import { SysPreference } from 'picsur-shared/dist/dto/syspreferences.dto';
|
||||
import { ESysPreferenceSchema } from 'picsur-shared/dist/entities/syspreference.entity';
|
||||
import {
|
||||
AsyncFailable,
|
||||
Fail,
|
||||
Failable,
|
||||
HasFailed
|
||||
} from 'picsur-shared/dist/types';
|
||||
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { Repository } from 'typeorm';
|
||||
import {
|
||||
SysPreferenceList,
|
||||
SysPreferenceValueTypes
|
||||
} from '../../models/dto/syspreferences.dto';
|
||||
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
|
||||
import { ESysPreferenceBackend, ESysPreferenceSchema } from '../../models/entities/syspreference.entity';
|
||||
import { PreferenceCommonService } from './preferencecommon.service';
|
||||
import { PreferenceDefaultsService } from './preferencedefaults.service';
|
||||
|
||||
@Injectable()
|
||||
|
@ -29,6 +24,7 @@ export class SysPreferenceService {
|
|||
@InjectRepository(ESysPreferenceBackend)
|
||||
private sysPreferenceRepository: Repository<ESysPreferenceBackend>,
|
||||
private defaultsService: PreferenceDefaultsService,
|
||||
private prefCommon: PreferenceCommonService,
|
||||
) {}
|
||||
|
||||
public async setPreference(
|
||||
|
@ -36,7 +32,7 @@ export class SysPreferenceService {
|
|||
value: PrefValueType,
|
||||
): AsyncFailable<DecodedSysPref> {
|
||||
// Validate
|
||||
let sysPreference = await this.validatePref(key, value);
|
||||
let sysPreference = await this.validateSysPref(key, value);
|
||||
if (HasFailed(sysPreference)) return sysPreference;
|
||||
|
||||
// Set
|
||||
|
@ -61,7 +57,10 @@ export class SysPreferenceService {
|
|||
|
||||
public async getPreference(key: string): AsyncFailable<DecodedSysPref> {
|
||||
// Validate
|
||||
let validatedKey = this.validatePrefKey(key);
|
||||
let validatedKey = this.prefCommon.validatePrefKey(
|
||||
key,
|
||||
SysPreference,
|
||||
);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
// Fetch
|
||||
|
@ -89,7 +88,11 @@ export class SysPreferenceService {
|
|||
}
|
||||
|
||||
// Return
|
||||
return this.retrieveConvertedValue(result.data);
|
||||
return this.prefCommon.validateAndUnpackPref(
|
||||
result.data,
|
||||
SysPreference,
|
||||
SysPreferenceValueTypes,
|
||||
);
|
||||
}
|
||||
|
||||
public async getStringPreference(key: string): AsyncFailable<string> {
|
||||
|
@ -135,51 +138,21 @@ export class SysPreferenceService {
|
|||
return this.setPreference(key, this.defaultsService.sysDefaults[key]());
|
||||
}
|
||||
|
||||
// This converts the raw string representation of the value to the correct type
|
||||
private retrieveConvertedValue(
|
||||
preference: ESysPreferenceBackend,
|
||||
): Failable<DecodedSysPref> {
|
||||
const key = this.validatePrefKey(preference.key);
|
||||
if (HasFailed(key)) return key;
|
||||
|
||||
const type = SysPreferenceValueTypes[key];
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value,
|
||||
type: 'string',
|
||||
};
|
||||
case 'number':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: parseInt(preference.value, 10),
|
||||
type: 'number',
|
||||
};
|
||||
case 'boolean':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value == 'true',
|
||||
type: 'boolean',
|
||||
};
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
|
||||
private async validatePref(
|
||||
private async validateSysPref(
|
||||
key: string,
|
||||
value: PrefValueType,
|
||||
): AsyncFailable<ESysPreferenceBackend> {
|
||||
const validatedKey = this.validatePrefKey(key);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
const validatedValue = this.validatePrefValue(validatedKey, value);
|
||||
if (HasFailed(validatedValue)) return validatedValue;
|
||||
const validated = await this.prefCommon.validatePref(
|
||||
key,
|
||||
value,
|
||||
SysPreference,
|
||||
SysPreferenceValueTypes,
|
||||
);
|
||||
if (HasFailed(validated)) return validated;
|
||||
|
||||
let verifySysPreference = new ESysPreferenceBackend();
|
||||
verifySysPreference.key = validatedKey;
|
||||
verifySysPreference.value = validatedValue;
|
||||
verifySysPreference.key = validated.key;
|
||||
verifySysPreference.value = validated.value;
|
||||
|
||||
// It should already be valid, but these two validators might go out of sync
|
||||
const result = ESysPreferenceSchema.safeParse(verifySysPreference);
|
||||
|
@ -190,34 +163,4 @@ export class SysPreferenceService {
|
|||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
private validatePrefKey(key: string): Failable<SysPreference> {
|
||||
if (!SysPreferenceList.includes(key)) return Fail('Invalid preference key');
|
||||
|
||||
return key as SysPreference;
|
||||
}
|
||||
|
||||
private validatePrefValue(
|
||||
// Key is required, because the type of the value depends on the key
|
||||
key: SysPreference,
|
||||
value: PrefValueType,
|
||||
): Failable<string> {
|
||||
const expectedType = SysPreferenceValueTypes[key];
|
||||
|
||||
const type = typeof value;
|
||||
if (type != expectedType) {
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return value as string;
|
||||
case 'number':
|
||||
return value.toString();
|
||||
case 'boolean':
|
||||
return value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,17 @@ import {
|
|||
PrefValueTypeStrings
|
||||
} from 'picsur-shared/dist/dto/preferences.dto';
|
||||
import { UsrPreference } from 'picsur-shared/dist/dto/usrpreferences.dto';
|
||||
import { EUsrPreferenceSchema } from 'picsur-shared/dist/entities/usrpreference';
|
||||
import {
|
||||
AsyncFailable,
|
||||
Fail,
|
||||
Failable,
|
||||
HasFailed
|
||||
} from 'picsur-shared/dist/types';
|
||||
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
||||
import { Repository } from 'typeorm';
|
||||
import {
|
||||
UsrPreferenceList,
|
||||
UsrPreferenceValueTypes
|
||||
} from '../../models/dto/usrpreferences.dto';
|
||||
import { EUsrPreferenceBackend } from '../../models/entities/usrpreference.entity';
|
||||
import {
|
||||
EUsrPreferenceBackend,
|
||||
EUsrPreferenceSchema
|
||||
} from '../../models/entities/usrpreference.entity';
|
||||
import { PreferenceCommonService } from './preferencecommon.service';
|
||||
import { PreferenceDefaultsService } from './preferencedefaults.service';
|
||||
|
||||
@Injectable()
|
||||
|
@ -27,23 +25,25 @@ export class UsrPreferenceService {
|
|||
|
||||
constructor(
|
||||
@InjectRepository(EUsrPreferenceBackend)
|
||||
private sysPreferenceRepository: Repository<EUsrPreferenceBackend>,
|
||||
private usrPreferenceRepository: Repository<EUsrPreferenceBackend>,
|
||||
private defaultsService: PreferenceDefaultsService,
|
||||
private prefCommon: PreferenceCommonService,
|
||||
) {}
|
||||
|
||||
public async setPreference(
|
||||
userid: string,
|
||||
key: string,
|
||||
value: PrefValueType,
|
||||
): AsyncFailable<DecodedUsrPref> {
|
||||
// Validate
|
||||
let sysPreference = await this.validatePref(key, value);
|
||||
if (HasFailed(sysPreference)) return sysPreference;
|
||||
let usrPreference = await this.validatePref(userid, key, value);
|
||||
if (HasFailed(usrPreference)) return usrPreference;
|
||||
|
||||
// Set
|
||||
try {
|
||||
// Upsert here, because we want to create a new record if it does not exist
|
||||
await this.sysPreferenceRepository.upsert(sysPreference, {
|
||||
conflictPaths: ['key'],
|
||||
await this.usrPreferenceRepository.upsert(usrPreference, {
|
||||
conflictPaths: ['key', 'user'],
|
||||
});
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
|
@ -52,24 +52,27 @@ export class UsrPreferenceService {
|
|||
|
||||
// Return
|
||||
return {
|
||||
key: sysPreference.key,
|
||||
key: usrPreference.key,
|
||||
value,
|
||||
// key has to be valid here, we validated it
|
||||
type: UsrPreferenceValueTypes[key as UsrPreference],
|
||||
user: '',
|
||||
user: userid,
|
||||
};
|
||||
}
|
||||
|
||||
public async getPreference(key: string): AsyncFailable<DecodedUsrPref> {
|
||||
public async getPreference(
|
||||
userid: string,
|
||||
key: string,
|
||||
): AsyncFailable<DecodedUsrPref> {
|
||||
// Validate
|
||||
let validatedKey = this.validatePrefKey(key);
|
||||
let validatedKey = this.prefCommon.validatePrefKey(key, UsrPreference);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
// Fetch
|
||||
let foundSysPreference: EUsrPreferenceBackend | null;
|
||||
let foundUsrPreference: EUsrPreferenceBackend | null;
|
||||
try {
|
||||
foundSysPreference = await this.sysPreferenceRepository.findOne({
|
||||
where: { key: validatedKey },
|
||||
foundUsrPreference = await this.usrPreferenceRepository.findOne({
|
||||
where: { key: validatedKey, userId: userid },
|
||||
cache: 60000,
|
||||
});
|
||||
} catch (e: any) {
|
||||
|
@ -78,48 +81,81 @@ export class UsrPreferenceService {
|
|||
}
|
||||
|
||||
// Fallback
|
||||
if (!foundSysPreference) {
|
||||
return this.saveDefault(validatedKey);
|
||||
if (!foundUsrPreference) {
|
||||
return this.saveDefault(userid, validatedKey);
|
||||
}
|
||||
|
||||
// Validate
|
||||
const result = EUsrPreferenceSchema.safeParse(foundSysPreference);
|
||||
const result = EUsrPreferenceSchema.safeParse(foundUsrPreference);
|
||||
if (!result.success) {
|
||||
this.logger.warn(result.error);
|
||||
return Fail('Invalid preference');
|
||||
}
|
||||
|
||||
// Return
|
||||
return this.retrieveConvertedValue(result.data);
|
||||
const unpacked = this.prefCommon.validateAndUnpackPref(
|
||||
result.data,
|
||||
UsrPreference,
|
||||
UsrPreferenceValueTypes,
|
||||
);
|
||||
if (HasFailed(unpacked)) return unpacked;
|
||||
return {
|
||||
...unpacked,
|
||||
user: result.data.userId,
|
||||
};
|
||||
}
|
||||
|
||||
public async getStringPreference(key: string): AsyncFailable<string> {
|
||||
return this.getPreferencePinned(key, 'string') as AsyncFailable<string>;
|
||||
public async getStringPreference(
|
||||
userid: string,
|
||||
key: string,
|
||||
): AsyncFailable<string> {
|
||||
return this.getPreferencePinned(
|
||||
userid,
|
||||
key,
|
||||
'string',
|
||||
) as AsyncFailable<string>;
|
||||
}
|
||||
|
||||
public async getNumberPreference(key: string): AsyncFailable<number> {
|
||||
return this.getPreferencePinned(key, 'number') as AsyncFailable<number>;
|
||||
public async getNumberPreference(
|
||||
userid: string,
|
||||
key: string,
|
||||
): AsyncFailable<number> {
|
||||
return this.getPreferencePinned(
|
||||
userid,
|
||||
key,
|
||||
'number',
|
||||
) as AsyncFailable<number>;
|
||||
}
|
||||
|
||||
public async getBooleanPreference(key: string): AsyncFailable<boolean> {
|
||||
return this.getPreferencePinned(key, 'boolean') as AsyncFailable<boolean>;
|
||||
public async getBooleanPreference(
|
||||
userid: string,
|
||||
key: string,
|
||||
): AsyncFailable<boolean> {
|
||||
return this.getPreferencePinned(
|
||||
userid,
|
||||
key,
|
||||
'boolean',
|
||||
) as AsyncFailable<boolean>;
|
||||
}
|
||||
|
||||
private async getPreferencePinned(
|
||||
userid: string,
|
||||
key: string,
|
||||
type: PrefValueTypeStrings,
|
||||
): AsyncFailable<PrefValueType> {
|
||||
let pref = await this.getPreference(key);
|
||||
let pref = await this.getPreference(userid, key);
|
||||
if (HasFailed(pref)) return pref;
|
||||
if (pref.type !== type) return Fail('Invalid preference type');
|
||||
|
||||
return pref.value;
|
||||
}
|
||||
|
||||
public async getAllPreferences(): AsyncFailable<DecodedUsrPref[]> {
|
||||
public async getAllPreferences(
|
||||
userid: string,
|
||||
): AsyncFailable<DecodedUsrPref[]> {
|
||||
// TODO: We are fetching each value invidually, we should fetch all at once
|
||||
let internalSysPrefs = await Promise.all(
|
||||
UsrPreferenceList.map((key) => this.getPreference(key)),
|
||||
UsrPreferenceList.map((key) => this.getPreference(userid, key)),
|
||||
);
|
||||
if (internalSysPrefs.some((pref) => HasFailed(pref))) {
|
||||
return Fail('Could not get all preferences');
|
||||
|
@ -131,59 +167,33 @@ export class UsrPreferenceService {
|
|||
// Private
|
||||
|
||||
private async saveDefault(
|
||||
userid: string,
|
||||
key: UsrPreference, // Force enum here because we dont validate
|
||||
): AsyncFailable<DecodedUsrPref> {
|
||||
return this.setPreference(key, this.defaultsService.sysDefaults[key]());
|
||||
}
|
||||
|
||||
// This converts the raw string representation of the value to the correct type
|
||||
private retrieveConvertedValue(
|
||||
preference: EUsrPreferenceBackend,
|
||||
): Failable<DecodedUsrPref> {
|
||||
const key = this.validatePrefKey(preference.key);
|
||||
if (HasFailed(key)) return key;
|
||||
|
||||
const type = UsrPreferenceValueTypes[key];
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value,
|
||||
type: 'string',
|
||||
user: '',
|
||||
};
|
||||
case 'number':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: parseInt(preference.value, 10),
|
||||
type: 'number',
|
||||
user: '',
|
||||
};
|
||||
case 'boolean':
|
||||
return {
|
||||
key: preference.key,
|
||||
value: preference.value == 'true',
|
||||
type: 'boolean',
|
||||
user: '',
|
||||
};
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
return this.setPreference(
|
||||
userid,
|
||||
key,
|
||||
this.defaultsService.sysDefaults[key](),
|
||||
);
|
||||
}
|
||||
|
||||
private async validatePref(
|
||||
userid: string,
|
||||
key: string,
|
||||
value: PrefValueType,
|
||||
): AsyncFailable<EUsrPreferenceBackend> {
|
||||
const validatedKey = this.validatePrefKey(key);
|
||||
if (HasFailed(validatedKey)) return validatedKey;
|
||||
|
||||
const validatedValue = this.validatePrefValue(validatedKey, value);
|
||||
if (HasFailed(validatedValue)) return validatedValue;
|
||||
const validated = await this.prefCommon.validatePref(
|
||||
key,
|
||||
value,
|
||||
UsrPreference,
|
||||
UsrPreferenceValueTypes,
|
||||
);
|
||||
if (HasFailed(validated)) return validated;
|
||||
|
||||
let verifySysPreference = new EUsrPreferenceBackend();
|
||||
verifySysPreference.key = validatedKey;
|
||||
verifySysPreference.value = validatedValue;
|
||||
verifySysPreference.key = validated.key;
|
||||
verifySysPreference.value = validated.value;
|
||||
verifySysPreference.userId = userid;
|
||||
|
||||
// It should already be valid, but these two validators might go out of sync
|
||||
const result = EUsrPreferenceSchema.safeParse(verifySysPreference);
|
||||
|
@ -194,34 +204,4 @@ export class UsrPreferenceService {
|
|||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
private validatePrefKey(key: string): Failable<UsrPreference> {
|
||||
if (!UsrPreferenceList.includes(key)) return Fail('Invalid preference key');
|
||||
|
||||
return key as UsrPreference;
|
||||
}
|
||||
|
||||
private validatePrefValue(
|
||||
// Key is required, because the type of the value depends on the key
|
||||
key: UsrPreference,
|
||||
value: PrefValueType,
|
||||
): Failable<string> {
|
||||
const expectedType = UsrPreferenceValueTypes[key];
|
||||
|
||||
const type = typeof value;
|
||||
if (type != expectedType) {
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return value as string;
|
||||
case 'number':
|
||||
return value.toString();
|
||||
case 'boolean':
|
||||
return value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
return Fail('Invalid preference value');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
import { ESysPreference } from 'picsur-shared/dist/entities/syspreference.entity';
|
||||
import { IsEntityID } from 'picsur-shared/dist/validators/entity-id.validator';
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import z from 'zod';
|
||||
|
||||
export const ESysPreferenceSchema = z.object({
|
||||
id: IsEntityID().optional(),
|
||||
key: z.string(),
|
||||
value: z.string(),
|
||||
});
|
||||
type ESysPreference = z.infer<typeof ESysPreferenceSchema>;
|
||||
|
||||
@Entity()
|
||||
export class ESysPreferenceBackend implements ESysPreference {
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
import { EUsrPreference } from 'picsur-shared/dist/entities/usrpreference';
|
||||
import { Column, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { IsEntityID } from 'picsur-shared/dist/validators/entity-id.validator';
|
||||
import { Column, Index, PrimaryGeneratedColumn, Unique } from 'typeorm';
|
||||
import z from 'zod';
|
||||
|
||||
export const EUsrPreferenceSchema = z.object({
|
||||
id: IsEntityID().optional(),
|
||||
key: z.string(),
|
||||
value: z.string(),
|
||||
userId: IsEntityID(),
|
||||
});
|
||||
type EUsrPreference = z.infer<typeof EUsrPreferenceSchema>;
|
||||
|
||||
@Unique(['key', 'userId'])
|
||||
export class EUsrPreferenceBackend implements EUsrPreference {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id?: string;
|
||||
|
||||
@Index()
|
||||
@Column({ nullable: false, unique: true })
|
||||
@Column({ nullable: false })
|
||||
key: string;
|
||||
|
||||
@Column({ nullable: false })
|
||||
|
@ -14,5 +24,5 @@ export class EUsrPreferenceBackend implements EUsrPreference {
|
|||
|
||||
@Index()
|
||||
@Column({ nullable: false })
|
||||
userId: number;
|
||||
userId: string;
|
||||
}
|
||||
|
|
|
@ -10,15 +10,21 @@ export const PrefValueTypes = tuple('string', 'number', 'boolean');
|
|||
|
||||
// Decoded Representations
|
||||
|
||||
export const DecodedSysPrefSchema = z.object({
|
||||
export const DecodedPrefSchema = z.object({
|
||||
key: z.string(),
|
||||
value: IsPrefValue(),
|
||||
type: z.enum(PrefValueTypes),
|
||||
})
|
||||
});
|
||||
export type DecodedPref = z.infer<typeof DecodedSysPrefSchema>;
|
||||
|
||||
// Usr and Sys
|
||||
|
||||
export const DecodedSysPrefSchema = DecodedPrefSchema;
|
||||
export type DecodedSysPref = z.infer<typeof DecodedSysPrefSchema>;
|
||||
|
||||
export const DecodedUsrPrefSchema = DecodedSysPrefSchema.merge(z.object({
|
||||
user: IsEntityID(),
|
||||
}))
|
||||
export const DecodedUsrPrefSchema = DecodedSysPrefSchema.merge(
|
||||
z.object({
|
||||
user: IsEntityID(),
|
||||
}),
|
||||
);
|
||||
export type DecodedUsrPref = z.infer<typeof DecodedUsrPrefSchema>;
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import { z } from 'zod';
|
||||
import { IsEntityID } from '../validators/entity-id.validator';
|
||||
|
||||
export const ESysPreferenceSchema = z.object({
|
||||
id: IsEntityID().optional(),
|
||||
key: z.string(),
|
||||
value: z.string(),
|
||||
});
|
||||
export type ESysPreference = z.infer<typeof ESysPreferenceSchema>;
|
|
@ -1,11 +0,0 @@
|
|||
import { z } from 'zod';
|
||||
import { IsEntityID } from '../validators/entity-id.validator';
|
||||
import { IsPosInt } from '../validators/positive-int.validator';
|
||||
|
||||
export const EUsrPreferenceSchema = z.object({
|
||||
id: IsEntityID().optional(),
|
||||
key: z.string(),
|
||||
value: z.string(),
|
||||
userId: IsPosInt(),
|
||||
})
|
||||
export type EUsrPreference = z.infer<typeof EUsrPreferenceSchema>;
|
Loading…
Reference in a new issue