@adstage/react-native-sdk 1.0.0

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +327 -0
  3. package/adstage-react-native.podspec +24 -0
  4. package/android/build.gradle +66 -0
  5. package/android/src/main/AndroidManifest.xml +4 -0
  6. package/android/src/main/java/io/nbase/adstage/reactnative/AdStageModule.kt +701 -0
  7. package/android/src/main/java/io/nbase/adstage/reactnative/AdStagePackage.kt +24 -0
  8. package/ios/AdStageModule.m +70 -0
  9. package/ios/AdStageModule.swift +457 -0
  10. package/lib/commonjs/AdStage.js +213 -0
  11. package/lib/commonjs/AdStage.js.map +1 -0
  12. package/lib/commonjs/deeplink/AdStageDeepLink.js +235 -0
  13. package/lib/commonjs/deeplink/AdStageDeepLink.js.map +1 -0
  14. package/lib/commonjs/event/AdStageEvent.js +689 -0
  15. package/lib/commonjs/event/AdStageEvent.js.map +1 -0
  16. package/lib/commonjs/index.js +34 -0
  17. package/lib/commonjs/index.js.map +1 -0
  18. package/lib/commonjs/promotion/AdStagePromotion.js +158 -0
  19. package/lib/commonjs/promotion/AdStagePromotion.js.map +1 -0
  20. package/lib/commonjs/types.js +2 -0
  21. package/lib/commonjs/types.js.map +1 -0
  22. package/lib/module/AdStage.js +206 -0
  23. package/lib/module/AdStage.js.map +1 -0
  24. package/lib/module/deeplink/AdStageDeepLink.js +228 -0
  25. package/lib/module/deeplink/AdStageDeepLink.js.map +1 -0
  26. package/lib/module/event/AdStageEvent.js +682 -0
  27. package/lib/module/event/AdStageEvent.js.map +1 -0
  28. package/lib/module/index.js +15 -0
  29. package/lib/module/index.js.map +1 -0
  30. package/lib/module/promotion/AdStagePromotion.js +151 -0
  31. package/lib/module/promotion/AdStagePromotion.js.map +1 -0
  32. package/lib/module/types.js +2 -0
  33. package/lib/module/types.js.map +1 -0
  34. package/lib/typescript/src/AdStage.d.ts +124 -0
  35. package/lib/typescript/src/AdStage.d.ts.map +1 -0
  36. package/lib/typescript/src/deeplink/AdStageDeepLink.d.ts +154 -0
  37. package/lib/typescript/src/deeplink/AdStageDeepLink.d.ts.map +1 -0
  38. package/lib/typescript/src/event/AdStageEvent.d.ts +426 -0
  39. package/lib/typescript/src/event/AdStageEvent.d.ts.map +1 -0
  40. package/lib/typescript/src/index.d.ts +13 -0
  41. package/lib/typescript/src/index.d.ts.map +1 -0
  42. package/lib/typescript/src/promotion/AdStagePromotion.d.ts +98 -0
  43. package/lib/typescript/src/promotion/AdStagePromotion.d.ts.map +1 -0
  44. package/lib/typescript/src/types.d.ts +305 -0
  45. package/lib/typescript/src/types.d.ts.map +1 -0
  46. package/package.json +105 -0
  47. package/src/AdStage.ts +212 -0
  48. package/src/deeplink/AdStageDeepLink.ts +246 -0
  49. package/src/event/AdStageEvent.ts +844 -0
  50. package/src/index.ts +48 -0
  51. package/src/promotion/AdStagePromotion.ts +162 -0
  52. package/src/types.ts +392 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * AdStage DeepLink 모듈
3
+ *
4
+ * 딥링크 생성, 수신, 처리를 담당합니다.
5
+ * Android DeeplinkHandler, iOS DeepLinkManager와 동일한 API를 제공합니다.
6
+ *
7
+ * @since 3.0.0
8
+ */
9
+
10
+ import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
11
+ import type {
12
+ DeepLinkData,
13
+ DeepLinkListener,
14
+ CreateDeepLinkRequest,
15
+ CreateDeepLinkResponse,
16
+ } from '../types';
17
+
18
+ const { AdStageModule } = NativeModules;
19
+ const eventEmitter = AdStageModule
20
+ ? new NativeEventEmitter(AdStageModule)
21
+ : null;
22
+
23
+ /**
24
+ * AdStage DeepLink 클래스
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // 딥링크 리스너 설정
29
+ * const unsubscribe = AdStage.deepLink.setListener((data) => {
30
+ * console.log('딥링크 수신:', data.shortPath);
31
+ * console.log('파라미터:', data.parameters);
32
+ * });
33
+ *
34
+ * // 딥링크 생성
35
+ * const result = await AdStage.deepLink.create({
36
+ * name: '여름 프로모션',
37
+ * channel: 'google-ads',
38
+ * campaign: 'summer_2024'
39
+ * });
40
+ * console.log('Short URL:', result.shortUrl);
41
+ *
42
+ * // 리스너 해제
43
+ * unsubscribe();
44
+ * ```
45
+ */
46
+ export class AdStageDeepLink {
47
+ private static subscription: ReturnType<
48
+ NativeEventEmitter['addListener']
49
+ > | null = null;
50
+
51
+ // ============================================
52
+ // Listener Management
53
+ // ============================================
54
+
55
+ /**
56
+ * 딥링크 리스너 설정
57
+ *
58
+ * 딥링크가 수신되면 콜백이 호출됩니다.
59
+ * 반환된 함수를 호출하면 리스너가 해제됩니다.
60
+ *
61
+ * @param listener - 딥링크 수신 콜백
62
+ * @returns 리스너 해제 함수
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const unsubscribe = AdStage.deepLink.setListener((data) => {
67
+ * // URL Scheme: myapp://adstage.net/ABCDEF
68
+ * // Universal Link: https://adstage.net/ABCDEF
69
+ * console.log('Short Path:', data.shortPath); // "ABCDEF"
70
+ * console.log('Link ID:', data.linkId);
71
+ * console.log('Parameters:', data.parameters);
72
+ * console.log('Source:', data.source); // "realtime" | "install"
73
+ * console.log('Event Type:', data.eventType); // "OPEN" | "INSTALL"
74
+ * });
75
+ *
76
+ * // 컴포넌트 unmount 시
77
+ * unsubscribe();
78
+ * ```
79
+ */
80
+ static setListener(listener: DeepLinkListener): () => void {
81
+ if (!eventEmitter) {
82
+ console.warn('AdStage: Native event emitter is not available');
83
+ return () => {};
84
+ }
85
+
86
+ // 기존 리스너 제거
87
+ this.removeListener();
88
+
89
+ this.subscription = eventEmitter.addListener(
90
+ 'onDeepLinkReceived',
91
+ (event: DeepLinkData) => {
92
+ listener(event);
93
+ }
94
+ );
95
+
96
+ // 네이티브에 리스너 설정 알림
97
+ AdStageModule?.setDeepLinkListener?.();
98
+
99
+ return () => this.removeListener();
100
+ }
101
+
102
+ /**
103
+ * 딥링크 리스너 제거
104
+ */
105
+ static removeListener(): void {
106
+ if (this.subscription) {
107
+ this.subscription.remove();
108
+ this.subscription = null;
109
+ }
110
+ AdStageModule?.removeDeepLinkListener?.();
111
+ }
112
+
113
+ // ============================================
114
+ // DeepLink Creation
115
+ // ============================================
116
+
117
+ /**
118
+ * 딥링크 생성
119
+ *
120
+ * @param request - 딥링크 생성 요청
121
+ * @returns 생성된 딥링크 정보
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * const result = await AdStage.deepLink.create({
126
+ * name: '여름 프로모션 링크',
127
+ * description: '2024년 여름 시즌용',
128
+ * channel: 'google-ads',
129
+ * campaign: 'summer_promotion_2024',
130
+ * redirectConfig: {
131
+ * type: 'STORE',
132
+ * android: {
133
+ * packageName: 'com.example.app',
134
+ * appScheme: 'myapp://promo'
135
+ * },
136
+ * ios: {
137
+ * appStoreId: '123456789',
138
+ * appScheme: 'myapp://promo'
139
+ * }
140
+ * },
141
+ * parameters: {
142
+ * productId: 'SUMMER_2024',
143
+ * discount: '20'
144
+ * }
145
+ * });
146
+ *
147
+ * console.log('Short URL:', result.shortUrl); // https://adstage.net/ABCDEF
148
+ * console.log('Short Path:', result.shortPath); // ABCDEF
149
+ * ```
150
+ */
151
+ static async create(
152
+ request: CreateDeepLinkRequest
153
+ ): Promise<CreateDeepLinkResponse> {
154
+ if (!AdStageModule) {
155
+ throw new Error('AdStage: Native module is not available');
156
+ }
157
+
158
+ if (!request.name) {
159
+ throw new Error('AdStage: name is required for creating a deep link');
160
+ }
161
+
162
+ const result = await AdStageModule.createDeepLink(request);
163
+
164
+ return {
165
+ shortUrl: result.shortUrl,
166
+ shortPath: result.shortPath,
167
+ linkId: result.linkId,
168
+ };
169
+ }
170
+
171
+ // ============================================
172
+ // DeepLink Handling
173
+ // ============================================
174
+
175
+ /**
176
+ * Pending 딥링크 확인 및 처리
177
+ *
178
+ * 앱이 종료된 상태에서 딥링크로 실행된 경우,
179
+ * SDK 초기화 후 이 메서드를 호출하여 pending 딥링크를 처리합니다.
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * // SDK 초기화 후
184
+ * await AdStage.initialize({ apiKey: '...' });
185
+ *
186
+ * // 리스너 설정
187
+ * AdStage.deepLink.setListener((data) => {
188
+ * console.log('딥링크:', data);
189
+ * });
190
+ *
191
+ * // Pending 딥링크 확인
192
+ * AdStage.deepLink.checkPendingDeepLink();
193
+ * ```
194
+ */
195
+ static checkPendingDeepLink(): void {
196
+ AdStageModule?.checkPendingDeepLink?.();
197
+ }
198
+
199
+ /**
200
+ * Intent 처리 (Android 전용)
201
+ *
202
+ * MainActivity에서 새로운 Intent가 들어올 때 호출합니다.
203
+ * iOS에서는 호출해도 무시됩니다.
204
+ *
205
+ * @example
206
+ * ```typescript
207
+ * // React Native에서 AppState 변경 감지
208
+ * import { Linking } from 'react-native';
209
+ *
210
+ * Linking.addEventListener('url', ({ url }) => {
211
+ * // Android에서는 네이티브에서 자동 처리되므로 필요 없음
212
+ * // 필요한 경우 수동 호출
213
+ * AdStage.deepLink.handleIntent();
214
+ * });
215
+ * ```
216
+ */
217
+ static handleIntent(): void {
218
+ if (Platform.OS === 'android') {
219
+ AdStageModule?.handleIntent?.();
220
+ }
221
+ }
222
+
223
+ /**
224
+ * URL에서 Short Path 추출
225
+ *
226
+ * @param url - 딥링크 URL
227
+ * @returns Short Path 또는 null
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * const shortPath = AdStage.deepLink.extractShortPath('https://adstage.net/ABCDEF');
232
+ * console.log(shortPath); // "ABCDEF"
233
+ * ```
234
+ */
235
+ static extractShortPath(url: string): string | null {
236
+ try {
237
+ const urlObj = new URL(url);
238
+ const pathParts = urlObj.pathname.split('/').filter(Boolean);
239
+ return pathParts[0] ?? null;
240
+ } catch {
241
+ // URL Scheme인 경우
242
+ const match = url.match(/adstage\.(?:net|app)\/([A-Za-z0-9]+)/);
243
+ return match?.[1] ?? null;
244
+ }
245
+ }
246
+ }