/* eslint-disable @typescript-eslint/no-explicit-any */ import knex from '@/db/knex' import { Knex } from 'knex' import { reduce } from 'lodash' /** * TODO: * ServerInvites: * - Get rid of the 'used' field, it's not used anymore */ type SchemaConfig = InnerSchemaConfig & { /** * Return schema helper with custom configuration options */ with: (params?: SchemaConfigParams) => InnerSchemaConfig /** * Helper with withoutTablePrefix set to true */ withoutTablePrefix: InnerSchemaConfig } type InnerSchemaConfig = { /** * Table name */ name: T /** * Get `knex(tableName)` QueryBuilder instance. Use the generic argument to type the results of the query. */ knex: () => Knex.QueryBuilder /** * Get names of table columns. The names can be prefixed with the table name or not, depending * on whether `withoutTablePrefix` was set when accessing the helper. */ col: { [colName in C]: string } /** * All of the column names in an array */ cols: string[] } type SchemaConfigParams = { /** * Configure `col` properties to not have the table name prefixed. For the most part you want the prefix, * cause this helps in queries with JOINS (when multiple tables have a col with the same name), but you don't * want the prefix when triggering UPDATE queries, because the `SET = ` syntax doesn't support * column names with table prefixes. */ withoutTablePrefix?: boolean } function buildTableHelper( tableName: T, columns: C[] ): SchemaConfig { function buildInnerSchemaConfig( params: SchemaConfigParams = {} ): InnerSchemaConfig { const colName = (col: string) => params.withoutTablePrefix ? col : `${tableName}.${col}` return { name: tableName, knex: () => knex(tableName), col: reduce( columns, (prev, curr) => { prev[curr] = colName(curr) return prev }, {} as Record ), cols: columns.map(colName) } } return { ...buildInnerSchemaConfig(), with: buildInnerSchemaConfig, withoutTablePrefix: buildInnerSchemaConfig({ withoutTablePrefix: true }) } } /* * TABLE HELPERS * The generated helpers are used like this: * * Streams.name - TableName * Streams.col.id - Get column names * Streams.knex() - Get knex() instance for this specific table * * Streams.with({...}) - configure helper, e.g. disable table name being prefixed to col names: * Streams.with({withoutTablePrefix: true}).col.id * * Streams.withoutTablePrefix.col.id - Shorthand for accessing columns without the table prefix */ export const Streams = buildTableHelper('streams', [ 'id', 'name', 'description', 'isPublic', 'clonedFrom', 'createdAt', 'updatedAt', 'allowPublicComments', 'isDiscoverable' ]) export const StreamAcl = buildTableHelper('stream_acl', [ 'userId', 'resourceId', 'role' ]) export const StreamFavorites = buildTableHelper('stream_favorites', [ 'streamId', 'userId', 'createdAt', 'cursor' ]) export const Users = buildTableHelper('users', [ 'id', 'suuid', 'createdAt', 'name', 'bio', 'company', 'email', 'verified', 'avatar', 'profiles', 'passwordDigest', 'ip' ]) export const ServerAcl = buildTableHelper('server_acl', ['userId', 'role']) export const Comments = buildTableHelper('comments', [ 'id', 'streamId', 'authorId', 'createdAt', 'updatedAt', 'text', 'screenshot', 'data', 'archived', 'parentComment' ]) export const CommentLinks = buildTableHelper('comment_links', [ 'commentId', 'resourceId', 'resourceType' ]) export const ServerInvites = buildTableHelper('server_invites', [ 'id', 'target', 'inviterId', 'createdAt', 'used', 'message', 'resourceTarget', 'resourceId', 'role', 'token' ]) export const PasswordResetTokens = buildTableHelper('pwdreset_tokens', [ 'id', 'email', 'createdAt' ]) export const RefreshTokens = buildTableHelper('refresh_tokens', [ 'id', 'tokenDigest', 'appId', 'userId', 'createdAt', 'lifespan' ]) export const AuthorizationCodes = buildTableHelper('authorization_codes', [ 'id', 'appId', 'userId', 'challenge', 'createdAt', 'lifespan' ]) export const ApiTokens = buildTableHelper('api_tokens', [ 'id', 'tokenDigest', 'owner', 'name', 'lastChars', 'revoked', 'lifespan', 'createdAt', 'lastUsed' ]) export const EmailVerifications = buildTableHelper('email_verifications', [ 'id', 'email', 'createdAt', 'used' ]) export const ServerAccessRequests = buildTableHelper('server_access_requests', [ 'id', 'requesterId', 'resourceType', 'resourceId', 'createdAt', 'updatedAt' ]) export const StreamActivity = buildTableHelper('stream_activity', [ 'streamId', 'time', 'resourceType', 'resourceId', 'actionType', 'userId', 'info', 'message' ]) export const UserNotificationPreferences = buildTableHelper( 'user_notification_preferences', ['userId', 'preferences'] ) export const Commits = buildTableHelper('commits', [ 'id', 'referencedObject', 'author', 'message', 'createdAt', 'sourceApplication', 'totalChildrenCount', 'parents' ]) export const StreamCommits = buildTableHelper('stream_commits', [ 'streamId', 'commitId' ]) export const BranchCommits = buildTableHelper('branch_commits', [ 'branchId', 'commitId' ]) export const Branches = buildTableHelper('branches', [ 'id', 'streamId', 'authorId', 'name', 'description', 'createdAt', 'updatedAt' ]) export const ScheduledTasks = buildTableHelper('scheduled_tasks', [ 'taskName', 'lockExpiresAt' ]) export const Objects = buildTableHelper('objects', [ 'id', 'speckleType', 'totalChildrenCount', 'totalChildrenCountByDepth', 'createdAt', 'data', 'streamId' ]) export { knex }