-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathconfig.ts
107 lines (93 loc) · 4.13 KB
/
config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { EntityManager } from 'typeorm'
import { CommentTipTier, GatewayConfig } from '../model'
import { withHiddenEntities } from './sql'
export enum ConfigVariable {
SupportNoCategoryVideo = 'SUPPORT_NO_CATEGORY_VIDEOS',
SupportNewCategories = 'SUPPORT_NEW_CATEGORIES',
CrtMarketCapMinVolumeJoy = 'CRT_MARKET_CAP_MIN_VOLUME_JOY',
KillSwitch = 'KILL_SWITCH_ON',
VideoViewPerUserTimeLimit = 'VIDEO_VIEW_PER_USER_TIME_LIMIT',
VideoRelevanceViewsTick = 'VIDEO_RELEVANCE_VIEWS_TICK',
RelevanceWeights = 'RELEVANCE_WEIGHTS',
AppPrivateKey = 'APP_PRIVATE_KEY',
AppRootDomain = 'APP_ROOT_DOMAIN',
SessionExpiryAfterInactivityMinutes = 'SESSION_EXPIRY_AFTER_INACTIVITY_MINUTES',
SessionMaxDurationHours = 'SESSION_MAX_DURATION_HOURS',
SendgridApiKey = 'SENDGRID_API_KEY',
SendgridFromEmail = 'SENDGRID_FROM_EMAIL',
AppName = 'APP_NAME',
EmailConfirmationRoute = 'EMAIL_CONFIRMATION_ROUTE',
EmailConfirmationTokenExpiryTimeHours = 'EMAIL_CONFIRMATION_TOKEN_EXPIRY_TIME_HOURS',
EmailConfirmationTokenRateLimit = 'EMAIL_CONFIRMATION_TOKEN_RATE_LIMIT',
AccountOwnershipProofExpiryTimeSeconds = 'ACCOUNT_OWNERSHIP_PROOF_EXPIRY_TIME_SECONDS',
EmailNotificationDeliveryMaxAttempts = 'EMAIL_NOTIFICATION_DELIVERY_MAX_ATTEMPTS',
AppAssetStorage = 'APP_ASSET_STORAGE',
AppNameAlt = 'APP_NAME_ALT',
NotificationAssetRoot = 'NOTIFICATION_ASSET_ROOT',
CommentTipTiers = 'COMMENT_TIP_TIERS',
}
const boolType = {
serialize: (v: boolean) => (v ? '1' : '0'),
deserialize: (v: string) => v === 'true' || v === '1',
} as const
const intType = {
serialize: (v: number) => v.toString(),
deserialize: (v: string) => parseInt(v),
} as const
const stringType = {
serialize: (v: string) => v,
deserialize: (v: string) => v,
}
const jsonType = <T>() => ({
serialize: (v: T) => JSON.stringify(v),
deserialize: (v: string) => JSON.parse(v) as T,
})
export type CommentTipTiers = { [key in CommentTipTier]: number }
export const configVariables = {
[ConfigVariable.SupportNoCategoryVideo]: boolType,
[ConfigVariable.SupportNewCategories]: boolType,
[ConfigVariable.CrtMarketCapMinVolumeJoy]: intType,
[ConfigVariable.KillSwitch]: boolType,
[ConfigVariable.VideoViewPerUserTimeLimit]: intType,
[ConfigVariable.VideoRelevanceViewsTick]: intType,
[ConfigVariable.RelevanceWeights]:
jsonType<[number, number, number, number, [number, number], number]>(),
[ConfigVariable.AppPrivateKey]: stringType,
[ConfigVariable.SessionMaxDurationHours]: intType,
[ConfigVariable.SessionExpiryAfterInactivityMinutes]: intType,
[ConfigVariable.SendgridApiKey]: stringType,
[ConfigVariable.SendgridFromEmail]: stringType,
[ConfigVariable.AppName]: stringType,
[ConfigVariable.EmailConfirmationRoute]: stringType,
[ConfigVariable.EmailConfirmationTokenExpiryTimeHours]: intType,
[ConfigVariable.AccountOwnershipProofExpiryTimeSeconds]: intType,
[ConfigVariable.EmailConfirmationTokenRateLimit]: intType,
[ConfigVariable.AppRootDomain]: stringType,
[ConfigVariable.EmailNotificationDeliveryMaxAttempts]: intType,
[ConfigVariable.AppAssetStorage]: stringType,
[ConfigVariable.AppNameAlt]: stringType,
[ConfigVariable.NotificationAssetRoot]: stringType,
[ConfigVariable.CommentTipTiers]: jsonType<CommentTipTiers>(),
} as const
type TypeOf<C extends ConfigVariable> = ReturnType<(typeof configVariables)[C]['deserialize']>
class Config {
async get<C extends ConfigVariable>(name: C, em: EntityManager): Promise<TypeOf<C>> {
const serialized = await withHiddenEntities(em, async () => {
return (await em.findOneBy(GatewayConfig, { id: name }))?.value ?? process.env[name]
})
if (serialized === undefined) {
throw new Error(`Cannot determine value of config variable ${name}`)
}
return configVariables[name].deserialize(serialized) as TypeOf<C>
}
async set<C extends ConfigVariable>(name: C, value: TypeOf<C>, em: EntityManager): Promise<void> {
const serialize = configVariables[name].serialize as (v: TypeOf<C>) => string
const configValue = new GatewayConfig({
id: name,
updatedAt: new Date(),
value: serialize(value),
})
await em.save(configValue)
}
}
export const config = new Config()