@apps-in-toss/native-modules 0.0.0-dev.1752115036458 → 0.0.0-dev.1757056983098

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 (77) hide show
  1. package/dist/bridges-meta.json +36 -13
  2. package/dist/index.cjs +343 -129
  3. package/dist/index.d.cts +1212 -418
  4. package/dist/index.d.ts +1212 -418
  5. package/dist/index.js +315 -108
  6. package/package.json +7 -8
  7. package/src/AppsInTossModule/constants.ts +6 -0
  8. package/src/AppsInTossModule/native-event-emitter/appsInTossEvent.ts +15 -0
  9. package/src/AppsInTossModule/native-event-emitter/contactsViral.ts +140 -0
  10. package/src/AppsInTossModule/native-event-emitter/event-plugins/EntryMessageExitedEvent.ts +10 -0
  11. package/src/AppsInTossModule/native-event-emitter/event-plugins/HomeIconButtonClickHandleEvent.ts +10 -0
  12. package/src/AppsInTossModule/native-event-emitter/event-plugins/UpdateLocationEvent.ts +60 -0
  13. package/src/AppsInTossModule/native-event-emitter/index.ts +6 -0
  14. package/src/AppsInTossModule/native-event-emitter/internal/AppBridgeCallbackEvent.ts +45 -0
  15. package/src/AppsInTossModule/native-event-emitter/internal/VisibilityChangedByTransparentServiceWebEvent.ts +50 -0
  16. package/src/AppsInTossModule/native-event-emitter/internal/appBridge.spec.ts +135 -0
  17. package/src/AppsInTossModule/native-event-emitter/internal/appBridge.ts +79 -0
  18. package/src/AppsInTossModule/native-event-emitter/internal/onVisibilityChangedByTransparentServiceWeb.ts +20 -0
  19. package/src/AppsInTossModule/native-event-emitter/nativeEventEmitter.ts +35 -0
  20. package/src/AppsInTossModule/native-event-emitter/startUpdateLocation.ts +98 -0
  21. package/src/AppsInTossModule/native-event-emitter/types.ts +4 -0
  22. package/src/AppsInTossModule/native-modules/AppsInTossModule.ts +89 -0
  23. package/src/AppsInTossModule/native-modules/ads/googleAdMob.ts +681 -0
  24. package/src/AppsInTossModule/native-modules/ads/googleAdMobV2.ts +363 -0
  25. package/src/AppsInTossModule/native-modules/ads/types.ts +123 -0
  26. package/src/AppsInTossModule/native-modules/appLogin.ts +29 -0
  27. package/src/AppsInTossModule/native-modules/checkoutPayment.ts +80 -0
  28. package/src/AppsInTossModule/native-modules/eventLog.spec.ts +300 -0
  29. package/src/AppsInTossModule/native-modules/eventLog.ts +77 -0
  30. package/src/AppsInTossModule/native-modules/fetchAlbumPhotos.ts +88 -0
  31. package/src/AppsInTossModule/native-modules/fetchContacts.ts +121 -0
  32. package/src/AppsInTossModule/native-modules/getClipboardText.ts +47 -0
  33. package/src/AppsInTossModule/native-modules/getCurrentLocation.ts +65 -0
  34. package/src/AppsInTossModule/native-modules/getDeviceId.ts +33 -0
  35. package/src/AppsInTossModule/native-modules/getGameCenterGameProfile.ts +68 -0
  36. package/src/AppsInTossModule/native-modules/getOperationalEnvironment.ts +37 -0
  37. package/src/AppsInTossModule/native-modules/getPermission.ts +58 -0
  38. package/src/AppsInTossModule/native-modules/getTossAppVersion.ts +33 -0
  39. package/src/AppsInTossModule/native-modules/getTossShareLink.ts +39 -0
  40. package/src/AppsInTossModule/native-modules/iap.ts +213 -0
  41. package/src/AppsInTossModule/native-modules/index.ts +104 -0
  42. package/src/AppsInTossModule/native-modules/isMinVersionSupported.spec.ts +190 -0
  43. package/src/AppsInTossModule/native-modules/isMinVersionSupported.ts +68 -0
  44. package/src/AppsInTossModule/native-modules/openCamera.ts +81 -0
  45. package/src/AppsInTossModule/native-modules/openGameCenterLeaderboard.ts +44 -0
  46. package/src/AppsInTossModule/native-modules/openPermissionDialog.ts +54 -0
  47. package/src/AppsInTossModule/native-modules/requestPermission.ts +63 -0
  48. package/src/AppsInTossModule/native-modules/saveBase64Data.ts +57 -0
  49. package/src/AppsInTossModule/native-modules/setClipboardText.ts +39 -0
  50. package/src/AppsInTossModule/native-modules/setDeviceOrientation.ts +74 -0
  51. package/src/AppsInTossModule/native-modules/storage.ts +100 -0
  52. package/src/AppsInTossModule/native-modules/submitGameCenterLeaderBoardScore.ts +74 -0
  53. package/src/AppsInTossModule/native-modules/tossCore.ts +29 -0
  54. package/src/BedrockModule/native-modules/core/BedrockCoreModule.ts +8 -0
  55. package/src/BedrockModule/native-modules/index.ts +4 -0
  56. package/src/BedrockModule/native-modules/natives/BedrockModule.ts +20 -0
  57. package/src/BedrockModule/native-modules/natives/closeView.ts +25 -0
  58. package/src/BedrockModule/native-modules/natives/generateHapticFeedback/index.ts +27 -0
  59. package/src/BedrockModule/native-modules/natives/generateHapticFeedback/types.ts +38 -0
  60. package/src/BedrockModule/native-modules/natives/getLocale.ts +46 -0
  61. package/src/BedrockModule/native-modules/natives/getNetworkStatus/index.ts +59 -0
  62. package/src/BedrockModule/native-modules/natives/getNetworkStatus/types.ts +1 -0
  63. package/src/BedrockModule/native-modules/natives/getPlatformOS.ts +37 -0
  64. package/src/BedrockModule/native-modules/natives/getSchemeUri.ts +27 -0
  65. package/src/BedrockModule/native-modules/natives/index.ts +11 -0
  66. package/src/BedrockModule/native-modules/natives/openURL.ts +40 -0
  67. package/src/BedrockModule/native-modules/natives/setIosSwipeGestureEnabled.ts +43 -0
  68. package/src/BedrockModule/native-modules/natives/setScreenAwakeMode.ts +66 -0
  69. package/src/BedrockModule/native-modules/natives/setSecureScreen.ts +31 -0
  70. package/src/BedrockModule/native-modules/natives/share.ts +36 -0
  71. package/src/async-bridges.ts +3 -0
  72. package/src/event-bridges.ts +2 -0
  73. package/src/index.ts +16 -0
  74. package/src/types.ts +108 -0
  75. package/src/utils/compareVersion.spec.ts +176 -0
  76. package/src/utils/compareVersion.ts +104 -0
  77. package/src/utils/generateUUID.ts +5 -0
@@ -0,0 +1,31 @@
1
+ import { BedrockModule } from './BedrockModule';
2
+
3
+ /**
4
+ * @public
5
+ * @name setSecureScreen
6
+ * @category 화면 제어
7
+ * @kind function
8
+ * @description
9
+ * 화면 캡쳐를 차단해서 민감한 정보가 유출되지 않도록 보호하거나, 필요할 경우 캡쳐를 허용하도록 설정해요. 예를 들어 보안이 중요한 화면에서 사용할 수 있어요.
10
+ *
11
+ * @param {object} options 화면 캡쳐 설정 옵션이에요.
12
+ * @param {boolean} options.enabled 화면 캡쳐를 차단할지 여부를 설정해요. `true`면 캡쳐를 차단하고, `false`면 허용해요.
13
+ * @returns {enabled: boolean} 현재 설정된 캡쳐 차단 상태를 반환해요.
14
+ *
15
+ * @example
16
+ * ### 캡쳐 허용 상태 변경하기
17
+ *
18
+ * ```tsx
19
+ * import { Button } from 'react-native';
20
+ * import { setSecureScreen } from '@apps-in-toss/native-modules';
21
+ *
22
+ * function SetSecureScreen() {
23
+ * return <Button title="캡쳐 막기" onPress={async () => {
24
+ * await setSecureScreen({ enabled: true });
25
+ * }} />;
26
+ * }
27
+ * ```
28
+ */
29
+ export function setSecureScreen(options: { enabled: boolean }): Promise<{ enabled: boolean }> {
30
+ return BedrockModule.setSecureScreen(options);
31
+ }
@@ -0,0 +1,36 @@
1
+ import { BedrockModule } from './BedrockModule';
2
+
3
+ /**
4
+ * @public
5
+ * @category 공유
6
+ * @kind function
7
+ * @name share
8
+ * @description
9
+ * 사용자가 콘텐츠를 다른 사람과 공유할 수 있도록 네이티브 공유 시트를 표시해요.
10
+ * `options.message` 속성에 공유할 메시지를 전달하면, 사용자가 선택할 수 있는 앱 목록이 표시돼요.
11
+ * 예를 들어, 사용자가 텍스트 메시지를 공유하거나 메모 앱에 저장하려고 할 때 유용해요.
12
+ * @param {object} options - 공유할 메시지를 담은 객체예요.
13
+ * @param {string} options.message - 공유할 텍스트 문자열이에요. 예를 들어, "안녕하세요! 이 내용을 공유합니다."
14
+ *
15
+ * @example
16
+ * ### 공유하기 기능 구현하기
17
+ *
18
+ * 아래는 버튼을 클릭하면 메시지를 공유하는 간단한 예제예요.
19
+ *
20
+ * ```tsx
21
+ * import { share } from '@apps-in-toss/native-modules';
22
+ * import { Button } from 'react-native';
23
+ *
24
+ * function MyPage() {
25
+ * return (
26
+ * <Button
27
+ * title="공유"
28
+ * onPress={() => share({ message: '공유할 메시지입니다.' })}
29
+ * />
30
+ * );
31
+ * }
32
+ * ```
33
+ */
34
+ export async function share(message: { message: string }) {
35
+ BedrockModule.share(message);
36
+ }
@@ -21,3 +21,6 @@ export * from './AppsInTossModule/native-modules/getTossShareLink';
21
21
  export * from './AppsInTossModule/native-modules/setDeviceOrientation';
22
22
  export * from './AppsInTossModule/native-modules/checkoutPayment';
23
23
  export * from './AppsInTossModule/native-modules/saveBase64Data';
24
+ export * from './AppsInTossModule/native-modules/getGameCenterGameProfile';
25
+ export * from './AppsInTossModule/native-modules/openGameCenterLeaderboard';
26
+ export * from './AppsInTossModule/native-modules/submitGameCenterLeaderBoardScore';
@@ -1,2 +1,4 @@
1
1
  // AppsInTossModule
2
2
  export * from './AppsInTossModule/native-event-emitter/startUpdateLocation';
3
+ export * from './AppsInTossModule/native-event-emitter/internal/onVisibilityChangedByTransparentServiceWeb';
4
+ export * from './AppsInTossModule/native-event-emitter/contactsViral';
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ // AppsInTossModule
2
+ export * from './AppsInTossModule/native-event-emitter';
3
+ export * from './AppsInTossModule/native-modules';
4
+
5
+ // BedrockModule
6
+ export * from './BedrockModule/native-modules';
7
+
8
+ // Types
9
+ export * from './types';
10
+
11
+ // Private
12
+ import { tossCoreEventLog } from './AppsInTossModule/native-modules/tossCore';
13
+ // eslint-disable-next-line @typescript-eslint/naming-convention
14
+ export const INTERNAL__module = {
15
+ tossCoreEventLog,
16
+ };
package/src/types.ts ADDED
@@ -0,0 +1,108 @@
1
+ export type PermissionStatus = 'notDetermined' | 'denied' | 'allowed';
2
+ export type PermissionAccess = 'read' | 'write' | 'access';
3
+ export type PermissionName = 'clipboard' | 'contacts' | 'photos' | 'geolocation' | 'camera';
4
+
5
+ // Log
6
+ export type Primitive = string | number | boolean | null | undefined | symbol;
7
+
8
+ /**
9
+ * @public
10
+ * @category 위치 정보
11
+ * @name Accuracy
12
+ * @description 위치 정확도 옵션이에요.
13
+ */
14
+ export enum Accuracy {
15
+ /**
16
+ * 오차범위 3KM 이내
17
+ */
18
+ Lowest = 1,
19
+ /**
20
+ * 오차범위 1KM 이내
21
+ */
22
+ Low,
23
+ /**
24
+ * 오차범위 몇 백미터 이내
25
+ */
26
+ Balanced,
27
+ /**
28
+ * 오차범위 10M 이내
29
+ */
30
+ High,
31
+ /**
32
+ * 가장 높은 정확도
33
+ */
34
+ Highest,
35
+ /**
36
+ * 네비게이션을 위한 최고 정확도
37
+ */
38
+ BestForNavigation,
39
+ }
40
+
41
+ /**
42
+ * @public
43
+ * @category 위치 정보
44
+ * @name Location
45
+ * @description 위치 정보를 나타내는 객체예요.
46
+ */
47
+ export interface Location {
48
+ /**
49
+ * Android에서만 지원하는 옵션이에요.
50
+ *
51
+ * - `FINE`: 정확한 위치
52
+ * - `COARSE`: 대략적인 위치
53
+ *
54
+ * @see https://developer.android.com/codelabs/approximate-location
55
+ */
56
+ accessLocation?: 'FINE' | 'COARSE';
57
+ /**
58
+ * 위치가 업데이트된 시점의 유닉스 타임스탬프예요.
59
+ */
60
+ timestamp: number;
61
+ /**
62
+ * @description 위치 정보를 나타내는 객체예요. 자세한 내용은 [LocationCoords](/react-native/reference/native-modules/Types/LocationCoords.html)을 참고해주세요.
63
+ */
64
+ coords: LocationCoords;
65
+ }
66
+
67
+ /**
68
+ * @public
69
+ * @category 위치 정보
70
+ * @name LocationCoords
71
+ * @description 세부 위치 정보를 나타내는 객체예요.
72
+ */
73
+ export interface LocationCoords {
74
+ /**
75
+ * 위도
76
+ */
77
+ latitude: number;
78
+ /**
79
+ * 경도
80
+ */
81
+ longitude: number;
82
+ /**
83
+ * 높이
84
+ */
85
+ altitude: number;
86
+ /**
87
+ * 위치 정확도
88
+ */
89
+ accuracy: number;
90
+ /**
91
+ * 고도 정확도
92
+ */
93
+ altitudeAccuracy: number;
94
+ /**
95
+ * 방향
96
+ */
97
+ heading: number;
98
+ }
99
+
100
+ /**
101
+ * 사진 조회 결과를 나타내는 타입이에요.
102
+ */
103
+ export interface ImageResponse {
104
+ /** 가져온 사진의 고유 ID예요. */
105
+ id: string;
106
+ /** 사진의 데이터 URI예요. `base64` 옵션이 `true`인 경우 Base64 문자열로 반환돼요. */
107
+ dataUri: string;
108
+ }
@@ -0,0 +1,176 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compareVersions } from './compareVersion.js';
3
+
4
+ describe('compareVersions', () => {
5
+ it('기본 버전 비교가 올바르게 작동해야 합니다', () => {
6
+ expect(compareVersions('1.0.0', '1.0.0')).toBe(0);
7
+ expect(compareVersions('1.0.0', '1.0.1')).toBe(-1);
8
+ expect(compareVersions('1.0.1', '1.0.0')).toBe(1);
9
+ expect(compareVersions('1.1.0', '1.0.0')).toBe(1);
10
+ expect(compareVersions('2.0.0', '1.0.0')).toBe(1);
11
+ });
12
+
13
+ it('다양한 길이의 버전을 비교할 수 있어야 합니다', () => {
14
+ expect(compareVersions('1', '1.0.0')).toBe(0);
15
+ expect(compareVersions('1.0', '1.0.0')).toBe(0);
16
+ expect(compareVersions('1', '2')).toBe(-1);
17
+ expect(compareVersions('1.0', '1.1')).toBe(-1);
18
+ expect(compareVersions('1.1', '1.0.1')).toBe(1);
19
+ expect(compareVersions('11.1.10', '11.0')).toBe(1);
20
+ expect(compareVersions('1.1.1', '1')).toBe(1);
21
+ expect(compareVersions('01.1.0', '1.01')).toBe(0);
22
+ expect(compareVersions('10.0.0', '10.114')).toBe(-1);
23
+ expect(compareVersions('1.0', '1.4.1')).toBe(-1);
24
+ });
25
+
26
+ it('와일드카드 버전을 올바르게 처리해야 합니다', () => {
27
+ expect(compareVersions('1.x', '1.0.0')).toBe(0);
28
+ expect(compareVersions('1.*', '1.1.0')).toBe(0);
29
+ expect(compareVersions('1.0.X', '1.0.1')).toBe(0);
30
+ expect(compareVersions('3', '3.x.x')).toBe(0);
31
+ expect(compareVersions('3.3', '3.x.x')).toBe(0);
32
+ expect(compareVersions('3.3.3', '3.x.x')).toBe(0);
33
+ expect(compareVersions('3.x.x', '3.3.3')).toBe(0);
34
+ expect(compareVersions('3.3.3', '3.X.X')).toBe(0);
35
+ expect(compareVersions('3.3.3', '3.3.x')).toBe(0);
36
+ expect(compareVersions('3.3.3', '3.*.*')).toBe(0);
37
+ expect(compareVersions('3.3.3', '3.3.*')).toBe(0);
38
+ expect(compareVersions('3.0.3', '3.0.*')).toBe(0);
39
+ expect(compareVersions('0.7.x', '0.6.0')).toBe(1);
40
+ expect(compareVersions('0.7.x', '0.6.0-asdf')).toBe(1);
41
+ expect(compareVersions('0.7.x', '0.6.2')).toBe(1);
42
+ expect(compareVersions('0.7.x', '0.7.0-asdf')).toBe(1);
43
+ expect(compareVersions('1.2.*', '1.1.3')).toBe(1);
44
+ expect(compareVersions('1.2.*', '1.1.9999')).toBe(1);
45
+ expect(compareVersions('1.2.x', '1.0.0')).toBe(1);
46
+ expect(compareVersions('1.2.x', '1.1.0')).toBe(1);
47
+ expect(compareVersions('1.2.x', '1.1.3')).toBe(1);
48
+ expect(compareVersions('2.*.*', '1.0.1')).toBe(1);
49
+ expect(compareVersions('2.*.*', '1.1.3')).toBe(1);
50
+ expect(compareVersions('2.x.x', '1.0.0')).toBe(1);
51
+ expect(compareVersions('2.x.x', '1.1.3')).toBe(1);
52
+ });
53
+
54
+ it('프리릴리스 버전을 올바르게 비교해야 합니다', () => {
55
+ expect(compareVersions('1.0.0-alpha', '1.0.0')).toBe(-1);
56
+ expect(compareVersions('1.0.0', '1.0.0-alpha')).toBe(1);
57
+ expect(compareVersions('1.0.0-alpha', '1.0.0-beta')).toBe(-1);
58
+ expect(compareVersions('1.0.0-beta.2', '1.0.0-beta.1')).toBe(1);
59
+ expect(compareVersions('1.0.0-alpha.1', '1.0.0-alpha')).toBe(1);
60
+ expect(compareVersions('1.0.0-alpha', '1.0.0-alpha.1')).toBe(-1);
61
+ expect(compareVersions('1.0.0-alpha.1', '1.0.0-alpha.beta')).toBe(-1);
62
+ expect(compareVersions('1.0.0-alpha.beta', '1.0.0-beta')).toBe(-1);
63
+ expect(compareVersions('1.0.0-beta', '1.0.0-beta.2')).toBe(-1);
64
+ expect(compareVersions('1.0.0-beta.2', '1.0.0-beta.11')).toBe(-1);
65
+ expect(compareVersions('1.0.0-beta.11', '1.0.0-rc.1')).toBe(-1);
66
+ expect(compareVersions('1.0.0-rc.1', '1.0.0')).toBe(-1);
67
+ expect(compareVersions('1.0.0-alpha', '1')).toBe(-1);
68
+ expect(compareVersions('1.0.0-beta.11', '1.0.0-beta.1')).toBe(1);
69
+ expect(compareVersions('1.0.0-beta.10', '1.0.0-beta.9')).toBe(1);
70
+ expect(compareVersions('1.0.0-beta.10', '1.0.0-beta.90')).toBe(-1);
71
+ expect(compareVersions('0.6.1-1', '0.6.1-0')).toBe(1);
72
+ expect(compareVersions('v0.5.4-pre', '0.5.4-alpha')).toBe(1);
73
+ });
74
+
75
+ it('접두사가 있는 버전을 올바르게 처리해야 합니다', () => {
76
+ expect(compareVersions('v1.0.0', '1.0.0')).toBe(0);
77
+ expect(compareVersions('^1.0.0', '1.0.0')).toBe(0);
78
+ expect(compareVersions('~1.0.0', '1.0.0')).toBe(0);
79
+ expect(compareVersions('v1.0.0', 'v1.0.0')).toBe(0);
80
+ expect(compareVersions('v1.0.0-alpha', '1.0.0-alpha')).toBe(0);
81
+ expect(compareVersions('v3.2.1', 'v2.3.2')).toBe(1);
82
+ });
83
+
84
+ it('선행 0을 무시해야 합니다', () => {
85
+ expect(compareVersions('01.0.0', '1')).toBe(0);
86
+ expect(compareVersions('01.0.0', '1.0.0')).toBe(0);
87
+ expect(compareVersions('1.01.0', '1.01.0')).toBe(0);
88
+ expect(compareVersions('1.0.03', '1.0.3')).toBe(0);
89
+ expect(compareVersions('1.0.03-alpha', '1.0.3-alpha')).toBe(0);
90
+ expect(compareVersions('v01.0.0', '1.0.0')).toBe(0);
91
+ expect(compareVersions('v01.0.0', '2.0.0')).toBe(-1);
92
+ });
93
+
94
+ it('빌드 메타데이터를 무시해야 합니다', () => {
95
+ expect(compareVersions('1.4.0-build.3928', '1.4.0-build.3928+sha.a8d9d4f')).toBe(0);
96
+ expect(compareVersions('1.4.0-build.3928+sha.b8dbdb0', '1.4.0-build.3928+sha.a8d9d4f')).toBe(0);
97
+ expect(compareVersions('1.0.0-alpha+001', '1.0.0-alpha')).toBe(0);
98
+ expect(compareVersions('1.0.0-beta+exp.sha.5114f85', '1.0.0-beta+exp.sha.999999')).toBe(0);
99
+ expect(compareVersions('1.0.0+20130313144700', '1.0.0')).toBe(0);
100
+ expect(compareVersions('1.0.0+20130313144700', '2.0.0')).toBe(-1);
101
+ expect(compareVersions('1.0.0+20130313144700', '1.0.1+11234343435')).toBe(-1);
102
+ expect(compareVersions('1.0.1+1', '1.0.1+2')).toBe(0);
103
+ expect(compareVersions('1.0.0+a-a', '1.0.0+a-b')).toBe(0);
104
+ });
105
+
106
+ it('4세그먼트 버전을 올바르게 처리해야 합니다', () => {
107
+ expect(compareVersions('1.0.0.0', '1')).toBe(0);
108
+ expect(compareVersions('1.0.0.0', '1.0')).toBe(0);
109
+ expect(compareVersions('1.0.0.0', '1.0.0')).toBe(0);
110
+ expect(compareVersions('1.0.0.0', '1.0.0.0')).toBe(0);
111
+ expect(compareVersions('1.2.3.4', '1.2.3.4')).toBe(0);
112
+ expect(compareVersions('1.2.3.4', '1.2.3.04')).toBe(0);
113
+ expect(compareVersions('v1.2.3.4', '01.2.3.4')).toBe(0);
114
+ expect(compareVersions('1.2.3.4', '1.2.3.5')).toBe(-1);
115
+ expect(compareVersions('1.2.3.5', '1.2.3.4')).toBe(1);
116
+ expect(compareVersions('1.0.0.0-alpha', '1.0.0-alpha')).toBe(0);
117
+ expect(compareVersions('1.0.0.0-alpha', '1.0.0.0-beta')).toBe(-1);
118
+ });
119
+
120
+ it('단일 세그먼트 버전을 올바르게 비교해야 합니다', () => {
121
+ expect(compareVersions('10', '9')).toBe(1);
122
+ expect(compareVersions('10', '10')).toBe(0);
123
+ expect(compareVersions('9', '10')).toBe(-1);
124
+ });
125
+
126
+ it('두 세그먼트 버전을 올바르게 비교해야 합니다', () => {
127
+ expect(compareVersions('10.8', '10.4')).toBe(1);
128
+ expect(compareVersions('10.1', '10.1')).toBe(0);
129
+ expect(compareVersions('10.1', '10.2')).toBe(-1);
130
+ });
131
+
132
+ it('세 세그먼트 버전을 올바르게 비교해야 합니다', () => {
133
+ expect(compareVersions('10.1.8', '10.0.4')).toBe(1);
134
+ expect(compareVersions('10.0.1', '10.0.1')).toBe(0);
135
+ expect(compareVersions('10.1.1', '10.2.2')).toBe(-1);
136
+ expect(compareVersions('11.0.10', '11.0.2')).toBe(1);
137
+ expect(compareVersions('11.0.2', '11.0.10')).toBe(-1);
138
+ });
139
+
140
+ it('추가 비교 테스트', () => {
141
+ expect(compareVersions('0.1.21', '0.1.5')).toBe(1);
142
+ expect(compareVersions('1', '0.0.0-beta')).toBe(1);
143
+ expect(compareVersions('1', '0.2.3')).toBe(1);
144
+ expect(compareVersions('1', '0.2.4')).toBe(1);
145
+ expect(compareVersions('1', '1.0.0-0')).toBe(1);
146
+ expect(compareVersions('1', '1.0.0-beta')).toBe(1);
147
+ expect(compareVersions('1.0', '0.0.0')).toBe(1);
148
+ expect(compareVersions('1.0', '0.1.0')).toBe(1);
149
+ expect(compareVersions('1.0', '0.1.2')).toBe(1);
150
+ expect(compareVersions('1.0.0', '0.0.0')).toBe(1);
151
+ expect(compareVersions('1.0.0', '0.0.1')).toBe(1);
152
+ expect(compareVersions('1.0.0', '0.2.3')).toBe(1);
153
+ expect(compareVersions('1.2.2', '1.2.1')).toBe(1);
154
+ expect(compareVersions('2', '1.0.0')).toBe(1);
155
+ expect(compareVersions('2', '1.0.0-beta')).toBe(1);
156
+ expect(compareVersions('2', '1.9999.9999')).toBe(1);
157
+ expect(compareVersions('2.0.0', '1.0.0')).toBe(1);
158
+ expect(compareVersions('2.0.0', '1.1.1')).toBe(1);
159
+ expect(compareVersions('2.0.0', '1.2.9')).toBe(1);
160
+ expect(compareVersions('2.0.0', '1.9999.9999')).toBe(1);
161
+ expect(compareVersions('2.3', '2.2.1')).toBe(1);
162
+ expect(compareVersions('2.3', '2.2.2')).toBe(1);
163
+ expect(compareVersions('2.4', '2.3.0')).toBe(1);
164
+ expect(compareVersions('2.4', '2.3.5')).toBe(1);
165
+ expect(compareVersions('3.2.1', '2.3.2')).toBe(1);
166
+ expect(compareVersions('3.2.1', '3.2.0')).toBe(1);
167
+ });
168
+
169
+ it('잘못된 버전 형식에 대해 오류를 발생시켜야 합니다', () => {
170
+ expect(() => compareVersions('invalid', '1.0.0')).toThrow();
171
+ expect(() => compareVersions('1.0.0', 'invalid')).toThrow();
172
+ expect(() => compareVersions('6.3.', '1.0.0')).toThrow();
173
+ expect(() => compareVersions('1.2.3a', '1.0.0')).toThrow();
174
+ expect(() => compareVersions('1.2.-3a', '1.0.0')).toThrow();
175
+ });
176
+ });
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Allowed arithmetic operators
3
+ */
4
+ export type CompareOperator = '>' | '>=' | '=' | '<' | '<=' | '!=';
5
+
6
+ /**
7
+ * RegExp to match semver versions like:
8
+ * - 1.0.0
9
+ * - ^1.2.3-alpha+build
10
+ * - v2.3
11
+ */
12
+ const SEMVER_REGEX =
13
+ /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\\-]+(?:\.[\da-z\\-]+)*))?(?:\+[\da-z\\-]+(?:\.[\da-z\\-]+)*)?)?)?$/i;
14
+
15
+ const isWildcard = (val: string) => ['*', 'x', 'X'].includes(val);
16
+
17
+ const tryParse = (val: string): string | number => {
18
+ const num = parseInt(val, 10);
19
+ return isNaN(num) ? val : num;
20
+ };
21
+
22
+ const coerceTypes = (a: string | number, b: string | number): [string | number, string | number] => {
23
+ return typeof a === typeof b ? [a, b] : [String(a), String(b)];
24
+ };
25
+
26
+ const compareValues = (a: string, b: string): number => {
27
+ if (isWildcard(a) || isWildcard(b)) {
28
+ return 0;
29
+ }
30
+
31
+ const [aVal, bVal] = coerceTypes(tryParse(a), tryParse(b));
32
+ if (aVal > bVal) {
33
+ return 1;
34
+ }
35
+ if (aVal < bVal) {
36
+ return -1;
37
+ }
38
+ return 0;
39
+ };
40
+
41
+ const parseVersion = (version: string): (string | undefined)[] => {
42
+ if (typeof version !== 'string') {
43
+ throw new TypeError('Invalid argument: expected a string');
44
+ }
45
+
46
+ const match = version.match(SEMVER_REGEX);
47
+ if (!match) {
48
+ throw new Error(`Invalid semver: '${version}'`);
49
+ }
50
+
51
+ const [, major, minor, patch, build, preRelease] = match;
52
+ return [major, minor, patch, build, preRelease];
53
+ };
54
+
55
+ const compareSegments = (a: (string | undefined)[], b: (string | undefined)[]): number => {
56
+ const maxLength = Math.max(a.length, b.length);
57
+
58
+ for (let i = 0; i < maxLength; i++) {
59
+ const segA = a[i] ?? '0';
60
+ const segB = b[i] ?? '0';
61
+ const result = compareValues(segA, segB);
62
+ if (result !== 0) {
63
+ return result;
64
+ }
65
+ }
66
+
67
+ return 0;
68
+ };
69
+
70
+ /**
71
+ * Compare [semver](https://semver.org/) version strings.
72
+ * Supports versions like `1`, `1.0`, `1.0.0`, and pre-release like `1.0.0-alpha`.
73
+ *
74
+ * @param v1 - First version
75
+ * @param v2 - Second version
76
+ * @returns 1 if v1 > v2, -1 if v1 < v2, 0 if equal
77
+ */
78
+ export const compareVersions = (v1: string, v2: string): number => {
79
+ const seg1 = parseVersion(v1);
80
+ const seg2 = parseVersion(v2);
81
+
82
+ const preRelease1 = seg1.pop();
83
+ const preRelease2 = seg2.pop();
84
+
85
+ const mainCompare = compareSegments(seg1, seg2);
86
+ if (mainCompare !== 0) {
87
+ return mainCompare;
88
+ }
89
+
90
+ // If both have pre-release
91
+ if (preRelease1 && preRelease2) {
92
+ return compareSegments(preRelease1.split('.'), preRelease2.split('.'));
93
+ }
94
+
95
+ // If only one has pre-release, it's considered lower precedence
96
+ if (preRelease1) {
97
+ return -1;
98
+ }
99
+ if (preRelease2) {
100
+ return 1;
101
+ }
102
+
103
+ return 0;
104
+ };
@@ -0,0 +1,5 @@
1
+ export function generateUUID(placeholder?: any): string {
2
+ return placeholder
3
+ ? (placeholder ^ ((Math.random() * 16) >> (placeholder / 4))).toString(16)
4
+ : (String(1e7) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, generateUUID);
5
+ }