Skip to content

Commit 2e096a5

Browse files
committed
refactor: replace hand-rolled helpers with es-toolkit
Use isString, isNotNil, isPlainObject, and delay instead of local type guards and sleep wrappers.
1 parent e229342 commit 2e096a5

18 files changed

Lines changed: 46 additions & 75 deletions

File tree

apps/admin/src/api/http.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isPlainObject } from 'es-toolkit'
2+
13
import { API_URL } from '~/constants/env'
24
import { SESSION_WITH_LOGIN } from '~/constants/keys'
35

@@ -285,13 +287,6 @@ function camelcaseKeys<T>(value: T): T {
285287
) as T
286288
}
287289

288-
function isPlainObject(value: unknown): value is Record<string, unknown> {
289-
if (!value || typeof value !== 'object') return false
290-
const prototype = Object.getPrototypeOf(value)
291-
292-
return prototype === Object.prototype || prototype === null
293-
}
294-
295290
function toCamelCase(value: string) {
296291
return value.replaceAll(/_([a-z])/g, (_, letter: string) =>
297292
letter.toUpperCase(),

apps/admin/src/features/templates/lib/fallback-props.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isPlainObject } from 'es-toolkit'
2+
13
import type { TemplateType } from '../types/templates'
24

35
const sharedPostProps = {
@@ -68,15 +70,6 @@ export const templateFallbackProps: Record<
6870
},
6971
}
7072

71-
function isPlainObject(value: unknown): value is Record<string, unknown> {
72-
return (
73-
value !== null &&
74-
typeof value === 'object' &&
75-
!Array.isArray(value) &&
76-
Object.getPrototypeOf(value) === Object.prototype
77-
)
78-
}
79-
8073
/**
8174
* Recursively merge `overrides` into `base`. Arrays and primitives in `overrides`
8275
* replace those in `base`. Objects merge key-by-key. Used to supplement

apps/core/src/modules/ai/ai-inflight/ai-inflight.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Injectable, Logger } from '@nestjs/common'
2+
import { delay } from 'es-toolkit'
23

34
import { AppErrorCode, createAppException } from '~/common/errors'
45
import { isDev } from '~/global/env.global'
56
import { RedisService } from '~/processors/redis/redis.service'
6-
import { sleep } from '~/utils/tool.util'
77

88
import type { AiInFlightOptions, AiStreamEvent } from './ai-inflight.types'
99

@@ -164,7 +164,7 @@ export class AiInFlightService {
164164

165165
const deadline = Date.now() + lockTtlSec * 1000
166166
while (Date.now() < deadline) {
167-
await sleep(200)
167+
await delay(200)
168168
if (
169169
(await redis.set(lockKey, lockValue, 'EX', lockTtlSec, 'NX')) === 'OK'
170170
) {
@@ -401,7 +401,7 @@ export class AiInFlightService {
401401
})
402402
}
403403

404-
await sleep(100)
404+
await delay(100)
405405
}
406406
}
407407
}

apps/core/src/modules/ai/ai-tts/tts-runtime.adapter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { delay } from 'es-toolkit'
2+
13
import { AppErrorCode, createAppException } from '~/common/errors'
2-
import { sleep } from '~/utils/tool.util'
34

45
import { resolveTtsBaseUrl } from './tts-base-url'
56
import {
@@ -60,7 +61,7 @@ export class TtsRuntimeAdapter implements ITtsRuntime {
6061
attempt === this.maxAttempts
6162
)
6263
break
63-
await sleep(this.retryDelayMs * 2 ** (attempt - 1))
64+
await delay(this.retryDelayMs * 2 ** (attempt - 1))
6465
}
6566
}
6667

apps/core/src/modules/ai/runtime/pi-runtime.adapter.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
getBuiltinModels,
1818
} from '@earendil-works/pi-ai/providers/all'
1919
import { Logger } from '@nestjs/common'
20+
import { isPlainObject } from 'es-toolkit/compat'
2021
import { jsonrepair } from 'jsonrepair'
2122
import { Value } from 'typebox/value'
2223

@@ -211,10 +212,6 @@ function resolveVertexScope(endpoint: string | undefined): {
211212
}
212213
}
213214

214-
function isObjectRecord(value: unknown): value is Record<string, unknown> {
215-
return typeof value === 'object' && value !== null && !Array.isArray(value)
216-
}
217-
218215
interface PiUsageLike {
219216
input?: number
220217
output?: number
@@ -689,7 +686,7 @@ export class PiRuntimeAdapter implements IModelRuntime {
689686
if (typeof args === 'string') {
690687
args = JSON.parse(args)
691688
}
692-
if (!isObjectRecord(args)) {
689+
if (!isPlainObject(args)) {
693690
throw new Error(
694691
'pi tool call arguments are neither an object nor JSON-parseable string',
695692
)
@@ -825,7 +822,7 @@ export class PiRuntimeAdapter implements IModelRuntime {
825822
.toolCall
826823
const fromEvent = evToolCall?.arguments
827824
let final: Record<string, unknown>
828-
if (isObjectRecord(fromEvent)) {
825+
if (isPlainObject(fromEvent)) {
829826
final = fromEvent
830827
} else {
831828
final = JSON.parse(jsonrepair(buffer)) as Record<string, unknown>

apps/core/src/modules/comment/comment.interceptor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import type {
44
NestInterceptor,
55
} from '@nestjs/common'
66
import { Injectable } from '@nestjs/common'
7+
import { isNotNil } from 'es-toolkit'
78
import { cloneDeep, isArrayLike, isObjectLike } from 'es-toolkit/compat'
89
import { map } from 'rxjs'
910

1011
import { getNestExecutionContextRequest } from '~/transformers/get-req.transformer'
1112
import { getAvatar } from '~/utils/tool.util'
12-
import { isDefined } from '~/utils/validator.util'
1313

1414
@Injectable()
1515
export class CommentFilterEmailInterceptor implements NestInterceptor {
@@ -28,7 +28,7 @@ export class CommentFilterEmailInterceptor implements NestInterceptor {
2828
try {
2929
if (isArrayLike(data?.data)) {
3030
data?.data?.forEach((item: any, i: number) => {
31-
if (isDefined(item.mail)) {
31+
if (isNotNil(item.mail)) {
3232
data.data[i].avatar = getAvatar(item.mail)
3333
delete data.data[i].mail
3434
}

apps/core/src/modules/cron-task/cron-task.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { Get, HttpCode, Param, Post } from '@nestjs/common'
2+
import { isString } from 'es-toolkit/compat'
23

34
import { ApiController } from '~/common/decorators/api-controller.decorator'
45
import { Auth } from '~/common/decorators/auth.decorator'
56
import { AppErrorCode, createAppException } from '~/common/errors'
6-
import { isString } from '~/utils/validator.util'
77

88
import { CronTaskService } from './cron-task.service'
99
import { CronTaskType, type CronTaskTypeValue } from './cron-task.types'

apps/core/src/modules/note/note.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Inject,
55
Injectable,
66
} from '@nestjs/common'
7+
import { isNotNil } from 'es-toolkit'
78
import { debounce, omit } from 'es-toolkit/compat'
89

910
import { AppErrorCode, createAppException } from '~/common/errors'
@@ -25,7 +26,6 @@ import { isLexical } from '~/utils/content.util'
2526
import { scheduleManager } from '~/utils/schedule.util'
2627
import { normalizeSlug } from '~/utils/slug.util'
2728
import { getLessThanNow } from '~/utils/time.util'
28-
import { isDefined } from '~/utils/validator.util'
2929

3030
import { AiSlugBackfillService } from '../ai/ai-writer/ai-slug-backfill.service'
3131
import { CommentService } from '../comment/comment.service'
@@ -425,10 +425,10 @@ export class NoteService {
425425
['title', 'text', 'mood', 'weather', 'meta', 'topicId', 'slug'] as const
426426
).some((key) => {
427427
if (key === 'slug' && hasSlugInput) return normalizedSlug !== oldDoc.slug
428-
return isDefined(data[key]) && data[key] !== oldDoc[key]
428+
return isNotNil(data[key]) && data[key] !== oldDoc[key]
429429
})
430430
const hasContentChanged = ['title', 'text'].some((key) =>
431-
isDefined(data[key as keyof NoteModel]),
431+
isNotNil(data[key as keyof NoteModel]),
432432
)
433433

434434
const patch = omit(data, [...NOTE_PROTECTED_KEYS, 'slug'] as const)

apps/core/src/modules/page/page.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Inject,
55
Injectable,
66
} from '@nestjs/common'
7+
import { isNotNil } from 'es-toolkit'
78
import { omit } from 'es-toolkit/compat'
89
import slugify from 'slugify'
910

@@ -19,7 +20,6 @@ import { LexicalService } from '~/processors/helper/helper.lexical.service'
1920
import { ContentFormat } from '~/shared/types/content-format.type'
2021
import { isLexical } from '~/utils/content.util'
2122
import { scheduleManager } from '~/utils/schedule.util'
22-
import { isDefined } from '~/utils/validator.util'
2323

2424
import { DraftRefType } from '../draft/draft.enum'
2525
import { DraftService } from '../draft/draft.service'
@@ -181,7 +181,7 @@ export class PageService {
181181
)
182182
}
183183

184-
if (['text', 'title', 'subtitle'].some((key) => isDefined(doc[key]))) {
184+
if (['text', 'title', 'subtitle'].some((key) => isNotNil(doc[key]))) {
185185
doc.modifiedAt = new Date()
186186
}
187187
if (doc.slug) {

apps/core/src/modules/post/post.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
OnApplicationBootstrap,
55
} from '@nestjs/common'
66
import { ModuleRef } from '@nestjs/core'
7+
import { isNotNil } from 'es-toolkit'
78
import { debounce, omit } from 'es-toolkit/compat'
89
import slugify from 'slugify'
910

@@ -27,7 +28,6 @@ import { ContentFormat } from '~/shared/types/content-format.type'
2728
import { isLexical } from '~/utils/content.util'
2829
import { scheduleManager } from '~/utils/schedule.util'
2930
import { getLessThanNow } from '~/utils/time.util'
30-
import { isDefined } from '~/utils/validator.util'
3131

3232
import type { CategoryService } from '../category/category.service'
3333
import { CommentService } from '../comment/comment.service'
@@ -428,7 +428,7 @@ export class PostService implements OnApplicationBootstrap {
428428
if (!category) throw createAppException(AppErrorCode.CATEGORY_NOT_FOUND)
429429
}
430430

431-
if ([data.text, data.title, data.slug].some(isDefined)) {
431+
if ([data.text, data.title, data.slug].some(isNotNil)) {
432432
data.modifiedAt = new Date()
433433
}
434434

0 commit comments

Comments
 (0)