@simplysm/core-common 14.0.42 → 14.0.43

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.
Files changed (47) hide show
  1. package/dist/env.js +1 -1
  2. package/dist/env.js.map +1 -1
  3. package/dist/extensions/arr-ext.helpers.js +1 -1
  4. package/dist/extensions/arr-ext.helpers.js.map +1 -1
  5. package/dist/extensions/arr-ext.js +25 -25
  6. package/dist/extensions/arr-ext.js.map +1 -1
  7. package/dist/types/date-only.js +2 -2
  8. package/dist/types/date-only.js.map +1 -1
  9. package/dist/types/date-time.js +2 -2
  10. package/dist/types/date-time.js.map +1 -1
  11. package/dist/types/time.js +2 -2
  12. package/dist/types/time.js.map +1 -1
  13. package/dist/utils/date-format.js +14 -14
  14. package/dist/utils/date-format.js.map +1 -1
  15. package/dist/utils/json.js +3 -3
  16. package/dist/utils/json.js.map +1 -1
  17. package/dist/utils/num.js +1 -1
  18. package/dist/utils/num.js.map +1 -1
  19. package/dist/utils/obj.d.ts.map +1 -1
  20. package/dist/utils/obj.js +14 -15
  21. package/dist/utils/obj.js.map +1 -1
  22. package/dist/utils/template-strings.js +1 -1
  23. package/dist/utils/template-strings.js.map +1 -1
  24. package/dist/utils/transferable.js +9 -9
  25. package/dist/utils/transferable.js.map +1 -1
  26. package/dist/utils/wait.js +1 -1
  27. package/dist/utils/wait.js.map +1 -1
  28. package/dist/utils/xml.js +1 -1
  29. package/dist/utils/xml.js.map +1 -1
  30. package/dist/utils/zip.js +1 -1
  31. package/dist/utils/zip.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/env.ts +1 -1
  34. package/src/extensions/arr-ext.helpers.ts +1 -1
  35. package/src/extensions/arr-ext.ts +25 -25
  36. package/src/types/date-only.ts +2 -2
  37. package/src/types/date-time.ts +2 -2
  38. package/src/types/time.ts +2 -2
  39. package/src/utils/date-format.ts +14 -14
  40. package/src/utils/json.ts +3 -3
  41. package/src/utils/num.ts +1 -1
  42. package/src/utils/obj.ts +14 -16
  43. package/src/utils/template-strings.ts +1 -1
  44. package/src/utils/transferable.ts +9 -9
  45. package/src/utils/wait.ts +1 -1
  46. package/src/utils/xml.ts +1 -1
  47. package/src/utils/zip.ts +1 -1
@@ -26,7 +26,7 @@ import type {
26
26
 
27
27
  const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
28
28
  single<T>(predicate?: (item: T, index: number) => boolean): T | undefined {
29
- const arr = predicate !== undefined ? this.filter(predicate) : this;
29
+ const arr = predicate != null ? this.filter(predicate) : this;
30
30
  if (arr.length > 1) {
31
31
  throw new ArgumentError("여러 개의 결과가 발견되었습니다.", { count: arr.length });
32
32
  }
@@ -34,7 +34,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
34
34
  },
35
35
 
36
36
  first<T>(predicate?: (item: T, index: number) => boolean): T | undefined {
37
- return predicate !== undefined ? this.find(predicate) : this[0];
37
+ return predicate != null ? this.find(predicate) : this[0];
38
38
  },
39
39
 
40
40
  async filterAsync<T>(predicate: (item: T, index: number) => Promise<boolean>): Promise<T[]> {
@@ -48,7 +48,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
48
48
  },
49
49
 
50
50
  last<T>(predicate?: (item: T, index: number) => boolean): T | undefined {
51
- if (predicate !== undefined) {
51
+ if (predicate != null) {
52
52
  for (let i = this.length - 1; i >= 0; i--) {
53
53
  if (predicate(this[i], i)) {
54
54
  return this[i];
@@ -113,7 +113,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
113
113
  },
114
114
 
115
115
  async mapManyAsync<T, R>(selector?: (item: T, index: number) => Promise<R[]>): Promise<T | R[]> {
116
- const arr = selector !== undefined ? await this.mapAsync(selector) : this;
116
+ const arr = selector != null ? await this.mapAsync(selector) : this;
117
117
  return arr.mapMany();
118
118
  },
119
119
 
@@ -139,13 +139,13 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
139
139
 
140
140
  for (let i = 0; i < this.length; i++) {
141
141
  const keyObj = keySelector(this[i], i);
142
- const valueObj = valueSelector !== undefined ? valueSelector(this[i], i) : this[i];
142
+ const valueObj = valueSelector != null ? valueSelector(this[i], i) : this[i];
143
143
 
144
144
  // 원시 key는 Map을 사용하여 O(n)으로 처리
145
145
  if (keyObj == null || typeof keyObj !== "object") {
146
146
  const keyStr = typeof keyObj + ":" + String(keyObj);
147
147
  const existingIndex = primitiveKeyIndex.get(keyStr);
148
- if (existingIndex !== undefined) {
148
+ if (existingIndex != null) {
149
149
  result[existingIndex].values.push(valueObj);
150
150
  } else {
151
151
  primitiveKeyIndex.set(keyStr, result.length);
@@ -156,7 +156,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
156
156
 
157
157
  // 객체 key는 기존 방식 O(n²) 사용
158
158
  const existsRecord = result.find((item) => equal(item.key, keyObj));
159
- if (existsRecord !== undefined) {
159
+ if (existsRecord != null) {
160
160
  existsRecord.values.push(valueObj);
161
161
  } else {
162
162
  result.push({ key: keyObj, values: [valueObj] });
@@ -176,7 +176,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
176
176
  const item = this[i];
177
177
 
178
178
  const keyObj = keySelector(item, i);
179
- const valueObj = valueSelector !== undefined ? valueSelector(item, i) : item;
179
+ const valueObj = valueSelector != null ? valueSelector(item, i) : item;
180
180
 
181
181
  if (result.has(keyObj)) {
182
182
  throw new ArgumentError("중복된 key입니다.", { duplicatedKey: keyObj });
@@ -197,7 +197,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
197
197
  const item = this[i];
198
198
 
199
199
  const keyObj = await keySelector(item, i);
200
- const valueObj = valueSelector !== undefined ? await valueSelector(item, i) : item;
200
+ const valueObj = valueSelector != null ? await valueSelector(item, i) : item;
201
201
 
202
202
  if (result.has(keyObj)) {
203
203
  throw new ArgumentError("중복된 key입니다.", { duplicatedKey: keyObj });
@@ -218,7 +218,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
218
218
  const item = this[i];
219
219
 
220
220
  const keyObj = keySelector(item, i);
221
- const valueObj = valueSelector !== undefined ? valueSelector(item, i) : item;
221
+ const valueObj = valueSelector != null ? valueSelector(item, i) : item;
222
222
 
223
223
  const arr = result.getOrCreate(keyObj, []);
224
224
  arr.push(valueObj);
@@ -237,7 +237,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
237
237
  const item = this[i];
238
238
 
239
239
  const keyObj = keySelector(item, i);
240
- const valueObj = valueSelector !== undefined ? valueSelector(item, i) : item;
240
+ const valueObj = valueSelector != null ? valueSelector(item, i) : item;
241
241
 
242
242
  const set = result.getOrCreate(keyObj, new Set<V | T>());
243
243
  set.add(valueObj);
@@ -280,10 +280,10 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
280
280
  const item = this[i];
281
281
 
282
282
  const key = keySelector(item, i);
283
- const valueObj = valueSelector !== undefined ? valueSelector(item, i) : item;
283
+ const valueObj = valueSelector != null ? valueSelector(item, i) : item;
284
284
 
285
285
  // undefined 값은 "없음"으로 처리하여 덮어쓰기 허용
286
- if (result[key] !== undefined) {
286
+ if (result[key] != null) {
287
287
  throw new ArgumentError("중복된 key입니다.", { duplicatedKey: key });
288
288
  }
289
289
  result[key] = valueObj;
@@ -345,7 +345,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
345
345
 
346
346
  const uncheckedTarget = [...target];
347
347
  const uncheckedTargetSet = new Set(uncheckedTarget);
348
- const hasKeys = options?.keys !== undefined && options.keys.length > 0;
348
+ const hasKeys = options?.keys != null && options.keys.length > 0;
349
349
  const excludeOpts = { topLevelExcludes: options?.excludes };
350
350
 
351
351
  // keys 옵션이 제공되면 target을 Map으로 사전 인덱싱하여 O(n×m) → O(n+m)으로 개선
@@ -381,7 +381,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
381
381
  }
382
382
 
383
383
  // 전체 일치가 없고 keys 옵션이 있으면 Map에서 O(1) 조회 수행
384
- if (sameTarget === undefined && keyIndexedTarget) {
384
+ if (sameTarget == null && keyIndexedTarget) {
385
385
  const sourceKeyStr = JSON.stringify(
386
386
  options!.keys!.map((k) => (sourceItem as Record<string, unknown>)[k]),
387
387
  );
@@ -392,9 +392,9 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
392
392
  }
393
393
  }
394
394
 
395
- if (sameTarget !== undefined) {
395
+ if (sameTarget != null) {
396
396
  uncheckedTargetSet.delete(sameTarget);
397
- } else if (sameKeyTarget !== undefined) {
397
+ } else if (sameKeyTarget != null) {
398
398
  result.push({ source: sourceItem, target: sameKeyTarget });
399
399
  uncheckedTargetSet.delete(sameKeyTarget);
400
400
  } else {
@@ -481,15 +481,15 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
481
481
 
482
482
  for (const diff of diffs) {
483
483
  // 업데이트 시
484
- if (diff.source !== undefined && diff.target !== undefined) {
484
+ if (diff.source != null && diff.target != null) {
485
485
  const sourceIndex = sourceIndexMap.get(diff.source);
486
- if (sourceIndex === undefined) {
486
+ if (sourceIndex == null) {
487
487
  throw new SdError("예상치 못한 오류: merge에서 source 항목을 찾을 수 없습니다.");
488
488
  }
489
489
  result[sourceIndex] = merge(diff.source, diff.target);
490
490
  }
491
491
  // 추가 시
492
- else if (diff.target !== undefined) {
492
+ else if (diff.target != null) {
493
493
  result.push(diff.target);
494
494
  }
495
495
  }
@@ -500,7 +500,7 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
500
500
  sum<T>(selector?: (item: T, index: number) => number): number {
501
501
  let result = 0;
502
502
  for (let i = 0; i < this.length; i++) {
503
- const item = selector !== undefined ? selector(this[i], i) : this[i];
503
+ const item = selector != null ? selector(this[i], i) : this[i];
504
504
  if (typeof item !== "number") {
505
505
  throw new ArgumentError("sum은 숫자에만 사용할 수 있습니다.", {
506
506
  type: typeof item,
@@ -515,13 +515,13 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
515
515
  min<T>(selector?: (item: T, index: number) => string | number): string | number | undefined {
516
516
  let result: string | number | undefined;
517
517
  for (let i = 0; i < this.length; i++) {
518
- const item = selector !== undefined ? selector(this[i], i) : this[i];
518
+ const item = selector != null ? selector(this[i], i) : this[i];
519
519
  if (typeof item !== "number" && typeof item !== "string") {
520
520
  throw new ArgumentError("min은 숫자/문자열에만 사용할 수 있습니다.", {
521
521
  type: typeof item,
522
522
  });
523
523
  }
524
- if (result === undefined || result > item) {
524
+ if (result == null || result > item) {
525
525
  result = item;
526
526
  }
527
527
  }
@@ -532,13 +532,13 @@ const arrayReadonlyExtensions: ReadonlyArrayExt<any> & ThisType<any[]> = {
532
532
  max<T>(selector?: (item: T, index: number) => string | number): string | number | undefined {
533
533
  let result: string | number | undefined;
534
534
  for (let i = 0; i < this.length; i++) {
535
- const item = selector !== undefined ? selector(this[i], i) : this[i];
535
+ const item = selector != null ? selector(this[i], i) : this[i];
536
536
  if (typeof item !== "number" && typeof item !== "string") {
537
537
  throw new ArgumentError("max는 숫자/문자열에만 사용할 수 있습니다.", {
538
538
  type: typeof item,
539
539
  });
540
540
  }
541
- if (result === undefined || result < item) {
541
+ if (result == null || result < item) {
542
542
  result = item;
543
543
  }
544
544
  }
@@ -26,11 +26,11 @@ export class DateOnly {
26
26
  /** Date 타입으로 생성 */
27
27
  constructor(date: Date);
28
28
  constructor(arg1?: number | Date, arg2?: number, arg3?: number) {
29
- if (arg1 === undefined) {
29
+ if (arg1 == null) {
30
30
  const tick = Date.now();
31
31
  const date = new Date(tick);
32
32
  this.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
33
- } else if (arg2 !== undefined && arg3 !== undefined) {
33
+ } else if (arg2 != null && arg3 != null) {
34
34
  this.date = new Date(arg1 as number, arg2 - 1, arg3);
35
35
  } else if (arg1 instanceof Date) {
36
36
  const date = arg1;
@@ -40,9 +40,9 @@ export class DateTime {
40
40
  arg6?: number,
41
41
  arg7?: number,
42
42
  ) {
43
- if (arg1 === undefined) {
43
+ if (arg1 == null) {
44
44
  this.date = new Date();
45
- } else if (arg2 !== undefined && arg3 !== undefined) {
45
+ } else if (arg2 != null && arg3 != null) {
46
46
  this.date = new Date(
47
47
  arg1 as number,
48
48
  arg2 - 1,
package/src/types/time.ts CHANGED
@@ -26,7 +26,7 @@ export class Time {
26
26
  /** Date 객체에서 시간 부분만 추출하여 생성 */
27
27
  constructor(date: Date);
28
28
  constructor(arg1?: number | Date, arg2?: number, arg3?: number, arg4?: number) {
29
- if (arg1 === undefined) {
29
+ if (arg1 == null) {
30
30
  const now = new Date();
31
31
  this._tick =
32
32
  (now.getMilliseconds() +
@@ -34,7 +34,7 @@ export class Time {
34
34
  now.getMinutes() * 60 * 1000 +
35
35
  now.getHours() * 60 * 60 * 1000) %
36
36
  Time._MS_PER_DAY;
37
- } else if (arg2 !== undefined) {
37
+ } else if (arg2 != null) {
38
38
  let tick =
39
39
  ((arg4 ?? 0) + (arg3 ?? 0) * 1000 + arg2 * 60 * 1000 + (arg1 as number) * 60 * 60 * 1000) %
40
40
  Time._MS_PER_DAY;
@@ -152,47 +152,47 @@ export function format(
152
152
  const { year, month, day, hour, minute, second, millisecond, timezoneOffsetMinutes } = args;
153
153
 
154
154
  const absOffsetMinutes =
155
- timezoneOffsetMinutes !== undefined ? Math.abs(timezoneOffsetMinutes) : undefined;
156
- const offsetHour = absOffsetMinutes !== undefined ? Math.floor(absOffsetMinutes / 60) : undefined;
157
- const offsetMinute = absOffsetMinutes !== undefined ? absOffsetMinutes % 60 : undefined;
155
+ timezoneOffsetMinutes != null ? Math.abs(timezoneOffsetMinutes) : undefined;
156
+ const offsetHour = absOffsetMinutes != null ? Math.floor(absOffsetMinutes / 60) : undefined;
157
+ const offsetMinute = absOffsetMinutes != null ? absOffsetMinutes % 60 : undefined;
158
158
  const offsetSign =
159
- timezoneOffsetMinutes !== undefined ? (timezoneOffsetMinutes >= 0 ? "+" : "-") : undefined;
159
+ timezoneOffsetMinutes != null ? (timezoneOffsetMinutes >= 0 ? "+" : "-") : undefined;
160
160
 
161
161
  const week =
162
- year !== undefined && month !== undefined && day !== undefined
162
+ year != null && month != null && day != null
163
163
  ? new Date(year, month - 1, day).getDay()
164
164
  : undefined;
165
165
 
166
166
  let result = formatString;
167
167
 
168
168
  // 연도
169
- if (year !== undefined) {
169
+ if (year != null) {
170
170
  const yearStr = year.toString();
171
171
  result = result.replace(patterns.yyyy, yearStr);
172
172
  result = result.replace(patterns.yy, yearStr.substring(2, 4));
173
173
  }
174
174
 
175
175
  // 월
176
- if (month !== undefined) {
176
+ if (month != null) {
177
177
  const monthStr = month.toString();
178
178
  result = result.replace(patterns.MM, monthStr.padStart(2, "0"));
179
179
  result = result.replace(patterns.M, monthStr);
180
180
  }
181
181
 
182
182
  // 요일
183
- if (week !== undefined) {
183
+ if (week != null) {
184
184
  result = result.replace(patterns.ddd, weekStrings[week]);
185
185
  }
186
186
 
187
187
  // 일
188
- if (day !== undefined) {
188
+ if (day != null) {
189
189
  const dayStr = day.toString();
190
190
  result = result.replace(patterns.dd, dayStr.padStart(2, "0"));
191
191
  result = result.replace(patterns.d, dayStr);
192
192
  }
193
193
 
194
194
  // 시
195
- if (hour !== undefined) {
195
+ if (hour != null) {
196
196
  result = result.replace(patterns.tt, hour < 12 ? "AM" : "PM");
197
197
 
198
198
  const hour12 = hour % 12 || 12;
@@ -206,21 +206,21 @@ export function format(
206
206
  }
207
207
 
208
208
  // 분
209
- if (minute !== undefined) {
209
+ if (minute != null) {
210
210
  const minuteStr = minute.toString();
211
211
  result = result.replace(patterns.mm, minuteStr.padStart(2, "0"));
212
212
  result = result.replace(patterns.m, minuteStr);
213
213
  }
214
214
 
215
215
  // 초
216
- if (second !== undefined) {
216
+ if (second != null) {
217
217
  const secondStr = second.toString();
218
218
  result = result.replace(patterns.ss, secondStr.padStart(2, "0"));
219
219
  result = result.replace(patterns.s, secondStr);
220
220
  }
221
221
 
222
222
  // 밀리초
223
- if (millisecond !== undefined) {
223
+ if (millisecond != null) {
224
224
  const msStr = millisecond.toString().padStart(3, "0");
225
225
  result = result.replace(patterns.fff, msStr);
226
226
  result = result.replace(patterns.ff, msStr.substring(0, 2));
@@ -228,7 +228,7 @@ export function format(
228
228
  }
229
229
 
230
230
  // 타임존
231
- if (offsetSign !== undefined && offsetHour !== undefined && offsetMinute !== undefined) {
231
+ if (offsetSign != null && offsetHour != null && offsetMinute != null) {
232
232
  result = result.replace(
233
233
  patterns.zzz,
234
234
  `${offsetSign}${offsetHour.toString().padStart(2, "0")}:${offsetMinute.toString().padStart(2, "0")}`,
package/src/utils/json.ts CHANGED
@@ -56,7 +56,7 @@ export function stringify(
56
56
  */
57
57
  const convertSpecialTypes = (key: string | undefined, value: unknown): unknown => {
58
58
  // 커스텀 replacer 적용
59
- const currValue = options?.replacer !== undefined ? options.replacer(key, value) : value;
59
+ const currValue = options?.replacer != null ? options.replacer(key, value) : value;
60
60
 
61
61
  if (currValue instanceof Date) {
62
62
  return { __type__: "Date", data: currValue.toISOString() };
@@ -121,7 +121,7 @@ export function stringify(
121
121
  }
122
122
 
123
123
  // 일반 객체 처리
124
- if (currValue !== null && typeof currValue === "object") {
124
+ if (currValue != null && typeof currValue === "object") {
125
125
  // 순환 참조 감지
126
126
  if (seen.has(currValue)) {
127
127
  throw new TypeError("Converting circular structure to JSON");
@@ -142,7 +142,7 @@ export function stringify(
142
142
  for (const [k, v] of Object.entries(currValue)) {
143
143
  const converted = convertSpecialTypes(k, v);
144
144
  // undefined는 JSON에서 제외됨
145
- if (converted !== undefined) {
145
+ if (converted != null) {
146
146
  result[k] = converted;
147
147
  }
148
148
  }
package/src/utils/num.ts CHANGED
@@ -29,7 +29,7 @@ export function parseInt(text: unknown): number | undefined {
29
29
  */
30
30
  export function parseRoundedInt(text: unknown): number | undefined {
31
31
  const float = parseFloat(text);
32
- return float !== undefined ? Math.round(float) : undefined;
32
+ return float != null ? Math.round(float) : undefined;
33
33
  }
34
34
 
35
35
  /**
package/src/utils/obj.ts CHANGED
@@ -22,7 +22,7 @@ export function clone<TObj>(source: TObj): TObj {
22
22
 
23
23
  function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unknown {
24
24
  // 원시 값은 그대로 반환
25
- if (typeof source !== "object" || source === null) {
25
+ if (typeof source !== "object" || source == null) {
26
26
  return source;
27
27
  }
28
28
 
@@ -66,14 +66,14 @@ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unkn
66
66
  cloned.message = source.message;
67
67
  cloned.name = source.name;
68
68
  cloned.stack = source.stack;
69
- if (source.cause !== undefined) {
69
+ if (source.cause != null) {
70
70
  cloned.cause = cloneImpl(source.cause, currPrevClones);
71
71
  }
72
72
  // 커스텀 Error 속성 복사
73
73
  for (const key of Object.keys(source)) {
74
74
  if (!["message", "name", "stack", "cause"].includes(key)) {
75
75
  const desc = Object.getOwnPropertyDescriptor(source, key);
76
- if (desc !== undefined) {
76
+ if (desc != null) {
77
77
  Object.defineProperty(cloned, key, {
78
78
  ...desc,
79
79
  value: "value" in desc ? cloneImpl(desc.value, currPrevClones) : desc.value,
@@ -352,13 +352,13 @@ function equalObject(
352
352
  ): boolean {
353
353
  const sourceKeys = Object.keys(source).filter(
354
354
  (key) =>
355
- (options?.topLevelIncludes === undefined || options.topLevelIncludes.includes(key)) &&
355
+ (options?.topLevelIncludes == null || options.topLevelIncludes.includes(key)) &&
356
356
  !options?.topLevelExcludes?.includes(key) &&
357
357
  source[key] != null,
358
358
  );
359
359
  const targetKeys = Object.keys(target).filter(
360
360
  (key) =>
361
- (options?.topLevelIncludes === undefined || options.topLevelIncludes.includes(key)) &&
361
+ (options?.topLevelIncludes == null || options.topLevelIncludes.includes(key)) &&
362
362
  !options?.topLevelExcludes?.includes(key) &&
363
363
  target[key] != null,
364
364
  );
@@ -460,16 +460,14 @@ export function merge<TSource, TMergeTarget>(
460
460
  return clone(target) as TSource & TMergeTarget;
461
461
  }
462
462
 
463
- if (target === undefined) {
463
+ if (target == null) {
464
+ // null(typeof "object")이면 useDelTargetNull 옵션 적용, undefined면 항상 clone
465
+ if (typeof target === "object" && opt?.useDelTargetNull) {
466
+ return undefined as TSource & TMergeTarget;
467
+ }
464
468
  return clone(source) as TSource & TMergeTarget;
465
469
  }
466
470
 
467
- if (target === null) {
468
- return opt?.useDelTargetNull
469
- ? (undefined as TSource & TMergeTarget)
470
- : (clone(source) as TSource & TMergeTarget);
471
- }
472
-
473
471
  if (typeof target !== "object") {
474
472
  return target as TSource & TMergeTarget;
475
473
  }
@@ -506,7 +504,7 @@ export function merge<TSource, TMergeTarget>(
506
504
  if (opt?.arrayProcess === "concat" && source instanceof Array && target instanceof Array) {
507
505
  let result = [...new Set([...source, ...target])];
508
506
  if (opt.useDelTargetNull) {
509
- result = result.filter((item) => item !== null);
507
+ result = result.filter((item) => item != null);
510
508
  }
511
509
  return result as TSource & TMergeTarget;
512
510
  }
@@ -516,7 +514,7 @@ export function merge<TSource, TMergeTarget>(
516
514
  const resultRec = clone(sourceRec);
517
515
  for (const key of Object.keys(target)) {
518
516
  resultRec[key] = merge(sourceRec[key], targetRec[key], opt);
519
- if (resultRec[key] === undefined) {
517
+ if (resultRec[key] == null) {
520
518
  delete resultRec[key];
521
519
  }
522
520
  }
@@ -706,7 +704,7 @@ export function getChainValue(
706
704
  const splits = getChainSplits(chain);
707
705
  let result: unknown = obj;
708
706
  for (const splitItem of splits) {
709
- if (optional && result === undefined) {
707
+ if (optional && result == null) {
710
708
  result = undefined;
711
709
  } else {
712
710
  result = (result as Record<string | number, unknown>)[splitItem];
@@ -813,7 +811,7 @@ export function deleteChainValue(obj: unknown, chain: string): void {
813
811
  export function clearUndefined<T extends object>(obj: T): T {
814
812
  const record = obj as Record<string, unknown>;
815
813
  for (const key of Object.keys(record)) {
816
- if (record[key] === undefined) {
814
+ if (record[key] == null) {
817
815
  delete record[key];
818
816
  }
819
817
  }
@@ -102,7 +102,7 @@ export function pgsql(strings: TemplateStringsArray, ...values: unknown[]): stri
102
102
 
103
103
  function _combine(strings: TemplateStringsArray, values: unknown[]): string {
104
104
  const raw = strings.reduce((result, str, i) => {
105
- const value = values[i] !== undefined ? String(values[i]) : "";
105
+ const value = values[i] != null ? String(values[i]) : "";
106
106
  return result + str + value;
107
107
  }, "");
108
108
  return _trimIndent(raw);
@@ -73,7 +73,7 @@ function encodeImpl(
73
73
 
74
74
  // 이미 인코딩된 객체이면 캐싱된 결과 재사용
75
75
  const cached = cache.get(obj);
76
- if (cached !== undefined) return cached;
76
+ if (cached != null) return cached;
77
77
 
78
78
  // 재귀 스택에 추가
79
79
  ancestors.add(obj);
@@ -118,8 +118,8 @@ function encodeImpl(
118
118
  name: errObj.name,
119
119
  message: errObj.message,
120
120
  stack: errObj.stack,
121
- ...(errObj.code !== undefined ? { code: errObj.code } : {}),
122
- ...(errObj.detail !== undefined
121
+ ...(errObj.code != null ? { code: errObj.code } : {}),
122
+ ...(errObj.detail != null
123
123
  ? {
124
124
  detail: encodeImpl(
125
125
  errObj.detail,
@@ -130,7 +130,7 @@ function encodeImpl(
130
130
  ),
131
131
  }
132
132
  : {}),
133
- ...(errObj.cause !== undefined
133
+ ...(errObj.cause != null
134
134
  ? {
135
135
  cause: encodeImpl(errObj.cause, transferList, [...path, "cause"], ancestors, cache),
136
136
  }
@@ -217,11 +217,11 @@ export function decode(obj: unknown): unknown {
217
217
  if (typed.__type__ === "DateOnly" && typeof data === "number") return new DateOnly(data);
218
218
  if (typed.__type__ === "Time" && typeof data === "number") return new Time(data);
219
219
  if (typed.__type__ === "Uuid" && typeof data === "string") return new Uuid(data);
220
- if (typed.__type__ === "RegExp" && typeof data === "object" && data !== null) {
220
+ if (typed.__type__ === "RegExp" && typeof data === "object" && data != null) {
221
221
  const regexData = data as { source: string; flags: string };
222
222
  return new RegExp(regexData.source, regexData.flags);
223
223
  }
224
- if (typed.__type__ === "Error" && typeof data === "object" && data !== null) {
224
+ if (typed.__type__ === "Error" && typeof data === "object" && data != null) {
225
225
  const errorData = data as {
226
226
  name: string;
227
227
  message: string;
@@ -238,9 +238,9 @@ export function decode(obj: unknown): unknown {
238
238
  err.name = errorData.name;
239
239
  err.stack = errorData.stack;
240
240
 
241
- if (errorData.code !== undefined) err.code = errorData.code;
242
- if (errorData.cause !== undefined) (err as Error).cause = decode(errorData.cause);
243
- if (errorData.detail !== undefined) err.detail = decode(errorData.detail);
241
+ if (errorData.code != null) err.code = errorData.code;
242
+ if (errorData.cause != null) (err as Error).cause = decode(errorData.cause);
243
+ if (errorData.detail != null) err.detail = decode(errorData.detail);
244
244
  return err;
245
245
  }
246
246
  }
package/src/utils/wait.ts CHANGED
@@ -23,7 +23,7 @@ export async function until(
23
23
  let count = 0;
24
24
  while (!(await forwarder())) {
25
25
  count++;
26
- if (maxCount !== undefined && count >= maxCount) {
26
+ if (maxCount != null && count >= maxCount) {
27
27
  throw new TimeoutError(count);
28
28
  }
29
29
 
package/src/utils/xml.ts CHANGED
@@ -79,7 +79,7 @@ function stripTagPrefix(obj: unknown): unknown {
79
79
  return obj.map((item) => stripTagPrefix(item));
80
80
  }
81
81
 
82
- if (typeof obj === "object" && obj !== null) {
82
+ if (typeof obj === "object" && obj != null) {
83
83
  const newObj: Record<string, unknown> = {};
84
84
  const record = obj as Record<string, unknown>;
85
85
 
package/src/utils/zip.ts CHANGED
@@ -182,7 +182,7 @@ export class ZipArchive {
182
182
  }
183
183
 
184
184
  const entry = entries.find((item) => item.filename === fileName) as FileEntry | undefined;
185
- return entry !== undefined;
185
+ return entry != null;
186
186
  }
187
187
  //#endregion
188
188