@uniai-fe/util-functions 0.2.0 → 0.2.1

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/README.md CHANGED
@@ -1,47 +1,3 @@
1
1
  # util / functions
2
2
 
3
3
  의존성을 최소화한 범용 도구 모음
4
-
5
- ## 빠른 사용법 (API + 환경변수)
6
-
7
- - 1단계만 기억하세요: **env 맵만 넘겨 `createBackendApiClientFromEnv`를 호출**합니다.
8
- - 예시:
9
-
10
- ```ts
11
- import { createBackendApiClientFromEnv } from "@uniai-fe/util-functions/api";
12
-
13
- // env 맵 → 도메인으로 바꿔주는 클라이언트를 한 번만 생성
14
- const api = createBackendApiClientFromEnv({
15
- ai: process.env.AI_API_BASE,
16
- db: process.env.DB_API_BASE,
17
- uniai: process.env.UNIAI_API_BASE,
18
- });
19
-
20
- export const { generateBackendQueryUrl_GET, fetchBackendQuery } = api;
21
- export const apiLog = api.logger; // == nextAPILog
22
- ```
23
-
24
- - 서비스 앱이든 모듈 패키지든 동일한 접근입니다. Next.js이면 `@uniai-fe/util-next`의 어댑터를 통해 같은 API를 그대로 사용하면 됩니다.
25
-
26
- ## 타입 선언 관리 메모
27
-
28
- - 내부 타입 정의는 `.d.ts` 대신 `.ts` 모듈(예: `src/core/format/types.ts`)로 유지합니다.
29
- - tsup 번들 과정에서 선언 전용 파일이 엔트리에 포함되면 경고가 발생할 수 있어,
30
- `.ts` 모듈로 import/export 하되 TypeScript가 컴파일 시 타입만 제거하도록 위임합니다.
31
-
32
- ## 동작 원리 / 로직 개요
33
-
34
- - `createBackendApiClientFromEnv`는 env 맵 → `resolveDomain` → API 클라이언트로 이어지는 단계를 한 번에 처리합니다. env가 비어 있으면 `process.env[${INFRA}_API_BASE]` → `infra` 문자열 순으로 fallback 합니다.
35
- - 직접 제어가 필요하면 `createEnvDomainResolver`를 사용해 resolver만 만들고 `createBackendApiClient`에 주입할 수 있습니다.
36
- - 클라이언트에서 얻을 수 있는 것들:
37
- - `generateBackendQueryUrl_GET`: 도메인 + 쿼리스트링 조합
38
- - `fetchBackendQuery`: POST/DELETE 등 본문 포함 요청과 로깅/대체응답 처리
39
- - `getQueryString`: 객체/URLSearchParams 직렬화
40
- - `logger`: 공통 포맷 로거
41
- - 이 구조 덕분에 최종 사용 단계는 “한 번 정의한 클라이언트에서 함수 가져다 쓰기”로 끝납니다.
42
-
43
- ## Next.js 유틸 안내
44
-
45
- - Next 서버 전용 API 도우미는 `@uniai-fe/util-next` 패키지로 이동했습니다.
46
- - 환경 구성(`api-infra.config.ts`)을 통해 도메인을 주입한 뒤 util-functions의 공용 API 헬퍼를 활용하세요.
47
- - JSX/파일 등 React 의존 유틸은 `@uniai-fe/util-react` 패키지에서 제공됩니다.
package/dist/index.cjs CHANGED
@@ -786,7 +786,7 @@ var fetchWithBody = async ({
786
786
  }
787
787
  };
788
788
 
789
- // src/user-agent/device-patterns.ts
789
+ // src/runtime-env/device.ts
790
790
  var apple = ["iPhone", "iPad", "iPod", "Mac", "Macintosh"];
791
791
  var tablet = ["Tablet", "iPad", "playbook", "silk"];
792
792
  var mobile = [
@@ -812,21 +812,17 @@ var mobile = [
812
812
  "Skyfire",
813
813
  "Zune"
814
814
  ];
815
- var devicePatterns = {
815
+ var userAgentCollection = {
816
816
  apple,
817
817
  tablet,
818
818
  mobile
819
819
  };
820
- var device_patterns_default = devicePatterns;
821
-
822
- // src/user-agent/module.ts
823
820
  var setLowerCase = (v) => String(v).toLowerCase();
824
- var deviceLowerCasePatterns = Object.fromEntries(
825
- Object.entries(device_patterns_default).map(([key, value]) => [
826
- key,
827
- value.map(setLowerCase)
828
- ])
829
- );
821
+ var deviceLowerCasePatterns = {
822
+ apple: apple.map(setLowerCase),
823
+ tablet: tablet.map(setLowerCase),
824
+ mobile: mobile.map(setLowerCase)
825
+ };
830
826
  var checkResponsiveDevice = (userAgent) => {
831
827
  const { mobile: mobile2, tablet: tablet2 } = deviceLowerCasePatterns;
832
828
  const clientAgent = setLowerCase(userAgent);
@@ -841,6 +837,50 @@ var checkAppleDevice = (userAgent) => {
841
837
  return apple2.some((agent) => clientAgent.includes(agent));
842
838
  };
843
839
 
840
+ // src/runtime-env/pwa.ts
841
+ var DISPLAY_MODE_QUERIES = [
842
+ { mode: "standalone", query: "(display-mode: standalone)" },
843
+ { mode: "fullscreen", query: "(display-mode: fullscreen)" },
844
+ { mode: "minimal-ui", query: "(display-mode: minimal-ui)" },
845
+ { mode: "browser", query: "(display-mode: browser)" }
846
+ ];
847
+ var STANDALONE_DISPLAY_MODES = /* @__PURE__ */ new Set([
848
+ "standalone",
849
+ "fullscreen",
850
+ "minimal-ui"
851
+ ]);
852
+ var isWindowAvailable = () => typeof window !== "undefined";
853
+ var detectDisplayMode = () => {
854
+ if (!isWindowAvailable() || typeof window.matchMedia !== "function") {
855
+ return "unknown";
856
+ }
857
+ for (const { mode, query } of DISPLAY_MODE_QUERIES) {
858
+ if (window.matchMedia(query).matches) {
859
+ return mode;
860
+ }
861
+ }
862
+ return "unknown";
863
+ };
864
+ var detectNavigatorStandalone = () => {
865
+ if (!isWindowAvailable()) {
866
+ return false;
867
+ }
868
+ const nav = window.navigator;
869
+ return typeof nav.standalone === "boolean" ? Boolean(nav.standalone) : false;
870
+ };
871
+ var getPwaRuntimeInfo = () => {
872
+ const displayMode = detectDisplayMode();
873
+ const navigatorStandalone = detectNavigatorStandalone();
874
+ if (displayMode === "unknown" && navigatorStandalone) {
875
+ return { isStandalone: true, displayMode: "standalone" };
876
+ }
877
+ return {
878
+ displayMode,
879
+ isStandalone: displayMode === "unknown" ? navigatorStandalone : STANDALONE_DISPLAY_MODES.has(displayMode)
880
+ };
881
+ };
882
+ var checkStandaloneApp = getPwaRuntimeInfo;
883
+
844
884
  // src/form/checkbox/module.ts
845
885
  var syncAllToEach = (checkStateObject, allCheckState) => Object.fromEntries(
846
886
  Object.entries(checkStateObject).map(([key]) => [key, allCheckState])
@@ -889,6 +929,7 @@ exports.capitalize = capitalize;
889
929
  exports.checkAppleDevice = checkAppleDevice;
890
930
  exports.checkDateMoment = checkDateMoment;
891
931
  exports.checkResponsiveDevice = checkResponsiveDevice;
932
+ exports.checkStandaloneApp = checkStandaloneApp;
892
933
  exports.convert2Digit = convert2Digit;
893
934
  exports.convertDigit = convertDigit;
894
935
  exports.convertLiter = convertLiter;
@@ -900,7 +941,6 @@ exports.covertGram = covertGram;
900
941
  exports.covertKilogram = covertKilogram;
901
942
  exports.dateFormat = dateFormat;
902
943
  exports.deltaFormat = deltaFormat;
903
- exports.devicePatterns = device_patterns_default;
904
944
  exports.distanceFormat = distanceFormat;
905
945
  exports.durationFormat = durationFormat;
906
946
  exports.escapeQuotes = escapeQuotes;
@@ -919,6 +959,7 @@ exports.getNextDay = getNextDay;
919
959
  exports.getNextWeeks = getNextWeeks;
920
960
  exports.getNumberReplaceComma = getNumberReplaceComma;
921
961
  exports.getPrevDay = getPrevDay;
962
+ exports.getPwaRuntimeInfo = getPwaRuntimeInfo;
922
963
  exports.getQueryString = getQueryString;
923
964
  exports.getRepeatCycleUnit = getRepeatCycleUnit;
924
965
  exports.getToday = getToday;
@@ -960,6 +1001,7 @@ exports.styleSpacingSize = styleSpacingSize;
960
1001
  exports.syncAllToEach = syncAllToEach;
961
1002
  exports.syncEachToAll = syncEachToAll;
962
1003
  exports.timeFormat = timeFormat;
1004
+ exports.userAgentCollection = userAgentCollection;
963
1005
  exports.weekOrderIndex = weekOrderIndex;
964
1006
  exports.weekOrderKo = weekOrderKo;
965
1007
  exports.weekdayByDayCode = weekdayByDayCode;