@effectstream/utils 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -0
- package/src/binary-search.test.ts +38 -0
- package/src/binary-search.ts +45 -0
- package/src/captcha.ts +21 -0
- package/src/concurrency/condVar.ts +52 -0
- package/src/concurrency/latch.test.ts +51 -0
- package/src/concurrency/latch.ts +61 -0
- package/src/concurrency/mod.ts +4 -0
- package/src/concurrency/retry.test.ts +59 -0
- package/src/concurrency/retry.ts +67 -0
- package/src/concurrency/utils.ts +33 -0
- package/src/config.ts +484 -0
- package/src/constants.ts +10 -0
- package/src/decorators/bound.ts +22 -0
- package/src/decorators/mod.ts +1 -0
- package/src/mod.ts +8 -0
- package/src/runtime-spawn.ts +188 -0
- package/src/runtime.ts +89 -0
- package/src/types/json-query.ts +36 -0
- package/src/types/misc.ts +173 -0
- package/src/types/mod.ts +6 -0
- package/src/types/nominal.ts +168 -0
- package/src/types/typebox-helpers.ts +446 -0
- package/src/types/utils.ts +60 -0
- package/src/types/validators/algorand.ts +120 -0
- package/src/types/validators/cardano.ts +139 -0
- package/src/types/validators/mina.ts +54 -0
- package/src/types/validators/minicbor.ts +468 -0
- package/src/types/validators/mod.ts +2 -0
- package/src/types/validators/utils.ts +34 -0
- package/src/viem.ts +41 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMPORTANT:
|
|
3
|
+
* This is BACKEND / EFFECTSTREAM only import.
|
|
4
|
+
* This should not be imported in frontend code as it will leak sensitive information.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { ENV } from "@effectstream/utils/node-env";
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// NOTE: To register a new config, we need to add it in the definitions, and then add the getter in the ENV class.
|
|
11
|
+
// TODO: Is it possible to do this automatically, or just once?
|
|
12
|
+
import dotenv from "dotenv";
|
|
13
|
+
import { getEnv, setEnv } from "./runtime.ts";
|
|
14
|
+
|
|
15
|
+
const MIDNIGHT_STORAGE_PASSWORD_DEFAULT = 'YourPasswordMy1!';
|
|
16
|
+
|
|
17
|
+
const EFFECTSTREAM_ENV = getEnv("EFFECTSTREAM_ENV");
|
|
18
|
+
if (EFFECTSTREAM_ENV) {
|
|
19
|
+
dotenv.config({
|
|
20
|
+
path: `.env.${EFFECTSTREAM_ENV}`,
|
|
21
|
+
override: true,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type ConfigDefinition = {
|
|
26
|
+
// Unique identifier for the config.
|
|
27
|
+
key: string;
|
|
28
|
+
// Whether the config is a secret value (it hides it from the terminal-interface).
|
|
29
|
+
isSecret?: boolean;
|
|
30
|
+
// Description of the config.
|
|
31
|
+
description: string;
|
|
32
|
+
// Whether the config is a system config and not managed by the user.
|
|
33
|
+
isSystem?: boolean;
|
|
34
|
+
} & ({
|
|
35
|
+
type: "string"
|
|
36
|
+
defaultValue: string | undefined;
|
|
37
|
+
} | {
|
|
38
|
+
type: "number";
|
|
39
|
+
defaultValue: number | undefined;
|
|
40
|
+
} | {
|
|
41
|
+
type: "boolean";
|
|
42
|
+
defaultValue: boolean | undefined;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const definitions: Record<string, ConfigDefinition> = {
|
|
46
|
+
EFFECTSTREAM_ENV: {
|
|
47
|
+
key: "EFFECTSTREAM_ENV",
|
|
48
|
+
type: "string",
|
|
49
|
+
defaultValue: undefined,
|
|
50
|
+
description: "Effectstream Environment. Example: 'local' or 'testnet'",
|
|
51
|
+
},
|
|
52
|
+
DB_HOST: {
|
|
53
|
+
key: "DB_HOST",
|
|
54
|
+
type: "string",
|
|
55
|
+
defaultValue: "localhost",
|
|
56
|
+
description: "Paima Engine Postgres Host URL. Example: 'localhost'",
|
|
57
|
+
},
|
|
58
|
+
DB_NAME: {
|
|
59
|
+
key: "DB_NAME",
|
|
60
|
+
type: "string",
|
|
61
|
+
defaultValue: "postgres",
|
|
62
|
+
description: "Paima Engine Postgres Database Name. Example: 'postgres'",
|
|
63
|
+
},
|
|
64
|
+
DB_PORT: {
|
|
65
|
+
key: "DB_PORT",
|
|
66
|
+
type: "number",
|
|
67
|
+
defaultValue: 5432,
|
|
68
|
+
description: "Paima Engine Postgres Port. Example: '5432'",
|
|
69
|
+
},
|
|
70
|
+
DB_PW: {
|
|
71
|
+
key: "DB_PW",
|
|
72
|
+
isSecret: true,
|
|
73
|
+
type: "string",
|
|
74
|
+
defaultValue: "postgres",
|
|
75
|
+
description: "Paima Engine Postgres Password. Example: 'password'",
|
|
76
|
+
},
|
|
77
|
+
DB_USER: {
|
|
78
|
+
key: "DB_USER",
|
|
79
|
+
type: "string",
|
|
80
|
+
defaultValue: "postgres",
|
|
81
|
+
description: "Paima Engine Postgres User. Example: 'postgres'",
|
|
82
|
+
},
|
|
83
|
+
NODE_ENV: {
|
|
84
|
+
key: "NODE_ENV",
|
|
85
|
+
type: "string",
|
|
86
|
+
defaultValue: undefined,
|
|
87
|
+
description: "Node Environment. Example: 'development' or 'production'",
|
|
88
|
+
},
|
|
89
|
+
ORCHESTRATOR_URL: {
|
|
90
|
+
key: "ORCHESTRATOR_URL",
|
|
91
|
+
type: "string",
|
|
92
|
+
defaultValue: "http://localhost",
|
|
93
|
+
description: "Paima Engine Orchestrator URL. Example: 'http://localhost'",
|
|
94
|
+
},
|
|
95
|
+
ORCHESTRATOR_PORT: {
|
|
96
|
+
key: "ORCHESTRATOR_PORT",
|
|
97
|
+
type: "number",
|
|
98
|
+
defaultValue: 0,
|
|
99
|
+
description:
|
|
100
|
+
"Paima Engine Orchestrator Port. Used by the TUI to monitor processes. Example: '3000'",
|
|
101
|
+
},
|
|
102
|
+
TUI_LOG_URL: {
|
|
103
|
+
key: "TUI_LOG_URL",
|
|
104
|
+
type: "string",
|
|
105
|
+
defaultValue: "http://localhost",
|
|
106
|
+
description: "TUI Log URL. Example: 'http://localhost'",
|
|
107
|
+
},
|
|
108
|
+
TUI_LOG_PORT: {
|
|
109
|
+
key: "TUI_LOG_PORT",
|
|
110
|
+
type: "number",
|
|
111
|
+
defaultValue: 11033,
|
|
112
|
+
description: "TUI Log Port. Example: '11033'",
|
|
113
|
+
},
|
|
114
|
+
SHELL: {
|
|
115
|
+
isSystem: true,
|
|
116
|
+
key: "SHELL",
|
|
117
|
+
type: "string",
|
|
118
|
+
defaultValue: undefined,
|
|
119
|
+
description:
|
|
120
|
+
"System shell path. This is set by the OS. Used to run TUI/tmux commands",
|
|
121
|
+
},
|
|
122
|
+
TMUX: {
|
|
123
|
+
isSystem: true,
|
|
124
|
+
key: "TMUX",
|
|
125
|
+
type: "string",
|
|
126
|
+
defaultValue: undefined,
|
|
127
|
+
description:
|
|
128
|
+
"System tmux path. This is set by Tmux itself. Used to check if the process is running in a tmux session",
|
|
129
|
+
},
|
|
130
|
+
RECAPTCHA_V3_FRONTEND: {
|
|
131
|
+
key: "RECAPTCHA_V3_FRONTEND",
|
|
132
|
+
type: "string",
|
|
133
|
+
defaultValue: undefined,
|
|
134
|
+
description:
|
|
135
|
+
"ReCaptcha V3 Frontend Key. Used by the Batcher to verify requests. Leave empty to disable. Example: '6Lc123456789012345678901234567890'",
|
|
136
|
+
},
|
|
137
|
+
BATCHER_PORT: {
|
|
138
|
+
key: "BATCHER_PORT",
|
|
139
|
+
type: "number",
|
|
140
|
+
defaultValue: 3334,
|
|
141
|
+
description: "Batcher Port. Example: '3334'",
|
|
142
|
+
},
|
|
143
|
+
STORE_HISTORICAL_GAME_INPUTS: {
|
|
144
|
+
key: "STORE_HISTORICAL_GAME_INPUTS",
|
|
145
|
+
type: "boolean",
|
|
146
|
+
defaultValue: true,
|
|
147
|
+
description: "Store Historical Game Inputs. Example: 'true' or 'false'",
|
|
148
|
+
},
|
|
149
|
+
MQTT_BROKER: {
|
|
150
|
+
key: "MQTT_BROKER",
|
|
151
|
+
type: "boolean",
|
|
152
|
+
defaultValue: true,
|
|
153
|
+
description: "MQTT Broker. Example: 'true' or 'false'",
|
|
154
|
+
},
|
|
155
|
+
MQTT_ENGINE_BROKER_URL: {
|
|
156
|
+
key: "MQTT_ENGINE_BROKER_URL",
|
|
157
|
+
type: "string",
|
|
158
|
+
defaultValue: "ws://127.0.0.1:8883",
|
|
159
|
+
description: "MQTT Engine Broker URL. Example: 'ws://127.0.0.1:8883'",
|
|
160
|
+
},
|
|
161
|
+
MQTT_ENGINE_BROKER_PORT: {
|
|
162
|
+
key: "MQTT_ENGINE_BROKER_PORT",
|
|
163
|
+
type: "number",
|
|
164
|
+
defaultValue: 8883,
|
|
165
|
+
description: "MQTT Engine Broker Port. Example: '8883'",
|
|
166
|
+
},
|
|
167
|
+
MQTT_BATCHER_BROKER_URL: {
|
|
168
|
+
key: "MQTT_BATCHER_BROKER_URL",
|
|
169
|
+
type: "string",
|
|
170
|
+
defaultValue: "ws://127.0.0.1:8884",
|
|
171
|
+
description: "MQTT Batcher Broker URL. Example: 'ws://127.0.0.1:8884'",
|
|
172
|
+
},
|
|
173
|
+
MQTT_BATCHER_BROKER_PORT: {
|
|
174
|
+
key: "MQTT_BATCHER_BROKER_PORT",
|
|
175
|
+
type: "number",
|
|
176
|
+
defaultValue: 8884,
|
|
177
|
+
description: "MQTT Batcher Broker Port. Example: '8884'",
|
|
178
|
+
},
|
|
179
|
+
EFFECTSTREAM_API_PORT: {
|
|
180
|
+
key: "EFFECTSTREAM_API_PORT",
|
|
181
|
+
type: "number",
|
|
182
|
+
defaultValue: 9999,
|
|
183
|
+
description:
|
|
184
|
+
"Main Paima API Port. Used by developers custom endpoints and RPC endpoints. Example: '9999'",
|
|
185
|
+
},
|
|
186
|
+
EFFECTSTREAM_EXPLORER_PORT: {
|
|
187
|
+
key: "EFFECTSTREAM_EXPLORER_PORT",
|
|
188
|
+
type: "number",
|
|
189
|
+
defaultValue: 10590,
|
|
190
|
+
description: "Explorer Port. Example: '10590'",
|
|
191
|
+
},
|
|
192
|
+
EFFECTSTREAM_CHAIN_ID: {
|
|
193
|
+
key: "EFFECTSTREAM_CHAIN_ID",
|
|
194
|
+
type: "number",
|
|
195
|
+
defaultValue: 87401284021,
|
|
196
|
+
description: "Paima Chain ID. Example: '87401284021'",
|
|
197
|
+
},
|
|
198
|
+
PGLITE: {
|
|
199
|
+
key: "PGLITE",
|
|
200
|
+
type: "boolean",
|
|
201
|
+
defaultValue: true,
|
|
202
|
+
description:
|
|
203
|
+
"Enable single connection mode and other specific PGLite features. IMPORTANT enable only for development. ('true' or 'false')",
|
|
204
|
+
},
|
|
205
|
+
PGLITE_DATA_DIR: {
|
|
206
|
+
key: "PGLITE_DATA_DIR",
|
|
207
|
+
type: "string",
|
|
208
|
+
defaultValue: "memory://",
|
|
209
|
+
description:
|
|
210
|
+
"PGLite data directory. Use 'memory://' for in-memory (default) or a file path for persistent storage. Example: './pglite-data'",
|
|
211
|
+
},
|
|
212
|
+
DEBUG_PGLITE: {
|
|
213
|
+
key: "DEBUG_PGLITE",
|
|
214
|
+
type: "number",
|
|
215
|
+
defaultValue: undefined,
|
|
216
|
+
description: "Enable PGLite Debug/Verbose mode. Example: '1'",
|
|
217
|
+
},
|
|
218
|
+
OTEL_COLLECTOR_PORT: {
|
|
219
|
+
key: "OTEL_COLLECTOR_PORT",
|
|
220
|
+
type: "number",
|
|
221
|
+
defaultValue: 4318,
|
|
222
|
+
description: "OTEL Collector Port. Example: '4318'",
|
|
223
|
+
},
|
|
224
|
+
DOCS_PORT: {
|
|
225
|
+
key: "DOCS_PORT",
|
|
226
|
+
type: "number",
|
|
227
|
+
defaultValue: 10600,
|
|
228
|
+
description: "Docs Port. Example: '10600'",
|
|
229
|
+
},
|
|
230
|
+
MIDNIGHT_STORAGE_PASSWORD: {
|
|
231
|
+
key: "MIDNIGHT_STORAGE_PASSWORD",
|
|
232
|
+
isSecret: true,
|
|
233
|
+
type: "string",
|
|
234
|
+
defaultValue: MIDNIGHT_STORAGE_PASSWORD_DEFAULT,
|
|
235
|
+
description: "Midnight Storage Password. Used to run the new node version or deploy contracts on Midnight. A random 16-character hex string is generated if not provided.",
|
|
236
|
+
},
|
|
237
|
+
API_KEY_OPEN_ENDPOINTS_EXPLORER: {
|
|
238
|
+
key: "API_KEY_OPEN_ENDPOINTS_EXPLORER",
|
|
239
|
+
isSecret: true,
|
|
240
|
+
type: "string",
|
|
241
|
+
defaultValue: "effectstream_api_explorer_endpoints_password",
|
|
242
|
+
description:
|
|
243
|
+
"API key to access open explorer endpoints (tables, primitives, addresses, scheduled-data).",
|
|
244
|
+
},
|
|
245
|
+
ENABLE_DEV_AND_DEBUG_ENDPOINTS: {
|
|
246
|
+
key: "ENABLE_DEV_AND_DEBUG_ENDPOINTS",
|
|
247
|
+
type: "boolean",
|
|
248
|
+
defaultValue: false,
|
|
249
|
+
description:
|
|
250
|
+
"Enable developer and debug endpoints (/debug/sync-protocols, /config, /db_acquire_lock, /db_release_lock, /force-batch, /clear-inputs). Should be disabled in production.",
|
|
251
|
+
},
|
|
252
|
+
EFFECTSTREAM_SNAPSHOT_INTERVAL_SECONDS: {
|
|
253
|
+
key: "EFFECTSTREAM_SNAPSHOT_INTERVAL_SECONDS",
|
|
254
|
+
type: "number",
|
|
255
|
+
defaultValue: undefined,
|
|
256
|
+
description:
|
|
257
|
+
"Wall-clock seconds between automated pg_dump snapshots. Leaving this unset disables snapshots entirely. Example: '3600' (1 hour).",
|
|
258
|
+
},
|
|
259
|
+
EFFECTSTREAM_SNAPSHOT_PATH: {
|
|
260
|
+
key: "EFFECTSTREAM_SNAPSHOT_PATH",
|
|
261
|
+
type: "string",
|
|
262
|
+
defaultValue: "./snapshots",
|
|
263
|
+
description: "Output directory for snapshot .dump files. Example: './backups'",
|
|
264
|
+
},
|
|
265
|
+
EFFECTSTREAM_SNAPSHOT_LAST_DAY_HOURLY: {
|
|
266
|
+
key: "EFFECTSTREAM_SNAPSHOT_LAST_DAY_HOURLY",
|
|
267
|
+
type: "boolean",
|
|
268
|
+
defaultValue: true,
|
|
269
|
+
description:
|
|
270
|
+
"Snapshot retention: keep one snapshot per hour for the last 24 hours. Set to 'false' to disable this tier.",
|
|
271
|
+
},
|
|
272
|
+
EFFECTSTREAM_SNAPSHOT_LAST_3_DAYS_SIX_HOURLY: {
|
|
273
|
+
key: "EFFECTSTREAM_SNAPSHOT_LAST_3_DAYS_SIX_HOURLY",
|
|
274
|
+
type: "boolean",
|
|
275
|
+
defaultValue: true,
|
|
276
|
+
description:
|
|
277
|
+
"Snapshot retention: keep one snapshot per 6-hour window for the last 3 days. Set to 'false' to disable this tier.",
|
|
278
|
+
},
|
|
279
|
+
EFFECTSTREAM_SNAPSHOT_LAST_N_DAYS: {
|
|
280
|
+
key: "EFFECTSTREAM_SNAPSHOT_LAST_N_DAYS",
|
|
281
|
+
type: "number",
|
|
282
|
+
defaultValue: 7,
|
|
283
|
+
description:
|
|
284
|
+
"Snapshot retention: keep one snapshot per day for this many days. Snapshots older than this are deleted. Default: 7.",
|
|
285
|
+
},
|
|
286
|
+
} as const;
|
|
287
|
+
|
|
288
|
+
type ENV_TYPES = string | number | boolean | undefined;
|
|
289
|
+
|
|
290
|
+
export class ENV {
|
|
291
|
+
static get EFFECTSTREAM_ENV(): string {
|
|
292
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_ENV);
|
|
293
|
+
}
|
|
294
|
+
static get MQTT_BROKER(): boolean {
|
|
295
|
+
return ENV.getConfig(definitions.MQTT_BROKER);
|
|
296
|
+
}
|
|
297
|
+
static get MQTT_ENGINE_BROKER_PORT(): number {
|
|
298
|
+
return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_PORT);
|
|
299
|
+
}
|
|
300
|
+
static get MQTT_BATCHER_BROKER_PORT(): number {
|
|
301
|
+
return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_PORT);
|
|
302
|
+
}
|
|
303
|
+
static get MQTT_ENGINE_BROKER_URL(): string {
|
|
304
|
+
return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_URL);
|
|
305
|
+
}
|
|
306
|
+
static get MQTT_BATCHER_BROKER_URL(): string {
|
|
307
|
+
return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_URL);
|
|
308
|
+
}
|
|
309
|
+
static get DB_HOST(): string {
|
|
310
|
+
return ENV.getConfig(definitions.DB_HOST);
|
|
311
|
+
}
|
|
312
|
+
static get DB_NAME(): string {
|
|
313
|
+
return ENV.getConfig(definitions.DB_NAME);
|
|
314
|
+
}
|
|
315
|
+
static get DB_PORT(): number {
|
|
316
|
+
return ENV.getConfig(definitions.DB_PORT);
|
|
317
|
+
}
|
|
318
|
+
static get DB_PW(): string {
|
|
319
|
+
return ENV.getConfig(definitions.DB_PW);
|
|
320
|
+
}
|
|
321
|
+
static get DB_USER(): string {
|
|
322
|
+
return ENV.getConfig(definitions.DB_USER);
|
|
323
|
+
}
|
|
324
|
+
static get NODE_ENV(): string {
|
|
325
|
+
return ENV.getConfig(definitions.NODE_ENV);
|
|
326
|
+
}
|
|
327
|
+
static get ORCHESTRATOR_URL(): string {
|
|
328
|
+
return ENV.getConfig(definitions.ORCHESTRATOR_URL);
|
|
329
|
+
}
|
|
330
|
+
static get ORCHESTRATOR_PORT(): number {
|
|
331
|
+
return ENV.getConfig(definitions.ORCHESTRATOR_PORT);
|
|
332
|
+
}
|
|
333
|
+
static set ORCHESTRATOR_PORT(port: number) {
|
|
334
|
+
setEnv(definitions.ORCHESTRATOR_PORT.key, String(port));
|
|
335
|
+
}
|
|
336
|
+
static get TUI_LOG_URL(): string {
|
|
337
|
+
return ENV.getConfig(definitions.TUI_LOG_URL);
|
|
338
|
+
}
|
|
339
|
+
static get TUI_LOG_PORT(): number {
|
|
340
|
+
return ENV.getConfig(definitions.TUI_LOG_PORT);
|
|
341
|
+
}
|
|
342
|
+
static get SHELL(): string {
|
|
343
|
+
return ENV.getConfig(definitions.SHELL);
|
|
344
|
+
}
|
|
345
|
+
static get TMUX(): string {
|
|
346
|
+
return ENV.getConfig(definitions.TMUX);
|
|
347
|
+
}
|
|
348
|
+
static get EFFECTSTREAM_API_PORT(): number {
|
|
349
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_API_PORT);
|
|
350
|
+
}
|
|
351
|
+
static get RECAPTCHA_V3_FRONTEND(): string {
|
|
352
|
+
return ENV.getConfig(definitions.RECAPTCHA_V3_FRONTEND);
|
|
353
|
+
}
|
|
354
|
+
static get BATCHER_PORT(): number {
|
|
355
|
+
return ENV.getConfig(definitions.BATCHER_PORT);
|
|
356
|
+
}
|
|
357
|
+
static get EFFECTSTREAM_EXPLORER_PORT(): number {
|
|
358
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_EXPLORER_PORT);
|
|
359
|
+
}
|
|
360
|
+
static get EFFECTSTREAM_CHAIN_ID(): number {
|
|
361
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_CHAIN_ID);
|
|
362
|
+
}
|
|
363
|
+
static get PGLITE(): boolean {
|
|
364
|
+
return ENV.getConfig(definitions.PGLITE);
|
|
365
|
+
}
|
|
366
|
+
static get PGLITE_DATA_DIR(): string {
|
|
367
|
+
return ENV.getConfig(definitions.PGLITE_DATA_DIR);
|
|
368
|
+
}
|
|
369
|
+
static get DEBUG_PGLITE(): number {
|
|
370
|
+
return ENV.getConfig(definitions.DEBUG_PGLITE);
|
|
371
|
+
}
|
|
372
|
+
static get OTEL_COLLECTOR_PORT(): number {
|
|
373
|
+
return ENV.getConfig(definitions.OTEL_COLLECTOR_PORT);
|
|
374
|
+
}
|
|
375
|
+
static get DOCS_PORT(): number {
|
|
376
|
+
return ENV.getConfig(definitions.DOCS_PORT);
|
|
377
|
+
}
|
|
378
|
+
static get MIDNIGHT_STORAGE_PASSWORD(): string {
|
|
379
|
+
return ENV.getConfig(definitions.MIDNIGHT_STORAGE_PASSWORD);
|
|
380
|
+
}
|
|
381
|
+
static get API_KEY_OPEN_ENDPOINTS_EXPLORER(): string {
|
|
382
|
+
return ENV.getConfig(definitions.API_KEY_OPEN_ENDPOINTS_EXPLORER);
|
|
383
|
+
}
|
|
384
|
+
static get ENABLE_DEV_AND_DEBUG_ENDPOINTS(): boolean {
|
|
385
|
+
return ENV.getConfig(definitions.ENABLE_DEV_AND_DEBUG_ENDPOINTS);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Wall-clock seconds between automated snapshots.
|
|
389
|
+
* Returns `undefined` (env var not set) to signal that snapshots are disabled.
|
|
390
|
+
*/
|
|
391
|
+
static get EFFECTSTREAM_SNAPSHOT_INTERVAL_SECONDS(): number | undefined {
|
|
392
|
+
const raw = getEnv(definitions.EFFECTSTREAM_SNAPSHOT_INTERVAL_SECONDS.key);
|
|
393
|
+
if (raw == null || raw === "") return undefined;
|
|
394
|
+
return parseInt(raw, 10);
|
|
395
|
+
}
|
|
396
|
+
static get EFFECTSTREAM_SNAPSHOT_PATH(): string {
|
|
397
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_SNAPSHOT_PATH);
|
|
398
|
+
}
|
|
399
|
+
static get EFFECTSTREAM_SNAPSHOT_LAST_DAY_HOURLY(): boolean {
|
|
400
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_SNAPSHOT_LAST_DAY_HOURLY);
|
|
401
|
+
}
|
|
402
|
+
static get EFFECTSTREAM_SNAPSHOT_LAST_3_DAYS_SIX_HOURLY(): boolean {
|
|
403
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_SNAPSHOT_LAST_3_DAYS_SIX_HOURLY);
|
|
404
|
+
}
|
|
405
|
+
static get EFFECTSTREAM_SNAPSHOT_LAST_N_DAYS(): number {
|
|
406
|
+
return ENV.getConfig(definitions.EFFECTSTREAM_SNAPSHOT_LAST_N_DAYS);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public static getConfig<T>(config: ConfigDefinition): T {
|
|
410
|
+
switch (config.type) {
|
|
411
|
+
case "string":
|
|
412
|
+
return ENV.getString(config.key, config.defaultValue) as T;
|
|
413
|
+
case "number":
|
|
414
|
+
return ENV.getNumber(config.key, config.defaultValue) as T;
|
|
415
|
+
case "boolean":
|
|
416
|
+
return ENV.getBoolean(config.key, config.defaultValue) as T;
|
|
417
|
+
default:
|
|
418
|
+
throw new Error(`Invalid config type: ${config}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
static getCurrentConfig(
|
|
423
|
+
showSecrets: boolean = false,
|
|
424
|
+
): Record<string, ENV_TYPES> {
|
|
425
|
+
const secretPlaceholder = "********";
|
|
426
|
+
const values: Record<string, ENV_TYPES> = {};
|
|
427
|
+
Object.entries(definitions).forEach(([key, config]) => {
|
|
428
|
+
if (config.isSecret) {
|
|
429
|
+
values[key] = showSecrets
|
|
430
|
+
? ENV[key as keyof typeof ENV] as any
|
|
431
|
+
: secretPlaceholder;
|
|
432
|
+
} else {
|
|
433
|
+
values[key] = ENV[key as keyof typeof ENV] as any;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
return values;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
static getDocumentation(): Record<string, {
|
|
440
|
+
defaultValue: ENV_TYPES;
|
|
441
|
+
description: string;
|
|
442
|
+
}> {
|
|
443
|
+
return Object.fromEntries(
|
|
444
|
+
Object.entries(definitions).map(([key, config]) => {
|
|
445
|
+
return [key, {
|
|
446
|
+
defaultValue: config.defaultValue,
|
|
447
|
+
description: config.description,
|
|
448
|
+
}];
|
|
449
|
+
}),
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
public static getBoolean(
|
|
454
|
+
key: string,
|
|
455
|
+
defaultValue = false,
|
|
456
|
+
): boolean {
|
|
457
|
+
const value = ENV.getEnv(key);
|
|
458
|
+
if (value == null || value === "") return defaultValue;
|
|
459
|
+
return ["true", "t", "1", "yes", "y"].includes(value.toLowerCase());
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
public static getNumber(
|
|
463
|
+
key: string,
|
|
464
|
+
defaultValue = 0,
|
|
465
|
+
): number {
|
|
466
|
+
const value = ENV.getEnv(key);
|
|
467
|
+
if (value == null || value === "") return defaultValue;
|
|
468
|
+
return parseInt(value, 10);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
public static getString(
|
|
472
|
+
key: string,
|
|
473
|
+
defaultValue = "",
|
|
474
|
+
): string {
|
|
475
|
+
const value = ENV.getEnv(key);
|
|
476
|
+
return value ?? defaultValue;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
private static getEnv(
|
|
480
|
+
key: string,
|
|
481
|
+
): string | undefined {
|
|
482
|
+
return getEnv(key);
|
|
483
|
+
}
|
|
484
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const DYNAMIC_PRIMITIVE_NAME_SEPARATOR = "##";
|
|
2
|
+
export function generateDynamicPrimitivePrefix(parentName: string): string {
|
|
3
|
+
return `${parentName}${DYNAMIC_PRIMITIVE_NAME_SEPARATOR}`;
|
|
4
|
+
}
|
|
5
|
+
export function generateDynamicPrimitiveName(
|
|
6
|
+
parentName: string,
|
|
7
|
+
id: number,
|
|
8
|
+
): string {
|
|
9
|
+
return `${generateDynamicPrimitivePrefix(parentName)}${id}`;
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avoids member functions having the wrong `this` value when passed as a function pointer.\
|
|
3
|
+
* AKA shortcut for `this.func.bind(this)`
|
|
4
|
+
*
|
|
5
|
+
* Taken form https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html
|
|
6
|
+
*
|
|
7
|
+
* Careful: this can cause a segmentation fault on Deno (https://github.com/denoland/deno/issues/25192)
|
|
8
|
+
*/
|
|
9
|
+
export function bound(
|
|
10
|
+
_originalMethod: any,
|
|
11
|
+
context: ClassMethodDecoratorContext<Record<string | symbol, any>>,
|
|
12
|
+
) {
|
|
13
|
+
const methodName = context.name;
|
|
14
|
+
if (context.private) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`'bound' cannot decorate private properties like ${methodName as string}.`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
context.addInitializer(function () {
|
|
20
|
+
this[methodName] = this[methodName].bind(this);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./bound.ts";
|
package/src/mod.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./types/mod.ts";
|
|
2
|
+
export * from "./constants.ts";
|
|
3
|
+
export * from "./viem.ts";
|
|
4
|
+
export * from "./captcha.ts";
|
|
5
|
+
export * from "./binary-search.ts";
|
|
6
|
+
export * from "./concurrency/mod.ts";
|
|
7
|
+
export * from "./decorators/mod.ts";
|
|
8
|
+
export * from "./runtime.ts";
|