Skip to content

Commit ee95f86

Browse files
committed
feat(core): add isNullish guard and consolidate call sites
1 parent 48b1434 commit ee95f86

5 files changed

Lines changed: 35 additions & 16 deletions

File tree

packages/core/src/shared-exports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ export {
270270
isErrorEvent,
271271
isEvent,
272272
isInstanceOf,
273+
isNullish,
273274
isParameterizedString,
274275
isPlainObject,
275276
isPrimitive,

packages/core/src/utils/is.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,14 @@ export function isVueViewModel(wat: unknown): wat is VueViewModel | VNode {
220220
export function isRequest(request: unknown): request is Request {
221221
return typeof Request !== 'undefined' && isInstanceOf(request, Request);
222222
}
223+
224+
/**
225+
* Checks whether given value is `null` or `undefined`.
226+
* {@link isNullish}.
227+
*
228+
* @param wat A value to be checked.
229+
* @returns A boolean representing the result.
230+
*/
231+
export function isNullish(wat: unknown): wat is null | undefined {
232+
return wat === null || wat === undefined;
233+
}

packages/core/test/lib/utils/is.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
isError,
66
isErrorEvent,
77
isInstanceOf,
8+
isNullish,
89
isPlainObject,
910
isPrimitive,
1011
isThenable,
@@ -192,3 +193,18 @@ describe('isPlainObject', () => {
192193
expect(isPlainObject(value)).toBe(expected);
193194
});
194195
});
196+
197+
describe('isNullish()', () => {
198+
test.each([
199+
[null, true],
200+
[undefined, true],
201+
[0, false],
202+
['', false],
203+
[false, false],
204+
[NaN, false],
205+
[{}, false],
206+
[[], false],
207+
])('%s is %s', (value, expected) => {
208+
expect(isNullish(value)).toBe(expected);
209+
});
210+
});

packages/nitro/src/runtime/hooks/captureStorageEvents.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as dc from 'node:diagnostics_channel';
22
import {
33
flushIfServerless,
44
GLOBAL_OBJ,
5+
isNullish,
56
SEMANTIC_ATTRIBUTE_CACHE_HIT,
67
SEMANTIC_ATTRIBUTE_CACHE_KEY,
78
SEMANTIC_ATTRIBUTE_SENTRY_OP,
@@ -99,10 +100,6 @@ function normalizeMethodName(methodName: string): string {
99100
return methodName.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
100101
}
101102

102-
function isEmptyValue(value: unknown): value is null | undefined {
103-
return value === null || value === undefined;
104-
}
105-
106103
interface CacheEntry<T = unknown> {
107104
value?: T;
108105
expires?: number;
@@ -116,7 +113,7 @@ interface ResponseCacheEntry {
116113

117114
function isCacheHit(key: unknown, value: unknown): boolean {
118115
try {
119-
const isEmpty = isEmptyValue(value);
116+
const isEmpty = isNullish(value);
120117
if (isEmpty || typeof key !== 'string' || !CACHED_FN_HANDLERS_RE.test(key)) {
121118
return !isEmpty;
122119
}
@@ -133,7 +130,7 @@ function validateCacheEntry(
133130
key: string,
134131
entry: CacheEntry | CacheEntry<ResponseCacheEntry & { status: number }>,
135132
): boolean {
136-
if (isEmptyValue(entry.value)) {
133+
if (isNullish(entry.value)) {
137134
return false;
138135
}
139136

packages/nuxt/src/runtime/utils/instrumentStorage.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
captureException,
33
debug,
44
flushIfServerless,
5+
isNullish,
56
SEMANTIC_ATTRIBUTE_CACHE_HIT,
67
SEMANTIC_ATTRIBUTE_CACHE_KEY,
78
SEMANTIC_ATTRIBUTE_SENTRY_OP,
@@ -209,13 +210,6 @@ function normalizeMethodName(methodName: string): string {
209210
return methodName.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
210211
}
211212

212-
/**
213-
* Checks if the value is empty, used for cache hit detection.
214-
*/
215-
function isEmptyValue(value: unknown): value is null | undefined {
216-
return value === null || value === undefined;
217-
}
218-
219213
/**
220214
* Creates the span start options for the storage method.
221215
*/
@@ -267,7 +261,7 @@ function normalizeKey(key: unknown, prefix: string): string {
267261
return `${prefix}${key.key}`;
268262
}
269263

270-
return `${prefix}${isEmptyValue(key) ? '' : String(key)}`;
264+
return `${prefix}${isNullish(key) ? '' : String(key)}`;
271265
}
272266

273267
const CACHED_FN_HANDLERS_RE = /^nitro:(functions|handlers):/i;
@@ -280,7 +274,7 @@ const CACHED_FN_HANDLERS_RE = /^nitro:(functions|handlers):/i;
280274
*/
281275
function isCacheHit(key: unknown, value: unknown): boolean {
282276
try {
283-
const isEmpty = isEmptyValue(value);
277+
const isEmpty = isNullish(value);
284278
// Empty value means no cache hit either way
285279
// Or if key doesn't match the cached function or handler patterns, we can return the empty value check
286280
if (isEmpty || typeof key !== 'string' || !CACHED_FN_HANDLERS_RE.test(key)) {
@@ -301,7 +295,7 @@ function validateCacheEntry(
301295
key: string,
302296
entry: CacheEntry | CacheEntry<ResponseCacheEntry & { status: number }>,
303297
): boolean {
304-
if (isEmptyValue(entry.value)) {
298+
if (isNullish(entry.value)) {
305299
return false;
306300
}
307301

0 commit comments

Comments
 (0)