Mass-rename via git mv (preserves history): server.js + 56 files in
src/** (db/, middleware/, routes/, utils/) renamed to .ts. Tests and
scripts stay .js for now — they run under plain node --test and do
not require tsx.
After rename, tsc --noEmit reported 53 errors across 13 files. Fixed:
INLINE FIXES (5 files):
- src/utils/prompts.ts: cast 3 dynamic property assignments to PROMPTS
via (PROMPTS as any).x — these are intentional runtime augmentations.
- src/routes/notes.ts: var opts: any = {...} so opts.model can be added
conditionally (was 'opts.model does not exist on {maxTokens:number}').
- src/routes/learningAI.ts:313 — drop redundant parseInt() on a value
that's already a number (assigned from line 246).
- src/routes/hospitalCourse.ts:66 — Date subtraction needs .getTime()
on each side; was 'arithmetic on type Date'.
- src/utils/transcribeLocal.ts: var args: any[] type annotation on
both branches (heterogeneous string/number array, var redeclaration).
@TS-NOCHECK (8 files — ad-hoc API shapes that need proper types in a
follow-up; runtime behavior unchanged, just opting these files out of
type-checking until they get real types):
- src/utils/ai.ts (5-provider AI client, optional system field across
shapes, Error subclassing with custom .code/.model)
- src/utils/embeddings.ts (Vertex/LiteLLM/OpenAI request shapes)
- src/routes/transcribe.ts (Node 20 File global from node:buffer,
unknown axios responses)
- src/routes/adminConfig.ts (same pattern as transcribe)
- src/routes/audioBackups.ts (req.body.X.length on unknown)
- src/routes/auth.ts (response.json() unknown in TS6, custom result
augmentation)
- src/routes/documents.ts (S3 client config built piecemeal)
- src/db/database.ts (db._cleanupInterval added at runtime)
Verification:
- npm run typecheck → 0 errors
- 46/46 unit tests pass
- tsx loads all 32 src/routes/*.ts cleanly (smoke test)
- Server start chain reaches DB connect step (fails locally because no
Postgres on dev box; in prod the docker-compose stack provides it)
Rollback anchor: ts-phase-1-2026-04-27 if anything misbehaves.
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
var crypto = require('crypto');
|
|
|
|
function hashToken(token) {
|
|
return crypto.createHash('sha256').update(token).digest('hex');
|
|
}
|
|
|
|
function parseUserAgent(ua) {
|
|
if (!ua) return 'Unknown device';
|
|
|
|
// Native PedScribe app (Capacitor appends "PedScribe-Android" / "PedScribe-iOS")
|
|
if (/PedScribe-Android/i.test(ua)) return 'PedScribe (Android)';
|
|
if (/PedScribe-iOS/i.test(ua)) return 'PedScribe (iOS)';
|
|
if (/Capacitor/i.test(ua)) {
|
|
if (/Android/i.test(ua)) return 'PedScribe (Android)';
|
|
if (/iPhone|iPad|iOS/i.test(ua)) return 'PedScribe (iOS)';
|
|
return 'PedScribe app';
|
|
}
|
|
|
|
var browser = 'Unknown browser';
|
|
var os = 'Unknown OS';
|
|
|
|
if (/Edg\//.test(ua)) browser = 'Edge';
|
|
else if (/OPR\/|Opera/.test(ua)) browser = 'Opera';
|
|
else if (/Firefox\//.test(ua)) browser = 'Firefox';
|
|
else if (/Safari\//.test(ua) && !/Chrome/.test(ua)) browser = 'Safari';
|
|
else if (/Chrome\//.test(ua)) browser = 'Chrome';
|
|
|
|
if (/Windows/.test(ua)) os = 'Windows';
|
|
else if (/Mac OS X/.test(ua)) os = 'macOS';
|
|
else if (/Android/.test(ua)) os = 'Android';
|
|
else if (/iPhone|iPad/.test(ua)) os = 'iOS';
|
|
else if (/Linux/.test(ua)) os = 'Linux';
|
|
else if (/CrOS/.test(ua)) os = 'ChromeOS';
|
|
|
|
return browser + ' on ' + os;
|
|
}
|
|
|
|
function generateSessionId() {
|
|
return crypto.randomUUID();
|
|
}
|
|
|
|
module.exports = { hashToken, parseUserAgent, generateSessionId };
|