forked from Ivasoft/mattermost-mobile
[Gekidou] Typings & PostMetadata structure (#5542)
* Typings & PostMetadata structure * comment out unused code * Remove duplicate interface * Fix getPreferenceAsBool defaultValue
This commit is contained in:
@@ -2,13 +2,11 @@ package com.mattermost.rnbeta;
|
||||
|
||||
import com.mattermost.rnbeta.generated.BasePackageList;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -32,16 +30,10 @@ import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.TurboReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.ReactMarkerConstants;
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
@@ -56,16 +48,6 @@ public class MainApplication extends NavigationApplication implements INotificat
|
||||
|
||||
public Boolean sharedExtensionIsOpened = false;
|
||||
|
||||
public long APP_START_TIME;
|
||||
|
||||
public long RELOAD;
|
||||
public long CONTENT_APPEARED;
|
||||
|
||||
public long PROCESS_PACKAGES_START;
|
||||
public long PROCESS_PACKAGES_END;
|
||||
|
||||
private Bundle mManagedConfig = null;
|
||||
|
||||
private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(new BasePackageList().getPackageList(), null);
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
@@ -77,15 +59,14 @@ public class MainApplication extends NavigationApplication implements INotificat
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
packages.add(new RNNotificationsPackage(MainApplication.this));
|
||||
|
||||
// Add unimodules
|
||||
List<ReactPackage> unimodules = Arrays.<ReactPackage>asList(
|
||||
new ModuleRegistryAdapter(mModuleRegistryProvider)
|
||||
List<ReactPackage> unimodules = Collections.singletonList(
|
||||
new ModuleRegistryAdapter(mModuleRegistryProvider)
|
||||
);
|
||||
packages.addAll(unimodules);
|
||||
|
||||
@@ -107,15 +88,12 @@ public class MainApplication extends NavigationApplication implements INotificat
|
||||
|
||||
@Override
|
||||
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
||||
return new ReactModuleInfoProvider() {
|
||||
@Override
|
||||
public Map<String, ReactModuleInfo> getReactModuleInfos() {
|
||||
Map<String, ReactModuleInfo> map = new HashMap<>();
|
||||
map.put("MattermostShare", new ReactModuleInfo("MattermostShare", "com.mattermost.share.ShareModule", false, false, true, false, false));
|
||||
map.put("NotificationPreferences", new ReactModuleInfo("NotificationPreferences", "com.mattermost.rnbeta.NotificationPreferencesModule", false, false, false, false, false));
|
||||
map.put("RNTextInputReset", new ReactModuleInfo("RNTextInputReset", "com.mattermost.rnbeta.RNTextInputResetModule", false, false, false, false, false));
|
||||
return map;
|
||||
}
|
||||
return () -> {
|
||||
Map<String, ReactModuleInfo> map = new HashMap<>();
|
||||
map.put("MattermostShare", new ReactModuleInfo("MattermostShare", "com.mattermost.share.ShareModule", false, false, true, false, false));
|
||||
map.put("NotificationPreferences", new ReactModuleInfo("NotificationPreferences", "com.mattermost.rnbeta.NotificationPreferencesModule", false, false, false, false, false));
|
||||
map.put("RNTextInputReset", new ReactModuleInfo("RNTextInputReset", "com.mattermost.rnbeta.RNTextInputResetModule", false, false, false, false, false));
|
||||
return map;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -175,54 +153,9 @@ public class MainApplication extends NavigationApplication implements INotificat
|
||||
return new CustomPushNotificationDrawer(context, defaultAppLaunchHelper);
|
||||
}
|
||||
|
||||
public ReactContext getRunningReactContext() {
|
||||
if (mReactNativeHost == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mReactNativeHost
|
||||
.getReactInstanceManager()
|
||||
.getCurrentReactContext();
|
||||
}
|
||||
|
||||
private void addReactMarkerListener() {
|
||||
ReactMarker.addListener(new ReactMarker.MarkerListener() {
|
||||
@Override
|
||||
public void logMarker(ReactMarkerConstants name, @Nullable String tag, int instanceKey) {
|
||||
if (name.toString() == ReactMarkerConstants.RELOAD.toString()) {
|
||||
APP_START_TIME = System.currentTimeMillis();
|
||||
RELOAD = System.currentTimeMillis();
|
||||
} else if (name.toString() == ReactMarkerConstants.PROCESS_PACKAGES_START.toString()) {
|
||||
PROCESS_PACKAGES_START = System.currentTimeMillis();
|
||||
} else if (name.toString() == ReactMarkerConstants.PROCESS_PACKAGES_END.toString()) {
|
||||
PROCESS_PACKAGES_END = System.currentTimeMillis();
|
||||
} else if (name.toString() == ReactMarkerConstants.CONTENT_APPEARED.toString()) {
|
||||
CONTENT_APPEARED = System.currentTimeMillis();
|
||||
ReactContext ctx = getRunningReactContext();
|
||||
|
||||
if (ctx != null) {
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
||||
map.putDouble("appReload", RELOAD);
|
||||
map.putDouble("appContentAppeared", CONTENT_APPEARED);
|
||||
|
||||
map.putDouble("processPackagesStart", PROCESS_PACKAGES_START);
|
||||
map.putDouble("processPackagesEnd", PROCESS_PACKAGES_END);
|
||||
|
||||
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).
|
||||
emit("nativeMetrics", map);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
@@ -236,13 +169,7 @@ public class MainApplication extends NavigationApplication implements INotificat
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import {getTimeZone} from 'react-native-localize';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {queryUserById} from '@queries/servers/user';
|
||||
import {updateMe} from '@actions/remote/user';
|
||||
import {Config} from '@typings/database/models/servers/config';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
export const isTimezoneEnabled = (config: Partial<Config>) => {
|
||||
export const isTimezoneEnabled = (config: Partial<ClientConfig>) => {
|
||||
return config?.ExperimentalTimezone === 'true';
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {General} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getServerCredentials} from '@init/credentials';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {queryCurrentUserId} from '@queries/servers/system';
|
||||
|
||||
import type {ClientResponse} from '@mattermost/react-native-network-client';
|
||||
import type {Client4Error} from '@typings/api/client';
|
||||
|
||||
import type {RawSystem} from '@typings/database/database';
|
||||
const HTTP_UNAUTHORIZED = 401;
|
||||
|
||||
export const doPing = async (serverUrl: string) => {
|
||||
const client = await NetworkManager.createClient(serverUrl);
|
||||
@@ -46,41 +49,32 @@ export const doPing = async (serverUrl: string) => {
|
||||
return {error: undefined};
|
||||
};
|
||||
|
||||
export const fetchConfigAndLicense = async (serverUrl: string) => {
|
||||
let client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
export const forceLogoutIfNecessary = async (serverUrl: string, err: Client4Error) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
try {
|
||||
const [config, license] = await Promise.all<ClientConfig, ClientLicense>([
|
||||
client.getClientConfigOld(),
|
||||
client.getClientLicenseOld(),
|
||||
]);
|
||||
const currentUserId = await queryCurrentUserId(database);
|
||||
|
||||
// If we have credentials for this server then update the values in the database
|
||||
const credentials = await getServerCredentials(serverUrl);
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (credentials && operator) {
|
||||
const systems: RawSystem[] = [{
|
||||
id: SYSTEM_IDENTIFIERS.CONFIG,
|
||||
value: JSON.stringify(config),
|
||||
}, {
|
||||
id: SYSTEM_IDENTIFIERS.LICENSE,
|
||||
value: JSON.stringify(license),
|
||||
}];
|
||||
|
||||
operator.handleSystem({systems, prepareRecordsOnly: false}).
|
||||
catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('An error ocurred while saving config & license', error);
|
||||
});
|
||||
}
|
||||
|
||||
return {config, license};
|
||||
} catch (error) {
|
||||
return {error};
|
||||
if ('status_code' in err && err.status_code === HTTP_UNAUTHORIZED && err?.url?.indexOf('/login') === -1 && currentUserId) {
|
||||
await logout(serverUrl);
|
||||
}
|
||||
|
||||
return {error: null};
|
||||
};
|
||||
|
||||
export const logout = async (serverUrl: string, skipServerLogout = false) => {
|
||||
if (!skipServerLogout) {
|
||||
try {
|
||||
const client = NetworkManager.getClient(serverUrl);
|
||||
await client.logout();
|
||||
} catch (error) {
|
||||
// We want to log the user even if logging out from the server failed
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('An error ocurred loging out from the server', serverUrl, error);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceEventEmitter.emit(General.SERVER_LOGOUT, serverUrl);
|
||||
};
|
||||
|
||||
40
app/actions/remote/preference.ts
Normal file
40
app/actions/remote/preference.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import DatabaseManager from '@database/manager';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
|
||||
import {forceLogoutIfNecessary} from './general';
|
||||
|
||||
export type MyPreferencesRequest = {
|
||||
preferences?: PreferenceType[];
|
||||
error?: never;
|
||||
}
|
||||
|
||||
export const fetchMyPreferences = async (serverUrl: string, fetchOnly = false): Promise<MyPreferencesRequest> => {
|
||||
let client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
try {
|
||||
const preferences = await client.getMyPreferences();
|
||||
|
||||
if (!fetchOnly) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (operator) {
|
||||
operator.handlePreferences({
|
||||
prepareRecordsOnly: false,
|
||||
preferences,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {preferences};
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(serverUrl, error);
|
||||
return {error};
|
||||
}
|
||||
};
|
||||
@@ -8,7 +8,6 @@ import DatabaseManager from '@database/manager';
|
||||
import PushNotifications from '@init/push_notifications';
|
||||
import {queryCommonSystemValues} from '@app/queries/servers/system';
|
||||
import {getSessions} from '@actions/remote/user';
|
||||
import {Config} from '@typings/database/models/servers/config';
|
||||
|
||||
const sortByNewest = (a: Session, b: Session) => {
|
||||
if (a.create_at > b.create_at) {
|
||||
@@ -20,7 +19,7 @@ const sortByNewest = (a: Session, b: Session) => {
|
||||
|
||||
export const scheduleExpiredNotification = async (serverUrl: string, intl: IntlShape) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl].database;
|
||||
const {currentUserId, config}: {currentUserId: string; config: Partial<Config>} = await queryCommonSystemValues(database);
|
||||
const {currentUserId, config}: {currentUserId: string; config: Partial<ClientConfig>} = await queryCommonSystemValues(database);
|
||||
|
||||
if (config.ExtendSessionLengthWithActivity === 'true') {
|
||||
PushNotifications.cancelAllLocalNotifications();
|
||||
|
||||
@@ -2,14 +2,19 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {logError} from '@actions/remote/error';
|
||||
import {forceLogoutIfNecessary} from '@actions/remote/user';
|
||||
import {forceLogoutIfNecessary} from '@actions/remote/general';
|
||||
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getServerCredentials} from '@init/credentials';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
|
||||
import type {RawSystem} from '@typings/database/database';
|
||||
export type ConfigAndLicenseRequest = {
|
||||
config?: ClientConfig;
|
||||
license?: ClientLicense;
|
||||
error?: never;
|
||||
}
|
||||
|
||||
export const getDataRetentionPolicy = async (serverUrl: string) => {
|
||||
export const fetchDataRetentionPolicy = async (serverUrl: string) => {
|
||||
let client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
@@ -29,7 +34,7 @@ export const getDataRetentionPolicy = async (serverUrl: string) => {
|
||||
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (operator) {
|
||||
const systems: RawSystem[] = [{
|
||||
const systems: IdValue[] = [{
|
||||
id: SYSTEM_IDENTIFIERS.DATA_RETENTION_POLICIES,
|
||||
value: JSON.stringify(data),
|
||||
}];
|
||||
@@ -43,3 +48,45 @@ export const getDataRetentionPolicy = async (serverUrl: string) => {
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchConfigAndLicense = async (serverUrl: string, fetchOnly = false): Promise<ConfigAndLicenseRequest> => {
|
||||
let client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
try {
|
||||
const [config, license] = await Promise.all<ClientConfig, ClientLicense>([
|
||||
client.getClientConfigOld(),
|
||||
client.getClientLicenseOld(),
|
||||
]);
|
||||
|
||||
// If we have credentials for this server then update the values in the database
|
||||
if (!fetchOnly) {
|
||||
const credentials = await getServerCredentials(serverUrl);
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (credentials && operator) {
|
||||
const systems: IdValue[] = [{
|
||||
id: SYSTEM_IDENTIFIERS.CONFIG,
|
||||
value: JSON.stringify(config),
|
||||
}, {
|
||||
id: SYSTEM_IDENTIFIERS.LICENSE,
|
||||
value: JSON.stringify(license),
|
||||
}];
|
||||
|
||||
operator.handleSystem({systems, prepareRecordsOnly: false}).
|
||||
catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('An error ocurred while saving config & license', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {config, license};
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(serverUrl, error);
|
||||
return {error};
|
||||
}
|
||||
};
|
||||
|
||||
57
app/actions/remote/team.ts
Normal file
57
app/actions/remote/team.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Model} from '@nozbe/watermelondb';
|
||||
|
||||
import DatabaseManager from '@database/manager';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {prepareMyTeams} from '@queries/servers/team';
|
||||
|
||||
import {forceLogoutIfNecessary} from './general';
|
||||
|
||||
export type MyTeamsRequest = {
|
||||
teams?: Team[];
|
||||
memberships?: TeamMembership[];
|
||||
unreads?: TeamUnread[];
|
||||
error?: never;
|
||||
}
|
||||
|
||||
export const fetchMyTeams = async (serverUrl: string, fetchOnly = false): Promise<MyTeamsRequest> => {
|
||||
let client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
try {
|
||||
const [teams, memberships, unreads] = await Promise.all<Team[], TeamMembership[], TeamUnread[]>([
|
||||
client.getMyTeams(),
|
||||
client.getMyTeamMembers(),
|
||||
client.getMyTeamUnreads(),
|
||||
]);
|
||||
|
||||
if (!fetchOnly) {
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
if (operator) {
|
||||
const prepare = prepareMyTeams(operator, teams, memberships, unreads);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
if (modelPromises.length) {
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
if (flattenedModels?.length > 0) {
|
||||
await operator.batchRecords(flattenedModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {teams, memberships, unreads};
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(serverUrl, error);
|
||||
return {error};
|
||||
}
|
||||
};
|
||||
@@ -1,42 +1,39 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {autoUpdateTimezone, getDeviceTimezone, isTimezoneEnabled} from '@actions/local/timezone';
|
||||
import {logError} from '@actions/remote/error';
|
||||
import {loadRolesIfNeeded} from '@actions/remote/role';
|
||||
import {getDataRetentionPolicy} from '@actions/remote/systems';
|
||||
import {Database, General} from '@constants';
|
||||
import {fetchDataRetentionPolicy} from '@actions/remote/systems';
|
||||
import {Database} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import analytics from '@init/analytics';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {queryDeviceToken} from '@queries/app/global';
|
||||
import {queryCommonSystemValues, queryCurrentUserId} from '@queries/servers/system';
|
||||
import {queryCommonSystemValues} from '@queries/servers/system';
|
||||
import {getCSRFFromCookie} from '@utils/security';
|
||||
|
||||
import type {Client4Error} from '@typings/api/client';
|
||||
import type {Config} from '@typings/database/models/servers/config';
|
||||
import type {LoadMeArgs, LoginArgs, RawMyTeam, RawPreference,
|
||||
RawRole, RawTeam, RawTeamMembership, RawUser} from '@typings/database/database';
|
||||
import type {License} from '@typings/database/models/servers/license';
|
||||
import type Role from '@typings/database/models/servers/role';
|
||||
import type User from '@typings/database/models/servers/user';
|
||||
import type {LoadMeArgs, LoginArgs} from '@typings/database/database';
|
||||
import type RoleModel from '@typings/database/models/servers/role';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
import {forceLogoutIfNecessary} from './general';
|
||||
|
||||
// import {initAfterLogin} from './init';
|
||||
|
||||
type LoadedUser = {
|
||||
currentUser?: RawUser;
|
||||
currentUser?: UserProfile;
|
||||
error?: Client4Error;
|
||||
}
|
||||
|
||||
const HTTP_UNAUTHORIZED = 401;
|
||||
|
||||
export const completeLogin = async (serverUrl: string, user: RawUser) => {
|
||||
export const completeLogin = async (serverUrl: string, user: UserProfile) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const {config, license}: { config: Partial<Config>; license: Partial<License> } = await queryCommonSystemValues(database);
|
||||
const {config, license}: { config: Partial<ClientConfig>; license: Partial<ClientLicense> } = await queryCommonSystemValues(database);
|
||||
|
||||
if (!Object.keys(config)?.length || !Object.keys(license)?.length) {
|
||||
return null;
|
||||
@@ -50,27 +47,12 @@ export const completeLogin = async (serverUrl: string, user: RawUser) => {
|
||||
|
||||
// Data retention
|
||||
if (config?.DataRetentionEnableMessageDeletion === 'true' && license?.IsLicensed === 'true' && license?.DataRetention === 'true') {
|
||||
getDataRetentionPolicy(serverUrl);
|
||||
fetchDataRetentionPolicy(serverUrl);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const forceLogoutIfNecessary = async (serverUrl: string, err: Client4Error) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return {error: `${serverUrl} database not found`};
|
||||
}
|
||||
|
||||
const currentUserId = await queryCurrentUserId(database);
|
||||
|
||||
if ('status_code' in err && err.status_code === HTTP_UNAUTHORIZED && err?.url?.indexOf('/login') === -1 && currentUserId) {
|
||||
await logout(serverUrl);
|
||||
}
|
||||
|
||||
return {error: null};
|
||||
};
|
||||
|
||||
export const getSessions = async (serverUrl: string, currentUserId: string) => {
|
||||
let client;
|
||||
try {
|
||||
@@ -91,7 +73,7 @@ export const getSessions = async (serverUrl: string, currentUserId: string) => {
|
||||
|
||||
export const login = async (serverUrl: string, {ldapOnly = false, loginId, mfaToken, password}: LoginArgs) => {
|
||||
let deviceToken;
|
||||
let user: RawUser;
|
||||
let user: UserProfile;
|
||||
|
||||
const appDatabase = DatabaseManager.appDatabase?.database;
|
||||
if (!appDatabase) {
|
||||
@@ -107,13 +89,13 @@ export const login = async (serverUrl: string, {ldapOnly = false, loginId, mfaTo
|
||||
|
||||
try {
|
||||
deviceToken = await queryDeviceToken(appDatabase);
|
||||
user = (await client.login(
|
||||
user = await client.login(
|
||||
loginId,
|
||||
password,
|
||||
mfaToken,
|
||||
deviceToken,
|
||||
ldapOnly,
|
||||
) as unknown) as RawUser;
|
||||
);
|
||||
|
||||
await DatabaseManager.createServerDatabase({
|
||||
config: {
|
||||
@@ -134,6 +116,8 @@ export const login = async (serverUrl: string, {ldapOnly = false, loginId, mfaTo
|
||||
await completeLogin(serverUrl, user);
|
||||
}
|
||||
|
||||
// initAfterLogin({serverUrl, user, deviceToken});
|
||||
|
||||
return {error: undefined};
|
||||
};
|
||||
|
||||
@@ -158,7 +142,7 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
}
|
||||
|
||||
if (!currentUser) {
|
||||
currentUser = (await client.getMe() as unknown) as RawUser;
|
||||
currentUser = await client.getMe();
|
||||
}
|
||||
} catch (e) {
|
||||
await forceLogoutIfNecessary(serverUrl, e);
|
||||
@@ -186,7 +170,7 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
|
||||
const [
|
||||
teams,
|
||||
teamMembers,
|
||||
teamMemberships,
|
||||
teamUnreads,
|
||||
preferences,
|
||||
config,
|
||||
@@ -201,17 +185,17 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
]);
|
||||
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl].operator;
|
||||
const teamRecords = operator.handleTeam({prepareRecordsOnly: true, teams: teams as RawTeam[]});
|
||||
const teamMembershipRecords = operator.handleTeamMemberships({prepareRecordsOnly: true, teamMemberships: (teamMembers as unknown) as RawTeamMembership[]});
|
||||
const teamRecords = operator.handleTeam({prepareRecordsOnly: true, teams});
|
||||
const teamMembershipRecords = operator.handleTeamMemberships({prepareRecordsOnly: true, teamMemberships});
|
||||
|
||||
const myTeams = teamUnreads.map((unread) => {
|
||||
const matchingTeam = teamMembers.find((team) => team.team_id === unread.team_id);
|
||||
const matchingTeam = teamMemberships.find((team) => team.team_id === unread.team_id);
|
||||
return {team_id: unread.team_id, roles: matchingTeam?.roles ?? '', is_unread: unread.msg_count > 0, mentions_count: unread.mention_count};
|
||||
});
|
||||
|
||||
const myTeamRecords = operator.handleMyTeam({
|
||||
prepareRecordsOnly: true,
|
||||
myTeams: (myTeams as unknown) as RawMyTeam[],
|
||||
myTeams,
|
||||
});
|
||||
|
||||
const systemRecords = operator.handleSystem({
|
||||
@@ -239,7 +223,7 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
|
||||
const preferenceRecords = operator.handlePreferences({
|
||||
prepareRecordsOnly: true,
|
||||
preferences: (preferences as unknown) as RawPreference[],
|
||||
preferences,
|
||||
});
|
||||
|
||||
let roles: string[] = [];
|
||||
@@ -247,18 +231,18 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
roles = roles.concat(role);
|
||||
}
|
||||
|
||||
for (const teamMember of teamMembers) {
|
||||
for (const teamMember of teamMemberships) {
|
||||
roles = roles.concat(teamMember.roles.split(' '));
|
||||
}
|
||||
|
||||
const rolesToLoad = new Set<string>(roles);
|
||||
|
||||
let rolesRecords: Role[] = [];
|
||||
let rolesRecords: RoleModel[] = [];
|
||||
if (rolesToLoad.size > 0) {
|
||||
const rolesByName = (await client.getRolesByNames(Array.from(rolesToLoad)) as unknown) as RawRole[];
|
||||
const rolesByName = await client.getRolesByNames(Array.from(rolesToLoad));
|
||||
|
||||
if (rolesByName?.length) {
|
||||
rolesRecords = await operator.handleRole({prepareRecordsOnly: true, roles: rolesByName}) as Role[];
|
||||
rolesRecords = await operator.handleRole({prepareRecordsOnly: true, roles: rolesByName});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,23 +259,6 @@ export const loadMe = async (serverUrl: string, {deviceToken, user}: LoadMeArgs)
|
||||
return {currentUser, error: undefined};
|
||||
};
|
||||
|
||||
export const logout = async (serverUrl: string, skipServerLogout = false) => {
|
||||
if (!skipServerLogout) {
|
||||
try {
|
||||
const client = NetworkManager.getClient(serverUrl);
|
||||
await client.logout();
|
||||
} catch (error) {
|
||||
// We want to log the user even if logging out from the server failed
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('An error ocurred loging out from the server', serverUrl, error);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceEventEmitter.emit(General.SERVER_LOGOUT, serverUrl);
|
||||
|
||||
return {data: true};
|
||||
};
|
||||
|
||||
export const ssoLogin = async (serverUrl: string, bearerToken: string, csrfToken: string) => {
|
||||
let deviceToken;
|
||||
|
||||
@@ -360,7 +327,7 @@ export const sendPasswordResetEmail = async (serverUrl: string, email: string) =
|
||||
};
|
||||
};
|
||||
|
||||
export const updateMe = async (serverUrl: string, user: User) => {
|
||||
export const updateMe = async (serverUrl: string, user: UserModel) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
if (!database) {
|
||||
@@ -374,9 +341,9 @@ export const updateMe = async (serverUrl: string, user: User) => {
|
||||
return {error};
|
||||
}
|
||||
|
||||
let data;
|
||||
let data: UserProfile;
|
||||
try {
|
||||
data = (await client.patchMe(user._raw) as unknown) as RawUser;
|
||||
data = await client.patchMe(user._raw);
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
return {error: e};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
export interface ClientPreferencesMix {
|
||||
savePreferences: (userId: string, preferences: PreferenceType[]) => Promise<any>;
|
||||
deletePreferences: (userId: string, preferences: PreferenceType[]) => Promise<any>;
|
||||
getMyPreferences: () => Promise<PreferenceType>;
|
||||
getMyPreferences: () => Promise<PreferenceType[]>;
|
||||
}
|
||||
|
||||
const ClientPreferences = (superclass: any) => class extends superclass {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const Preferences: Dictionary<any> = {
|
||||
const Preferences: Record<string, any> = {
|
||||
CATEGORY_CHANNEL_OPEN_TIME: 'channel_open_time',
|
||||
CATEGORY_CHANNEL_APPROXIMATE_VIEW_TIME: 'channel_approximate_view_time',
|
||||
CATEGORY_DIRECT_CHANNEL_SHOW: 'direct_channel_show',
|
||||
@@ -39,6 +39,7 @@ const Preferences: Dictionary<any> = {
|
||||
ADVANCED_CODE_BLOCK_ON_CTRL_ENTER: 'code_block_ctrl_enter',
|
||||
ADVANCED_SEND_ON_CTRL_ENTER: 'send_on_ctrl_enter',
|
||||
CATEGORY_THEME: 'theme',
|
||||
TEAMS_ORDER: 'teams_order',
|
||||
THEMES: {
|
||||
default: {
|
||||
type: 'Mattermost',
|
||||
|
||||
@@ -12,14 +12,14 @@ import urlParse from 'url-parse';
|
||||
import {MIGRATION_EVENTS, MM_TABLES} from '@constants/database';
|
||||
import AppDataOperator from '@database/operator/app_data_operator';
|
||||
import AppDatabaseMigrations from '@app/database/migration/app';
|
||||
import {Info, Global, Servers} from '@app/database/models/app';
|
||||
import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
|
||||
import {schema as appSchema} from '@app/database/schema/app';
|
||||
import ServerDatabaseMigrations from '@database/migration/server';
|
||||
import {Channel, ChannelInfo, ChannelMembership, CustomEmoji, Draft, File,
|
||||
Group, GroupMembership, GroupsInChannel, GroupsInTeam, MyChannel, MyChannelSettings, MyTeam,
|
||||
Post, PostMetadata, PostsInChannel, PostsInThread, PreferenceModel, Reaction, Role,
|
||||
SlashCommand, SystemModel, Team, TeamChannelHistory, TeamMembership, TeamSearchHistory,
|
||||
TermsOfService, User,
|
||||
import {ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
|
||||
GroupModel, GroupMembershipModel, GroupsInChannelModel, GroupsInTeamModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
|
||||
PostModel, PostMetadataModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
|
||||
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
|
||||
TermsOfServiceModel, UserModel,
|
||||
} from '@database/models/server';
|
||||
import {serverSchema} from '@database/schema/server';
|
||||
import {queryActiveServer, queryServer} from '@queries/app/servers';
|
||||
@@ -50,36 +50,13 @@ class DatabaseManager {
|
||||
private readonly serverModels: Models;
|
||||
|
||||
constructor() {
|
||||
this.appModels = [Info, Global, Servers];
|
||||
this.appModels = [InfoModel, GlobalModel, ServersModel];
|
||||
this.serverModels = [
|
||||
Channel,
|
||||
ChannelInfo,
|
||||
ChannelMembership,
|
||||
CustomEmoji,
|
||||
Draft,
|
||||
File,
|
||||
Group,
|
||||
GroupMembership,
|
||||
GroupsInChannel,
|
||||
GroupsInTeam,
|
||||
MyChannel,
|
||||
MyChannelSettings,
|
||||
MyTeam,
|
||||
Post,
|
||||
PostMetadata,
|
||||
PostsInChannel,
|
||||
PostsInThread,
|
||||
PreferenceModel,
|
||||
Reaction,
|
||||
Role,
|
||||
SlashCommand,
|
||||
SystemModel,
|
||||
Team,
|
||||
TeamChannelHistory,
|
||||
TeamMembership,
|
||||
TeamSearchHistory,
|
||||
TermsOfService,
|
||||
User,
|
||||
ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
|
||||
GroupModel, GroupMembershipModel, GroupsInChannelModel, GroupsInTeamModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
|
||||
PostModel, PostMetadataModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
|
||||
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
|
||||
TermsOfServiceModel, UserModel,
|
||||
];
|
||||
this.databaseDirectory = '';
|
||||
}
|
||||
@@ -89,6 +66,14 @@ class DatabaseManager {
|
||||
for await (const serverUrl of serverUrls) {
|
||||
await this.initServerDatabase(serverUrl);
|
||||
}
|
||||
this.appDatabase?.operator.handleInfo({
|
||||
info: [{
|
||||
build_number: '123',
|
||||
created_at: Date.now(),
|
||||
version_number: '2.0.0',
|
||||
}],
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
};
|
||||
|
||||
private createAppDatabase = async (): Promise<AppDatabase|undefined> => {
|
||||
@@ -108,7 +93,7 @@ class DatabaseManager {
|
||||
|
||||
return this.appDatabase;
|
||||
} catch (e) {
|
||||
// TODO : report to sentry? Show something on the UI ?
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -141,7 +126,7 @@ class DatabaseManager {
|
||||
|
||||
return serverDatabase;
|
||||
} catch (e) {
|
||||
// TODO : report to sentry? Show something on the UI ?
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +145,7 @@ class DatabaseManager {
|
||||
|
||||
private addServerToAppDatabase = async ({databaseFilePath, displayName, serverUrl}: RegisterServerDatabaseArgs): Promise<void> => {
|
||||
try {
|
||||
const isServerPresent = await this.isServerPresent(serverUrl); // TODO: Use normalized serverUrl
|
||||
const isServerPresent = await this.isServerPresent(serverUrl);
|
||||
|
||||
if (this.appDatabase?.database && !isServerPresent) {
|
||||
const appDatabase = this.appDatabase.database;
|
||||
@@ -171,14 +156,14 @@ class DatabaseManager {
|
||||
server.displayName = displayName;
|
||||
server.mentionCount = 0;
|
||||
server.unreadCount = 0;
|
||||
server.url = serverUrl; // TODO: Use normalized serverUrl
|
||||
server.url = serverUrl;
|
||||
server.isSecured = urlParse(serverUrl).protocol === 'https';
|
||||
server.lastActiveAt = 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO : report to sentry? Show something on the UI ?
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,7 +204,7 @@ class DatabaseManager {
|
||||
await database.action(async () => {
|
||||
const servers = await database.collections.get(SERVERS).query(Q.where('url', serverUrl)).fetch();
|
||||
if (servers.length) {
|
||||
servers[0].update((server: Servers) => {
|
||||
servers[0].update((server: ServersModel) => {
|
||||
server.lastActiveAt = Date.now();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,15 +11,15 @@ import urlParse from 'url-parse';
|
||||
|
||||
import {MIGRATION_EVENTS, MM_TABLES} from '@constants/database';
|
||||
import AppDataOperator from '@database/operator/app_data_operator';
|
||||
import AppDatabaseMigrations from '@app/database/migration/app';
|
||||
import {Info, Global, Servers} from '@app/database/models/app';
|
||||
import {schema as appSchema} from '@app/database/schema/app';
|
||||
import AppDatabaseMigrations from '@database/migration/app';
|
||||
import {InfoModel, GlobalModel, ServersModel} from '@database/models/app';
|
||||
import {schema as appSchema} from '@database/schema/app';
|
||||
import ServerDatabaseMigrations from '@database/migration/server';
|
||||
import {Channel, ChannelInfo, ChannelMembership, CustomEmoji, Draft, File,
|
||||
Group, GroupMembership, GroupsInChannel, GroupsInTeam, MyChannel, MyChannelSettings, MyTeam,
|
||||
Post, PostMetadata, PostsInChannel, PostsInThread, PreferenceModel, Reaction, Role,
|
||||
SlashCommand, SystemModel, Team, TeamChannelHistory, TeamMembership, TeamSearchHistory,
|
||||
TermsOfService, User,
|
||||
import {ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
|
||||
GroupModel, GroupMembershipModel, GroupsInChannelModel, GroupsInTeamModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
|
||||
PostModel, PostMetadataModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
|
||||
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
|
||||
TermsOfServiceModel, UserModel,
|
||||
} from '@database/models/server';
|
||||
import {serverSchema} from '@database/schema/server';
|
||||
import {queryActiveServer, queryServer} from '@queries/app/servers';
|
||||
@@ -43,13 +43,13 @@ class DatabaseManager {
|
||||
private readonly serverModels: Models;
|
||||
|
||||
constructor() {
|
||||
this.appModels = [Info, Global, Servers];
|
||||
this.appModels = [InfoModel, GlobalModel, ServersModel];
|
||||
this.serverModels = [
|
||||
Channel, ChannelInfo, ChannelMembership, CustomEmoji, Draft, File,
|
||||
Group, GroupMembership, GroupsInChannel, GroupsInTeam, MyChannel, MyChannelSettings, MyTeam,
|
||||
Post, PostMetadata, PostsInChannel, PostsInThread, PreferenceModel, Reaction, Role,
|
||||
SlashCommand, SystemModel, Team, TeamChannelHistory, TeamMembership, TeamSearchHistory,
|
||||
TermsOfService, User,
|
||||
ChannelModel, ChannelInfoModel, ChannelMembershipModel, CustomEmojiModel, DraftModel, FileModel,
|
||||
GroupModel, GroupMembershipModel, GroupsInChannelModel, GroupsInTeamModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
|
||||
PostModel, PostMetadataModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
|
||||
SlashCommandModel, SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
|
||||
TermsOfServiceModel, UserModel,
|
||||
];
|
||||
|
||||
this.databaseDirectory = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupDatabase : FileSystem.documentDirectory;
|
||||
@@ -182,7 +182,7 @@ class DatabaseManager {
|
||||
*/
|
||||
private addServerToAppDatabase = async ({databaseFilePath, displayName, serverUrl}: RegisterServerDatabaseArgs): Promise<void> => {
|
||||
try {
|
||||
const isServerPresent = await this.isServerPresent(serverUrl); // TODO: Use normalized serverUrl
|
||||
const isServerPresent = await this.isServerPresent(serverUrl);
|
||||
|
||||
if (this.appDatabase?.database && !isServerPresent) {
|
||||
const appDatabase = this.appDatabase.database;
|
||||
@@ -193,7 +193,7 @@ class DatabaseManager {
|
||||
server.displayName = displayName;
|
||||
server.mentionCount = 0;
|
||||
server.unreadCount = 0;
|
||||
server.url = serverUrl; // TODO: Use normalized serverUrl
|
||||
server.url = serverUrl;
|
||||
server.isSecured = urlParse(serverUrl).protocol === 'https';
|
||||
server.lastActiveAt = 0;
|
||||
});
|
||||
@@ -260,7 +260,7 @@ class DatabaseManager {
|
||||
await database.action(async () => {
|
||||
const servers = await database.collections.get(SERVERS).query(Q.where('url', serverUrl)).fetch();
|
||||
if (servers.length) {
|
||||
servers[0].update((server: Servers) => {
|
||||
servers[0].update((server: ServersModel) => {
|
||||
server.lastActiveAt = Date.now();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ const {GLOBAL} = MM_TABLES.APP;
|
||||
* The Global model will act as a dictionary of name-value pairs. The value field can be a JSON object or any other
|
||||
* data type. It will hold information that applies to the whole app ( e.g. sidebar settings for tablets)
|
||||
*/
|
||||
export default class Global extends Model {
|
||||
export default class GlobalModel extends Model {
|
||||
/** table (name) : global */
|
||||
static table = GLOBAL;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export {default as Info} from './info';
|
||||
export {default as Global} from './global';
|
||||
export {default as Servers} from './servers';
|
||||
export {default as InfoModel} from './info';
|
||||
export {default as GlobalModel} from './global';
|
||||
export {default as ServersModel} from './servers';
|
||||
|
||||
@@ -12,7 +12,7 @@ const {INFO} = MM_TABLES.APP;
|
||||
* The App model will hold information - such as the version number, build number and creation date -
|
||||
* for the Mattermost mobile app.
|
||||
*/
|
||||
export default class Info extends Model {
|
||||
export default class InfoModel extends Model {
|
||||
/** table (name) : info */
|
||||
static table = INFO;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const {SERVERS} = MM_TABLES.APP;
|
||||
* The Server model will help us to identify the various servers a user will log in; in the context of
|
||||
* multi-server support system. The db_path field will hold the App-Groups file-path
|
||||
*/
|
||||
export default class Servers extends Model {
|
||||
export default class ServersModel extends Model {
|
||||
/** table (name) : servers */
|
||||
static table = SERVERS;
|
||||
|
||||
|
||||
@@ -6,16 +6,17 @@ import {children, field, immutableRelation, lazy} from '@nozbe/watermelondb/deco
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import ChannelInfo from '@typings/database/models/servers/channel_info';
|
||||
import ChannelMembership from '@typings/database/models/servers/channel_membership';
|
||||
import Draft from '@typings/database/models/servers/draft';
|
||||
import GroupsInChannel from '@typings/database/models/servers/groups_in_channel';
|
||||
import MyChannel from '@typings/database/models/servers/my_channel';
|
||||
import MyChannelSettings from '@typings/database/models/servers/my_channel_settings';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import PostsInChannel from '@typings/database/models/servers/posts_in_channel';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type PostsInChannelModel from '@typings/database/models/servers/posts_in_channel';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
@@ -34,7 +35,7 @@ const {
|
||||
/**
|
||||
* The Channel model represents a channel in the Mattermost app.
|
||||
*/
|
||||
export default class Channel extends Model {
|
||||
export default class ChannelModel extends Model {
|
||||
/** table (name) : Channel */
|
||||
static table = CHANNEL;
|
||||
|
||||
@@ -103,32 +104,32 @@ export default class Channel extends Model {
|
||||
@field('type') type!: string;
|
||||
|
||||
/** members : Users belonging to this channel */
|
||||
@children(CHANNEL_MEMBERSHIP) members!: ChannelMembership[];
|
||||
@children(CHANNEL_MEMBERSHIP) members!: ChannelMembershipModel[];
|
||||
|
||||
/** drafts : All drafts for this channel */
|
||||
@children(DRAFT) drafts!: Draft[];
|
||||
@children(DRAFT) drafts!: DraftModel[];
|
||||
|
||||
/** groupsInChannel : Every group contained in this channel */
|
||||
@children(GROUPS_IN_CHANNEL) groupsInChannel!: GroupsInChannel[];
|
||||
@children(GROUPS_IN_CHANNEL) groupsInChannel!: GroupsInChannelModel[];
|
||||
|
||||
/** posts : All posts made in that channel */
|
||||
@children(POST) posts!: Post[];
|
||||
@children(POST) posts!: PostModel[];
|
||||
|
||||
/** postsInChannel : a section of the posts for that channel bounded by a range */
|
||||
@children(POSTS_IN_CHANNEL) postsInChannel!: PostsInChannel[];
|
||||
@children(POSTS_IN_CHANNEL) postsInChannel!: PostsInChannelModel[];
|
||||
|
||||
/** team : The TEAM to which this CHANNEL belongs */
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
|
||||
/** creator : The USER who created this CHANNEL*/
|
||||
@immutableRelation(USER, 'creator_id') creator!: Relation<User>;
|
||||
@immutableRelation(USER, 'creator_id') creator!: Relation<UserModel>;
|
||||
|
||||
/** info : Query returning extra information about this channel from CHANNEL_INFO table */
|
||||
@lazy info = this.collections.get(CHANNEL_INFO).query(Q.on(CHANNEL, 'id', this.id)) as Query<ChannelInfo>;
|
||||
@lazy info = this.collections.get(CHANNEL_INFO).query(Q.on(CHANNEL, 'id', this.id)) as Query<ChannelInfoModel>;
|
||||
|
||||
/** membership : Query returning the membership data for the current user if it belongs to this channel */
|
||||
@lazy membership = this.collections.get(MY_CHANNEL).query(Q.on(CHANNEL, 'id', this.id)) as Query<MyChannel>;
|
||||
@lazy membership = this.collections.get(MY_CHANNEL).query(Q.on(CHANNEL, 'id', this.id)) as Query<MyChannelModel>;
|
||||
|
||||
/** settings: User specific settings/preferences for this channel */
|
||||
@lazy settings = this.collections.get(MY_CHANNEL_SETTINGS).query(Q.on(CHANNEL, 'id', this.id)) as Query<MyChannelSettings>;
|
||||
@lazy settings = this.collections.get(MY_CHANNEL_SETTINGS).query(Q.on(CHANNEL, 'id', this.id)) as Query<MyChannelSettingsModel>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
const {CHANNEL, CHANNEL_INFO} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -15,7 +16,7 @@ const {CHANNEL, CHANNEL_INFO} = MM_TABLES.SERVER;
|
||||
* In a Separation of Concerns approach, ChannelInfo will provide additional information about a channel but on a more
|
||||
* specific level.
|
||||
*/
|
||||
export default class ChannelInfo extends Model {
|
||||
export default class ChannelInfoModel extends Model {
|
||||
/** table (name) : ChannelInfo */
|
||||
static table = CHANNEL_INFO;
|
||||
|
||||
@@ -45,5 +46,5 @@ export default class ChannelInfo extends Model {
|
||||
@field('purpose') purpose!: string;
|
||||
|
||||
/** channel : The lazy query property to the record from CHANNEL table */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import {Q, Query, Relation} from '@nozbe/watermelondb';
|
||||
import {field, immutableRelation, lazy} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {CHANNEL, CHANNEL_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -15,7 +16,7 @@ const {CHANNEL, CHANNEL_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
* The ChannelMembership model represents the 'association table' where many channels have users and many users are on
|
||||
* channels ( N:N relationship between model Users and model Channel)
|
||||
*/
|
||||
export default class ChannelMembership extends Model {
|
||||
export default class ChannelMembershipModel extends Model {
|
||||
/** table (name) : ChannelMembership */
|
||||
static table = CHANNEL_MEMBERSHIP;
|
||||
|
||||
@@ -36,18 +37,18 @@ export default class ChannelMembership extends Model {
|
||||
@field('user_id') userId!: string;
|
||||
|
||||
/** memberChannel : The related channel this member belongs to */
|
||||
@immutableRelation(CHANNEL, 'channel_id') memberChannel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') memberChannel!: Relation<ChannelModel>;
|
||||
|
||||
/** memberUser : The related member belonging to the channel */
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<UserModel>;
|
||||
|
||||
/**
|
||||
* getAllChannelsForUser - Retrieves all the channels that the user is part of
|
||||
*/
|
||||
@lazy getAllChannelsForUser = this.collections.get(CHANNEL).query(Q.on(USER, 'id', this.userId)) as Query<Channel>;
|
||||
@lazy getAllChannelsForUser = this.collections.get(CHANNEL).query(Q.on(USER, 'id', this.userId)) as Query<ChannelModel>;
|
||||
|
||||
/**
|
||||
* getAllUsersInChannel - Retrieves all the users who are part of this channel
|
||||
*/
|
||||
@lazy getAllUsersInChannel = this.collections.get(USER).query(Q.on(CHANNEL, 'id', this.channelId)) as Query<User>;
|
||||
@lazy getAllUsersInChannel = this.collections.get(USER).query(Q.on(CHANNEL, 'id', this.channelId)) as Query<UserModel>;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {MM_TABLES} from '@constants/database';
|
||||
const {CUSTOM_EMOJI} = MM_TABLES.SERVER;
|
||||
|
||||
/** The CustomEmoji model describes all the custom emojis used in the Mattermost app */
|
||||
export default class CustomEmoji extends Model {
|
||||
export default class CustomEmojiModel extends Model {
|
||||
/** table (name) : CustomEmoji */
|
||||
static table = CUSTOM_EMOJI;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const {CHANNEL, DRAFT, POST} = MM_TABLES.SERVER;
|
||||
/**
|
||||
* The Draft model represents the draft state of messages in Direct/Group messages and in channels
|
||||
*/
|
||||
export default class Draft extends Model {
|
||||
export default class DraftModel extends Model {
|
||||
/** table (name) : Draft */
|
||||
static table = DRAFT;
|
||||
|
||||
|
||||
@@ -6,14 +6,15 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
const {FILE, POST} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The File model works in pair with the Post model. It hosts information about the files shared in a Post
|
||||
*/
|
||||
export default class File extends Model {
|
||||
export default class FileModel extends Model {
|
||||
/** table (name) : File */
|
||||
static table = FILE;
|
||||
|
||||
@@ -52,5 +53,5 @@ export default class File extends Model {
|
||||
@field('width') width!: number;
|
||||
|
||||
/** post : The related Post record for this file */
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<Post>;
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<PostModel>;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {children, field} from '@nozbe/watermelondb/decorators';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import GroupMembership from '@typings/database/models/servers/group_membership';
|
||||
import GroupsInChannel from '@typings/database/models/servers/groups_in_channel';
|
||||
import GroupsInTeam from '@typings/database/models/servers/groups_in_team';
|
||||
|
||||
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
|
||||
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
|
||||
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
|
||||
|
||||
const {GROUP, GROUPS_IN_CHANNEL, GROUPS_IN_TEAM, GROUP_MEMBERSHIP} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -16,7 +17,7 @@ const {GROUP, GROUPS_IN_CHANNEL, GROUPS_IN_TEAM, GROUP_MEMBERSHIP} = MM_TABLES.S
|
||||
* all users who are in the mobile team. If one needs to send that group a message, then s/he can mention the group's
|
||||
* name in the message. (e.g @mobile_team)
|
||||
*/
|
||||
export default class Group extends Model {
|
||||
export default class GroupModel extends Model {
|
||||
/** table (name) : Group */
|
||||
static table = GROUP;
|
||||
|
||||
@@ -40,11 +41,11 @@ export default class Group extends Model {
|
||||
@field('name') name!: string;
|
||||
|
||||
/** groupsInChannel : All the related children records from GroupsInChannel */
|
||||
@children(GROUPS_IN_CHANNEL) groupsInChannel!: GroupsInChannel[];
|
||||
@children(GROUPS_IN_CHANNEL) groupsInChannel!: GroupsInChannelModel[];
|
||||
|
||||
/** groupsInTeam : All the related children records from GroupsInTeam */
|
||||
@children(GROUPS_IN_TEAM) groupsInTeam!: GroupsInTeam[];
|
||||
@children(GROUPS_IN_TEAM) groupsInTeam!: GroupsInTeamModel[];
|
||||
|
||||
/** groupMemberships : All the related children records from GroupMembership */
|
||||
@children(GROUP_MEMBERSHIP) groupMemberships!: GroupMembership[];
|
||||
@children(GROUP_MEMBERSHIP) groupMemberships!: GroupMembershipModel[];
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ import {field, immutableRelation, lazy} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {GROUP, GROUP_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -15,7 +16,7 @@ const {GROUP, GROUP_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
* The GroupMembership model represents the 'association table' where many groups have users and many users are in
|
||||
* groups (relationship type N:N)
|
||||
*/
|
||||
export default class GroupMembership extends Model {
|
||||
export default class GroupMembershipModel extends Model {
|
||||
/** table (name) : GroupMembership */
|
||||
static table = GROUP_MEMBERSHIP;
|
||||
|
||||
@@ -36,18 +37,18 @@ export default class GroupMembership extends Model {
|
||||
@field('user_id') userId!: string;
|
||||
|
||||
/** memberGroup : The related group this user belongs to */
|
||||
@immutableRelation(GROUP, 'group_id') memberGroup!: Relation<Group>;
|
||||
@immutableRelation(GROUP, 'group_id') memberGroup!: Relation<GroupModel>;
|
||||
|
||||
/** memberUser : The related user in the group */
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<UserModel>;
|
||||
|
||||
/**
|
||||
* getAllGroupsForUser : Retrieves all the groups that the user is part of
|
||||
*/
|
||||
@lazy getAllGroupsForUser = this.collections.get(GROUP).query(Q.on(USER, 'id', this.userId)) as Query<Group>;
|
||||
@lazy getAllGroupsForUser = this.collections.get(GROUP).query(Q.on(USER, 'id', this.userId)) as Query<GroupModel>;
|
||||
|
||||
/**
|
||||
* getAllUsersInGroup : Retrieves all the users who are part of this group
|
||||
*/
|
||||
@lazy getAllUsersInGroup = this.collections.get(USER).query(Q.on(GROUP, 'id', this.groupId)) as Query<User>;
|
||||
@lazy getAllUsersInGroup = this.collections.get(USER).query(Q.on(GROUP, 'id', this.groupId)) as Query<UserModel>;
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
|
||||
const {GROUP, GROUPS_IN_CHANNEL, CHANNEL} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The GroupsInChannel links the Channel model with the Group model
|
||||
*/
|
||||
export default class GroupsInChannel extends Model {
|
||||
export default class GroupsInChannelModel extends Model {
|
||||
/** table (name) : GroupsInChannel */
|
||||
static table = GROUPS_IN_CHANNEL;
|
||||
|
||||
@@ -41,8 +42,8 @@ export default class GroupsInChannel extends Model {
|
||||
@field('timezone_count') timezoneCount!: number;
|
||||
|
||||
/** channel : The related record to the parent Channel model */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
|
||||
/** group : The related record to the parent Group model */
|
||||
@immutableRelation(GROUP, 'group_id') group!: Relation<Group>;
|
||||
@immutableRelation(GROUP, 'group_id') group!: Relation<GroupModel>;
|
||||
}
|
||||
|
||||
@@ -5,16 +5,17 @@ import {Relation} from '@nozbe/watermelondb';
|
||||
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
const {GROUP, GROUPS_IN_TEAM, TEAM} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The GroupsInTeam links the Team model with the Group model
|
||||
*/
|
||||
export default class GroupsInTeam extends Model {
|
||||
export default class GroupsInTeamModel extends Model {
|
||||
/** table (name) : GroupsInTeam */
|
||||
static table = GROUPS_IN_TEAM;
|
||||
|
||||
@@ -35,8 +36,8 @@ export default class GroupsInTeam extends Model {
|
||||
@field('team_id') teamId!: string;
|
||||
|
||||
/** team : The related record to the parent Team model */
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
|
||||
/** group : The related record to the parent Team model */
|
||||
@immutableRelation(GROUP, 'group_id') group!: Relation<Group>;
|
||||
@immutableRelation(GROUP, 'group_id') group!: Relation<GroupModel>;
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export {default as ChannelInfo} from './channel_info';
|
||||
export {default as ChannelMembership} from './channel_membership';
|
||||
export {default as Channel} from './channel';
|
||||
export {default as CustomEmoji} from './custom_emoji';
|
||||
export {default as Draft} from './draft';
|
||||
export {default as File} from './file';
|
||||
export {default as GroupMembership} from './group_membership';
|
||||
export {default as GroupsInChannel} from './groups_in_channel';
|
||||
export {default as GroupsInTeam} from './groups_in_team';
|
||||
export {default as Group} from './group';
|
||||
export {default as MyChannelSettings} from './my_channel_settings';
|
||||
export {default as MyChannel} from './my_channel';
|
||||
export {default as MyTeam} from './my_team';
|
||||
export {default as PostMetadata} from './post_metadata';
|
||||
export {default as PostsInChannel} from './posts_in_channel';
|
||||
export {default as PostsInThread} from './posts_in_thread';
|
||||
export {default as Post} from './post';
|
||||
export {default as ChannelInfoModel} from './channel_info';
|
||||
export {default as ChannelMembershipModel} from './channel_membership';
|
||||
export {default as ChannelModel} from './channel';
|
||||
export {default as CustomEmojiModel} from './custom_emoji';
|
||||
export {default as DraftModel} from './draft';
|
||||
export {default as FileModel} from './file';
|
||||
export {default as GroupMembershipModel} from './group_membership';
|
||||
export {default as GroupsInChannelModel} from './groups_in_channel';
|
||||
export {default as GroupsInTeamModel} from './groups_in_team';
|
||||
export {default as GroupModel} from './group';
|
||||
export {default as MyChannelSettingsModel} from './my_channel_settings';
|
||||
export {default as MyChannelModel} from './my_channel';
|
||||
export {default as MyTeamModel} from './my_team';
|
||||
export {default as PostMetadataModel} from './post_metadata';
|
||||
export {default as PostsInChannelModel} from './posts_in_channel';
|
||||
export {default as PostsInThreadModel} from './posts_in_thread';
|
||||
export {default as PostModel} from './post';
|
||||
export {default as PreferenceModel} from './preference';
|
||||
export {default as Reaction} from './reaction';
|
||||
export {default as Role} from './role';
|
||||
export {default as SlashCommand} from './slash_command';
|
||||
export {default as ReactionModel} from './reaction';
|
||||
export {default as RoleModel} from './role';
|
||||
export {default as SlashCommandModel} from './slash_command';
|
||||
export {default as SystemModel} from './system';
|
||||
export {default as TeamChannelHistory} from './team_channel_history';
|
||||
export {default as TeamMembership} from './team_membership';
|
||||
export {default as TeamSearchHistory} from './team_search_history';
|
||||
export {default as Team} from './team';
|
||||
export {default as TermsOfService} from './terms_of_service';
|
||||
export {default as User} from './user';
|
||||
export {default as TeamChannelHistoryModel} from './team_channel_history';
|
||||
export {default as TeamMembershipModel} from './team_membership';
|
||||
export {default as TeamSearchHistoryModel} from './team_search_history';
|
||||
export {default as TeamModel} from './team';
|
||||
export {default as TermsOfServiceModel} from './terms_of_service';
|
||||
export {default as UserModel} from './user';
|
||||
|
||||
@@ -5,15 +5,16 @@ import {Relation} from '@nozbe/watermelondb';
|
||||
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
const {CHANNEL, MY_CHANNEL} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* MyChannel is an extension of the Channel model but it lists only the Channels the app's user belongs to
|
||||
*/
|
||||
export default class MyChannel extends Model {
|
||||
export default class MyChannelModel extends Model {
|
||||
/** table (name) : MyChannel */
|
||||
static table = MY_CHANNEL;
|
||||
|
||||
@@ -43,5 +44,5 @@ export default class MyChannel extends Model {
|
||||
@field('roles') roles!: string;
|
||||
|
||||
/** channel : The relation pointing to the CHANNEL table */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {safeParseJSON} from '@utils/helpers';
|
||||
|
||||
import type Channel from '@typings/database/models/servers/channel';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
const {CHANNEL, MY_CHANNEL_SETTINGS} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -16,7 +16,7 @@ const {CHANNEL, MY_CHANNEL_SETTINGS} = MM_TABLES.SERVER;
|
||||
* The MyChannelSettings model represents the specific user's configuration to
|
||||
* the channel this user belongs to.
|
||||
*/
|
||||
export default class MyChannelSettings extends Model {
|
||||
export default class MyChannelSettingsModel extends Model {
|
||||
/** table (name) : MyChannelSettings */
|
||||
static table = MY_CHANNEL_SETTINGS;
|
||||
|
||||
@@ -31,8 +31,8 @@ export default class MyChannelSettings extends Model {
|
||||
@field('channel_id') channelId!: string;
|
||||
|
||||
/** notify_props : Configurations with regards to this channel */
|
||||
@json('notify_props', safeParseJSON) notifyProps!: NotifyProps;
|
||||
@json('notify_props', safeParseJSON) notifyProps!: ChannelNotifyProps;
|
||||
|
||||
/** channel : The relation pointing to the CHANNEL table */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
}
|
||||
|
||||
@@ -6,14 +6,15 @@ import {field, relation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
const {TEAM, MY_TEAM} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* MyTeam represents only the teams that the current user belongs to
|
||||
*/
|
||||
export default class MyTeam extends Model {
|
||||
export default class MyTeamModel extends Model {
|
||||
/** table (name) : MyTeam */
|
||||
static table = MY_TEAM;
|
||||
|
||||
@@ -37,5 +38,5 @@ export default class MyTeam extends Model {
|
||||
@field('team_id') teamId!: string;
|
||||
|
||||
/** team : The relation to the TEAM, that this user belongs to */
|
||||
@relation(MY_TEAM, 'team_id') team!: Relation<Team>;
|
||||
@relation(MY_TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
}
|
||||
|
||||
@@ -8,20 +8,20 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {safeParseJSON} from '@utils/helpers';
|
||||
|
||||
import type Channel from '@typings/database/models/servers/channel';
|
||||
import type Draft from '@typings/database/models/servers/draft';
|
||||
import type File from '@typings/database/models/servers/file';
|
||||
import type PostInThread from '@typings/database/models/servers/posts_in_thread';
|
||||
import type PostMetadata from '@typings/database/models/servers/post_metadata';
|
||||
import type Reaction from '@typings/database/models/servers/reaction';
|
||||
import type User from '@typings/database/models/servers/user';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
import type FileModel from '@typings/database/models/servers/file';
|
||||
import type PostInThreadModel from '@typings/database/models/servers/posts_in_thread';
|
||||
import type PostMetadataModel from '@typings/database/models/servers/post_metadata';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {CHANNEL, DRAFT, FILE, POST, POSTS_IN_THREAD, POST_METADATA, REACTION, USER} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The Post model is the building block of communication in the Mattermost app.
|
||||
*/
|
||||
export default class Post extends Model {
|
||||
export default class PostModel extends Model {
|
||||
/** table (name) : Post */
|
||||
static table = POST;
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class Post extends Model {
|
||||
/** A POST can have multiple POSTS_IN_THREAD. (relationship is 1:N)*/
|
||||
[POSTS_IN_THREAD]: {type: 'has_many', foreignKey: 'post_id'},
|
||||
|
||||
/** A POST can have multiple POST_METADATA. (relationship is 1:N)*/
|
||||
/** A POST can have POST_METADATA. (relationship is 1:1)*/
|
||||
[POST_METADATA]: {type: 'has_many', foreignKey: 'post_id'},
|
||||
|
||||
/** A POST can have multiple REACTION. (relationship is 1:N)*/
|
||||
@@ -93,23 +93,23 @@ export default class Post extends Model {
|
||||
@json('props', safeParseJSON) props!: object;
|
||||
|
||||
// A draft can be associated with this post for as long as this post is a parent post
|
||||
@lazy draft = this.collections.get(DRAFT).query(Q.on(POST, 'id', this.id)) as Query<Draft>;
|
||||
@lazy draft = this.collections.get(DRAFT).query(Q.on(POST, 'id', this.id)) as Query<DraftModel>;
|
||||
|
||||
/** postsInThread: The thread to which this post is associated */
|
||||
@lazy postsInThread = this.collections.get(POSTS_IN_THREAD).query(Q.on(POST, 'id', this.id)) as Query<PostInThread>;
|
||||
@lazy postsInThread = this.collections.get(POSTS_IN_THREAD).query(Q.on(POST, 'id', this.id)) as Query<PostInThreadModel>;
|
||||
|
||||
/** files: All the files associated with this Post */
|
||||
@children(FILE) files!: File[];
|
||||
@children(FILE) files!: FileModel[];
|
||||
|
||||
/** metadata: All the extra data associated with this Post */
|
||||
@children(POST_METADATA) metadata!: PostMetadata[];
|
||||
@children(POST_METADATA) metadata!: PostMetadataModel[];
|
||||
|
||||
/** reactions: All the reactions associated with this Post */
|
||||
@children(REACTION) reactions!: Reaction[];
|
||||
@children(REACTION) reactions!: ReactionModel[];
|
||||
|
||||
/** author: The author of this Post */
|
||||
@immutableRelation(USER, 'user_id') author!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') author!: Relation<UserModel>;
|
||||
|
||||
/** channel: The channel which is presenting this Post */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
}
|
||||
|
||||
@@ -8,15 +8,14 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {safeParseJSON} from '@utils/helpers';
|
||||
|
||||
import type {PostMetadataData, PostMetadataType} from '@typings/database/database';
|
||||
import type Post from '@typings/database/models/servers/post';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
const {POST, POST_METADATA} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* PostMetadata provides additional information on a POST
|
||||
*/
|
||||
export default class PostMetadata extends Model {
|
||||
export default class PostMetadataModel extends Model {
|
||||
/** table (name) : PostMetadata */
|
||||
static table = POST_METADATA;
|
||||
|
||||
@@ -30,12 +29,9 @@ export default class PostMetadata extends Model {
|
||||
/** post_id : The foreign key of the parent POST model */
|
||||
@field('post_id') postId!: string;
|
||||
|
||||
/** type : The type will work in tandem with the value present in the field 'data'. One 'type' for each kind of 'data' */
|
||||
@field('type') type!: PostMetadataType;
|
||||
|
||||
/** data : Different types of data ranging from embeds to images. */
|
||||
@json('data', safeParseJSON) data!: PostMetadataData;
|
||||
@json('data', safeParseJSON) data!: PostMetadata;
|
||||
|
||||
/** post: The record representing the POST parent. */
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<Post>;
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<PostModel>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
|
||||
const {CHANNEL, POSTS_IN_CHANNEL} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -14,7 +15,7 @@ const {CHANNEL, POSTS_IN_CHANNEL} = MM_TABLES.SERVER;
|
||||
* PostsInChannel model helps us to combine adjacent posts together without leaving
|
||||
* gaps in between for an efficient user reading experience of posts.
|
||||
*/
|
||||
export default class PostsInChannel extends Model {
|
||||
export default class PostsInChannelModel extends Model {
|
||||
/** table (name) : PostsInChannel */
|
||||
static table = POSTS_IN_CHANNEL;
|
||||
|
||||
@@ -35,5 +36,5 @@ export default class PostsInChannel extends Model {
|
||||
@field('latest') latest!: number;
|
||||
|
||||
/** channel : The parent record of the channel for those posts */
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<Channel>;
|
||||
@immutableRelation(CHANNEL, 'channel_id') channel!: Relation<ChannelModel>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
const {POST, POSTS_IN_THREAD} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -14,7 +15,7 @@ const {POST, POSTS_IN_THREAD} = MM_TABLES.SERVER;
|
||||
* PostsInThread model helps us to combine adjacent threads together without leaving
|
||||
* gaps in between for an efficient user reading experience for threads.
|
||||
*/
|
||||
export default class PostsInThread extends Model {
|
||||
export default class PostsInThreadModel extends Model {
|
||||
/** table (name) : PostsInThread */
|
||||
static table = POSTS_IN_THREAD;
|
||||
|
||||
@@ -35,5 +36,5 @@ export default class PostsInThread extends Model {
|
||||
@field('post_id') postId!: string;
|
||||
|
||||
/** post : The related record to the parent Post model */
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<Post>;
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<PostModel>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {PREFERENCE, USER} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -14,7 +15,7 @@ const {PREFERENCE, USER} = MM_TABLES.SERVER;
|
||||
* The Preference model hold information about the user's preference in the app.
|
||||
* This includes settings about the account, the themes, etc.
|
||||
*/
|
||||
export default class Preference extends Model {
|
||||
export default class PreferenceModel extends Model {
|
||||
/** table (name) : Preference */
|
||||
static table = PREFERENCE;
|
||||
|
||||
@@ -38,5 +39,5 @@ export default class Preference extends Model {
|
||||
@field('value') value!: string;
|
||||
|
||||
/** user : The related record to the parent User model */
|
||||
@immutableRelation(USER, 'user_id') user!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') user!: Relation<UserModel>;
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {POST, REACTION, USER} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The Reaction Model is used to present the reactions a user had on a particular post
|
||||
*/
|
||||
export default class Reaction extends Model {
|
||||
export default class ReactionModel extends Model {
|
||||
/** table (name) : Reaction */
|
||||
static table = REACTION;
|
||||
|
||||
@@ -41,8 +42,8 @@ export default class Reaction extends Model {
|
||||
@field('user_id') userId!: string;
|
||||
|
||||
/** user : The related record to the User model */
|
||||
@immutableRelation(USER, 'user_id') user!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') user!: Relation<UserModel>;
|
||||
|
||||
/** post : The related record to the Post model */
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<Post>;
|
||||
@immutableRelation(POST, 'post_id') post!: Relation<PostModel>;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {safeParseJSON} from '@utils/helpers';
|
||||
const {ROLE} = MM_TABLES.SERVER;
|
||||
|
||||
/** The Role model will describe the set of permissions for each role */
|
||||
export default class Role extends Model {
|
||||
export default class RoleModel extends Model {
|
||||
/** table (name) : Role */
|
||||
static table = ROLE;
|
||||
|
||||
|
||||
@@ -6,14 +6,15 @@ import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
const {SLASH_COMMAND, TEAM} = MM_TABLES.SERVER;
|
||||
|
||||
/**
|
||||
* The SlashCommand model describes the commands of the various commands available in each team.
|
||||
*/
|
||||
export default class SlashCommand extends Model {
|
||||
export default class SlashCommandModel extends Model {
|
||||
/** table (name) : SlashCommand */
|
||||
static table = SLASH_COMMAND;
|
||||
|
||||
@@ -52,5 +53,5 @@ export default class SlashCommand extends Model {
|
||||
@field('update_at') updateAt!: number;
|
||||
|
||||
/** team : The related parent TEAM record */
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ const {SYSTEM} = MM_TABLES.SERVER;
|
||||
* will mostly hold configuration information about the client, the licences and some
|
||||
* custom data (e.g. recent emoji used)
|
||||
*/
|
||||
export default class System extends Model {
|
||||
export default class SystemModel extends Model {
|
||||
/** table (name) : System */
|
||||
static table = SYSTEM;
|
||||
|
||||
|
||||
@@ -6,13 +6,14 @@ import {children, field, lazy} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import GroupsInTeam from '@typings/database/models/servers/groups_in_team';
|
||||
import MyTeam from '@typings/database/models/servers/my_team';
|
||||
import SlashCommand from '@typings/database/models/servers/slash_command';
|
||||
import TeamChannelHistory from '@typings/database/models/servers/team_channel_history';
|
||||
import TeamMembership from '@typings/database/models/servers/team_membership';
|
||||
import TeamSearchHistory from '@typings/database/models/servers/team_search_history';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
|
||||
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
@@ -28,7 +29,7 @@ const {
|
||||
/**
|
||||
* A Team houses and enables communication to happen across channels and users.
|
||||
*/
|
||||
export default class Team extends Model {
|
||||
export default class TeamModel extends Model {
|
||||
/** table (name) : Team */
|
||||
static table = TEAM;
|
||||
|
||||
@@ -85,23 +86,23 @@ export default class Team extends Model {
|
||||
@field('allowed_domains') allowedDomains!: string;
|
||||
|
||||
/** channels : All the channels associated with this team */
|
||||
@children(CHANNEL) channels!: Channel[];
|
||||
@children(CHANNEL) channels!: ChannelModel[];
|
||||
|
||||
/** groupsInTeam : All the groups associated with this team */
|
||||
@children(GROUPS_IN_TEAM) groupsInTeam!: GroupsInTeam[];
|
||||
@children(GROUPS_IN_TEAM) groupsInTeam!: GroupsInTeamModel[];
|
||||
|
||||
/** myTeam : Retrieves additional information about the team that this user is possibly part of. This query might yield no result if the user isn't part of a team. */
|
||||
@lazy myTeam = this.collections.get(MY_TEAM).query(Q.on(TEAM, 'id', this.id)) as Query<MyTeam>;
|
||||
@lazy myTeam = this.collections.get(MY_TEAM).query(Q.on(TEAM, 'id', this.id)) as Query<MyTeamModel>;
|
||||
|
||||
/** slashCommands : All the slash commands associated with this team */
|
||||
@children(SLASH_COMMAND) slashCommands!: SlashCommand[];
|
||||
@children(SLASH_COMMAND) slashCommands!: SlashCommandModel[];
|
||||
|
||||
/** teamChannelHistory : A history of the channels in this team that has been visited, ordered by the most recent and capped to the last 5 */
|
||||
@lazy teamChannelHistory = this.collections.get(TEAM_CHANNEL_HISTORY).query(Q.on(TEAM, 'id', this.id)) as Query<TeamChannelHistory>;
|
||||
@lazy teamChannelHistory = this.collections.get(TEAM_CHANNEL_HISTORY).query(Q.on(TEAM, 'id', this.id)) as Query<TeamChannelHistoryModel>;
|
||||
|
||||
/** members : All the users associated with this team */
|
||||
@children(TEAM_MEMBERSHIP) members!: TeamMembership[];
|
||||
@children(TEAM_MEMBERSHIP) members!: TeamMembershipModel[];
|
||||
|
||||
/** teamSearchHistories : All the searches performed on this team */
|
||||
@children(TEAM_SEARCH_HISTORY) teamSearchHistories!: TeamSearchHistory[];
|
||||
@children(TEAM_SEARCH_HISTORY) teamSearchHistories!: TeamSearchHistoryModel[];
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {safeParseJSON} from '@utils/helpers';
|
||||
|
||||
import type Team from '@typings/database/models/servers/team';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
const {TEAM, TEAM_CHANNEL_HISTORY} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -16,7 +16,7 @@ const {TEAM, TEAM_CHANNEL_HISTORY} = MM_TABLES.SERVER;
|
||||
* The TeamChannelHistory model helps keeping track of the last channel visited
|
||||
* by the user.
|
||||
*/
|
||||
export default class TeamChannelHistory extends Model {
|
||||
export default class TeamChannelHistoryModel extends Model {
|
||||
/** table (name) : TeamChannelHistory */
|
||||
static table = TEAM_CHANNEL_HISTORY;
|
||||
|
||||
@@ -34,5 +34,5 @@ export default class TeamChannelHistory extends Model {
|
||||
@json('channel_ids', safeParseJSON) channelIds!: string[];
|
||||
|
||||
/** team : The related record from the parent Team model */
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ import {field, immutableRelation, lazy} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {TEAM, TEAM_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -15,7 +16,7 @@ const {TEAM, TEAM_MEMBERSHIP, USER} = MM_TABLES.SERVER;
|
||||
* The TeamMembership model represents the 'association table' where many teams have users and many users are in
|
||||
* teams (relationship type N:N)
|
||||
*/
|
||||
export default class TeamMembership extends Model {
|
||||
export default class TeamMembershipModel extends Model {
|
||||
/** table (name) : TeamMembership */
|
||||
static table = TEAM_MEMBERSHIP;
|
||||
|
||||
@@ -36,18 +37,18 @@ export default class TeamMembership extends Model {
|
||||
@field('user_id') userId!: string;
|
||||
|
||||
/** memberUser: The related user in the team */
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<User>;
|
||||
@immutableRelation(USER, 'user_id') memberUser!: Relation<UserModel>;
|
||||
|
||||
/** memberTeam : The related team of users */
|
||||
@immutableRelation(TEAM, 'team_id') memberTeam!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') memberTeam!: Relation<TeamModel>;
|
||||
|
||||
/**
|
||||
* getAllTeamsForUser - Retrieves all the teams that the user is part of
|
||||
*/
|
||||
@lazy getAllTeamsForUser = this.collections.get(TEAM).query(Q.on(USER, 'id', this.userId)) as Query<Team>;
|
||||
@lazy getAllTeamsForUser = this.collections.get(TEAM).query(Q.on(USER, 'id', this.userId)) as Query<TeamModel>;
|
||||
|
||||
/**
|
||||
* getAllUsersInTeam - Retrieves all the users who are part of this team
|
||||
*/
|
||||
@lazy getAllUsersInTeam = this.collections.get(USER).query(Q.on(TEAM, 'id', this.teamId)) as Query<User>;
|
||||
@lazy getAllUsersInTeam = this.collections.get(USER).query(Q.on(TEAM, 'id', this.teamId)) as Query<UserModel>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {field, immutableRelation, text} from '@nozbe/watermelondb/decorators';
|
||||
import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
const {TEAM, TEAM_SEARCH_HISTORY} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -14,7 +15,7 @@ const {TEAM, TEAM_SEARCH_HISTORY} = MM_TABLES.SERVER;
|
||||
* The TeamSearchHistory model holds the term searched within a team. The searches are performed
|
||||
* at team level in the app.
|
||||
*/
|
||||
export default class TeamSearchHistory extends Model {
|
||||
export default class TeamSearchHistoryModel extends Model {
|
||||
/** table (name) : TeamSearchHistory */
|
||||
static table = TEAM_SEARCH_HISTORY;
|
||||
|
||||
@@ -38,5 +39,5 @@ export default class TeamSearchHistory extends Model {
|
||||
@text('term') term!: string;
|
||||
|
||||
/** team : The related record to the parent team model */
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<Team>;
|
||||
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const {TERMS_OF_SERVICE} = MM_TABLES.SERVER;
|
||||
/**
|
||||
* The model for Terms of Service
|
||||
*/
|
||||
export default class TermsOfService extends Model {
|
||||
export default class TermsOfServiceModel extends Model {
|
||||
/** table (name) : TermsOfService */
|
||||
static table = TERMS_OF_SERVICE;
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {safeParseJSON} from '@utils/helpers';
|
||||
|
||||
import type Channel from '@typings/database/models/servers/channel';
|
||||
import type ChannelMembership from '@typings/database/models/servers/channel_membership';
|
||||
import type GroupMembership from '@typings/database/models/servers/group_membership';
|
||||
import type Post from '@typings/database/models/servers/post';
|
||||
import type Preference from '@typings/database/models/servers/preference';
|
||||
import type Reaction from '@typings/database/models/servers/reaction';
|
||||
import type TeamMembership from '@typings/database/models/servers/team_membership';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
@@ -30,7 +30,7 @@ const {
|
||||
* The User model represents the 'USER' table and its relationship to other
|
||||
* shareholders in the app.
|
||||
*/
|
||||
export default class User extends Model {
|
||||
export default class UserModel extends Model {
|
||||
/** table (name) : User */
|
||||
static table = USER;
|
||||
|
||||
@@ -105,34 +105,34 @@ export default class User extends Model {
|
||||
@field('username') username!: string;
|
||||
|
||||
/** notify_props : Notification preferences/configurations */
|
||||
@json('notify_props', safeParseJSON) notifyProps!: NotifyProps;
|
||||
@json('notify_props', safeParseJSON) notifyProps!: UserNotifyProps | null;
|
||||
|
||||
/** props : Custom objects ( e.g. custom status) can be stored in there. Its type definition is known as
|
||||
* 'excess property check' in Typescript land. We keep using it till we build up the final shape of this object.
|
||||
*/
|
||||
@json('props', safeParseJSON) props!: UserProps;
|
||||
@json('props', safeParseJSON) props!: UserProps | null;
|
||||
|
||||
/** timezone : The timezone for this user */
|
||||
@json('timezone', safeParseJSON) timezone!: Timezone;
|
||||
@json('timezone', safeParseJSON) timezone!: UserTimezone | null;
|
||||
|
||||
/** channelsCreated : All the channels that this user created */
|
||||
@children(CHANNEL) channelsCreated!: Channel[];
|
||||
@children(CHANNEL) channelsCreated!: ChannelModel[];
|
||||
|
||||
/** channels : All the channels that this user is part of */
|
||||
@children(CHANNEL_MEMBERSHIP) channels!: ChannelMembership[];
|
||||
@children(CHANNEL_MEMBERSHIP) channels!: ChannelMembershipModel[];
|
||||
|
||||
/** groups : All the groups that this user is part of */
|
||||
@children(GROUP_MEMBERSHIP) groups!: GroupMembership[];
|
||||
@children(GROUP_MEMBERSHIP) groups!: GroupMembershipModel[];
|
||||
|
||||
/** posts : All the posts that this user has written*/
|
||||
@children(POST) posts!: Post[];
|
||||
@children(POST) posts!: PostModel[];
|
||||
|
||||
/** preferences : All user preferences */
|
||||
@children(PREFERENCE) preferences!: Preference[];
|
||||
@children(PREFERENCE) preferences!: PreferenceModel[];
|
||||
|
||||
/** reactions : All the reactions to posts that this user had */
|
||||
@children(REACTION) reactions!: Reaction[];
|
||||
@children(REACTION) reactions!: ReactionModel[];
|
||||
|
||||
/** teams : All the team that this user is part of */
|
||||
@children(TEAM_MEMBERSHIP) teams!: TeamMembership[];
|
||||
@children(TEAM_MEMBERSHIP) teams!: TeamMembershipModel[];
|
||||
}
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Info from '@typings/database/models/app/info';
|
||||
import {RawInfo, RawGlobal, RawServers} from '@typings/database/database';
|
||||
import Global from '@typings/database/models/app/global';
|
||||
import Servers from '@typings/database/models/app/servers';
|
||||
import type InfoModel from '@typings/database/models/app/info';
|
||||
import type GlobalModel from '@typings/database/models/app/global';
|
||||
|
||||
export const isRecordInfoEqualToRaw = (record: Info, raw: RawInfo) => {
|
||||
export const isRecordInfoEqualToRaw = (record: InfoModel, raw: AppInfo) => {
|
||||
return (raw.build_number === record.buildNumber && raw.version_number === record.versionNumber);
|
||||
};
|
||||
|
||||
export const isRecordGlobalEqualToRaw = (record: Global, raw: RawGlobal) => {
|
||||
export const isRecordGlobalEqualToRaw = (record: GlobalModel, raw: IdValue) => {
|
||||
return raw.id === record.id && raw.value === record.value;
|
||||
};
|
||||
|
||||
export const isRecordServerEqualToRaw = (record: Servers, raw: RawServers) => {
|
||||
return raw.url === record.url && raw.db_path === record.dbPath;
|
||||
};
|
||||
|
||||
@@ -5,14 +5,11 @@ import DatabaseManager from '@database/manager';
|
||||
import {
|
||||
isRecordInfoEqualToRaw,
|
||||
isRecordGlobalEqualToRaw,
|
||||
isRecordServerEqualToRaw,
|
||||
} from '@database/operator/app_data_operator/comparator';
|
||||
import {
|
||||
transformInfoRecord,
|
||||
transformGlobalRecord,
|
||||
transformServersRecord,
|
||||
} from '@database/operator/app_data_operator/transformers';
|
||||
import {RawGlobal, RawServers} from '@typings/database/database';
|
||||
|
||||
describe('** APP DATA OPERATOR **', () => {
|
||||
beforeAll(async () => {
|
||||
@@ -72,7 +69,7 @@ describe('** APP DATA OPERATOR **', () => {
|
||||
expect(appOperator).toBeTruthy();
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(appOperator as any, 'handleRecords');
|
||||
const global: RawGlobal[] = [{id: 'global-1-name', value: 'global-1-value'}];
|
||||
const global: IdValue[] = [{id: 'global-1-name', value: 'global-1-value'}];
|
||||
|
||||
await appOperator?.handleGlobal({
|
||||
global,
|
||||
@@ -88,49 +85,4 @@ describe('** APP DATA OPERATOR **', () => {
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('=> HandleServers: should write to SERVERS table', async () => {
|
||||
const appDatabase = DatabaseManager.appDatabase?.database;
|
||||
const appOperator = DatabaseManager.appDatabase?.operator;
|
||||
expect(appDatabase).toBeTruthy();
|
||||
expect(appOperator).toBeTruthy();
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(appOperator as any, 'handleRecords');
|
||||
|
||||
const servers: RawServers[] = [
|
||||
{
|
||||
db_path: 'server.db',
|
||||
display_name: 'community',
|
||||
mention_count: 0,
|
||||
unread_count: 0,
|
||||
url: 'https://community.mattermost.com',
|
||||
isSecured: true,
|
||||
lastActiveAt: 1623926359,
|
||||
},
|
||||
];
|
||||
|
||||
await appOperator?.handleServers({
|
||||
servers,
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
|
||||
expect(spyOnHandleRecords).toHaveBeenCalledWith({
|
||||
fieldName: 'url',
|
||||
transformer: transformServersRecord,
|
||||
findMatchingRecordBy: isRecordServerEqualToRaw,
|
||||
createOrUpdateRawValues: [
|
||||
{
|
||||
db_path: 'server.db',
|
||||
display_name: 'community',
|
||||
mention_count: 0,
|
||||
unread_count: 0,
|
||||
url: 'https://community.mattermost.com',
|
||||
isSecured: true,
|
||||
lastActiveAt: 1623926359,
|
||||
},
|
||||
],
|
||||
tableName: 'Servers',
|
||||
prepareRecordsOnly: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,35 +3,24 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import DataOperatorException from '@database/exceptions/data_operator_exception';
|
||||
import {
|
||||
isRecordInfoEqualToRaw,
|
||||
isRecordGlobalEqualToRaw,
|
||||
isRecordServerEqualToRaw,
|
||||
} from '@database/operator/app_data_operator/comparator';
|
||||
import {
|
||||
transformInfoRecord,
|
||||
transformGlobalRecord,
|
||||
transformServersRecord,
|
||||
} from '@database/operator/app_data_operator/transformers';
|
||||
import {isRecordInfoEqualToRaw, isRecordGlobalEqualToRaw} from '@database/operator/app_data_operator/comparator';
|
||||
import {transformInfoRecord, transformGlobalRecord} from '@database/operator/app_data_operator/transformers';
|
||||
import BaseDataOperator from '@database/operator/base_data_operator';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {
|
||||
HandleInfoArgs,
|
||||
HandleGlobalArgs,
|
||||
HandleServersArgs,
|
||||
} from '@typings/database/database';
|
||||
|
||||
const {APP: {INFO, GLOBAL, SERVERS}} = MM_TABLES;
|
||||
import type {HandleInfoArgs, HandleGlobalArgs} from '@typings/database/database';
|
||||
|
||||
const {APP: {INFO, GLOBAL}} = MM_TABLES;
|
||||
|
||||
export default class AppDataOperator extends BaseDataOperator {
|
||||
handleInfo = async ({info, prepareRecordsOnly = true}: HandleInfoArgs) => {
|
||||
handleInfo = ({info, prepareRecordsOnly = true}: HandleInfoArgs) => {
|
||||
if (!info.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleInfo',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'version_number',
|
||||
findMatchingRecordBy: isRecordInfoEqualToRaw,
|
||||
transformer: transformInfoRecord,
|
||||
@@ -39,8 +28,6 @@ export default class AppDataOperator extends BaseDataOperator {
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: info, key: 'version_number'}),
|
||||
tableName: INFO,
|
||||
});
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
handleGlobal = async ({global, prepareRecordsOnly = true}: HandleGlobalArgs) => {
|
||||
@@ -50,7 +37,7 @@ export default class AppDataOperator extends BaseDataOperator {
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordGlobalEqualToRaw,
|
||||
transformer: transformGlobalRecord,
|
||||
@@ -58,26 +45,5 @@ export default class AppDataOperator extends BaseDataOperator {
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: global, key: 'id'}),
|
||||
tableName: GLOBAL,
|
||||
});
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
handleServers = async ({servers, prepareRecordsOnly = true}: HandleServersArgs) => {
|
||||
if (!servers.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleServers',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
fieldName: 'url',
|
||||
findMatchingRecordBy: isRecordServerEqualToRaw,
|
||||
transformer: transformServersRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: servers, key: 'display_name'}),
|
||||
tableName: SERVERS,
|
||||
});
|
||||
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers';
|
||||
import Info from '@typings/database/models/app/info';
|
||||
import {TransformerArgs, RawInfo, RawGlobal, RawServers} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import Global from '@typings/database/models/app/global';
|
||||
import Servers from '@typings/database/models/app/servers';
|
||||
|
||||
const {INFO, GLOBAL, SERVERS} = MM_TABLES.APP;
|
||||
import type {Model} from '@nozbe/watermelondb';
|
||||
|
||||
import type InfoModel from '@typings/database/models/app/info';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import type GlobalModel from '@typings/database/models/app/global';
|
||||
|
||||
const {INFO, GLOBAL} = MM_TABLES.APP;
|
||||
|
||||
/**
|
||||
* transformInfoRecord: Prepares a record of the APP database 'Info' table for update or create actions.
|
||||
@@ -18,12 +20,12 @@ const {INFO, GLOBAL, SERVERS} = MM_TABLES.APP;
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
*/
|
||||
export const transformInfoRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawInfo;
|
||||
const record = value.record as Info;
|
||||
export const transformInfoRecord = ({action, database, value}: TransformerArgs): Promise<Model> => {
|
||||
const raw = value.raw as AppInfo;
|
||||
const record = value.record as InfoModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (app: Info) => {
|
||||
const fieldsMapper = (app: InfoModel) => {
|
||||
app._raw.id = isCreateAction ? app.id : record.id;
|
||||
app.buildNumber = raw?.build_number;
|
||||
app.createdAt = raw?.created_at;
|
||||
@@ -46,10 +48,10 @@ export const transformInfoRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
*/
|
||||
export const transformGlobalRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawGlobal;
|
||||
export const transformGlobalRecord = ({action, database, value}: TransformerArgs): Promise<Model> => {
|
||||
const raw = value.raw as IdValue;
|
||||
|
||||
const fieldsMapper = (global: Global) => {
|
||||
const fieldsMapper = (global: GlobalModel) => {
|
||||
global._raw.id = raw?.id;
|
||||
global.value = raw?.value;
|
||||
};
|
||||
@@ -63,34 +65,3 @@ export const transformGlobalRecord = ({action, database, value}: TransformerArgs
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* transformServersRecord: Prepares a record of the APP database 'Servers' table for update or create actions.
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
*/
|
||||
export const transformServersRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawServers;
|
||||
const record = value.record as Servers;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (servers: Servers) => {
|
||||
servers._raw.id = isCreateAction ? servers.id : record.id;
|
||||
servers.dbPath = raw?.db_path;
|
||||
servers.displayName = raw?.display_name;
|
||||
servers.mentionCount = raw?.mention_count;
|
||||
servers.unreadCount = raw?.unread_count;
|
||||
servers.url = raw?.url;
|
||||
servers.isSecured = raw?.isSecured;
|
||||
servers.lastActiveAt = raw?.lastActiveAt;
|
||||
};
|
||||
|
||||
return prepareBaseRecord({
|
||||
action,
|
||||
database,
|
||||
tableName: SERVERS,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import DatabaseManager from '@database/manager';
|
||||
import {
|
||||
transformInfoRecord,
|
||||
transformGlobalRecord,
|
||||
transformServersRecord,
|
||||
} from '@database/operator/app_data_operator/transformers/index';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
|
||||
@@ -14,33 +13,6 @@ describe('** APP DATA TRANSFORMER **', () => {
|
||||
await DatabaseManager.init([]);
|
||||
});
|
||||
|
||||
it('=> transformServersRecord: should return an array of type Servers', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
const database = DatabaseManager.appDatabase?.database;
|
||||
expect(database).toBeTruthy();
|
||||
|
||||
const preparedRecords = await transformServersRecord({
|
||||
action: OperationType.CREATE,
|
||||
database: database!,
|
||||
value: {
|
||||
record: undefined,
|
||||
raw: {
|
||||
db_path: 'mm-server',
|
||||
display_name: 's-displayName',
|
||||
mention_count: 1,
|
||||
unread_count: 0,
|
||||
url: 'https://community.mattermost.com',
|
||||
isSecured: true,
|
||||
lastActiveAt: 1623926359,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Servers');
|
||||
});
|
||||
|
||||
it('=> transformInfoRecord: should return an array of type Info', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
@@ -61,7 +33,7 @@ describe('** APP DATA TRANSFORMER **', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Info');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('InfoModel');
|
||||
});
|
||||
|
||||
it('=> transformGlobalRecord: should return an array of type Global', async () => {
|
||||
@@ -80,6 +52,6 @@ describe('** APP DATA TRANSFORMER **', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Global');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GlobalModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,6 @@ import type {
|
||||
OperationArgs,
|
||||
ProcessRecordResults,
|
||||
ProcessRecordsArgs,
|
||||
RawValue,
|
||||
RecordPair,
|
||||
} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
@@ -123,7 +122,7 @@ export default class BaseDataOperator {
|
||||
* @throws {DataOperatorException}
|
||||
* @returns {Promise<Model[]>}
|
||||
*/
|
||||
prepareRecords = async ({tableName, createRaws, deleteRaws, updateRaws, transformer}: OperationArgs) => {
|
||||
prepareRecords = async ({tableName, createRaws, deleteRaws, updateRaws, transformer}: OperationArgs): Promise<Model[]> => {
|
||||
if (!this.database) {
|
||||
throw new DataOperatorException('Database not defined');
|
||||
}
|
||||
@@ -180,7 +179,7 @@ export default class BaseDataOperator {
|
||||
* @throws {DataOperatorException}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
batchRecords = async (models: Model[]) => {
|
||||
batchRecords = async (models: Model[]): Promise<void> => {
|
||||
try {
|
||||
if (models.length > 0) {
|
||||
await this.database.action(async () => {
|
||||
@@ -203,7 +202,7 @@ export default class BaseDataOperator {
|
||||
* @param {string} handleRecordsArgs.tableName
|
||||
* @returns {Promise<Model[]>}
|
||||
*/
|
||||
handleRecords = async ({findMatchingRecordBy, fieldName, transformer, createOrUpdateRawValues, deleteRawValues = [], tableName, prepareRecordsOnly = true}: HandleRecordsArgs) => {
|
||||
handleRecords = async ({findMatchingRecordBy, fieldName, transformer, createOrUpdateRawValues, deleteRawValues = [], tableName, prepareRecordsOnly = true}: HandleRecordsArgs): Promise<Model[]> => {
|
||||
if (!createOrUpdateRawValues.length) {
|
||||
throw new DataOperatorException(
|
||||
`An empty "rawValues" array has been passed to the handleRecords method for tableName ${tableName}`,
|
||||
|
||||
@@ -1,54 +1,29 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import ChannelInfo from '@typings/database/models/servers/channel_info';
|
||||
import ChannelMembership from '@typings/database/models/servers/channel_membership';
|
||||
import CustomEmoji from '@typings/database/models/servers/custom_emoji';
|
||||
import {
|
||||
RawChannel,
|
||||
RawChannelInfo,
|
||||
RawChannelMembership,
|
||||
RawCustomEmoji,
|
||||
RawDraft,
|
||||
RawGroup,
|
||||
RawGroupMembership,
|
||||
RawGroupsInChannel,
|
||||
RawGroupsInTeam,
|
||||
RawMyChannel,
|
||||
RawMyChannelSettings,
|
||||
RawMyTeam,
|
||||
RawPost,
|
||||
RawPreference,
|
||||
RawRole,
|
||||
RawSlashCommand,
|
||||
RawSystem,
|
||||
RawTeam,
|
||||
RawTeamChannelHistory,
|
||||
RawTeamMembership,
|
||||
RawTeamSearchHistory,
|
||||
RawTermsOfService,
|
||||
RawUser,
|
||||
} from '@typings/database/database';
|
||||
import Draft from '@typings/database/models/servers/draft';
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
import GroupMembership from '@typings/database/models/servers/group_membership';
|
||||
import GroupsInChannel from '@typings/database/models/servers/groups_in_channel';
|
||||
import GroupsInTeam from '@typings/database/models/servers/groups_in_team';
|
||||
import MyChannel from '@typings/database/models/servers/my_channel';
|
||||
import MyChannelSettings from '@typings/database/models/servers/my_channel_settings';
|
||||
import MyTeam from '@typings/database/models/servers/my_team';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import Preference from '@typings/database/models/servers/preference';
|
||||
import Role from '@typings/database/models/servers/role';
|
||||
import SlashCommand from '@typings/database/models/servers/slash_command';
|
||||
import System from '@typings/database/models/servers/system';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import TeamChannelHistory from '@typings/database/models/servers/team_channel_history';
|
||||
import TeamMembership from '@typings/database/models/servers/team_membership';
|
||||
import TeamSearchHistory from '@typings/database/models/servers/team_search_history';
|
||||
import TermsOfService from '@typings/database/models/servers/terms_of_service';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
|
||||
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
|
||||
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type RoleModel from '@typings/database/models/servers/role';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
|
||||
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
|
||||
import type TermsOfServiceModel from '@typings/database/models/servers/terms_of_service';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
/**
|
||||
* This file contains all the comparators that are used by the handlers to find out which records to truly update and
|
||||
@@ -57,31 +32,31 @@ import User from '@typings/database/models/servers/user';
|
||||
* 'record' and the 'raw'
|
||||
*/
|
||||
|
||||
export const isRecordRoleEqualToRaw = (record: Role, raw: RawRole) => {
|
||||
export const isRecordRoleEqualToRaw = (record: RoleModel, raw: Role) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordSystemEqualToRaw = (record: System, raw: RawSystem) => {
|
||||
export const isRecordSystemEqualToRaw = (record: SystemModel, raw: IdValue) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordTermsOfServiceEqualToRaw = (record: TermsOfService, raw: RawTermsOfService) => {
|
||||
export const isRecordTermsOfServiceEqualToRaw = (record: TermsOfServiceModel, raw: TermsOfService) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordDraftEqualToRaw = (record: Draft, raw: RawDraft) => {
|
||||
export const isRecordDraftEqualToRaw = (record: DraftModel, raw: Draft) => {
|
||||
return raw.channel_id === record.channelId;
|
||||
};
|
||||
|
||||
export const isRecordPostEqualToRaw = (record: Post, raw: RawPost) => {
|
||||
export const isRecordPostEqualToRaw = (record: PostModel, raw: Post) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordUserEqualToRaw = (record: User, raw: RawUser) => {
|
||||
export const isRecordUserEqualToRaw = (record: UserModel, raw: UserProfile) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordPreferenceEqualToRaw = (record: Preference, raw: RawPreference) => {
|
||||
export const isRecordPreferenceEqualToRaw = (record: PreferenceModel, raw: PreferenceType) => {
|
||||
return (
|
||||
raw.category === record.category &&
|
||||
raw.name === record.name &&
|
||||
@@ -89,66 +64,66 @@ export const isRecordPreferenceEqualToRaw = (record: Preference, raw: RawPrefere
|
||||
);
|
||||
};
|
||||
|
||||
export const isRecordTeamMembershipEqualToRaw = (record: TeamMembership, raw: RawTeamMembership) => {
|
||||
export const isRecordTeamMembershipEqualToRaw = (record: TeamMembershipModel, raw: TeamMembership) => {
|
||||
return raw.team_id === record.teamId && raw.user_id === record.userId;
|
||||
};
|
||||
|
||||
export const isRecordCustomEmojiEqualToRaw = (record: CustomEmoji, raw: RawCustomEmoji) => {
|
||||
export const isRecordCustomEmojiEqualToRaw = (record: CustomEmojiModel, raw: CustomEmoji) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordGroupMembershipEqualToRaw = (record: GroupMembership, raw: RawGroupMembership) => {
|
||||
export const isRecordGroupMembershipEqualToRaw = (record: GroupMembershipModel, raw: GroupMembership) => {
|
||||
return raw.user_id === record.userId && raw.group_id === record.groupId;
|
||||
};
|
||||
|
||||
export const isRecordChannelMembershipEqualToRaw = (record: ChannelMembership, raw: RawChannelMembership) => {
|
||||
export const isRecordChannelMembershipEqualToRaw = (record: ChannelMembershipModel, raw: ChannelMembership) => {
|
||||
return raw.user_id === record.userId && raw.channel_id === record.channelId;
|
||||
};
|
||||
|
||||
export const isRecordGroupEqualToRaw = (record: Group, raw: RawGroup) => {
|
||||
export const isRecordGroupEqualToRaw = (record: GroupModel, raw: Group) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordGroupsInTeamEqualToRaw = (record: GroupsInTeam, raw: RawGroupsInTeam) => {
|
||||
export const isRecordGroupsInTeamEqualToRaw = (record: GroupsInTeamModel, raw: GroupTeam) => {
|
||||
return raw.team_id === record.teamId && raw.group_id === record.groupId;
|
||||
};
|
||||
|
||||
export const isRecordGroupsInChannelEqualToRaw = (record: GroupsInChannel, raw: RawGroupsInChannel) => {
|
||||
export const isRecordGroupsInChannelEqualToRaw = (record: GroupsInChannelModel, raw: GroupChannel) => {
|
||||
return raw.channel_id === record.channelId && raw.group_id === record.groupId;
|
||||
};
|
||||
|
||||
export const isRecordTeamEqualToRaw = (record: Team, raw: RawTeam) => {
|
||||
export const isRecordTeamEqualToRaw = (record: TeamModel, raw: Team) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordTeamChannelHistoryEqualToRaw = (record: TeamChannelHistory, raw: RawTeamChannelHistory) => {
|
||||
export const isRecordTeamChannelHistoryEqualToRaw = (record: TeamChannelHistoryModel, raw: TeamChannelHistory) => {
|
||||
return raw.team_id === record.teamId;
|
||||
};
|
||||
|
||||
export const isRecordTeamSearchHistoryEqualToRaw = (record: TeamSearchHistory, raw: RawTeamSearchHistory) => {
|
||||
export const isRecordTeamSearchHistoryEqualToRaw = (record: TeamSearchHistoryModel, raw: TeamSearchHistory) => {
|
||||
return raw.team_id === record.teamId && raw.term === record.term;
|
||||
};
|
||||
|
||||
export const isRecordSlashCommandEqualToRaw = (record: SlashCommand, raw: RawSlashCommand) => {
|
||||
export const isRecordSlashCommandEqualToRaw = (record: SlashCommandModel, raw: SlashCommand) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordMyTeamEqualToRaw = (record: MyTeam, raw: RawMyTeam) => {
|
||||
export const isRecordMyTeamEqualToRaw = (record: MyTeamModel, raw: MyTeam) => {
|
||||
return raw.team_id === record.teamId;
|
||||
};
|
||||
|
||||
export const isRecordChannelEqualToRaw = (record: Channel, raw: RawChannel) => {
|
||||
export const isRecordChannelEqualToRaw = (record: ChannelModel, raw: Channel) => {
|
||||
return raw.id === record.id;
|
||||
};
|
||||
|
||||
export const isRecordMyChannelSettingsEqualToRaw = (record: MyChannelSettings, raw: RawMyChannelSettings) => {
|
||||
export const isRecordMyChannelSettingsEqualToRaw = (record: MyChannelSettingsModel, raw: ChannelMembership) => {
|
||||
return raw.channel_id === record.channelId;
|
||||
};
|
||||
|
||||
export const isRecordChannelInfoEqualToRaw = (record: ChannelInfo, raw: RawChannelInfo) => {
|
||||
export const isRecordChannelInfoEqualToRaw = (record: ChannelInfoModel, raw: ChannelInfo) => {
|
||||
return raw.channel_id === record.channelId;
|
||||
};
|
||||
|
||||
export const isRecordMyChannelEqualToRaw = (record: MyChannel, raw: RawMyChannel) => {
|
||||
export const isRecordMyChannelEqualToRaw = (record: MyChannelModel, raw: ChannelMembership) => {
|
||||
return raw.channel_id === record.channelId;
|
||||
};
|
||||
|
||||
@@ -17,8 +17,6 @@ import {
|
||||
|
||||
import ServerDataOperator from '..';
|
||||
|
||||
import type {RawChannel} from '@typings/database/database';
|
||||
|
||||
describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
let operator: ServerDataOperator;
|
||||
beforeAll(async () => {
|
||||
@@ -30,7 +28,7 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const channels: RawChannel[] = [
|
||||
const channels: Channel[] = [
|
||||
{
|
||||
create_at: 1600185541285,
|
||||
creator_id: '',
|
||||
@@ -42,14 +40,11 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
id: 'kjlw9j1ttnxwig7tnqgebg7dtipno',
|
||||
last_post_at: 1617311494451,
|
||||
name: 'gh781zkzkhh357b4bejephjz5u8daw__9ciscaqbrpd6d8s68k76xb9bte',
|
||||
policy_id: 'policy',
|
||||
props: null,
|
||||
purpose: '',
|
||||
scheme_id: null,
|
||||
shared: false,
|
||||
team_id: '',
|
||||
total_msg_count: 585,
|
||||
total_msg_count_root: 1,
|
||||
type: 'D',
|
||||
update_at: 1604401077256,
|
||||
},
|
||||
@@ -75,17 +70,21 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const settings = [
|
||||
const settings: ChannelMembership[] = [
|
||||
{
|
||||
user_id: 'me',
|
||||
channel_id: 'c',
|
||||
roles: '',
|
||||
msg_count: 0,
|
||||
mention_count: 0,
|
||||
last_viewed_at: 0,
|
||||
last_update_at: 0,
|
||||
notify_props: {
|
||||
desktop: 'all',
|
||||
desktop_sound: true,
|
||||
email: true,
|
||||
first_name: true,
|
||||
mention_keys: '',
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'mention',
|
||||
channel: true,
|
||||
ignore_channel_mentions: 'default',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -109,7 +108,7 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
it('=> HandleChannelInfo: should write to the CHANNEL_INFO table', async () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator as any, 'handleRecords');
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const channelInfos = [
|
||||
{
|
||||
channel_id: 'c',
|
||||
@@ -142,14 +141,23 @@ describe('*** Operator: Channel Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const myChannels = [
|
||||
const myChannels: ChannelMembership[] = [
|
||||
{
|
||||
user_id: 'me',
|
||||
channel_id: 'c',
|
||||
last_post_at: 1617311494451,
|
||||
last_viewed_at: 1617311494451,
|
||||
mentions_count: 3,
|
||||
message_count: 10,
|
||||
last_update_at: 1617311494451,
|
||||
mention_count: 3,
|
||||
msg_count: 10,
|
||||
roles: 'guest',
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
mark_unread: 'mention',
|
||||
push: 'mention',
|
||||
ignore_channel_mentions: 'default',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -16,16 +16,12 @@ import {
|
||||
transformMyChannelSettingsRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/channel';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import ChannelInfo from '@typings/database/models/servers/channel_info';
|
||||
import {
|
||||
HandleChannelArgs,
|
||||
HandleChannelInfoArgs,
|
||||
HandleMyChannelArgs,
|
||||
HandleMyChannelSettingsArgs,
|
||||
} from '@typings/database/database';
|
||||
import MyChannel from '@typings/database/models/servers/my_channel';
|
||||
import MyChannelSettings from '@typings/database/models/servers/my_channel_settings';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type {HandleChannelArgs, HandleChannelInfoArgs, HandleMyChannelArgs, HandleMyChannelSettingsArgs} from '@typings/database/database';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
@@ -35,10 +31,10 @@ const {
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface ChannelHandlerMix {
|
||||
handleChannel: ({channels, prepareRecordsOnly}: HandleChannelArgs) => Channel[] | boolean;
|
||||
handleMyChannelSettings: ({settings, prepareRecordsOnly}: HandleMyChannelSettingsArgs) => MyChannelSettings[] | boolean;
|
||||
handleChannelInfo: ({channelInfos, prepareRecordsOnly}: HandleChannelInfoArgs) => ChannelInfo[] | boolean;
|
||||
handleMyChannel: ({myChannels, prepareRecordsOnly}: HandleMyChannelArgs) => MyChannel[] | boolean;
|
||||
handleChannel: ({channels, prepareRecordsOnly}: HandleChannelArgs) => Promise<ChannelModel[]>;
|
||||
handleMyChannelSettings: ({settings, prepareRecordsOnly}: HandleMyChannelSettingsArgs) => Promise<MyChannelSettingsModel[]>;
|
||||
handleChannelInfo: ({channelInfos, prepareRecordsOnly}: HandleChannelInfoArgs) => Promise<ChannelInfoModel[]>;
|
||||
handleMyChannel: ({myChannels, prepareRecordsOnly}: HandleMyChannelArgs) => Promise<MyChannelModel[]>;
|
||||
}
|
||||
|
||||
const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
@@ -48,11 +44,9 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawChannel[]} channelsArgs.channels
|
||||
* @param {boolean} channelsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Channel[]}
|
||||
* @returns {Promise<ChannelModel[]>}
|
||||
*/
|
||||
handleChannel = async ({channels, prepareRecordsOnly = true}: HandleChannelArgs) => {
|
||||
let records: Channel[] = [];
|
||||
|
||||
handleChannel = ({channels, prepareRecordsOnly = true}: HandleChannelArgs): Promise<ChannelModel[]> => {
|
||||
if (!channels.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "channels" array has been passed to the handleChannel method',
|
||||
@@ -61,7 +55,7 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: channels, key: 'id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordChannelEqualToRaw,
|
||||
transformer: transformChannelRecord,
|
||||
@@ -69,8 +63,6 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: CHANNEL,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,11 +71,9 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawMyChannelSettings[]} settingsArgs.settings
|
||||
* @param {boolean} settingsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {MyChannelSettings[]}
|
||||
* @returns {Promise<MyChannelSettingsModel[]>}
|
||||
*/
|
||||
handleMyChannelSettings = async ({settings, prepareRecordsOnly = true}: HandleMyChannelSettingsArgs) => {
|
||||
let records: MyChannelSettings[] = [];
|
||||
|
||||
handleMyChannelSettings = ({settings, prepareRecordsOnly = true}: HandleMyChannelSettingsArgs): Promise<MyChannelSettingsModel[]> => {
|
||||
if (!settings.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "settings" array has been passed to the handleMyChannelSettings method',
|
||||
@@ -92,7 +82,7 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: settings, key: 'channel_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'channel_id',
|
||||
findMatchingRecordBy: isRecordMyChannelSettingsEqualToRaw,
|
||||
transformer: transformMyChannelSettingsRecord,
|
||||
@@ -100,8 +90,6 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: MY_CHANNEL_SETTINGS,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -110,11 +98,9 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawChannelInfo[]} channelInfosArgs.channelInfos
|
||||
* @param {boolean} channelInfosArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {ChannelInfo[]}
|
||||
* @returns {Promise<ChannelInfoModel[]>}
|
||||
*/
|
||||
handleChannelInfo = async ({channelInfos, prepareRecordsOnly = true}: HandleChannelInfoArgs) => {
|
||||
let records: ChannelInfo[] = [];
|
||||
|
||||
handleChannelInfo = ({channelInfos, prepareRecordsOnly = true}: HandleChannelInfoArgs): Promise<ChannelInfoModel[]> => {
|
||||
if (!channelInfos.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "channelInfos" array has been passed to the handleMyChannelSettings method',
|
||||
@@ -126,7 +112,7 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
key: 'channel_id',
|
||||
});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'channel_id',
|
||||
findMatchingRecordBy: isRecordChannelInfoEqualToRaw,
|
||||
transformer: transformChannelInfoRecord,
|
||||
@@ -134,8 +120,6 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: CHANNEL_INFO,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -144,11 +128,9 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawMyChannel[]} myChannelsArgs.myChannels
|
||||
* @param {boolean} myChannelsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {MyChannel[]}
|
||||
* @returns {Promise<MyChannelModel[]>}
|
||||
*/
|
||||
handleMyChannel = async ({myChannels, prepareRecordsOnly = true}: HandleMyChannelArgs) => {
|
||||
let records: MyChannel[] = [];
|
||||
|
||||
handleMyChannel = ({myChannels, prepareRecordsOnly = true}: HandleMyChannelArgs): Promise<MyChannelModel[]> => {
|
||||
if (!myChannels.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "myChannels" array has been passed to the handleMyChannel method',
|
||||
@@ -160,7 +142,7 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
key: 'channel_id',
|
||||
});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'channel_id',
|
||||
findMatchingRecordBy: isRecordMyChannelEqualToRaw,
|
||||
transformer: transformMyChannelRecord,
|
||||
@@ -168,8 +150,6 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: MY_CHANNEL,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -28,18 +28,20 @@ describe('*** Operator: Group Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const groups = [
|
||||
const groups: Group[] = [
|
||||
{
|
||||
id: 'id_groupdfjdlfkjdkfdsf',
|
||||
name: 'mobile_team',
|
||||
display_name: 'mobile team',
|
||||
description: '',
|
||||
source: '',
|
||||
remote_id: '',
|
||||
create_at: 0,
|
||||
update_at: 0,
|
||||
delete_at: 0,
|
||||
has_syncables: true,
|
||||
type: '',
|
||||
member_count: 1,
|
||||
allow_reference: false,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -16,16 +16,12 @@ import {
|
||||
transformGroupsInTeamRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/group';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {
|
||||
HandleGroupArgs,
|
||||
HandleGroupMembershipArgs,
|
||||
HandleGroupsInChannelArgs,
|
||||
HandleGroupsInTeamArgs,
|
||||
} from '@typings/database/database';
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
import GroupMembership from '@typings/database/models/servers/group_membership';
|
||||
import GroupsInChannel from '@typings/database/models/servers/groups_in_channel';
|
||||
import GroupsInTeam from '@typings/database/models/servers/groups_in_team';
|
||||
|
||||
import type {HandleGroupArgs, HandleGroupMembershipArgs, HandleGroupsInChannelArgs, HandleGroupsInTeamArgs} from '@typings/database/database';
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
|
||||
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
|
||||
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
|
||||
|
||||
const {
|
||||
GROUP,
|
||||
@@ -35,10 +31,10 @@ const {
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface GroupHandlerMix {
|
||||
handleGroupMembership: ({groupMemberships, prepareRecordsOnly}: HandleGroupMembershipArgs) => GroupMembership[] | boolean;
|
||||
handleGroup: ({groups, prepareRecordsOnly}: HandleGroupArgs) => Group[] | boolean;
|
||||
handleGroupsInTeam: ({groupsInTeams, prepareRecordsOnly}: HandleGroupsInTeamArgs) => GroupsInTeam[] | boolean;
|
||||
handleGroupsInChannel: ({groupsInChannels, prepareRecordsOnly}: HandleGroupsInChannelArgs) => GroupsInChannel[] | boolean;
|
||||
handleGroupMembership: ({groupMemberships, prepareRecordsOnly}: HandleGroupMembershipArgs) => Promise<GroupMembershipModel[]>;
|
||||
handleGroup: ({groups, prepareRecordsOnly}: HandleGroupArgs) => Promise<GroupModel[]>;
|
||||
handleGroupsInTeam: ({groupsInTeams, prepareRecordsOnly}: HandleGroupsInTeamArgs) => Promise<GroupsInTeamModel[]>;
|
||||
handleGroupsInChannel: ({groupsInChannels, prepareRecordsOnly}: HandleGroupsInChannelArgs) => Promise<GroupsInChannelModel[]>;
|
||||
}
|
||||
|
||||
const GroupHandler = (superclass: any) => class extends superclass {
|
||||
@@ -48,11 +44,9 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawGroupMembership[]} groupMembershipsArgs.groupMemberships
|
||||
* @param {boolean} groupMembershipsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {GroupMembership[]}
|
||||
* @returns {Promise<GroupMembershipModel[]>}
|
||||
*/
|
||||
handleGroupMembership = async ({groupMemberships, prepareRecordsOnly = true}: HandleGroupMembershipArgs) => {
|
||||
let records: GroupMembership[] = [];
|
||||
|
||||
handleGroupMembership = ({groupMemberships, prepareRecordsOnly = true}: HandleGroupMembershipArgs): Promise<GroupMembershipModel[]> => {
|
||||
if (!groupMemberships.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "groupMemberships" array has been passed to the handleGroupMembership method',
|
||||
@@ -61,7 +55,7 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupMemberships, key: 'group_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordGroupMembershipEqualToRaw,
|
||||
transformer: transformGroupMembershipRecord,
|
||||
@@ -69,8 +63,6 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: GROUP_MEMBERSHIP,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,11 +71,9 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawGroup[]} groupsArgs.groups
|
||||
* @param {boolean} groupsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Group[]}
|
||||
* @returns {Promise<GroupModel[]>}
|
||||
*/
|
||||
handleGroup = async ({groups, prepareRecordsOnly = true}: HandleGroupArgs) => {
|
||||
let records: Group[] = [];
|
||||
|
||||
handleGroup = ({groups, prepareRecordsOnly = true}: HandleGroupArgs): Promise<GroupModel[]> => {
|
||||
if (!groups.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "groups" array has been passed to the handleGroup method',
|
||||
@@ -92,7 +82,7 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: groups, key: 'name'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'name',
|
||||
findMatchingRecordBy: isRecordGroupEqualToRaw,
|
||||
transformer: transformGroupRecord,
|
||||
@@ -100,8 +90,6 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: GROUP,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -110,11 +98,9 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawGroupsInTeam[]} groupsInTeamsArgs.groupsInTeams
|
||||
* @param {boolean} groupsInTeamsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {GroupsInTeam[]}
|
||||
* @returns {Promise<GroupsInTeamModel[]>}
|
||||
*/
|
||||
handleGroupsInTeam = async ({groupsInTeams, prepareRecordsOnly = true}: HandleGroupsInTeamArgs) => {
|
||||
let records: GroupsInTeam[] = [];
|
||||
|
||||
handleGroupsInTeam = ({groupsInTeams, prepareRecordsOnly = true}: HandleGroupsInTeamArgs): Promise<GroupsInTeamModel[]> => {
|
||||
if (!groupsInTeams.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "groups" array has been passed to the handleGroupsInTeam method',
|
||||
@@ -123,7 +109,7 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupsInTeams, key: 'group_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'group_id',
|
||||
findMatchingRecordBy: isRecordGroupsInTeamEqualToRaw,
|
||||
transformer: transformGroupsInTeamRecord,
|
||||
@@ -131,8 +117,6 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: GROUPS_IN_TEAM,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -141,11 +125,9 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawGroupsInChannel[]} groupsInChannelsArgs.groupsInChannels
|
||||
* @param {boolean} groupsInChannelsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {GroupsInChannel[]}
|
||||
* @returns {Promise<GroupsInChannelModel[]>}
|
||||
*/
|
||||
handleGroupsInChannel = async ({groupsInChannels, prepareRecordsOnly = true}: HandleGroupsInChannelArgs) => {
|
||||
let records: GroupsInChannel[] = [];
|
||||
|
||||
handleGroupsInChannel = ({groupsInChannels, prepareRecordsOnly = true}: HandleGroupsInChannelArgs): Promise<GroupsInChannelModel[]> => {
|
||||
if (!groupsInChannels.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "groups" array has been passed to the handleGroupsInTeam method',
|
||||
@@ -154,7 +136,7 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupsInChannels, key: 'channel_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'group_id',
|
||||
findMatchingRecordBy: isRecordGroupsInChannelEqualToRaw,
|
||||
transformer: transformGroupsInChannelRecord,
|
||||
@@ -162,8 +144,6 @@ const GroupHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: GROUPS_IN_CHANNEL,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -15,9 +15,10 @@ import {
|
||||
transformSystemRecord,
|
||||
transformTermsOfServiceRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/general';
|
||||
import {RawRole, RawTermsOfService} from '@typings/database/database';
|
||||
|
||||
import ServerDataOperator from '..';
|
||||
import type {Model} from '@nozbe/watermelondb';
|
||||
|
||||
import type ServerDataOperator from '..';
|
||||
|
||||
describe('*** DataOperator: Base Handlers tests ***', () => {
|
||||
let operator: ServerDataOperator;
|
||||
@@ -31,7 +32,7 @@ describe('*** DataOperator: Base Handlers tests ***', () => {
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
|
||||
const roles: RawRole[] = [
|
||||
const roles: Role[] = [
|
||||
{
|
||||
id: 'custom-role-id-1',
|
||||
name: 'custom-role-1',
|
||||
@@ -58,7 +59,7 @@ describe('*** DataOperator: Base Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const emojis = [
|
||||
const emojis: CustomEmoji[] = [
|
||||
{
|
||||
id: 'i',
|
||||
create_at: 1580913641769,
|
||||
@@ -112,7 +113,7 @@ describe('*** DataOperator: Base Handlers tests ***', () => {
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
|
||||
const termOfService: RawTermsOfService[] = [
|
||||
const termOfService: TermsOfService[] = [
|
||||
{
|
||||
id: 'tos-1',
|
||||
accepted_at: 1,
|
||||
@@ -145,13 +146,20 @@ describe('*** DataOperator: Base Handlers tests ***', () => {
|
||||
expect(appDatabase).toBeTruthy();
|
||||
expect(appOperator).toBeTruthy();
|
||||
|
||||
const findMatchingRecordBy = (existing: Model, newRecord: any) => {
|
||||
return existing === newRecord;
|
||||
};
|
||||
|
||||
const transformer = async (model: Model) => model;
|
||||
|
||||
await expect(
|
||||
operator?.handleRecords({
|
||||
fieldName: 'invalidField',
|
||||
tableName: 'INVALID_TABLE_NAME',
|
||||
|
||||
// @ts-expect-error: Type does not match RawValue
|
||||
createOrUpdateRawValues: [{id: 'tos-1', accepted_at: 1}],
|
||||
findMatchingRecordBy,
|
||||
transformer,
|
||||
createOrUpdateRawValues: [{id: 'tos-1', value: '1'}],
|
||||
prepareRecordsOnly: false,
|
||||
}),
|
||||
).rejects.toThrow(DataOperatorException);
|
||||
});
|
||||
|
||||
@@ -17,85 +17,82 @@ import {
|
||||
transformTermsOfServiceRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/general';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {HandleCustomEmojiArgs, HandleRoleArgs, HandleSystemArgs, HandleTOSArgs, OperationArgs} from '@typings/database/database';
|
||||
|
||||
import type {HandleCustomEmojiArgs, HandleRoleArgs, HandleSystemArgs, HandleTOSArgs, OperationArgs} from '@typings/database/database';
|
||||
import type RoleModel from '@typings/database/models/servers/role';
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
import type TermsOfServiceModel from '@typings/database/models/servers/terms_of_service';
|
||||
|
||||
const {SERVER: {CUSTOM_EMOJI, ROLE, SYSTEM, TERMS_OF_SERVICE}} = MM_TABLES;
|
||||
|
||||
export default class ServerDataOperatorBase extends BaseDataOperator {
|
||||
handleRole = async ({roles, prepareRecordsOnly = true}: HandleRoleArgs) => {
|
||||
handleRole = ({roles, prepareRecordsOnly = true}: HandleRoleArgs) => {
|
||||
if (!roles.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleRole',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordRoleEqualToRaw,
|
||||
transformer: transformRoleRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: roles, key: 'id'}),
|
||||
tableName: ROLE,
|
||||
});
|
||||
|
||||
return records;
|
||||
}) as Promise<RoleModel[]>;
|
||||
}
|
||||
|
||||
handleCustomEmojis = async ({emojis, prepareRecordsOnly = true}: HandleCustomEmojiArgs) => {
|
||||
handleCustomEmojis = ({emojis, prepareRecordsOnly = true}: HandleCustomEmojiArgs) => {
|
||||
if (!emojis.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleCustomEmojis',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordCustomEmojiEqualToRaw,
|
||||
transformer: transformCustomEmojiRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: emojis, key: 'id'}),
|
||||
tableName: CUSTOM_EMOJI,
|
||||
});
|
||||
|
||||
return records;
|
||||
}) as Promise<CustomEmojiModel[]>;
|
||||
}
|
||||
|
||||
handleSystem = async ({systems, prepareRecordsOnly = true}: HandleSystemArgs) => {
|
||||
handleSystem = ({systems, prepareRecordsOnly = true}: HandleSystemArgs) => {
|
||||
if (!systems.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleSystem',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordSystemEqualToRaw,
|
||||
transformer: transformSystemRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: systems, key: 'id'}),
|
||||
tableName: SYSTEM,
|
||||
});
|
||||
|
||||
return records;
|
||||
}) as Promise<SystemModel[]>;
|
||||
}
|
||||
|
||||
handleTermOfService = async ({termOfService, prepareRecordsOnly = true}: HandleTOSArgs) => {
|
||||
handleTermOfService = ({termOfService, prepareRecordsOnly = true}: HandleTOSArgs) => {
|
||||
if (!termOfService.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "values" array has been passed to the handleTermOfService',
|
||||
);
|
||||
}
|
||||
|
||||
const records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordTermsOfServiceEqualToRaw,
|
||||
transformer: transformTermsOfServiceRecord,
|
||||
prepareRecordsOnly,
|
||||
createOrUpdateRawValues: getUniqueRawsBy({raws: termOfService, key: 'id'}),
|
||||
tableName: TERMS_OF_SERVICE,
|
||||
});
|
||||
|
||||
return records;
|
||||
}) as Promise<TermsOfServiceModel[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +104,7 @@ export default class ServerDataOperatorBase extends BaseDataOperator {
|
||||
* @param {(TransformerArgs) => Promise<Model>} execute.recordOperator
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
execute = async ({createRaws, transformer, tableName, updateRaws}: OperationArgs) => {
|
||||
execute = async ({createRaws, transformer, tableName, updateRaws}: OperationArgs): Promise<void> => {
|
||||
const models = await this.prepareRecords({
|
||||
tableName,
|
||||
createRaws,
|
||||
|
||||
@@ -58,9 +58,9 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
});
|
||||
|
||||
it('=> HandlePosts: should write to the Post and its sub-child tables', async () => {
|
||||
expect.assertions(12);
|
||||
// expect.assertions(12);
|
||||
|
||||
const posts = [
|
||||
const posts: Post[] = [
|
||||
{
|
||||
id: '8swgtrrdiff89jnsiwiip3y1eoe',
|
||||
create_at: 1596032651747,
|
||||
@@ -96,8 +96,6 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
post_id: 'a7ebyw883trm884p1qcgt8yw4a',
|
||||
emoji_name: 'clap',
|
||||
create_at: 1608252965442,
|
||||
update_at: 1608252965442,
|
||||
delete_at: 0,
|
||||
},
|
||||
],
|
||||
embeds: [
|
||||
@@ -235,8 +233,6 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
post_id: 'a7ebyw883trm884p1qcgt8yw4a',
|
||||
emoji_name: 'clap',
|
||||
create_at: 1608252965442,
|
||||
update_at: 1608252965442,
|
||||
delete_at: 0,
|
||||
},
|
||||
],
|
||||
prepareRecordsOnly: true,
|
||||
@@ -268,9 +264,9 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
|
||||
expect(spyOnHandlePostMetadata).toHaveBeenCalledTimes(1);
|
||||
expect(spyOnHandlePostMetadata).toHaveBeenCalledWith({
|
||||
embeds: [
|
||||
{
|
||||
embed: [
|
||||
metadatas: [{
|
||||
data: {
|
||||
embeds: [
|
||||
{
|
||||
type: 'opengraph',
|
||||
url: 'https://github.com/mickmister/mattermost-plugin-default-theme',
|
||||
@@ -297,11 +293,6 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
},
|
||||
},
|
||||
],
|
||||
postId: '8swgtrrdiff89jnsiwiip3y1eoe',
|
||||
},
|
||||
],
|
||||
images: [
|
||||
{
|
||||
images: {
|
||||
'https://community-release.mattermost.com/api/v4/image?url=https%3A%2F%2Favatars1.githubusercontent.com%2Fu%2F6913320%3Fs%3D400%26v%3D4': {
|
||||
width: 400,
|
||||
@@ -310,9 +301,9 @@ describe('*** Operator: Post Handlers tests ***', () => {
|
||||
frame_count: 0,
|
||||
},
|
||||
},
|
||||
postId: '8swgtrrdiff89jnsiwiip3y1eoe',
|
||||
},
|
||||
],
|
||||
post_id: '8swgtrrdiff89jnsiwiip3y1eoe',
|
||||
}],
|
||||
prepareRecordsOnly: true,
|
||||
});
|
||||
|
||||
|
||||
@@ -17,27 +17,15 @@ import {
|
||||
} from '@database/operator/server_data_operator/transformers/post';
|
||||
import {getRawRecordPairs, getUniqueRawsBy, retrieveRecords} from '@database/operator/utils/general';
|
||||
import {createPostsChain, sanitizePosts} from '@database/operator/utils/post';
|
||||
import {
|
||||
HandleDraftArgs,
|
||||
HandleFilesArgs,
|
||||
HandlePostMetadataArgs,
|
||||
HandlePostsArgs,
|
||||
PostImage,
|
||||
RawCustomEmoji,
|
||||
RawEmbed,
|
||||
RawFile,
|
||||
RawPost,
|
||||
RawPostMetadata,
|
||||
RawPostsInThread,
|
||||
RawReaction, RecordPair,
|
||||
} from '@typings/database/database';
|
||||
import Draft from '@typings/database/models/servers/draft';
|
||||
import File from '@typings/database/models/servers/file';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import PostMetadata from '@typings/database/models/servers/post_metadata';
|
||||
import PostsInChannel from '@typings/database/models/servers/posts_in_channel';
|
||||
import PostsInThread from '@typings/database/models/servers/posts_in_thread';
|
||||
import Reaction from '@typings/database/models/servers/reaction';
|
||||
|
||||
import type {HandleDraftArgs, HandleFilesArgs, HandlePostMetadataArgs, HandlePostsArgs, RecordPair} from '@typings/database/database';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
import type FileModel from '@typings/database/models/servers/file';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type PostMetadataModel from '@typings/database/models/servers/post_metadata';
|
||||
import type PostsInChannelModel from '@typings/database/models/servers/posts_in_channel';
|
||||
import type PostsInThreadModel from '@typings/database/models/servers/posts_in_thread';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
|
||||
const {
|
||||
DRAFT,
|
||||
@@ -49,12 +37,12 @@ const {
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface PostHandlerMix {
|
||||
handleDraft: ({drafts, prepareRecordsOnly}: HandleDraftArgs) => Draft[] | boolean;
|
||||
handleFiles: ({files, prepareRecordsOnly}: HandleFilesArgs) => Promise<File[] | any[]>;
|
||||
handlePostMetadata: ({embeds, images, prepareRecordsOnly}: HandlePostMetadataArgs) => Promise<any[] | PostMetadata[]>;
|
||||
handleDraft: ({drafts, prepareRecordsOnly}: HandleDraftArgs) => Promise<DraftModel[]>;
|
||||
handleFiles: ({files, prepareRecordsOnly}: HandleFilesArgs) => Promise<FileModel[]>;
|
||||
handlePostMetadata: ({metadatas, prepareRecordsOnly}: HandlePostMetadataArgs) => Promise<PostMetadataModel[]>;
|
||||
handlePosts: ({orders, values, previousPostId}: HandlePostsArgs) => Promise<void>;
|
||||
handlePostsInChannel: (posts: RawPost[]) => Promise<void>;
|
||||
handlePostsInThread: (rootPosts: RawPostsInThread[]) => Promise<void>;
|
||||
handlePostsInChannel: (posts: Post[]) => Promise<void>;
|
||||
handlePostsInThread: (rootPosts: PostsInThread[]) => Promise<void>;
|
||||
}
|
||||
|
||||
const PostHandler = (superclass: any) => class extends superclass {
|
||||
@@ -64,11 +52,9 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
* @param {RawDraft[]} draftsArgs.drafts
|
||||
* @param {boolean} draftsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Draft[]}
|
||||
* @returns {Promise<DraftModel[]>}
|
||||
*/
|
||||
handleDraft = async ({drafts, prepareRecordsOnly = true}: HandleDraftArgs) => {
|
||||
let records: Draft[] = [];
|
||||
|
||||
handleDraft = ({drafts, prepareRecordsOnly = true}: HandleDraftArgs): Promise<DraftModel[]> => {
|
||||
if (!drafts.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "drafts" array has been passed to the handleDraft method',
|
||||
@@ -77,7 +63,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: drafts, key: 'channel_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'channel_id',
|
||||
findMatchingRecordBy: isRecordDraftEqualToRaw,
|
||||
transformer: transformDraftRecord,
|
||||
@@ -85,8 +71,6 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: DRAFT,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -97,7 +81,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
* @param {string | undefined} handlePosts.previousPostId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handlePosts = async ({orders, values, previousPostId}: HandlePostsArgs) => {
|
||||
handlePosts = async ({orders, values, previousPostId}: HandlePostsArgs): Promise<void> => {
|
||||
const tableName = POST;
|
||||
|
||||
// We rely on the order array; if it is empty, we stop processing
|
||||
@@ -110,7 +94,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
const rawValues = getUniqueRawsBy({
|
||||
raws: values,
|
||||
key: 'id',
|
||||
}) as RawPost[];
|
||||
}) as Post[];
|
||||
|
||||
// By sanitizing the values, we are separating 'posts' that needs updating ( i.e. un-ordered posts ) from those that need to be created in our database
|
||||
const {postsOrdered, postsUnordered} = sanitizePosts({
|
||||
@@ -128,12 +112,11 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
if (futureEntries.createRaws?.length) {
|
||||
let batch: Model[] = [];
|
||||
let files: RawFile[] = [];
|
||||
const files: FileInfo[] = [];
|
||||
const postsInThread = [];
|
||||
let reactions: RawReaction[] = [];
|
||||
let emojis: RawCustomEmoji[] = [];
|
||||
const images: Array<{ images: Dictionary<PostImage>; postId: string }> = [];
|
||||
const embeds: Array<{ embed: RawEmbed[]; postId: string }> = [];
|
||||
const reactions: Reaction[] = [];
|
||||
const emojis: CustomEmoji[] = [];
|
||||
const metadatas: Metadata[] = [];
|
||||
|
||||
// We create the 'chain of posts' by linking each posts' previousId to the post before it in the order array
|
||||
const linkedRawPosts: RecordPair[] = createPostsChain({
|
||||
@@ -147,7 +130,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
createRaws: linkedRawPosts,
|
||||
transformer: transformPostRecord,
|
||||
tableName,
|
||||
})) as Post[];
|
||||
})) as PostModel[];
|
||||
|
||||
// Appends the processed records into the final batch array
|
||||
batch = batch.concat(posts);
|
||||
@@ -163,31 +146,36 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
}
|
||||
|
||||
if (post?.metadata && Object.keys(post?.metadata).length > 0) {
|
||||
const metadata = post.metadata;
|
||||
const data = post.metadata;
|
||||
|
||||
// Extracts reaction from post's metadata
|
||||
reactions = reactions.concat(metadata?.reactions ?? []);
|
||||
if (data.reactions) {
|
||||
reactions.push(...data.reactions);
|
||||
delete data.reactions;
|
||||
}
|
||||
|
||||
// Extracts emojis from post's metadata
|
||||
emojis = emojis.concat(metadata?.emojis ?? []);
|
||||
if (data.emojis) {
|
||||
emojis.push(...data.emojis);
|
||||
delete data.emojis;
|
||||
}
|
||||
|
||||
// Extracts files from post's metadata
|
||||
files = files.concat(metadata?.files ?? []);
|
||||
|
||||
// Extracts images and embeds from post's metadata
|
||||
if (metadata?.images) {
|
||||
images.push({images: metadata.images, postId: post.id});
|
||||
if (data.files) {
|
||||
files.push(...data.files);
|
||||
delete data.files;
|
||||
}
|
||||
|
||||
if (metadata?.embeds) {
|
||||
embeds.push({embed: metadata.embeds, postId: post.id});
|
||||
}
|
||||
metadatas.push({
|
||||
data,
|
||||
post_id: post.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (reactions.length) {
|
||||
// calls handler for Reactions
|
||||
const postReactions = (await this.handleReactions({reactions, prepareRecordsOnly: true})) as Reaction[];
|
||||
const postReactions = (await this.handleReactions({reactions, prepareRecordsOnly: true})) as ReactionModel[];
|
||||
batch = batch.concat(postReactions);
|
||||
}
|
||||
|
||||
@@ -197,11 +185,10 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
batch = batch.concat(postFiles);
|
||||
}
|
||||
|
||||
if (images.length || embeds.length) {
|
||||
if (metadatas.length) {
|
||||
// calls handler for postMetadata ( embeds and images )
|
||||
const postMetadata = await this.handlePostMetadata({
|
||||
images,
|
||||
embeds,
|
||||
metadatas,
|
||||
prepareRecordsOnly: true,
|
||||
});
|
||||
|
||||
@@ -230,7 +217,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
}
|
||||
|
||||
if (postsUnordered.length) {
|
||||
// Truly update those posts that have a different update_at value
|
||||
// Truly update those posts that have a different update_at value
|
||||
await this.handleRecords({
|
||||
findMatchingRecordBy: isRecordPostEqualToRaw,
|
||||
fieldName: 'id',
|
||||
@@ -247,9 +234,9 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
* @param {HandleFilesArgs} handleFiles
|
||||
* @param {RawFile[]} handleFiles.files
|
||||
* @param {boolean} handleFiles.prepareRecordsOnly
|
||||
* @returns {Promise<File[] | any[]>}
|
||||
* @returns {Promise<FileModel[]>}
|
||||
*/
|
||||
handleFiles = async ({files, prepareRecordsOnly}: HandleFilesArgs) => {
|
||||
handleFiles = async ({files, prepareRecordsOnly}: HandleFilesArgs): Promise<FileModel[]> => {
|
||||
if (!files.length) {
|
||||
return [];
|
||||
}
|
||||
@@ -268,7 +255,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
await this.batchRecords(postFiles);
|
||||
}
|
||||
|
||||
return [];
|
||||
return postFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -277,40 +264,11 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
* @param {{embed: RawEmbed[], postId: string}[] | undefined} handlePostMetadata.embeds
|
||||
* @param {{images: Dictionary<PostImage>, postId: string}[] | undefined} handlePostMetadata.images
|
||||
* @param {boolean} handlePostMetadata.prepareRecordsOnly
|
||||
* @returns {Promise<any[] | PostMetadata[]>}
|
||||
* @returns {Promise<PostMetadataModel[]>}
|
||||
*/
|
||||
handlePostMetadata = async ({embeds, images, prepareRecordsOnly}: HandlePostMetadataArgs) => {
|
||||
const metadata: RawPostMetadata[] = [];
|
||||
|
||||
if (images?.length) {
|
||||
images.forEach((image) => {
|
||||
const imageEntry = Object.entries(image.images);
|
||||
metadata.push({
|
||||
data: {...imageEntry?.[0]?.[1], url: imageEntry?.[0]?.[0]},
|
||||
type: 'images',
|
||||
postId: image.postId,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (embeds?.length) {
|
||||
embeds.forEach((postEmbed) => {
|
||||
postEmbed.embed.forEach((embed: RawEmbed) => {
|
||||
metadata.push({
|
||||
data: {...embed.data},
|
||||
type: embed.type,
|
||||
postId: postEmbed.postId,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!metadata.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
handlePostMetadata = async ({metadatas, prepareRecordsOnly}: HandlePostMetadataArgs): Promise<PostMetadataModel[]> => {
|
||||
const postMetas = await this.prepareRecords({
|
||||
createRaws: getRawRecordPairs(metadata),
|
||||
createRaws: getRawRecordPairs([metadatas]),
|
||||
transformer: transformPostMetadataRecord,
|
||||
tableName: POST_METADATA,
|
||||
});
|
||||
@@ -323,31 +281,31 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
await this.batchRecords(postMetas);
|
||||
}
|
||||
|
||||
return [];
|
||||
return postMetas;
|
||||
};
|
||||
|
||||
/**
|
||||
* handlePostsInThread: Handler responsible for the Create/Update operations occurring on the PostsInThread table from the 'Server' schema
|
||||
* @param {RawPostsInThread[]} rootPosts
|
||||
* @param {PostsInThread[]} rootPosts
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handlePostsInThread = async (rootPosts: RawPostsInThread[]) => {
|
||||
handlePostsInThread = async (rootPosts: PostsInThread[]): Promise<void> => {
|
||||
if (!rootPosts.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const postIds = rootPosts.map((postThread) => postThread.post_id);
|
||||
const rawPostsInThreads: RawPostsInThread[] = [];
|
||||
const rawPostsInThreads: PostsInThread[] = [];
|
||||
|
||||
// Retrieves all threads whereby their root_id can be one of the element in the postIds array
|
||||
const threads = (await this.database.collections.
|
||||
get(POST).
|
||||
query(Q.where('root_id', Q.oneOf(postIds))).
|
||||
fetch()) as Post[];
|
||||
fetch()) as PostModel[];
|
||||
|
||||
// The aim here is to find the last reply in that thread; hence the latest create_at value
|
||||
rootPosts.forEach((rootPost) => {
|
||||
const maxCreateAt: number = threads.reduce((max: number, thread: Post) => {
|
||||
const maxCreateAt: number = threads.reduce((max: number, thread: PostModel) => {
|
||||
return thread.createAt > max ? thread.createAt : maxCreateAt;
|
||||
}, 0);
|
||||
|
||||
@@ -360,7 +318,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
createRaws: getRawRecordPairs(rawPostsInThreads),
|
||||
transformer: transformPostInThreadRecord,
|
||||
tableName: POSTS_IN_THREAD,
|
||||
})) as PostsInThread[];
|
||||
})) as PostsInThreadModel[];
|
||||
|
||||
if (postInThreadRecords?.length) {
|
||||
await this.batchRecords(postInThreadRecords);
|
||||
@@ -370,15 +328,15 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
/**
|
||||
* handlePostsInChannel: Handler responsible for the Create/Update operations occurring on the PostsInChannel table from the 'Server' schema
|
||||
* @param {RawPost[]} posts
|
||||
* @param {Post[]} posts
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
handlePostsInChannel = async (posts: RawPost[]) => {
|
||||
handlePostsInChannel = async (posts: Post[]): Promise<void> => {
|
||||
// At this point, the parameter 'posts' is already a chain of posts. Now, we have to figure out how to plug it
|
||||
// into existing chains in the PostsInChannel table
|
||||
|
||||
if (!posts.length) {
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort a clone of 'posts' array by create_at
|
||||
@@ -387,7 +345,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
});
|
||||
|
||||
// The first element (beginning of chain)
|
||||
const tipOfChain: RawPost = sortedPosts[0];
|
||||
const tipOfChain: Post = sortedPosts[0];
|
||||
|
||||
// Channel Id for this chain of posts
|
||||
const channelId = tipOfChain.channel_id;
|
||||
@@ -404,7 +362,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
database: this.database,
|
||||
tableName: POSTS_IN_CHANNEL,
|
||||
condition: Q.where('channel_id', channelId),
|
||||
})) as PostsInChannel[];
|
||||
})) as PostsInChannelModel[];
|
||||
|
||||
const createPostsInChannelRecord = async () => {
|
||||
await this.execute({
|
||||
@@ -417,7 +375,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
// chunk length 0; then it's a new chunk to be added to the PostsInChannel table
|
||||
if (chunks.length === 0) {
|
||||
await createPostsInChannelRecord();
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort chunks (in-place) by earliest field ( oldest to newest )
|
||||
@@ -426,7 +384,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
});
|
||||
|
||||
let found = false;
|
||||
let targetChunk: PostsInChannel;
|
||||
let targetChunk: PostsInChannelModel;
|
||||
|
||||
for (const chunk of chunks) {
|
||||
// find if we should plug the chain before
|
||||
@@ -446,7 +404,7 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
database: this.database,
|
||||
tableName: POST,
|
||||
condition: Q.where('create_at', earliest),
|
||||
})) as Post[];
|
||||
})) as PostModel[];
|
||||
|
||||
if (potentialPosts?.length > 0) {
|
||||
const targetPost = potentialPosts[0];
|
||||
@@ -463,15 +421,11 @@ const PostHandler = (superclass: any) => class extends superclass {
|
||||
});
|
||||
} else {
|
||||
await createPostsInChannelRecord();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await createPostsInChannelRecord();
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('*** Operator: Team Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const teams = [
|
||||
const teams: Team[] = [
|
||||
{
|
||||
id: 'rcgiyftm7jyrxnmdfdfa1osd8zswby',
|
||||
create_at: 1445538153952,
|
||||
@@ -73,16 +73,16 @@ describe('*** Operator: Team Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const teamMemberships = [
|
||||
const teamMemberships: TeamMembership[] = [
|
||||
{
|
||||
team_id: 'a',
|
||||
user_id: 'ab',
|
||||
roles: '3ngdqe1e7tfcbmam4qgnxp91bw',
|
||||
roles: '',
|
||||
delete_at: 0,
|
||||
scheme_guest: false,
|
||||
msg_count: 0,
|
||||
mention_count: 0,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
explicit_roles: '',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -162,7 +162,7 @@ describe('*** Operator: Team Handlers tests ***', () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
|
||||
const teamSearchHistories = [
|
||||
const teamSearchHistories: TeamSearchHistory[] = [
|
||||
{
|
||||
team_id: 'a',
|
||||
term: 'termA',
|
||||
|
||||
@@ -20,20 +20,17 @@ import {
|
||||
transformTeamSearchHistoryRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/team';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {
|
||||
HandleMyTeamArgs,
|
||||
HandleSlashCommandArgs,
|
||||
HandleTeamArgs,
|
||||
HandleTeamChannelHistoryArgs,
|
||||
HandleTeamMembershipArgs,
|
||||
HandleTeamSearchHistoryArgs,
|
||||
|
||||
import type {
|
||||
HandleMyTeamArgs, HandleSlashCommandArgs, HandleTeamArgs,
|
||||
HandleTeamChannelHistoryArgs, HandleTeamMembershipArgs, HandleTeamSearchHistoryArgs,
|
||||
} from '@typings/database/database';
|
||||
import MyTeam from '@typings/database/models/servers/my_team';
|
||||
import SlashCommand from '@typings/database/models/servers/slash_command';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import TeamChannelHistory from '@typings/database/models/servers/team_channel_history';
|
||||
import TeamMembership from '@typings/database/models/servers/team_membership';
|
||||
import TeamSearchHistory from '@typings/database/models/servers/team_search_history';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
|
||||
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
|
||||
|
||||
const {
|
||||
MY_TEAM,
|
||||
@@ -45,25 +42,24 @@ const {
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface TeamHandlerMix {
|
||||
handleTeamMemberships: ({teamMemberships, prepareRecordsOnly}: HandleTeamMembershipArgs) => TeamMembership[];
|
||||
handleTeam: ({teams, prepareRecordsOnly}: HandleTeamArgs) => Team[];
|
||||
handleTeamChannelHistory: ({teamChannelHistories, prepareRecordsOnly}: HandleTeamChannelHistoryArgs) => TeamChannelHistory[];
|
||||
handleSlashCommand: ({slashCommands, prepareRecordsOnly}: HandleSlashCommandArgs) => SlashCommand[];
|
||||
handleMyTeam: ({myTeams, prepareRecordsOnly}: HandleMyTeamArgs) => MyTeam[];
|
||||
handleTeamMemberships: ({teamMemberships, prepareRecordsOnly}: HandleTeamMembershipArgs) => Promise<TeamMembershipModel[]>;
|
||||
handleTeam: ({teams, prepareRecordsOnly}: HandleTeamArgs) => Promise<TeamModel[]>;
|
||||
handleTeamChannelHistory: ({teamChannelHistories, prepareRecordsOnly}: HandleTeamChannelHistoryArgs) => Promise<TeamChannelHistoryModel[]>;
|
||||
handleTeamSearchHistory: ({teamSearchHistories, prepareRecordsOnly}: HandleTeamSearchHistoryArgs) => Promise<TeamSearchHistoryModel[]>;
|
||||
handleSlashCommand: ({slashCommands, prepareRecordsOnly}: HandleSlashCommandArgs) => Promise<SlashCommandModel[]>;
|
||||
handleMyTeam: ({myTeams, prepareRecordsOnly}: HandleMyTeamArgs) => Promise<MyTeamModel[]>;
|
||||
}
|
||||
|
||||
const TeamHandler = (superclass: any) => class extends superclass {
|
||||
/**
|
||||
* handleTeamMemberships: Handler responsible for the Create/Update operations occurring on the TEAM_MEMBERSHIP table from the 'Server' schema
|
||||
* @param {HandleTeamMembershipArgs} teamMembershipsArgs
|
||||
* @param {RawTeamMembership[]} teamMembershipsArgs.teamMemberships
|
||||
* @param {TeamMembership[]} teamMembershipsArgs.teamMemberships
|
||||
* @param {boolean} teamMembershipsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {TeamMembership[]}
|
||||
* @returns {Promise<TeamMembershipModel[]>}
|
||||
*/
|
||||
handleTeamMemberships = async ({teamMemberships, prepareRecordsOnly = true}: HandleTeamMembershipArgs) => {
|
||||
let records: TeamMembership[] = [];
|
||||
|
||||
handleTeamMemberships = ({teamMemberships, prepareRecordsOnly = true}: HandleTeamMembershipArgs): Promise<TeamMembershipModel[]> => {
|
||||
if (!teamMemberships.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "teamMemberships" array has been passed to the handleTeamMemberships method',
|
||||
@@ -72,7 +68,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: teamMemberships, key: 'team_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordTeamMembershipEqualToRaw,
|
||||
transformer: transformTeamMembershipRecord,
|
||||
@@ -80,21 +76,17 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
tableName: TEAM_MEMBERSHIP,
|
||||
prepareRecordsOnly,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleTeam: Handler responsible for the Create/Update operations occurring on the TEAM table from the 'Server' schema
|
||||
* @param {HandleTeamArgs} teamsArgs
|
||||
* @param {RawTeam[]} teamsArgs.teams
|
||||
* @param {Team[]} teamsArgs.teams
|
||||
* @param {boolean} teamsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Team[]}
|
||||
* @returns {Promise<TeamModel[]>}
|
||||
*/
|
||||
handleTeam = async ({teams, prepareRecordsOnly = true}: HandleTeamArgs) => {
|
||||
let records: Team[] = [];
|
||||
|
||||
handleTeam = ({teams, prepareRecordsOnly = true}: HandleTeamArgs): Promise<TeamModel[]> => {
|
||||
if (!teams.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "teams" array has been passed to the handleTeam method',
|
||||
@@ -103,7 +95,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: teams, key: 'id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordTeamEqualToRaw,
|
||||
transformer: transformTeamRecord,
|
||||
@@ -111,21 +103,17 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: TEAM,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleTeamChannelHistory: Handler responsible for the Create/Update operations occurring on the TEAM_CHANNEL_HISTORY table from the 'Server' schema
|
||||
* @param {HandleTeamChannelHistoryArgs} teamChannelHistoriesArgs
|
||||
* @param {RawTeamChannelHistory[]} teamChannelHistoriesArgs.teamChannelHistories
|
||||
* @param {TeamChannelHistory[]} teamChannelHistoriesArgs.teamChannelHistories
|
||||
* @param {boolean} teamChannelHistoriesArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {TeamChannelHistory[]}
|
||||
* @returns {Promise<TeamChannelHistoryModel[]>}
|
||||
*/
|
||||
handleTeamChannelHistory = async ({teamChannelHistories, prepareRecordsOnly = true}: HandleTeamChannelHistoryArgs) => {
|
||||
let records: TeamChannelHistory[] = [];
|
||||
|
||||
handleTeamChannelHistory = ({teamChannelHistories, prepareRecordsOnly = true}: HandleTeamChannelHistoryArgs): Promise<TeamChannelHistoryModel[]> => {
|
||||
if (!teamChannelHistories.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "teamChannelHistories" array has been passed to the handleTeamChannelHistory method',
|
||||
@@ -134,7 +122,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: teamChannelHistories, key: 'team_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'team_id',
|
||||
findMatchingRecordBy: isRecordTeamChannelHistoryEqualToRaw,
|
||||
transformer: transformTeamChannelHistoryRecord,
|
||||
@@ -142,21 +130,17 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: TEAM_CHANNEL_HISTORY,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleTeamSearchHistory: Handler responsible for the Create/Update operations occurring on the TEAM_SEARCH_HISTORY table from the 'Server' schema
|
||||
* @param {HandleTeamSearchHistoryArgs} teamSearchHistoriesArgs
|
||||
* @param {RawTeamSearchHistory[]} teamSearchHistoriesArgs.teamSearchHistories
|
||||
* @param {TeamSearchHistory[]} teamSearchHistoriesArgs.teamSearchHistories
|
||||
* @param {boolean} teamSearchHistoriesArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {TeamSearchHistory[]}
|
||||
* @returns {Promise<TeamSearchHistoryModel[]>}
|
||||
*/
|
||||
handleTeamSearchHistory = async ({teamSearchHistories, prepareRecordsOnly = true}: HandleTeamSearchHistoryArgs) => {
|
||||
let records: TeamSearchHistory[] = [];
|
||||
|
||||
handleTeamSearchHistory = ({teamSearchHistories, prepareRecordsOnly = true}: HandleTeamSearchHistoryArgs): Promise<TeamSearchHistoryModel[]> => {
|
||||
if (!teamSearchHistories.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "teamSearchHistories" array has been passed to the handleTeamSearchHistory method',
|
||||
@@ -165,7 +149,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: teamSearchHistories, key: 'term'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'team_id',
|
||||
findMatchingRecordBy: isRecordTeamSearchHistoryEqualToRaw,
|
||||
transformer: transformTeamSearchHistoryRecord,
|
||||
@@ -173,21 +157,17 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: TEAM_SEARCH_HISTORY,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleSlashCommand: Handler responsible for the Create/Update operations occurring on the SLASH_COMMAND table from the 'Server' schema
|
||||
* @param {HandleSlashCommandArgs} slashCommandsArgs
|
||||
* @param {RawSlashCommand[]} slashCommandsArgs.slashCommands
|
||||
* @param {SlashCommand[]} slashCommandsArgs.slashCommands
|
||||
* @param {boolean} slashCommandsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {SlashCommand[]}
|
||||
* @returns {Promise<SlashCommandModel[]>}
|
||||
*/
|
||||
handleSlashCommand = async ({slashCommands, prepareRecordsOnly = true}: HandleSlashCommandArgs) => {
|
||||
let records: SlashCommand[] = [];
|
||||
|
||||
handleSlashCommand = ({slashCommands, prepareRecordsOnly = true}: HandleSlashCommandArgs): Promise<SlashCommandModel[]> => {
|
||||
if (!slashCommands.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "slashCommands" array has been passed to the handleSlashCommand method',
|
||||
@@ -196,7 +176,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: slashCommands, key: 'id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordSlashCommandEqualToRaw,
|
||||
transformer: transformSlashCommandRecord,
|
||||
@@ -204,21 +184,17 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: SLASH_COMMAND,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleMyTeam: Handler responsible for the Create/Update operations occurring on the MY_TEAM table from the 'Server' schema
|
||||
* @param {HandleMyTeamArgs} myTeamsArgs
|
||||
* @param {RawMyTeam[]} myTeamsArgs.myTeams
|
||||
* @param {MyTeam[]} myTeamsArgs.myTeams
|
||||
* @param {boolean} myTeamsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {MyTeam[]}
|
||||
* @returns {Promise<MyTeamModel[]>}
|
||||
*/
|
||||
handleMyTeam = async ({myTeams, prepareRecordsOnly = true}: HandleMyTeamArgs) => {
|
||||
let records: MyTeam[] = [];
|
||||
|
||||
handleMyTeam = ({myTeams, prepareRecordsOnly = true}: HandleMyTeamArgs): Promise<MyTeamModel[]> => {
|
||||
if (!myTeams.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "myTeams" array has been passed to the handleSlashCommand method',
|
||||
@@ -227,7 +203,7 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: myTeams, key: 'team_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'team_id',
|
||||
findMatchingRecordBy: isRecordMyTeamEqualToRaw,
|
||||
transformer: transformMyTeamRecord,
|
||||
@@ -235,8 +211,6 @@ const TeamHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: MY_TEAM,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -32,10 +32,8 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
reactions: [
|
||||
{
|
||||
create_at: 1608263728086,
|
||||
delete_at: 0,
|
||||
emoji_name: 'p4p1',
|
||||
post_id: '4r9jmr7eqt8dxq3f9woypzurry',
|
||||
update_at: 1608263728077,
|
||||
user_id: 'ooumoqgq3bfiijzwbn8badznwc',
|
||||
},
|
||||
],
|
||||
@@ -52,7 +50,7 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
it('=> HandleUsers: should write to the User table', async () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const users = [
|
||||
const users: UserProfile[] = [
|
||||
{
|
||||
id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
create_at: 1599457495881,
|
||||
@@ -71,19 +69,19 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
props: {},
|
||||
notify_props: {
|
||||
desktop: 'all',
|
||||
desktop_sound: true,
|
||||
email: true,
|
||||
first_name: true,
|
||||
desktop_sound: 'true',
|
||||
email: 'true',
|
||||
first_name: 'true',
|
||||
mark_unread: 'mention',
|
||||
mention_keys: '',
|
||||
push: 'mention',
|
||||
channel: true,
|
||||
auto_responder_active: false,
|
||||
channel: 'true',
|
||||
auto_responder_active: 'false',
|
||||
auto_responder_message: 'Hello, I am out of office and unable to respond to messages.',
|
||||
comments: 'never',
|
||||
desktop_notification_sound: 'Hello',
|
||||
push_status: 'online',
|
||||
},
|
||||
last_password_update: 1604323112537,
|
||||
last_picture_update: 1604686302260,
|
||||
locale: 'en',
|
||||
timezone: {
|
||||
@@ -159,7 +157,7 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
|
||||
it('=> HandleChannelMembership: should write to the CHANNEL_MEMBERSHIP table', async () => {
|
||||
expect.assertions(2);
|
||||
const channelMemberships = [
|
||||
const channelMemberships: ChannelMembership[] = [
|
||||
{
|
||||
channel_id: '17bfnb1uwb8epewp4q3x3rx9go',
|
||||
user_id: '9ciscaqbrpd6d8s68k76xb9bte',
|
||||
@@ -175,10 +173,8 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_guest: false,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
explicit_roles: '',
|
||||
},
|
||||
{
|
||||
channel_id: '1yw6gxfr4bn1jbyp9nr7d53yew',
|
||||
@@ -195,10 +191,8 @@ describe('*** Operator: User Handlers tests ***', () => {
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1615300540549,
|
||||
scheme_guest: false,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
explicit_roles: '',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -17,18 +17,18 @@ import {
|
||||
} from '@database/operator/server_data_operator/transformers/user';
|
||||
import {getRawRecordPairs, getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {sanitizeReactions} from '@database/operator/utils/reaction';
|
||||
import ChannelMembership from '@typings/database/models/servers/channel_membership';
|
||||
import CustomEmoji from '@typings/database/models/servers/custom_emoji';
|
||||
import {
|
||||
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type {
|
||||
HandleChannelMembershipArgs,
|
||||
HandlePreferencesArgs,
|
||||
HandleReactionsArgs,
|
||||
HandleUsersArgs,
|
||||
RawReaction,
|
||||
} from '@typings/database/database';
|
||||
import Preference from '@typings/database/models/servers/preference';
|
||||
import Reaction from '@typings/database/models/servers/reaction';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {
|
||||
CHANNEL_MEMBERSHIP,
|
||||
@@ -39,24 +39,22 @@ const {
|
||||
} = MM_TABLES.SERVER;
|
||||
|
||||
export interface UserHandlerMix {
|
||||
handleChannelMembership: ({channelMemberships, prepareRecordsOnly}: HandleChannelMembershipArgs) => Promise<ChannelMembership[]>;
|
||||
handlePreferences: ({preferences, prepareRecordsOnly}: HandlePreferencesArgs) => Promise<Preference[]>;
|
||||
handleReactions: ({reactions, prepareRecordsOnly}: HandleReactionsArgs) => Promise<Array<Reaction | CustomEmoji>>;
|
||||
handleUsers: ({users, prepareRecordsOnly}: HandleUsersArgs) => Promise<User[]>;
|
||||
handleChannelMembership: ({channelMemberships, prepareRecordsOnly}: HandleChannelMembershipArgs) => Promise<ChannelMembershipModel[]>;
|
||||
handlePreferences: ({preferences, prepareRecordsOnly}: HandlePreferencesArgs) => Promise<PreferenceModel[]>;
|
||||
handleReactions: ({reactions, prepareRecordsOnly}: HandleReactionsArgs) => Promise<Array<ReactionModel | CustomEmojiModel>>;
|
||||
handleUsers: ({users, prepareRecordsOnly}: HandleUsersArgs) => Promise<UserModel[]>;
|
||||
}
|
||||
|
||||
const UserHandler = (superclass: any) => class extends superclass {
|
||||
/**
|
||||
* handleChannelMembership: Handler responsible for the Create/Update operations occurring on the CHANNEL_MEMBERSHIP table from the 'Server' schema
|
||||
* @param {HandleChannelMembershipArgs} channelMembershipsArgs
|
||||
* @param {RawChannelMembership[]} channelMembershipsArgs.channelMemberships
|
||||
* @param {ChannelMembership[]} channelMembershipsArgs.channelMemberships
|
||||
* @param {boolean} channelMembershipsArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<ChannelMembership[]>}
|
||||
* @returns {Promise<ChannelMembershipModel[]>}
|
||||
*/
|
||||
handleChannelMembership = async ({channelMemberships, prepareRecordsOnly = true}: HandleChannelMembershipArgs) => {
|
||||
let records: ChannelMembership[] = [];
|
||||
|
||||
handleChannelMembership = ({channelMemberships, prepareRecordsOnly = true}: HandleChannelMembershipArgs): Promise<ChannelMembershipModel[]> => {
|
||||
if (!channelMemberships.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "channelMemberships" array has been passed to the handleChannelMembership method',
|
||||
@@ -65,7 +63,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: channelMemberships, key: 'channel_id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordChannelMembershipEqualToRaw,
|
||||
transformer: transformChannelMembershipRecord,
|
||||
@@ -73,21 +71,17 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handlePreferences: Handler responsible for the Create/Update operations occurring on the PREFERENCE table from the 'Server' schema
|
||||
* @param {HandlePreferencesArgs} preferencesArgs
|
||||
* @param {RawPreference[]} preferencesArgs.preferences
|
||||
* @param {PreferenceType[]} preferencesArgs.preferences
|
||||
* @param {boolean} preferencesArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<Preference[]>}
|
||||
* @returns {Promise<PreferenceModel[]>}
|
||||
*/
|
||||
handlePreferences = async ({preferences, prepareRecordsOnly = true}: HandlePreferencesArgs) => {
|
||||
let records: Preference[] = [];
|
||||
|
||||
handlePreferences = ({preferences, prepareRecordsOnly = true}: HandlePreferencesArgs): Promise<PreferenceModel[]> => {
|
||||
if (!preferences.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "preferences" array has been passed to the handlePreferences method',
|
||||
@@ -96,7 +90,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: preferences, key: 'name'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'user_id',
|
||||
findMatchingRecordBy: isRecordPreferenceEqualToRaw,
|
||||
transformer: transformPreferenceRecord,
|
||||
@@ -104,20 +98,18 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
createOrUpdateRawValues,
|
||||
tableName: PREFERENCE,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleReactions: Handler responsible for the Create/Update operations occurring on the Reaction table from the 'Server' schema
|
||||
* @param {HandleReactionsArgs} handleReactions
|
||||
* @param {RawReaction[]} handleReactions.reactions
|
||||
* @param {Reaction[]} handleReactions.reactions
|
||||
* @param {boolean} handleReactions.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<(Reaction| CustomEmoji)[]>}
|
||||
* @returns {Promise<Array<(ReactionModel | CustomEmojiModel)>>}
|
||||
*/
|
||||
handleReactions = async ({reactions, prepareRecordsOnly}: HandleReactionsArgs) => {
|
||||
let batchRecords: Array<Reaction| CustomEmoji> = [];
|
||||
handleReactions = async ({reactions, prepareRecordsOnly}: HandleReactionsArgs): Promise<Array<(ReactionModel | CustomEmojiModel)>> => {
|
||||
let batchRecords: Array<ReactionModel | CustomEmojiModel> = [];
|
||||
|
||||
if (!reactions.length) {
|
||||
throw new DataOperatorException(
|
||||
@@ -125,7 +117,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
);
|
||||
}
|
||||
|
||||
const rawValues = getUniqueRawsBy({raws: reactions, key: 'emoji_name'}) as RawReaction[];
|
||||
const rawValues = getUniqueRawsBy({raws: reactions, key: 'emoji_name'}) as Reaction[];
|
||||
|
||||
const {
|
||||
createEmojis,
|
||||
@@ -143,7 +135,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
createRaws: createReactions,
|
||||
transformer: transformReactionRecord,
|
||||
tableName: REACTION,
|
||||
})) as Reaction[];
|
||||
})) as ReactionModel[];
|
||||
batchRecords = batchRecords.concat(reactionsRecords);
|
||||
}
|
||||
|
||||
@@ -153,7 +145,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
createRaws: getRawRecordPairs(createEmojis),
|
||||
transformer: transformCustomEmojiRecord,
|
||||
tableName: CUSTOM_EMOJI,
|
||||
})) as CustomEmoji[];
|
||||
})) as CustomEmojiModel[];
|
||||
batchRecords = batchRecords.concat(emojiRecords);
|
||||
}
|
||||
|
||||
@@ -167,20 +159,18 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
await this.batchRecords(batchRecords);
|
||||
}
|
||||
|
||||
return [];
|
||||
return batchRecords;
|
||||
};
|
||||
|
||||
/**
|
||||
* handleUsers: Handler responsible for the Create/Update operations occurring on the User table from the 'Server' schema
|
||||
* @param {HandleUsersArgs} usersArgs
|
||||
* @param {RawUser[]} usersArgs.users
|
||||
* @param {UserProfile[]} usersArgs.users
|
||||
* @param {boolean} usersArgs.prepareRecordsOnly
|
||||
* @throws DataOperatorException
|
||||
* @returns {Promise<User[]>}
|
||||
* @returns {Promise<UserModel[]>}
|
||||
*/
|
||||
handleUsers = async ({users, prepareRecordsOnly = true}: HandleUsersArgs) => {
|
||||
let records: User[] = [];
|
||||
|
||||
handleUsers = async ({users, prepareRecordsOnly = true}: HandleUsersArgs): Promise<UserModel[]> => {
|
||||
if (!users.length) {
|
||||
throw new DataOperatorException(
|
||||
'An empty "users" array has been passed to the handleUsers method',
|
||||
@@ -189,7 +179,7 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
|
||||
const createOrUpdateRawValues = getUniqueRawsBy({raws: users, key: 'id'});
|
||||
|
||||
records = await this.handleRecords({
|
||||
return this.handleRecords({
|
||||
fieldName: 'id',
|
||||
findMatchingRecordBy: isRecordUserEqualToRaw,
|
||||
transformer: transformUserRecord,
|
||||
@@ -197,8 +187,6 @@ const UserHandler = (superclass: any) => class extends superclass {
|
||||
tableName: USER,
|
||||
prepareRecordsOnly,
|
||||
});
|
||||
|
||||
return records;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
extra_update_at: 0,
|
||||
creator_id: '',
|
||||
scheme_id: null,
|
||||
props: null,
|
||||
group_constrained: null,
|
||||
shared: null,
|
||||
},
|
||||
@@ -46,7 +45,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords.collection.modelClass.name).toBe('Channel');
|
||||
expect(preparedRecords.collection.modelClass.name).toBe('ChannelModel');
|
||||
});
|
||||
|
||||
it('=> transformMyChannelSettingsRecord: should return an array of type MyChannelSettings', async () => {
|
||||
@@ -55,28 +54,34 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
const database = await createTestConnection({databaseName: 'channel_prepare_records', setActive: true});
|
||||
expect(database).toBeTruthy();
|
||||
|
||||
const raw: ChannelMembership = {
|
||||
channel_id: 'c',
|
||||
user_id: 'me',
|
||||
roles: '',
|
||||
last_viewed_at: 0,
|
||||
msg_count: 0,
|
||||
mention_count: 0,
|
||||
last_update_at: 0,
|
||||
notify_props: {
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
push: 'mention',
|
||||
mark_unread: 'mention',
|
||||
ignore_channel_mentions: 'default',
|
||||
},
|
||||
};
|
||||
|
||||
const preparedRecords = await transformMyChannelSettingsRecord({
|
||||
action: OperationType.CREATE,
|
||||
database: database!,
|
||||
value: {
|
||||
record: undefined,
|
||||
raw: {
|
||||
channel_id: 'c',
|
||||
notify_props: {
|
||||
desktop: 'all',
|
||||
desktop_sound: true,
|
||||
email: true,
|
||||
first_name: true,
|
||||
mention_keys: '',
|
||||
push: 'mention',
|
||||
channel: true,
|
||||
},
|
||||
},
|
||||
raw,
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelSettings');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelSettingsModel');
|
||||
});
|
||||
|
||||
it('=> transformChannelInfoRecord: should return an array of type ChannelInfo', async () => {
|
||||
@@ -102,7 +107,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelInfo');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelInfoModel');
|
||||
});
|
||||
|
||||
it('=> transformMyChannelRecord: should return an array of type MyChannel', async () => {
|
||||
@@ -118,16 +123,19 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
|
||||
record: undefined,
|
||||
raw: {
|
||||
channel_id: 'cd',
|
||||
user_id: 'guest',
|
||||
last_post_at: 1617311494451,
|
||||
last_viewed_at: 1617311494451,
|
||||
mentions_count: 3,
|
||||
message_count: 10,
|
||||
last_update_at: 0,
|
||||
mention_count: 3,
|
||||
msg_count: 10,
|
||||
roles: 'guest',
|
||||
notify_props: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyChannel');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,18 +3,13 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import ChannelInfo from '@typings/database/models/servers/channel_info';
|
||||
import {
|
||||
TransformerArgs,
|
||||
RawChannel,
|
||||
RawChannelInfo,
|
||||
RawMyChannel,
|
||||
RawMyChannelSettings,
|
||||
} from '@typings/database/database';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import MyChannel from '@typings/database/models/servers/my_channel';
|
||||
import MyChannelSettings from '@typings/database/models/servers/my_channel_settings';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
|
||||
const {
|
||||
CHANNEL,
|
||||
@@ -28,15 +23,15 @@ const {
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<ChannelModel>}
|
||||
*/
|
||||
export const transformChannelRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawChannel;
|
||||
const record = value.record as Channel;
|
||||
export const transformChannelRecord = ({action, database, value}: TransformerArgs): Promise<ChannelModel> => {
|
||||
const raw = value.raw as Channel;
|
||||
const record = value.record as ChannelModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (channel: Channel) => {
|
||||
const fieldsMapper = (channel: ChannelModel) => {
|
||||
channel._raw.id = isCreateAction ? (raw?.id ?? channel.id) : record.id;
|
||||
channel.createAt = raw.create_at;
|
||||
channel.creatorId = raw.creator_id;
|
||||
@@ -54,7 +49,7 @@ export const transformChannelRecord = ({action, database, value}: TransformerArg
|
||||
tableName: CHANNEL,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<ChannelModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -62,14 +57,14 @@ export const transformChannelRecord = ({action, database, value}: TransformerArg
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<MyChannelSettingsModel>}
|
||||
*/
|
||||
export const transformMyChannelSettingsRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawMyChannelSettings;
|
||||
const record = value.record as MyChannelSettings;
|
||||
export const transformMyChannelSettingsRecord = ({action, database, value}: TransformerArgs): Promise<MyChannelSettingsModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as MyChannelSettingsModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (myChannelSetting: MyChannelSettings) => {
|
||||
const fieldsMapper = (myChannelSetting: MyChannelSettingsModel) => {
|
||||
myChannelSetting._raw.id = isCreateAction ? myChannelSetting.id : record.id;
|
||||
myChannelSetting.channelId = raw.channel_id;
|
||||
myChannelSetting.notifyProps = raw.notify_props;
|
||||
@@ -81,7 +76,7 @@ export const transformMyChannelSettingsRecord = ({action, database, value}: Tran
|
||||
tableName: MY_CHANNEL_SETTINGS,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<MyChannelSettingsModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -89,14 +84,14 @@ export const transformMyChannelSettingsRecord = ({action, database, value}: Tran
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<ChannelInfoModel>}
|
||||
*/
|
||||
export const transformChannelInfoRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawChannelInfo;
|
||||
const record = value.record as ChannelInfo;
|
||||
export const transformChannelInfoRecord = ({action, database, value}: TransformerArgs): Promise<ChannelInfoModel> => {
|
||||
const raw = value.raw as ChannelInfo;
|
||||
const record = value.record as ChannelInfoModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (channelInfo: ChannelInfo) => {
|
||||
const fieldsMapper = (channelInfo: ChannelInfoModel) => {
|
||||
channelInfo._raw.id = isCreateAction ? channelInfo.id : record.id;
|
||||
channelInfo.channelId = raw.channel_id;
|
||||
channelInfo.guestCount = raw.guest_count;
|
||||
@@ -112,7 +107,7 @@ export const transformChannelInfoRecord = ({action, database, value}: Transforme
|
||||
tableName: CHANNEL_INFO,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<ChannelInfoModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,20 +115,20 @@ export const transformChannelInfoRecord = ({action, database, value}: Transforme
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<MyChannelModel>}
|
||||
*/
|
||||
export const transformMyChannelRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawMyChannel;
|
||||
const record = value.record as MyChannel;
|
||||
export const transformMyChannelRecord = ({action, database, value}: TransformerArgs): Promise<MyChannelModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as MyChannelModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (myChannel: MyChannel) => {
|
||||
const fieldsMapper = (myChannel: MyChannelModel) => {
|
||||
myChannel._raw.id = isCreateAction ? myChannel.id : record.id;
|
||||
myChannel.channelId = raw.channel_id;
|
||||
myChannel.roles = raw.roles;
|
||||
myChannel.messageCount = raw.message_count;
|
||||
myChannel.mentionsCount = raw.mentions_count;
|
||||
myChannel.lastPostAt = raw.last_post_at;
|
||||
myChannel.messageCount = raw.msg_count;
|
||||
myChannel.mentionsCount = raw.mention_count;
|
||||
myChannel.lastPostAt = raw.last_post_at || 0;
|
||||
myChannel.lastViewedAt = raw.last_viewed_at;
|
||||
};
|
||||
|
||||
@@ -143,6 +138,6 @@ export const transformMyChannelRecord = ({action, database, value}: TransformerA
|
||||
tableName: MY_CHANNEL,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<MyChannelModel>;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('*** Role Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Role');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('RoleModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('*** System Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('System');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('SystemModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,7 +79,7 @@ describe('*** TOS Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TermsOfService');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TermsOfServiceModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ describe('*** CustomEmoj Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('CustomEmoji');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('CustomEmojiModel');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,18 +3,13 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import CustomEmoji from '@typings/database/models/servers/custom_emoji';
|
||||
import {
|
||||
TransformerArgs,
|
||||
RawCustomEmoji,
|
||||
RawRole,
|
||||
RawSystem,
|
||||
RawTermsOfService,
|
||||
} from '@typings/database/database';
|
||||
|
||||
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import Role from '@typings/database/models/servers/role';
|
||||
import System from '@typings/database/models/servers/system';
|
||||
import TermsOfService from '@typings/database/models/servers/terms_of_service';
|
||||
import type RoleModel from '@typings/database/models/servers/role';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
import type TermsOfServiceModel from '@typings/database/models/servers/terms_of_service';
|
||||
|
||||
const {
|
||||
CUSTOM_EMOJI,
|
||||
@@ -28,15 +23,15 @@ const {
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<CustomEmojiModel>}
|
||||
*/
|
||||
export const transformCustomEmojiRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawCustomEmoji;
|
||||
const record = value.record as CustomEmoji;
|
||||
export const transformCustomEmojiRecord = ({action, database, value}: TransformerArgs): Promise<CustomEmojiModel> => {
|
||||
const raw = value.raw as CustomEmoji;
|
||||
const record = value.record as CustomEmojiModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (emoji: CustomEmoji) => {
|
||||
const fieldsMapper = (emoji: CustomEmojiModel) => {
|
||||
emoji._raw.id = isCreateAction ? (raw?.id ?? emoji.id) : record.id;
|
||||
emoji.name = raw.name;
|
||||
};
|
||||
@@ -47,7 +42,7 @@ export const transformCustomEmojiRecord = ({action, database, value}: Transforme
|
||||
tableName: CUSTOM_EMOJI,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<CustomEmojiModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,15 +50,15 @@ export const transformCustomEmojiRecord = ({action, database, value}: Transforme
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<RoleModel>}
|
||||
*/
|
||||
export const transformRoleRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawRole;
|
||||
const record = value.record as Role;
|
||||
export const transformRoleRecord = ({action, database, value}: TransformerArgs): Promise<RoleModel> => {
|
||||
const raw = value.raw as Role;
|
||||
const record = value.record as RoleModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (role: Role) => {
|
||||
const fieldsMapper = (role: RoleModel) => {
|
||||
role._raw.id = isCreateAction ? (raw?.id ?? role.id) : record.id;
|
||||
role.name = raw?.name;
|
||||
role.permissions = raw?.permissions;
|
||||
@@ -75,7 +70,7 @@ export const transformRoleRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: ROLE,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<RoleModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -83,13 +78,13 @@ export const transformRoleRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<SystemModel>}
|
||||
*/
|
||||
export const transformSystemRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawSystem;
|
||||
export const transformSystemRecord = ({action, database, value}: TransformerArgs): Promise<SystemModel> => {
|
||||
const raw = value.raw as IdValue;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (system: System) => {
|
||||
const fieldsMapper = (system: SystemModel) => {
|
||||
system._raw.id = raw?.id;
|
||||
system.value = raw?.value;
|
||||
};
|
||||
@@ -100,7 +95,7 @@ export const transformSystemRecord = ({action, database, value}: TransformerArgs
|
||||
tableName: SYSTEM,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<SystemModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,15 +103,15 @@ export const transformSystemRecord = ({action, database, value}: TransformerArgs
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<TermsOfServiceModel>}
|
||||
*/
|
||||
export const transformTermsOfServiceRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawTermsOfService;
|
||||
const record = value.record as TermsOfService;
|
||||
export const transformTermsOfServiceRecord = ({action, database, value}: TransformerArgs): Promise<TermsOfServiceModel> => {
|
||||
const raw = value.raw as TermsOfService;
|
||||
const record = value.record as TermsOfServiceModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (tos: TermsOfService) => {
|
||||
const fieldsMapper = (tos: TermsOfServiceModel) => {
|
||||
tos._raw.id = isCreateAction ? (raw?.id ?? tos.id) : record.id;
|
||||
tos.acceptedAt = raw?.accepted_at;
|
||||
};
|
||||
@@ -127,5 +122,5 @@ export const transformTermsOfServiceRecord = ({action, database, value}: Transfo
|
||||
tableName: TERMS_OF_SERVICE,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<TermsOfServiceModel>;
|
||||
};
|
||||
|
||||
@@ -27,18 +27,20 @@ describe('*** GROUP Prepare Records Test ***', () => {
|
||||
name: 'mobile_team',
|
||||
display_name: 'mobile team',
|
||||
description: '',
|
||||
source: '',
|
||||
type: '',
|
||||
remote_id: '',
|
||||
create_at: 0,
|
||||
update_at: 0,
|
||||
delete_at: 0,
|
||||
has_syncables: true,
|
||||
member_count: 0,
|
||||
allow_reference: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Group');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupModel');
|
||||
});
|
||||
|
||||
it('=> transformGroupsInTeamRecord: should return an array of type GroupsInTeam', async () => {
|
||||
@@ -66,7 +68,7 @@ describe('*** GROUP Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInTeam');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInTeamModel');
|
||||
});
|
||||
|
||||
it('=> transformGroupsInChannelRecord: should return an array of type GroupsInChannel', async () => {
|
||||
@@ -97,7 +99,7 @@ describe('*** GROUP Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInChannel');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInChannelModel');
|
||||
});
|
||||
|
||||
it('=> transformGroupMembershipRecord: should return an array of type GroupMembership', async () => {
|
||||
@@ -119,6 +121,6 @@ describe('*** GROUP Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupMembership');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('GroupMembershipModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,18 +3,13 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import {
|
||||
TransformerArgs,
|
||||
RawGroup,
|
||||
RawGroupMembership,
|
||||
RawGroupsInChannel,
|
||||
RawGroupsInTeam,
|
||||
} from '@typings/database/database';
|
||||
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import Group from '@typings/database/models/servers/group';
|
||||
import GroupMembership from '@typings/database/models/servers/group_membership';
|
||||
import GroupsInChannel from '@typings/database/models/servers/groups_in_channel';
|
||||
import GroupsInTeam from '@typings/database/models/servers/groups_in_team';
|
||||
import type GroupModel from '@typings/database/models/servers/group';
|
||||
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
|
||||
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
|
||||
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
|
||||
|
||||
const {
|
||||
GROUP,
|
||||
@@ -28,15 +23,15 @@ const {
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<GroupMembershipModel>}
|
||||
*/
|
||||
export const transformGroupMembershipRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawGroupMembership;
|
||||
const record = value.record as GroupMembership;
|
||||
export const transformGroupMembershipRecord = ({action, database, value}: TransformerArgs): Promise<GroupMembershipModel> => {
|
||||
const raw = value.raw as GroupMembership;
|
||||
const record = value.record as GroupMembershipModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (groupMember: GroupMembership) => {
|
||||
const fieldsMapper = (groupMember: GroupMembershipModel) => {
|
||||
groupMember._raw.id = isCreateAction ? (raw?.id ?? groupMember.id) : record.id;
|
||||
groupMember.groupId = raw.group_id;
|
||||
groupMember.userId = raw.user_id;
|
||||
@@ -48,7 +43,7 @@ export const transformGroupMembershipRecord = ({action, database, value}: Transf
|
||||
tableName: GROUP_MEMBERSHIP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<GroupMembershipModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -56,15 +51,15 @@ export const transformGroupMembershipRecord = ({action, database, value}: Transf
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<GroupModel>}
|
||||
*/
|
||||
export const transformGroupRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawGroup;
|
||||
const record = value.record as Group;
|
||||
export const transformGroupRecord = ({action, database, value}: TransformerArgs): Promise<GroupModel> => {
|
||||
const raw = value.raw as Group;
|
||||
const record = value.record as GroupModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (group: Group) => {
|
||||
const fieldsMapper = (group: GroupModel) => {
|
||||
group._raw.id = isCreateAction ? (raw?.id ?? group.id) : record.id;
|
||||
group.name = raw.name;
|
||||
group.displayName = raw.display_name;
|
||||
@@ -76,7 +71,7 @@ export const transformGroupRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: GROUP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<GroupModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -84,14 +79,14 @@ export const transformGroupRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<GroupsInTeamModel>}
|
||||
*/
|
||||
export const transformGroupsInTeamRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawGroupsInTeam;
|
||||
const record = value.record as GroupsInTeam;
|
||||
export const transformGroupsInTeamRecord = ({action, database, value}: TransformerArgs): Promise<GroupsInTeamModel> => {
|
||||
const raw = value.raw as GroupTeam;
|
||||
const record = value.record as GroupsInTeamModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (groupsInTeam: GroupsInTeam) => {
|
||||
const fieldsMapper = (groupsInTeam: GroupsInTeamModel) => {
|
||||
groupsInTeam._raw.id = isCreateAction ? groupsInTeam.id : record.id;
|
||||
groupsInTeam.teamId = raw.team_id;
|
||||
groupsInTeam.groupId = raw.group_id;
|
||||
@@ -103,7 +98,7 @@ export const transformGroupsInTeamRecord = ({action, database, value}: Transform
|
||||
tableName: GROUPS_IN_TEAM,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<GroupsInTeamModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -111,14 +106,14 @@ export const transformGroupsInTeamRecord = ({action, database, value}: Transform
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<GroupsInChannelModel>}
|
||||
*/
|
||||
export const transformGroupsInChannelRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawGroupsInChannel;
|
||||
const record = value.record as GroupsInChannel;
|
||||
export const transformGroupsInChannelRecord = ({action, database, value}: TransformerArgs): Promise<GroupsInChannelModel> => {
|
||||
const raw = value.raw as GroupChannel;
|
||||
const record = value.record as GroupsInChannelModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (groupsInChannel: GroupsInChannel) => {
|
||||
const fieldsMapper = (groupsInChannel: GroupsInChannelModel) => {
|
||||
groupsInChannel._raw.id = isCreateAction ? groupsInChannel.id : record.id;
|
||||
groupsInChannel.channelId = raw.channel_id;
|
||||
groupsInChannel.groupId = raw.group_id;
|
||||
@@ -132,5 +127,5 @@ export const transformGroupsInChannelRecord = ({action, database, value}: Transf
|
||||
tableName: GROUPS_IN_CHANNEL,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<GroupsInChannelModel>;
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Post');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('PostModel');
|
||||
});
|
||||
|
||||
it('=> transformPostInThreadRecord: should return an array of type PostsInThread', async () => {
|
||||
@@ -75,7 +75,7 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe(
|
||||
'PostsInThread',
|
||||
'PostsInThreadModel',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -91,13 +91,17 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
value: {
|
||||
record: undefined,
|
||||
raw: {
|
||||
id: 'file-id',
|
||||
post_id: 'ps81iqbddesfby8jayz7owg4yypoo',
|
||||
name: 'test_file',
|
||||
extension: '.jpg',
|
||||
has_preview_image: true,
|
||||
mime_type: 'image/jpeg',
|
||||
size: 1000,
|
||||
create_at: 1609253011321,
|
||||
delete_at: 1609253011321,
|
||||
height: 20,
|
||||
width: 20,
|
||||
update_at: 1609253011321,
|
||||
user_id: 'wqyby5r5pinxxdqhoaomtacdhc',
|
||||
},
|
||||
@@ -105,7 +109,7 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('File');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('FileModel');
|
||||
});
|
||||
|
||||
it('=> transformPostMetadataRecord: should return an array of type PostMetadata', async () => {
|
||||
@@ -121,15 +125,33 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
record: undefined,
|
||||
raw: {
|
||||
id: 'ps81i4yypoo',
|
||||
data: {},
|
||||
postId: 'ps81iqbddesfby8jayz7owg4yypoo',
|
||||
type: 'opengraph',
|
||||
data: {
|
||||
files: [
|
||||
{
|
||||
id: 'mjagj4ta4tb93f7mwdn68yw9rc',
|
||||
user_id: 'gy5cnn5q9i8txdkcrj4dhntnta',
|
||||
post_id: '4wpufe8d5pd7jpwshzrumgjd7r',
|
||||
create_at: 1626207675617,
|
||||
update_at: 1626207675617,
|
||||
delete_at: 0,
|
||||
name: 'Image Pasted at 2021-7-13 22-21.png',
|
||||
extension: 'png',
|
||||
size: 4668,
|
||||
mime_type: 'image/png',
|
||||
width: 67,
|
||||
height: 116,
|
||||
has_preview_image: true,
|
||||
mini_preview: '/9j/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIABAAEAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APPv2c/gr8O/GvwHbWNW0CDW/Elxd6nbS3janMH090jj+xK1tDIHEUhZy0wjl27ANpDZXhP2kvgzo3wk8OeDjZPpbahfXE8bm2kdbqWKOOIieWFpXMSs7yKoYKxCZIGcCz+zvB8J5vD98vjIacmutFCLGfV4XlsIzvfzjKsfzmTGzAY7dp45zXjvirV9I1LXdRW4gXw7GLib7Iuh6J59uyo22IqWnDhZASzZ6bVwOTjuelS7vockKr9m4RUdd9r6equvkz//2Q==',
|
||||
},
|
||||
],
|
||||
},
|
||||
post_id: 'ps81iqbddesfby8jayz7owg4yypoo',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('PostMetadata');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('PostMetadataModel');
|
||||
});
|
||||
|
||||
it('=> transformDraftRecord: should return an array of type Draft', async () => {
|
||||
@@ -154,7 +176,7 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Draft');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('DraftModel');
|
||||
});
|
||||
|
||||
it('=> transformPostsInChannelRecord: should return an array of type PostsInChannel', async () => {
|
||||
@@ -179,7 +201,7 @@ describe('*** POST Prepare Records Test ***', () => {
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe(
|
||||
'PostsInChannel',
|
||||
'PostsInChannelModel',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,22 +4,15 @@ import {Q} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import type{
|
||||
TransformerArgs,
|
||||
RawDraft,
|
||||
RawFile,
|
||||
RawPost,
|
||||
RawPostMetadata,
|
||||
RawPostsInChannel,
|
||||
RawPostsInThread,
|
||||
} from '@typings/database/database';
|
||||
import Draft from '@typings/database/models/servers/draft';
|
||||
|
||||
import type{TransformerArgs} from '@typings/database/database';
|
||||
import type DraftModel from '@typings/database/models/servers/draft';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import File from '@typings/database/models/servers/file';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import PostMetadata from '@typings/database/models/servers/post_metadata';
|
||||
import PostsInChannel from '@typings/database/models/servers/posts_in_channel';
|
||||
import PostsInThread from '@typings/database/models/servers/posts_in_thread';
|
||||
import type FileModel from '@typings/database/models/servers/file';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type PostMetadataModel from '@typings/database/models/servers/post_metadata';
|
||||
import type PostsInChannelModel from '@typings/database/models/servers/posts_in_channel';
|
||||
import type PostsInThreadModel from '@typings/database/models/servers/posts_in_thread';
|
||||
|
||||
const {
|
||||
DRAFT,
|
||||
@@ -35,15 +28,15 @@ const {
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<PostModel>}
|
||||
*/
|
||||
export const transformPostRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawPost;
|
||||
const record = value.record as Post;
|
||||
export const transformPostRecord = ({action, database, value}: TransformerArgs): Promise<PostModel> => {
|
||||
const raw = value.raw as Post;
|
||||
const record = value.record as PostModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (post: Post) => {
|
||||
const fieldsMapper = (post: PostModel) => {
|
||||
post._raw.id = isCreateAction ? (raw?.id ?? post.id) : record.id;
|
||||
post.channelId = raw.channel_id;
|
||||
post.createAt = raw.create_at;
|
||||
@@ -67,7 +60,7 @@ export const transformPostRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: POST,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<PostModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -75,14 +68,14 @@ export const transformPostRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<PostsInThreadModel>}
|
||||
*/
|
||||
export const transformPostInThreadRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawPostsInThread;
|
||||
const record = value.record as PostsInThread;
|
||||
export const transformPostInThreadRecord = ({action, database, value}: TransformerArgs): Promise<PostsInThreadModel> => {
|
||||
const raw = value.raw as PostsInThread;
|
||||
const record = value.record as PostsInThreadModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (postsInThread: PostsInThread) => {
|
||||
const fieldsMapper = (postsInThread: PostsInThreadModel) => {
|
||||
postsInThread.postId = isCreateAction ? raw.post_id : record.id;
|
||||
postsInThread.earliest = raw.earliest;
|
||||
postsInThread.latest = raw.latest!;
|
||||
@@ -94,7 +87,7 @@ export const transformPostInThreadRecord = ({action, database, value}: Transform
|
||||
tableName: POSTS_IN_THREAD,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<PostsInThreadModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -102,15 +95,15 @@ export const transformPostInThreadRecord = ({action, database, value}: Transform
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<FileModel>}
|
||||
*/
|
||||
export const transformFileRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawFile;
|
||||
const record = value.record as File;
|
||||
export const transformFileRecord = ({action, database, value}: TransformerArgs): Promise<FileModel> => {
|
||||
const raw = value.raw as FileInfo;
|
||||
const record = value.record as FileModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (file: File) => {
|
||||
const fieldsMapper = (file: FileModel) => {
|
||||
file._raw.id = isCreateAction ? (raw?.id ?? file.id) : record.id;
|
||||
file.postId = raw.post_id;
|
||||
file.name = raw.name;
|
||||
@@ -129,7 +122,7 @@ export const transformFileRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: FILE,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<FileModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -137,18 +130,17 @@ export const transformFileRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<PostMetadataModel>}
|
||||
*/
|
||||
export const transformPostMetadataRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawPostMetadata;
|
||||
const record = value.record as PostMetadata;
|
||||
export const transformPostMetadataRecord = ({action, database, value}: TransformerArgs): Promise<PostMetadataModel> => {
|
||||
const raw = value.raw as Metadata;
|
||||
const record = value.record as PostMetadataModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (postMeta: PostMetadata) => {
|
||||
const fieldsMapper = (postMeta: PostMetadataModel) => {
|
||||
postMeta._raw.id = isCreateAction ? postMeta.id : record.id;
|
||||
postMeta.data = raw.data;
|
||||
postMeta.postId = raw.postId;
|
||||
postMeta.type = raw.type;
|
||||
postMeta.postId = raw.post_id;
|
||||
};
|
||||
|
||||
return prepareBaseRecord({
|
||||
@@ -157,7 +149,7 @@ export const transformPostMetadataRecord = ({action, database, value}: Transform
|
||||
tableName: POST_METADATA,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<PostMetadataModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -165,14 +157,14 @@ export const transformPostMetadataRecord = ({action, database, value}: Transform
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<DraftModel>}
|
||||
*/
|
||||
export const transformDraftRecord = ({action, database, value}: TransformerArgs) => {
|
||||
export const transformDraftRecord = ({action, database, value}: TransformerArgs): Promise<DraftModel> => {
|
||||
const emptyFileInfo: FileInfo[] = [];
|
||||
const raw = value.raw as RawDraft;
|
||||
const raw = value.raw as Draft;
|
||||
|
||||
// We use the raw id as Draft is client side only and we would only be creating/deleting drafts
|
||||
const fieldsMapper = (draft: Draft) => {
|
||||
const fieldsMapper = (draft: DraftModel) => {
|
||||
draft._raw.id = draft.id;
|
||||
draft.rootId = raw?.root_id ?? '';
|
||||
draft.message = raw?.message ?? '';
|
||||
@@ -186,7 +178,7 @@ export const transformDraftRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: DRAFT,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<DraftModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -194,14 +186,14 @@ export const transformDraftRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<PostsInChannelModel>}
|
||||
*/
|
||||
export const transformPostsInChannelRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawPostsInChannel;
|
||||
const record = value.record as PostsInChannel;
|
||||
export const transformPostsInChannelRecord = ({action, database, value}: TransformerArgs): Promise<PostsInChannelModel> => {
|
||||
const raw = value.raw as PostsInChannel;
|
||||
const record = value.record as PostsInChannelModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (postsInChannel: PostsInChannel) => {
|
||||
const fieldsMapper = (postsInChannel: PostsInChannelModel) => {
|
||||
postsInChannel._raw.id = isCreateAction ? postsInChannel.id : record.id;
|
||||
postsInChannel.channelId = raw.channel_id;
|
||||
postsInChannel.earliest = raw.earliest;
|
||||
@@ -214,5 +206,5 @@ export const transformPostsInChannelRecord = ({action, database, value}: Transfo
|
||||
tableName: POSTS_IN_CHANNEL,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<PostsInChannelModel>;
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('SlashCommand');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('SlashCommandModel');
|
||||
});
|
||||
|
||||
it('=> transformMyTeamRecord: should return an array of type MyTeam', async () => {
|
||||
@@ -71,7 +71,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyTeam');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('MyTeamModel');
|
||||
});
|
||||
|
||||
it('=> transformTeamRecord: should return an array of type Team', async () => {
|
||||
@@ -107,7 +107,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Team');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamModel');
|
||||
});
|
||||
|
||||
it('=> transformTeamChannelHistoryRecord: should return an array of type Team', async () => {
|
||||
@@ -129,7 +129,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamChannelHistory');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamChannelHistoryModel');
|
||||
});
|
||||
|
||||
it('=> transformTeamSearchHistoryRecord: should return an array of type TeamSearchHistory', async () => {
|
||||
@@ -153,7 +153,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamSearchHistory');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamSearchHistoryModel');
|
||||
});
|
||||
|
||||
it('=> transformTeamMembershipRecord: should return an array of type TeamMembership', async () => {
|
||||
@@ -172,15 +172,15 @@ describe('*** TEAM Prepare Records Test ***', () => {
|
||||
user_id: 'ab',
|
||||
roles: '3ngdqe1e7tfcbmam4qgnxp91bw',
|
||||
delete_at: 0,
|
||||
scheme_guest: false,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
explicit_roles: '',
|
||||
msg_count: 0,
|
||||
mention_count: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamMembership');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('TeamMembershipModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,22 +4,14 @@
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import type {
|
||||
TransformerArgs,
|
||||
RawMyTeam,
|
||||
RawSlashCommand,
|
||||
RawTeam,
|
||||
RawTeamChannelHistory,
|
||||
RawTeamMembership,
|
||||
RawTeamSearchHistory,
|
||||
} from '@typings/database/database';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import MyTeam from '@typings/database/models/servers/my_team';
|
||||
import SlashCommand from '@typings/database/models/servers/slash_command';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import TeamChannelHistory from '@typings/database/models/servers/team_channel_history';
|
||||
import TeamMembership from '@typings/database/models/servers/team_membership';
|
||||
import TeamSearchHistory from '@typings/database/models/servers/team_search_history';
|
||||
import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
|
||||
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
|
||||
|
||||
const {
|
||||
MY_TEAM,
|
||||
@@ -35,15 +27,15 @@ const {
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<TeamMembershipModel>}
|
||||
*/
|
||||
export const transformTeamMembershipRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawTeamMembership;
|
||||
const record = value.record as TeamMembership;
|
||||
export const transformTeamMembershipRecord = ({action, database, value}: TransformerArgs): Promise<TeamMembershipModel> => {
|
||||
const raw = value.raw as TeamMembership;
|
||||
const record = value.record as TeamMembershipModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (teamMembership: TeamMembership) => {
|
||||
const fieldsMapper = (teamMembership: TeamMembershipModel) => {
|
||||
teamMembership._raw.id = isCreateAction ? (raw?.id ?? teamMembership.id) : record.id;
|
||||
teamMembership.teamId = raw.team_id;
|
||||
teamMembership.userId = raw.user_id;
|
||||
@@ -55,7 +47,7 @@ export const transformTeamMembershipRecord = ({action, database, value}: Transfo
|
||||
tableName: TEAM_MEMBERSHIP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<TeamMembershipModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -63,15 +55,15 @@ export const transformTeamMembershipRecord = ({action, database, value}: Transfo
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<TeamModel>}
|
||||
*/
|
||||
export const transformTeamRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawTeam;
|
||||
const record = value.record as Team;
|
||||
export const transformTeamRecord = ({action, database, value}: TransformerArgs): Promise<TeamModel> => {
|
||||
const raw = value.raw as Team;
|
||||
const record = value.record as TeamModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (team: Team) => {
|
||||
const fieldsMapper = (team: TeamModel) => {
|
||||
team._raw.id = isCreateAction ? (raw?.id ?? team.id) : record.id;
|
||||
team.isAllowOpenInvite = raw.allow_open_invite;
|
||||
team.description = raw.description;
|
||||
@@ -90,7 +82,7 @@ export const transformTeamRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: TEAM,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<TeamModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -98,14 +90,14 @@ export const transformTeamRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<TeamChannelHistoryModel>}
|
||||
*/
|
||||
export const transformTeamChannelHistoryRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawTeamChannelHistory;
|
||||
const record = value.record as TeamChannelHistory;
|
||||
export const transformTeamChannelHistoryRecord = ({action, database, value}: TransformerArgs): Promise<TeamChannelHistoryModel> => {
|
||||
const raw = value.raw as TeamChannelHistory;
|
||||
const record = value.record as TeamChannelHistoryModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (teamChannelHistory: TeamChannelHistory) => {
|
||||
const fieldsMapper = (teamChannelHistory: TeamChannelHistoryModel) => {
|
||||
teamChannelHistory._raw.id = isCreateAction ? (teamChannelHistory.id) : record.id;
|
||||
teamChannelHistory.teamId = raw.team_id;
|
||||
teamChannelHistory.channelIds = raw.channel_ids;
|
||||
@@ -117,7 +109,7 @@ export const transformTeamChannelHistoryRecord = ({action, database, value}: Tra
|
||||
tableName: TEAM_CHANNEL_HISTORY,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<TeamChannelHistoryModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -125,14 +117,14 @@ export const transformTeamChannelHistoryRecord = ({action, database, value}: Tra
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<TeamSearchHistoryModel>}
|
||||
*/
|
||||
export const transformTeamSearchHistoryRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawTeamSearchHistory;
|
||||
const record = value.record as TeamSearchHistory;
|
||||
export const transformTeamSearchHistoryRecord = ({action, database, value}: TransformerArgs): Promise<TeamSearchHistoryModel> => {
|
||||
const raw = value.raw as TeamSearchHistory;
|
||||
const record = value.record as TeamSearchHistoryModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (teamSearchHistory: TeamSearchHistory) => {
|
||||
const fieldsMapper = (teamSearchHistory: TeamSearchHistoryModel) => {
|
||||
teamSearchHistory._raw.id = isCreateAction ? (teamSearchHistory.id) : record.id;
|
||||
teamSearchHistory.createdAt = raw.created_at;
|
||||
teamSearchHistory.displayTerm = raw.display_term;
|
||||
@@ -146,7 +138,7 @@ export const transformTeamSearchHistoryRecord = ({action, database, value}: Tran
|
||||
tableName: TEAM_SEARCH_HISTORY,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<TeamSearchHistoryModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -154,15 +146,15 @@ export const transformTeamSearchHistoryRecord = ({action, database, value}: Tran
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<SlashCommandModel>}
|
||||
*/
|
||||
export const transformSlashCommandRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawSlashCommand;
|
||||
const record = value.record as SlashCommand;
|
||||
export const transformSlashCommandRecord = ({action, database, value}: TransformerArgs): Promise<SlashCommandModel> => {
|
||||
const raw = value.raw as SlashCommand;
|
||||
const record = value.record as SlashCommandModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (slashCommand: SlashCommand) => {
|
||||
const fieldsMapper = (slashCommand: SlashCommandModel) => {
|
||||
slashCommand._raw.id = isCreateAction ? (raw?.id ?? slashCommand.id) : record.id;
|
||||
slashCommand.isAutoComplete = raw.auto_complete;
|
||||
slashCommand.description = raw.description;
|
||||
@@ -181,7 +173,7 @@ export const transformSlashCommandRecord = ({action, database, value}: Transform
|
||||
tableName: SLASH_COMMAND,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<SlashCommandModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -189,14 +181,14 @@ export const transformSlashCommandRecord = ({action, database, value}: Transform
|
||||
* @param {DataFactory} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<MyTeamModel>}
|
||||
*/
|
||||
export const transformMyTeamRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawMyTeam;
|
||||
const record = value.record as MyTeam;
|
||||
export const transformMyTeamRecord = ({action, database, value}: TransformerArgs): Promise<MyTeamModel> => {
|
||||
const raw = value.raw as MyTeam;
|
||||
const record = value.record as MyTeamModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const fieldsMapper = (myTeam: MyTeam) => {
|
||||
const fieldsMapper = (myTeam: MyTeamModel) => {
|
||||
myTeam._raw.id = isCreateAction ? myTeam.id : record.id;
|
||||
myTeam.teamId = raw.team_id;
|
||||
myTeam.roles = raw.roles;
|
||||
@@ -210,5 +202,5 @@ export const transformMyTeamRecord = ({action, database, value}: TransformerArgs
|
||||
tableName: MY_TEAM,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<MyTeamModel>;
|
||||
};
|
||||
|
||||
@@ -38,16 +38,14 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
push: 'default',
|
||||
},
|
||||
last_update_at: 1613667352029,
|
||||
scheme_guest: false,
|
||||
scheme_user: true,
|
||||
scheme_admin: false,
|
||||
explicit_roles: '',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelMembership');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ChannelMembershipModel');
|
||||
});
|
||||
|
||||
it('=> transformPreferenceRecord: should return an array of type Preference', async () => {
|
||||
@@ -66,7 +64,7 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Preference');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('PreferenceModel');
|
||||
});
|
||||
|
||||
it('=> transformReactionRecord: should return an array of type Reaction', async () => {
|
||||
@@ -93,7 +91,7 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('Reaction');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('ReactionModel');
|
||||
});
|
||||
|
||||
it('=> transformUserRecord: should return an array of type User', async () => {
|
||||
@@ -114,9 +112,8 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
update_at: 1607683720173,
|
||||
delete_at: 0,
|
||||
username: 'a.l',
|
||||
auth_service: 'saml',
|
||||
auth_service: '',
|
||||
email: 'a.l@mattermost.com',
|
||||
email_verified: true,
|
||||
nickname: '',
|
||||
first_name: 'A',
|
||||
last_name: 'L',
|
||||
@@ -125,19 +122,19 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
props: {},
|
||||
notify_props: {
|
||||
desktop: 'all',
|
||||
desktop_sound: true,
|
||||
email: true,
|
||||
first_name: true,
|
||||
desktop_sound: 'true',
|
||||
email: 'true',
|
||||
first_name: 'true',
|
||||
mention_keys: '',
|
||||
mark_unread: 'mention',
|
||||
push: 'mention',
|
||||
channel: true,
|
||||
auto_responder_active: false,
|
||||
channel: 'true',
|
||||
auto_responder_active: 'false',
|
||||
auto_responder_message: 'Hello, I am out of office and unable to respond to messages.',
|
||||
comments: 'never',
|
||||
desktop_notification_sound: 'Hello',
|
||||
push_status: 'online',
|
||||
},
|
||||
last_password_update: 1604323112537,
|
||||
last_picture_update: 1604686302260,
|
||||
locale: 'en',
|
||||
timezone: {
|
||||
@@ -150,6 +147,6 @@ describe('*** USER Prepare Records Test ***', () => {
|
||||
});
|
||||
|
||||
expect(preparedRecords).toBeTruthy();
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('User');
|
||||
expect(preparedRecords!.collection.modelClass.name).toBe('UserModel');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import ChannelMembership from '@typings/database/models/servers/channel_membership';
|
||||
import {TransformerArgs, RawChannelMembership, RawPreference, RawReaction, RawUser} from '@typings/database/database';
|
||||
|
||||
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
import Preference from '@typings/database/models/servers/preference';
|
||||
import Reaction from '@typings/database/models/servers/reaction';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {
|
||||
CHANNEL_MEMBERSHIP,
|
||||
@@ -22,15 +23,15 @@ const {
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<ReactionModel>}
|
||||
*/
|
||||
export const transformReactionRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawReaction;
|
||||
const record = value.record as Reaction;
|
||||
export const transformReactionRecord = ({action, database, value}: TransformerArgs): Promise<ReactionModel> => {
|
||||
const raw = value.raw as Reaction;
|
||||
const record = value.record as ReactionModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// id of reaction comes from server response
|
||||
const fieldsMapper = (reaction: Reaction) => {
|
||||
const fieldsMapper = (reaction: ReactionModel) => {
|
||||
reaction._raw.id = isCreateAction ? (raw?.id ?? reaction.id) : record.id;
|
||||
reaction.userId = raw.user_id;
|
||||
reaction.postId = raw.post_id;
|
||||
@@ -44,7 +45,7 @@ export const transformReactionRecord = ({action, database, value}: TransformerAr
|
||||
tableName: REACTION,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<ReactionModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -52,15 +53,15 @@ export const transformReactionRecord = ({action, database, value}: TransformerAr
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<UserModel>}
|
||||
*/
|
||||
export const transformUserRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawUser;
|
||||
const record = value.record as User;
|
||||
export const transformUserRecord = ({action, database, value}: TransformerArgs): Promise<UserModel> => {
|
||||
const raw = value.raw as UserProfile;
|
||||
const record = value.record as UserModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// id of user comes from server response
|
||||
const fieldsMapper = (user: User) => {
|
||||
const fieldsMapper = (user: UserModel) => {
|
||||
user._raw.id = isCreateAction ? (raw?.id ?? user.id) : record.id;
|
||||
user.authService = raw.auth_service;
|
||||
user.deleteAt = raw.delete_at;
|
||||
@@ -76,8 +77,8 @@ export const transformUserRecord = ({action, database, value}: TransformerArgs)
|
||||
user.roles = raw.roles;
|
||||
user.username = raw.username;
|
||||
user.notifyProps = raw.notify_props;
|
||||
user.props = raw.props;
|
||||
user.timezone = raw.timezone;
|
||||
user.props = raw.props || null;
|
||||
user.timezone = raw.timezone || null;
|
||||
user.isBot = raw.is_bot;
|
||||
};
|
||||
|
||||
@@ -87,7 +88,7 @@ export const transformUserRecord = ({action, database, value}: TransformerArgs)
|
||||
tableName: USER,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<UserModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -95,15 +96,15 @@ export const transformUserRecord = ({action, database, value}: TransformerArgs)
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<PreferenceModel>}
|
||||
*/
|
||||
export const transformPreferenceRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawPreference;
|
||||
const record = value.record as Preference;
|
||||
export const transformPreferenceRecord = ({action, database, value}: TransformerArgs): Promise<PreferenceModel> => {
|
||||
const raw = value.raw as PreferenceType;
|
||||
const record = value.record as PreferenceModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// id of preference comes from server response
|
||||
const fieldsMapper = (preference: Preference) => {
|
||||
const fieldsMapper = (preference: PreferenceModel) => {
|
||||
preference._raw.id = isCreateAction ? preference.id : record.id;
|
||||
preference.category = raw.category;
|
||||
preference.name = raw.name;
|
||||
@@ -117,7 +118,7 @@ export const transformPreferenceRecord = ({action, database, value}: Transformer
|
||||
tableName: PREFERENCE,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<PreferenceModel>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -125,15 +126,15 @@ export const transformPreferenceRecord = ({action, database, value}: Transformer
|
||||
* @param {TransformerArgs} operator
|
||||
* @param {Database} operator.database
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<Model>}
|
||||
* @returns {Promise<ChannelMembershipModel>}
|
||||
*/
|
||||
export const transformChannelMembershipRecord = ({action, database, value}: TransformerArgs) => {
|
||||
const raw = value.raw as RawChannelMembership;
|
||||
const record = value.record as ChannelMembership;
|
||||
export const transformChannelMembershipRecord = ({action, database, value}: TransformerArgs): Promise<ChannelMembershipModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as ChannelMembershipModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
|
||||
const fieldsMapper = (channelMember: ChannelMembership) => {
|
||||
const fieldsMapper = (channelMember: ChannelMembershipModel) => {
|
||||
channelMember._raw.id = isCreateAction ? (raw?.id ?? channelMember.id) : record.id;
|
||||
channelMember.channelId = raw.channel_id;
|
||||
channelMember.userId = raw.user_id;
|
||||
@@ -145,5 +146,5 @@ export const transformChannelMembershipRecord = ({action, database, value}: Tran
|
||||
tableName: CHANNEL_MEMBERSHIP,
|
||||
value,
|
||||
fieldsMapper,
|
||||
});
|
||||
}) as Promise<ChannelMembershipModel>;
|
||||
};
|
||||
|
||||
@@ -2,23 +2,13 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import Channel from '@typings/database/models/servers/channel';
|
||||
import {
|
||||
IdenticalRecordArgs,
|
||||
RangeOfValueArgs,
|
||||
RawChannel,
|
||||
RawPost,
|
||||
RawSlashCommand,
|
||||
RawTeam,
|
||||
RawUser,
|
||||
RawValue,
|
||||
RecordPair,
|
||||
RetrieveRecordsArgs,
|
||||
} from '@typings/database/database';
|
||||
import Post from '@typings/database/models/servers/post';
|
||||
import SlashCommand from '@typings/database/models/servers/slash_command';
|
||||
import Team from '@typings/database/models/servers/team';
|
||||
import User from '@typings/database/models/servers/user';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type {IdenticalRecordArgs, RangeOfValueArgs, RecordPair, RetrieveRecordsArgs} from '@typings/database/database';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type SlashCommandModel from '@typings/database/models/servers/slash_command';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {CHANNEL, POST, SLASH_COMMAND, TEAM, USER} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -34,8 +24,8 @@ const {CHANNEL, POST, SLASH_COMMAND, TEAM, USER} = MM_TABLES.SERVER;
|
||||
export const getValidRecordsForUpdate = ({tableName, newValue, existingRecord}: IdenticalRecordArgs) => {
|
||||
const guardTables = [CHANNEL, POST, SLASH_COMMAND, TEAM, USER];
|
||||
if (guardTables.includes(tableName)) {
|
||||
type Raw = RawPost | RawUser | RawTeam | RawSlashCommand | RawChannel;
|
||||
type ExistingRecord = Post | User | Team | SlashCommand | Channel;
|
||||
type Raw = Post | UserProfile | Team | SlashCommand | Channel;
|
||||
type ExistingRecord = PostModel | UserModel | TeamModel | SlashCommandModel | ChannelModel;
|
||||
|
||||
const shouldUpdate = (newValue as Raw).update_at === (existingRecord as ExistingRecord).updateAt;
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ChainPostsArgs, RawPost, RecordPair, SanitizePostsArgs} from '@typings/database/database';
|
||||
import type {ChainPostsArgs, RecordPair, SanitizePostsArgs} from '@typings/database/database';
|
||||
|
||||
/**
|
||||
* sanitizePosts: Creates arrays of ordered and unordered posts. Unordered posts are those posts that are not
|
||||
* present in the orders array
|
||||
* @param {SanitizePostsArgs} sanitizePosts
|
||||
* @param {RawPost[]} sanitizePosts.posts
|
||||
* @param {Post[]} sanitizePosts.posts
|
||||
* @param {string[]} sanitizePosts.orders
|
||||
*/
|
||||
export const sanitizePosts = ({posts, orders}: SanitizePostsArgs) => {
|
||||
const orderedPosts: RawPost[] = [];
|
||||
const unOrderedPosts: RawPost[] = [];
|
||||
const orderedPosts: Post[] = [];
|
||||
const unOrderedPosts: Post[] = [];
|
||||
|
||||
posts.forEach((post) => {
|
||||
if (post?.id && orders.includes(post.id)) {
|
||||
@@ -33,9 +33,9 @@ export const sanitizePosts = ({posts, orders}: SanitizePostsArgs) => {
|
||||
* by the previous_post_id field.
|
||||
* @param {ChainPostsArgs} chainPosts
|
||||
* @param {string[]} chainPosts.orders
|
||||
* @param {RawPost[]} chainPosts.rawPosts
|
||||
* @param {Post[]} chainPosts.rawPosts
|
||||
* @param {string} chainPosts.previousPostId
|
||||
* @returns {RawPost[]}
|
||||
* @returns {Post[]}
|
||||
*/
|
||||
export const createPostsChain = ({orders, rawPosts, previousPostId = ''}: ChainPostsArgs) => {
|
||||
const posts: RecordPair[] = [];
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
import {Q} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {RecordPair, SanitizeReactionsArgs} from '@typings/database/database';
|
||||
import Reaction from '@typings/database/models/servers/reaction';
|
||||
|
||||
import type {RecordPair, SanitizeReactionsArgs} from '@typings/database/database';
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
|
||||
const {REACTION} = MM_TABLES.SERVER;
|
||||
|
||||
@@ -22,10 +23,10 @@ export const sanitizeReactions = async ({database, post_id, rawReactions}: Sanit
|
||||
const reactions = (await database.collections.
|
||||
get(REACTION).
|
||||
query(Q.where('post_id', post_id)).
|
||||
fetch()) as Reaction[];
|
||||
fetch()) as ReactionModel[];
|
||||
|
||||
// similarObjects: Contains objects that are in both the RawReaction array and in the Reaction table
|
||||
const similarObjects: Reaction[] = [];
|
||||
const similarObjects: ReactionModel[] = [];
|
||||
|
||||
const createReactions: RecordPair[] = [];
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {createPostsChain, sanitizePosts} from '@database/operator/utils/post';
|
||||
import {sanitizeReactions} from '@database/operator/utils/reaction';
|
||||
import {RawPost} from '@typings/database/database';
|
||||
import Reaction from '@typings/database/models/servers/reaction';
|
||||
|
||||
import type ReactionModel from '@typings/database/models/servers/reaction';
|
||||
|
||||
import {mockedPosts, mockedReactions} from './mock';
|
||||
|
||||
describe('DataOperator: Utils tests', () => {
|
||||
it('=> sanitizePosts: should filter between ordered and unordered posts', () => {
|
||||
const {postsOrdered, postsUnordered} = sanitizePosts({
|
||||
posts: Object.values(mockedPosts.posts),
|
||||
posts: Object.values(mockedPosts.posts) as Post[],
|
||||
orders: mockedPosts.order,
|
||||
});
|
||||
expect(postsOrdered.length).toBe(4);
|
||||
@@ -23,42 +23,42 @@ describe('DataOperator: Utils tests', () => {
|
||||
const previousPostId = 'prev_xxyuoxmehne';
|
||||
const chainedOfPosts = createPostsChain({
|
||||
orders: mockedPosts.order,
|
||||
rawPosts: Object.values(mockedPosts.posts),
|
||||
rawPosts: Object.values(mockedPosts.posts) as Post[],
|
||||
previousPostId,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
const post1 = chainedOfPosts.find((post) => {
|
||||
const p = post.raw as unknown as RawPost;
|
||||
const p = post.raw as Post;
|
||||
return p.id === '8swgtrrdiff89jnsiwiip3y1eoe';
|
||||
})?.raw as unknown as RawPost;
|
||||
})?.raw as Post;
|
||||
|
||||
expect(post1).toBeTruthy();
|
||||
expect(post1?.prev_post_id).toBe(previousPostId);
|
||||
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
const post2 = chainedOfPosts.find((post) => {
|
||||
const p = post.raw as unknown as RawPost;
|
||||
const p = post.raw as Post;
|
||||
return p.id === '8fcnk3p1jt8mmkaprgajoxz115a';
|
||||
})?.raw as unknown as RawPost;
|
||||
})?.raw as Post;
|
||||
|
||||
expect(post2).toBeTruthy();
|
||||
expect(post2!.prev_post_id).toBe('8swgtrrdiff89jnsiwiip3y1eoe');
|
||||
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
const post3 = chainedOfPosts.find((post) => {
|
||||
const p = post.raw as unknown as RawPost;
|
||||
const p = post.raw as Post;
|
||||
return p.id === '3y3w3a6gkbg73bnj3xund9o5ic';
|
||||
})?.raw as unknown as RawPost;
|
||||
})?.raw as Post;
|
||||
|
||||
expect(post3).toBeTruthy();
|
||||
expect(post3?.prev_post_id).toBe('8fcnk3p1jt8mmkaprgajoxz115a');
|
||||
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
const post4 = chainedOfPosts.find((post) => {
|
||||
const p = post.raw as unknown as RawPost;
|
||||
const p = post.raw as Post;
|
||||
return p.id === '4btbnmticjgw7ewd3qopmpiwqw';
|
||||
})?.raw as unknown as RawPost;
|
||||
})?.raw as Post;
|
||||
|
||||
expect(post4).toBeTruthy();
|
||||
expect(post4!.prev_post_id).toBe('3y3w3a6gkbg73bnj3xund9o5ic');
|
||||
@@ -82,12 +82,10 @@ describe('DataOperator: Utils tests', () => {
|
||||
post_id: '8ww8kb1dbpf59fu4d5xhu5nf5w',
|
||||
emoji_name: 'tada_will_be_removed',
|
||||
create_at: 1601558322701,
|
||||
update_at: 1601558322701,
|
||||
delete_at: 0,
|
||||
},
|
||||
],
|
||||
prepareRecordsOnly: true,
|
||||
}) as Reaction[];
|
||||
}) as ReactionModel[];
|
||||
|
||||
// Jest in not using the same database instance amongst the Singletons; hence, we are creating the reaction record here
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
|
||||
@@ -12,6 +12,5 @@ export default tableSchema({
|
||||
columns: [
|
||||
{name: 'data', type: 'string'},
|
||||
{name: 'post_id', type: 'string', isIndexed: true},
|
||||
{name: 'type', type: 'string'},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -208,12 +208,10 @@ describe('*** Test schema for SERVER database ***', () => {
|
||||
columns: {
|
||||
data: {name: 'data', type: 'string'},
|
||||
post_id: {name: 'post_id', type: 'string', isIndexed: true},
|
||||
type: {name: 'type', type: 'string'},
|
||||
},
|
||||
columnArray: [
|
||||
{name: 'data', type: 'string'},
|
||||
{name: 'post_id', type: 'string', isIndexed: true},
|
||||
{name: 'type', type: 'string'},
|
||||
],
|
||||
},
|
||||
[POST]: {
|
||||
|
||||
26
app/helpers/api/preference.ts
Normal file
26
app/helpers/api/preference.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export function getPreferenceValue(preferences: PreferenceType[], category: string, name: string, defaultValue: unknown = '') {
|
||||
const pref = preferences.find((p) => p.category === category && p.name === name);
|
||||
|
||||
return pref?.value || defaultValue;
|
||||
}
|
||||
|
||||
export function getPreferenceAsBool(preferences: PreferenceType[], category: string, name: string, defaultValue = false) {
|
||||
const value = getPreferenceValue(preferences, category, name, defaultValue);
|
||||
if (typeof value === 'boolean') {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value !== 'false';
|
||||
}
|
||||
|
||||
export function getPreferenceAsInt(preferences: PreferenceType[], category: string, name: string, defaultValue = 0) {
|
||||
const value = getPreferenceValue(preferences, category, name, defaultValue);
|
||||
if (value) {
|
||||
return parseInt(value as string, 10);
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
62
app/helpers/api/team.ts
Normal file
62
app/helpers/api/team.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {DEFAULT_LOCALE} from '@i18n';
|
||||
|
||||
export const selectDefaultTeam = (teams: Team[], locale = DEFAULT_LOCALE, userTeamOrderPreference = '', primaryTeam = '') => {
|
||||
let defaultTeam;
|
||||
|
||||
if (!teams.length) {
|
||||
return defaultTeam;
|
||||
}
|
||||
|
||||
if (primaryTeam) {
|
||||
defaultTeam = teams.find((t) => t.name.toLowerCase() === primaryTeam.toLowerCase());
|
||||
}
|
||||
|
||||
if (!defaultTeam) {
|
||||
defaultTeam = sortTeamsByUserPreference(teams, locale, userTeamOrderPreference)[0];
|
||||
}
|
||||
|
||||
return defaultTeam;
|
||||
};
|
||||
|
||||
export const sortTeamsByUserPreference = (teams: Team[], locale: string, teamsOrder = '') => {
|
||||
if (!teams.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const teamsOrderList = teamsOrder.split(',').filter((t) => t);
|
||||
|
||||
if (!teamsOrderList.length) {
|
||||
return [...teams].sort(sortTeamsWithLocale(locale));
|
||||
}
|
||||
|
||||
const customSortedTeams = teams.filter((team) => {
|
||||
if (team !== null) {
|
||||
return teamsOrderList.includes(team.id);
|
||||
}
|
||||
return false;
|
||||
}).sort((a, b) => {
|
||||
return teamsOrderList.indexOf(a.id) - teamsOrderList.indexOf(b.id);
|
||||
});
|
||||
|
||||
const otherTeams = teams.filter((team) => {
|
||||
if (team !== null) {
|
||||
return !teamsOrderList.includes(team.id);
|
||||
}
|
||||
return false;
|
||||
}).sort(sortTeamsWithLocale(locale));
|
||||
|
||||
return [...customSortedTeams, ...otherTeams];
|
||||
};
|
||||
|
||||
export function sortTeamsWithLocale(locale: string): (a: Team, b: Team) => number {
|
||||
return (a: Team, b: Team): number => {
|
||||
if (a.display_name !== b.display_name) {
|
||||
return a.display_name.toLowerCase().localeCompare(b.display_name.toLowerCase(), locale, {numeric: true});
|
||||
}
|
||||
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase(), locale, {numeric: true});
|
||||
};
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import {Alert, DeviceEventEmitter, Linking, Platform} from 'react-native';
|
||||
import CookieManager, {Cookie} from '@react-native-cookies/cookies';
|
||||
import semver from 'semver';
|
||||
|
||||
import {fetchConfigAndLicense} from '@actions/remote/general';
|
||||
import {fetchConfigAndLicense} from '@actions/remote/systems';
|
||||
import LocalConfig from '@assets/config.json';
|
||||
import {General, REDIRECT_URL_SCHEME, REDIRECT_URL_SCHEME_DEV} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
|
||||
15
app/queries/servers/preference.ts
Normal file
15
app/queries/servers/preference.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
|
||||
export const prepareMyPreferences = (operator: ServerDataOperator, preferences: PreferenceType[]) => {
|
||||
try {
|
||||
return operator.handlePreferences({
|
||||
prepareRecordsOnly: true,
|
||||
preferences,
|
||||
});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
@@ -4,13 +4,15 @@
|
||||
import {Database} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import System from '@typings/database/models/servers/system';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
const {SERVER: {SYSTEM}} = MM_TABLES;
|
||||
|
||||
export const queryCurrentChannelId = async (serverDatabase: Database) => {
|
||||
try {
|
||||
const currentChannelId = await serverDatabase.get(SYSTEM).find(SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID) as System;
|
||||
const currentChannelId = await serverDatabase.get(SYSTEM).find(SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID) as SystemModel;
|
||||
return currentChannelId?.value || '';
|
||||
} catch {
|
||||
return '';
|
||||
@@ -19,7 +21,7 @@ export const queryCurrentChannelId = async (serverDatabase: Database) => {
|
||||
|
||||
export const queryCurrentUserId = async (serverDatabase: Database) => {
|
||||
try {
|
||||
const currentUserId = await serverDatabase.get(SYSTEM).find(SYSTEM_IDENTIFIERS.CURRENT_USER_ID) as System;
|
||||
const currentUserId = await serverDatabase.get(SYSTEM).find(SYSTEM_IDENTIFIERS.CURRENT_USER_ID) as SystemModel;
|
||||
return currentUserId?.value || '';
|
||||
} catch {
|
||||
return '';
|
||||
@@ -27,7 +29,7 @@ export const queryCurrentUserId = async (serverDatabase: Database) => {
|
||||
};
|
||||
|
||||
export const queryCommonSystemValues = async (database: Database) => {
|
||||
const systemRecords = (await database.collections.get(SYSTEM).query().fetch()) as System[];
|
||||
const systemRecords = (await database.collections.get(SYSTEM).query().fetch()) as SystemModel[];
|
||||
let config = {};
|
||||
let license = {};
|
||||
let currentChannelId = '';
|
||||
@@ -61,3 +63,37 @@ export const queryCommonSystemValues = async (database: Database) => {
|
||||
license,
|
||||
};
|
||||
};
|
||||
|
||||
export const prepareCommonSystemValues = (
|
||||
operator: ServerDataOperator, config: ClientConfig, license: ClientLicense,
|
||||
currentUserId: string, currentTeamId: string, currentChannelId: string) => {
|
||||
try {
|
||||
return operator.handleSystem({
|
||||
systems: [
|
||||
{
|
||||
id: SYSTEM_IDENTIFIERS.CONFIG,
|
||||
value: JSON.stringify(config),
|
||||
},
|
||||
{
|
||||
id: SYSTEM_IDENTIFIERS.LICENSE,
|
||||
value: JSON.stringify(license),
|
||||
},
|
||||
{
|
||||
id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID,
|
||||
value: currentUserId,
|
||||
},
|
||||
{
|
||||
id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID,
|
||||
value: currentTeamId,
|
||||
},
|
||||
{
|
||||
id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID,
|
||||
value: currentChannelId,
|
||||
},
|
||||
],
|
||||
prepareRecordsOnly: true,
|
||||
});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
23
app/queries/servers/team.ts
Normal file
23
app/queries/servers/team.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
|
||||
export const prepareMyTeams = (operator: ServerDataOperator, teams: Team[], memberships: TeamMembership[], unreads: TeamUnread[]) => {
|
||||
try {
|
||||
const teamRecords = operator.handleTeam({prepareRecordsOnly: true, teams});
|
||||
const teamMembershipRecords = operator.handleTeamMemberships({prepareRecordsOnly: true, teamMemberships: memberships});
|
||||
const myTeams: MyTeam[] = unreads.map((unread) => {
|
||||
const matchingTeam = memberships.find((team) => team.team_id === unread.team_id);
|
||||
return {team_id: unread.team_id, roles: matchingTeam?.roles ?? '', is_unread: unread.msg_count > 0, mentions_count: unread.mention_count};
|
||||
});
|
||||
const myTeamRecords = operator.handleMyTeam({
|
||||
prepareRecordsOnly: true,
|
||||
myTeams,
|
||||
});
|
||||
|
||||
return [teamRecords, teamMembershipRecords, myTeamRecords];
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
|
||||
import type {LaunchProps} from '@typings/launch';
|
||||
|
||||
import {logout} from '@actions/remote/user';
|
||||
import {logout} from '@actions/remote/general';
|
||||
import {useServerUrl} from '@context/server_url';
|
||||
import {useTheme} from '@context/theme';
|
||||
|
||||
|
||||
@@ -19,16 +19,14 @@ import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
import ErrorText from '@components/error_text';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import {login} from '@actions/remote/user';
|
||||
import {Config} from '@typings/database/models/servers/config';
|
||||
import {License} from '@typings/database/models/servers/license';
|
||||
import {t} from '@utils/i18n';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
type MFAProps = {
|
||||
config: Partial<Config>;
|
||||
config: Partial<ClientConfig>;
|
||||
goToChannel: () => void;
|
||||
license: Partial<License>;
|
||||
license: Partial<ClientLicense>;
|
||||
loginId: string;
|
||||
password: string;
|
||||
serverUrl: string;
|
||||
|
||||
@@ -12,7 +12,8 @@ import Button from 'react-native-button';
|
||||
import {Navigation, NavigationFunctionComponent} from 'react-native-navigation';
|
||||
import {SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {doPing, fetchConfigAndLicense} from '@actions/remote/general';
|
||||
import {doPing} from '@actions/remote/general';
|
||||
import {fetchConfigAndLicense} from '@actions/remote/systems';
|
||||
import LocalConfig from '@assets/config.json';
|
||||
import AppVersion from '@components/app_version';
|
||||
import ErrorText, {ClientErrorWithIntl} from '@components/error_text';
|
||||
|
||||
@@ -27,6 +27,7 @@ module.exports = {
|
||||
'@constants': './app/constants',
|
||||
'@context': './app/context',
|
||||
'@database': './app/database',
|
||||
'@helpers': './app/helpers',
|
||||
'@i18n': './app/i18n',
|
||||
'@init': './app/init',
|
||||
'@notifications': './app/notifications',
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"@constants/*": ["app/constants/*"],
|
||||
"@context/*": ["app/context/*"],
|
||||
"@database/*": ["app/database/*"],
|
||||
"@helpers/*": ["app/helpers/*"],
|
||||
"@i18n": ["app/i18n/index"],
|
||||
"@init/*": ["app/init/*"],
|
||||
"@notifications": ["app/notifications/index"],
|
||||
|
||||
11
types/api/channels.d.ts
vendored
11
types/api/channels.d.ts
vendored
@@ -28,12 +28,13 @@ type Channel = {
|
||||
total_msg_count: number;
|
||||
extra_update_at: number;
|
||||
creator_id: string;
|
||||
scheme_id: string;
|
||||
scheme_id: string|null;
|
||||
isCurrent?: boolean;
|
||||
teammate_id?: string;
|
||||
status?: string;
|
||||
fake?: boolean;
|
||||
group_constrained: boolean;
|
||||
group_constrained: boolean|null;
|
||||
shared: boolean|null;
|
||||
};
|
||||
type ChannelWithTeamData = Channel & {
|
||||
team_display_name: string;
|
||||
@@ -41,6 +42,7 @@ type ChannelWithTeamData = Channel & {
|
||||
team_update_at: number;
|
||||
}
|
||||
type ChannelMembership = {
|
||||
id?: string;
|
||||
channel_id: string;
|
||||
user_id: string;
|
||||
roles: string;
|
||||
@@ -48,9 +50,10 @@ type ChannelMembership = {
|
||||
msg_count: number;
|
||||
mention_count: number;
|
||||
notify_props: Partial<ChannelNotifyProps>;
|
||||
last_post_at?: number;
|
||||
last_update_at: number;
|
||||
scheme_user: boolean;
|
||||
scheme_admin: boolean;
|
||||
scheme_user?: boolean;
|
||||
scheme_admin?: boolean;
|
||||
post_root_id?: string;
|
||||
};
|
||||
type ChannelUnread = {
|
||||
|
||||
12
types/api/emojis.d.ts
vendored
12
types/api/emojis.d.ts
vendored
@@ -3,11 +3,12 @@
|
||||
|
||||
type EmojiCategory = (
|
||||
| 'recent'
|
||||
| 'people'
|
||||
| 'nature'
|
||||
| 'foods'
|
||||
| 'activity'
|
||||
| 'places'
|
||||
| 'smileys-emotion'
|
||||
| 'people-body'
|
||||
| 'animals-nature'
|
||||
| 'food-drink'
|
||||
| 'travel-places'
|
||||
| 'activities'
|
||||
| 'objects'
|
||||
| 'symbols'
|
||||
| 'flags'
|
||||
@@ -21,7 +22,6 @@ type CustomEmoji = {
|
||||
delete_at: number;
|
||||
creator_id: string;
|
||||
name: string;
|
||||
category: 'custom';
|
||||
};
|
||||
|
||||
type SystemEmoji = {
|
||||
|
||||
5
types/api/files.d.ts
vendored
5
types/api/files.d.ts
vendored
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
type FileInfo = {
|
||||
id: string;
|
||||
id?: string;
|
||||
user_id: string;
|
||||
post_id: string;
|
||||
create_at: number;
|
||||
@@ -10,12 +10,13 @@ type FileInfo = {
|
||||
delete_at: number;
|
||||
name: string;
|
||||
extension: string;
|
||||
mini_preview?: string;
|
||||
size: number;
|
||||
mime_type: string;
|
||||
width: number;
|
||||
height: number;
|
||||
has_preview_image: boolean;
|
||||
clientId: string;
|
||||
clientId?: string;
|
||||
localPath?: string;
|
||||
uri?: string;
|
||||
loading?: boolean;
|
||||
|
||||
8
types/api/groups.d.ts
vendored
8
types/api/groups.d.ts
vendored
@@ -18,7 +18,7 @@ type Group = {
|
||||
delete_at: number;
|
||||
has_syncables: boolean;
|
||||
member_count: number;
|
||||
scheme_admin: boolean;
|
||||
scheme_admin?: boolean;
|
||||
allow_reference: boolean;
|
||||
};
|
||||
type GroupTeam = {
|
||||
@@ -27,7 +27,7 @@ type GroupTeam = {
|
||||
team_type: string;
|
||||
group_id: string;
|
||||
auto_add: boolean;
|
||||
scheme_admin: boolean;
|
||||
scheme_admin?: boolean;
|
||||
create_at: number;
|
||||
delete_at: number;
|
||||
update_at: number;
|
||||
@@ -41,10 +41,12 @@ type GroupChannel = {
|
||||
team_type: string;
|
||||
group_id: string;
|
||||
auto_add: boolean;
|
||||
scheme_admin: boolean;
|
||||
scheme_admin?: boolean;
|
||||
create_at: number;
|
||||
delete_at: number;
|
||||
update_at: number;
|
||||
member_count: number;
|
||||
timezone_count: number;
|
||||
};
|
||||
type GroupSyncables = {
|
||||
teams: GroupTeam[];
|
||||
|
||||
43
types/api/posts.d.ts
vendored
43
types/api/posts.d.ts
vendored
@@ -1,20 +1,22 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
type PostType = 'system_add_remove' |
|
||||
'system_add_to_channel' |
|
||||
'system_add_to_team' |
|
||||
'system_channel_deleted' |
|
||||
'system_channel_restored' |
|
||||
'system_displayname_change' |
|
||||
'system_convert_channel' |
|
||||
'system_ephemeral' |
|
||||
'system_header_change' |
|
||||
'system_join_channel' |
|
||||
'system_join_leave' |
|
||||
'system_leave_channel' |
|
||||
'system_purpose_change' |
|
||||
'system_remove_from_channel';
|
||||
type PostType =
|
||||
| ''
|
||||
| 'system_add_remove'
|
||||
| 'system_add_to_channel'
|
||||
| 'system_add_to_team'
|
||||
| 'system_channel_deleted'
|
||||
| 'system_channel_restored'
|
||||
| 'system_displayname_change'
|
||||
| 'system_convert_channel'
|
||||
| 'system_ephemeral'
|
||||
| 'system_header_change'
|
||||
| 'system_join_channel'
|
||||
| 'system_join_leave'
|
||||
| 'system_leave_channel'
|
||||
| 'system_purpose_change'
|
||||
| 'system_remove_from_channel';
|
||||
|
||||
type PostEmbedType = 'image' | 'message_attachment' | 'opengraph';
|
||||
|
||||
@@ -32,11 +34,11 @@ type PostImage = {
|
||||
};
|
||||
|
||||
type PostMetadata = {
|
||||
embeds: PostEmbed[];
|
||||
emojis: CustomEmoji[];
|
||||
files: FileInfo[];
|
||||
images: Dictionary<PostImage>;
|
||||
reactions: Reaction[];
|
||||
embeds?: PostEmbed[];
|
||||
emojis?: CustomEmoji[];
|
||||
files?: FileInfo[];
|
||||
images?: Dictionary<PostImage>;
|
||||
reactions?: Reaction[];
|
||||
};
|
||||
|
||||
type Post = {
|
||||
@@ -59,10 +61,13 @@ type Post = {
|
||||
reply_count: number;
|
||||
file_ids?: any[];
|
||||
metadata: PostMetadata;
|
||||
last_reply_at?: number;
|
||||
failed?: boolean;
|
||||
user_activity_posts?: Post[];
|
||||
state?: 'DELETED';
|
||||
ownPost?: boolean;
|
||||
prev_post_id?: string;
|
||||
participants: null|string[];
|
||||
};
|
||||
|
||||
type PostWithFormatData = Post & {
|
||||
|
||||
1
types/api/reactions.d.ts
vendored
1
types/api/reactions.d.ts
vendored
@@ -2,6 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
type Reaction = {
|
||||
id?: string;
|
||||
user_id: string;
|
||||
post_id: string;
|
||||
emoji_name: string;
|
||||
|
||||
14
types/api/roles.d.ts
vendored
14
types/api/roles.d.ts
vendored
@@ -6,12 +6,12 @@ type ChannelModerationRoles = 'members' | 'guests';
|
||||
type Role = {
|
||||
id: string;
|
||||
name: string;
|
||||
display_name: string;
|
||||
description: string;
|
||||
create_at: number;
|
||||
update_at: number;
|
||||
delete_at: number;
|
||||
display_name?: string;
|
||||
description?: string;
|
||||
create_at?: number;
|
||||
update_at?: number;
|
||||
delete_at?: number;
|
||||
permissions: string[];
|
||||
scheme_managed: boolean;
|
||||
built_in: boolean;
|
||||
scheme_managed?: boolean;
|
||||
built_in?: boolean;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user