tudada-sdk-types 0.0.1-2
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 +150 -0
- package/global.d.ts +28 -0
- package/index.d.ts +1175 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# tudada-sdk-types
|
|
2
|
+
|
|
3
|
+
TypeScript type definitions for TudadaSDK - H5 web game SDK for Tudada platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install tudada-sdk-types
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Global Types (Recommended)
|
|
14
|
+
|
|
15
|
+
After installing `tudada-sdk-types`, global types are **automatically available** without any import:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// No import needed! Types are automatically recognized
|
|
19
|
+
TudadaSDK.login({
|
|
20
|
+
success: (res) => console.log('Login code:', res.code),
|
|
21
|
+
fail: (err) => console.error('Login failed:', err.errMsg),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const systemInfo = TudadaSDK.getSystemInfoSync();
|
|
25
|
+
console.log('Platform:', systemInfo.platform);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This works because the package includes `global.d.ts` which declares the global `TudadaSDK` and `tudadaSDK` variables.
|
|
29
|
+
|
|
30
|
+
### Import Types
|
|
31
|
+
|
|
32
|
+
You can also import types directly:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import type {
|
|
36
|
+
LoginOption,
|
|
37
|
+
LoginSuccessResult,
|
|
38
|
+
SystemInfo,
|
|
39
|
+
UserInfo,
|
|
40
|
+
RewardedVideoAd,
|
|
41
|
+
} from 'tudada-sdk-types';
|
|
42
|
+
|
|
43
|
+
// Use types in your code
|
|
44
|
+
const handleLogin = (options: LoginOption) => {
|
|
45
|
+
TudadaSDK.login(options);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const systemInfo: SystemInfo = TudadaSDK.getSystemInfoSync();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Available Types
|
|
52
|
+
|
|
53
|
+
### Auth API
|
|
54
|
+
- `LoginOption`, `LoginSuccessResult`
|
|
55
|
+
- `CheckSessionOption`
|
|
56
|
+
- `GetUserInfoOption`, `GetUserInfoSuccessResult`, `UserInfo`
|
|
57
|
+
|
|
58
|
+
### Storage API
|
|
59
|
+
- `SetStorageOption`, `GetStorageOption`, `GetStorageSuccessResult`
|
|
60
|
+
- `RemoveStorageOption`, `ClearStorageOption`
|
|
61
|
+
- `StorageInfo`
|
|
62
|
+
- `TudadaStore`, `TudadaStoreGetOption`, `TudadaStoreSaveOption`
|
|
63
|
+
|
|
64
|
+
### System API
|
|
65
|
+
- `SystemInfo`, `GetSystemInfoOption`
|
|
66
|
+
- `WindowInfo`, `GetWindowInfoOption`
|
|
67
|
+
- `AppBaseInfo`, `GetAppBaseInfoOption`
|
|
68
|
+
- `DeviceInfo`, `GetDeviceInfoOption`
|
|
69
|
+
- `Platform`, `SafeArea`
|
|
70
|
+
|
|
71
|
+
### UI API
|
|
72
|
+
- `MenuButtonBoundingClientRect`
|
|
73
|
+
|
|
74
|
+
### Device API
|
|
75
|
+
- `VibrateShortOption`, `VibrateLongOption`, `VibrateType`
|
|
76
|
+
- `ShowKeyboardOption`, `HideKeyboardOption`
|
|
77
|
+
- `OnKeyboardInputCallback`, `OnKeyboardConfirmCallback`, `OnKeyboardCompleteCallback`
|
|
78
|
+
|
|
79
|
+
### Clipboard API
|
|
80
|
+
- `SetClipboardDataOption`
|
|
81
|
+
- `GetClipboardDataOption`, `GetClipboardDataSuccessResult`
|
|
82
|
+
|
|
83
|
+
### Ad API
|
|
84
|
+
- `CreateRewardedVideoAdOption`
|
|
85
|
+
- `RewardedVideoAd`
|
|
86
|
+
|
|
87
|
+
### Lifecycle API
|
|
88
|
+
- `OnShowCallback`, `OnShowCallbackResult`
|
|
89
|
+
- `OnHideCallback`, `OnHideCallbackResult`
|
|
90
|
+
- `ExitMiniProgramOption`, `RestartMiniProgramOption`
|
|
91
|
+
|
|
92
|
+
### SDK Interface
|
|
93
|
+
- `ITudadaSDK` - Main SDK interface
|
|
94
|
+
|
|
95
|
+
### Common Types
|
|
96
|
+
- `GeneralCallbackResult`
|
|
97
|
+
- `Mock<T>`
|
|
98
|
+
|
|
99
|
+
## Global Variables
|
|
100
|
+
|
|
101
|
+
When TudadaSDK is loaded via script tag, the following global variables are available:
|
|
102
|
+
|
|
103
|
+
- `TudadaSDK` / `tudadaSDK` - Main SDK instance
|
|
104
|
+
- `window.TudadaSDK` / `window.tudadaSDK`
|
|
105
|
+
|
|
106
|
+
## Example
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import type { SystemInfo, UserInfo, RewardedVideoAd } from 'tudada-sdk-types';
|
|
110
|
+
|
|
111
|
+
// Get system info
|
|
112
|
+
const systemInfo: SystemInfo = TudadaSDK.getSystemInfoSync();
|
|
113
|
+
console.log('Platform:', systemInfo.platform);
|
|
114
|
+
console.log('Screen size:', systemInfo.screenWidth, 'x', systemInfo.screenHeight);
|
|
115
|
+
|
|
116
|
+
// Login
|
|
117
|
+
TudadaSDK.login({
|
|
118
|
+
success: (res) => {
|
|
119
|
+
console.log('Login code:', res.code);
|
|
120
|
+
|
|
121
|
+
// Get user info
|
|
122
|
+
TudadaSDK.getUserInfo({
|
|
123
|
+
success: (userRes) => {
|
|
124
|
+
const user: UserInfo = userRes.userInfo;
|
|
125
|
+
console.log('Nickname:', user.nickName);
|
|
126
|
+
console.log('Avatar:', user.avatarUrl);
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Create rewarded video ad
|
|
133
|
+
const ad: RewardedVideoAd = TudadaSDK.createRewardedVideoAd({
|
|
134
|
+
adUnitId: 'your-ad-unit-id',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
ad.onLoad(() => console.log('Ad loaded'));
|
|
138
|
+
ad.onError((err) => console.error('Ad error:', err.errMsg));
|
|
139
|
+
ad.onClose((res) => {
|
|
140
|
+
if (res.isEnded) {
|
|
141
|
+
console.log('Ad completed - give reward!');
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
ad.load().then(() => ad.show());
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
package/global.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TudadaSDK 글로벌 타입 선언
|
|
3
|
+
*
|
|
4
|
+
* 이 파일은 import 없이도 TudadaSDK 글로벌 변수의 타입을 자동으로 인식하게 합니다.
|
|
5
|
+
* npm install tudada-sdk-types 후 별도 설정 없이 바로 사용 가능합니다.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // import 없이 바로 사용 가능
|
|
10
|
+
* TudadaSDK.login({
|
|
11
|
+
* success: (res) => console.log('Login code:', res.code),
|
|
12
|
+
* fail: (err) => console.error('Login failed:', err.errMsg),
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* const systemInfo = TudadaSDK.getSystemInfoSync();
|
|
16
|
+
* console.log('Platform:', systemInfo.platform);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/// <reference path="./index.d.ts" />
|
|
21
|
+
|
|
22
|
+
declare const TudadaSDK: import('./index').ITudadaSDK;
|
|
23
|
+
declare const tudadaSDK: import('./index').ITudadaSDK;
|
|
24
|
+
|
|
25
|
+
interface Window {
|
|
26
|
+
TudadaSDK: import('./index').ITudadaSDK;
|
|
27
|
+
tudadaSDK: import('./index').ITudadaSDK;
|
|
28
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,1175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TudadaSDK - H5 웹 게임을 위한 투다다 서비스 연동 SDK
|
|
3
|
+
*
|
|
4
|
+
* @description
|
|
5
|
+
* H5/웹 브라우저 환경에서 게임과 투다다(Tudada) 서비스를 연결하기 위한 SDK입니다.
|
|
6
|
+
* WeChat Mini Game(wx) API와 호환되는 인터페이스를 제공합니다.
|
|
7
|
+
*
|
|
8
|
+
* ## 지원 API
|
|
9
|
+
*
|
|
10
|
+
* - **Storage**: 로컬 스토리지 (setStorage, getStorage, removeStorage, clearStorage)
|
|
11
|
+
* - **System**: 시스템/디바이스 정보 (getSystemInfo, getWindowInfo, getDeviceInfo)
|
|
12
|
+
* - **Auth**: 로그인/세션 (login, checkSession)
|
|
13
|
+
* - **UI**: UI 정보 (getMenuButtonBoundingClientRect)
|
|
14
|
+
* - **Device**: 디바이스 제어 (vibrateShort, vibrateLong, showKeyboard, hideKeyboard, onKeyboardInput, offKeyboardInput, onKeyboardConfirm, offKeyboardConfirm, onKeyboardComplete, offKeyboardComplete)
|
|
15
|
+
* - **Clipboard**: 클립보드 (setClipboardData, getClipboardData)
|
|
16
|
+
* - **Ad**: 광고 (createRewardedVideoAd)
|
|
17
|
+
* - **Lifecycle**: 앱 라이프사이클 (onShow, onHide, exitMiniProgram, restartMiniProgram)
|
|
18
|
+
*
|
|
19
|
+
* ## 설치
|
|
20
|
+
*
|
|
21
|
+
* tudada-game-sdk는 CDN을 통해 배포됩니다. HTML 파일에 스크립트 태그로 불러오세요.
|
|
22
|
+
*
|
|
23
|
+
* ```html
|
|
24
|
+
* <!-- CDN으로 SDK 로드 -->
|
|
25
|
+
* <script src="https://your-cdn-url.com/tudadaGameSDK.js"></script>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* ## 사용법
|
|
29
|
+
*
|
|
30
|
+
* **⚠️ 중요**: SDK는 스크립트 로드 시 자동으로 초기화됩니다.
|
|
31
|
+
* 게임 코드는 반드시 `TudadaGameSDK.waitForReady()` 완료를 기다린 후에 실행되어야 합니다.
|
|
32
|
+
*
|
|
33
|
+
* ### 기본 사용법 (SDK 초기화 대기 후 게임 로드)
|
|
34
|
+
*
|
|
35
|
+
* ```html
|
|
36
|
+
* <!DOCTYPE html>
|
|
37
|
+
* <html>
|
|
38
|
+
* <body>
|
|
39
|
+
* <!-- 1. SDK 먼저 로드 (자동으로 초기화됨) -->
|
|
40
|
+
* <script src="https://your-cdn-url.com/tudadaGameSDK.js"></script>
|
|
41
|
+
*
|
|
42
|
+
* <!-- 2. SDK 초기화 대기 후 게임 로드 -->
|
|
43
|
+
* <script>
|
|
44
|
+
* TudadaGameSDK.waitForReady()
|
|
45
|
+
* .then(() => {
|
|
46
|
+
* console.log('SDK 초기화 완료');
|
|
47
|
+
*
|
|
48
|
+
* // 초기화 완료 후 게임 스크립트 동적 로드
|
|
49
|
+
* const gameScript = document.createElement('script');
|
|
50
|
+
* gameScript.src = './game.js';
|
|
51
|
+
* document.body.appendChild(gameScript);
|
|
52
|
+
* })
|
|
53
|
+
* .catch((error) => {
|
|
54
|
+
* console.error('SDK 초기화 실패:', error);
|
|
55
|
+
* });
|
|
56
|
+
* </script>
|
|
57
|
+
* </body>
|
|
58
|
+
* </html>
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* ### API 사용 예시 (game.js 내부)
|
|
62
|
+
*
|
|
63
|
+
* ```javascript
|
|
64
|
+
* // SDK 초기화 완료 후 실행되는 게임 코드
|
|
65
|
+
*
|
|
66
|
+
* // Storage API
|
|
67
|
+
* TudadaSDK.setStorageSync('score', 100);
|
|
68
|
+
* const score = TudadaSDK.getStorageSync('score');
|
|
69
|
+
*
|
|
70
|
+
* // System API
|
|
71
|
+
* const systemInfo = TudadaSDK.getSystemInfoSync();
|
|
72
|
+
* console.log('플랫폼:', systemInfo.platform);
|
|
73
|
+
*
|
|
74
|
+
* // Ad API
|
|
75
|
+
* const ad = TudadaSDK.createRewardedVideoAd({ adUnitId: 'your-ad-unit-id' });
|
|
76
|
+
* ad.onClose((res) => {
|
|
77
|
+
* if (res.isEnded) console.log('보상 지급!');
|
|
78
|
+
* });
|
|
79
|
+
* ad.load().then(() => ad.show());
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* ### Unity WebGL 게임 예시
|
|
83
|
+
*
|
|
84
|
+
* ```html
|
|
85
|
+
* <body>
|
|
86
|
+
* <canvas id="unity-canvas"></canvas>
|
|
87
|
+
* <script src="https://your-cdn-url.com/tudadaGameSDK.js"></script>
|
|
88
|
+
*
|
|
89
|
+
* <script>
|
|
90
|
+
* TudadaGameSDK.waitForReady()
|
|
91
|
+
* .then(() => {
|
|
92
|
+
* console.log('✅ SDK 초기화 완료');
|
|
93
|
+
*
|
|
94
|
+
* // Unity 로더 동적 로드
|
|
95
|
+
* const unityLoader = document.createElement('script');
|
|
96
|
+
* unityLoader.src = './Build/UnityLoader.js';
|
|
97
|
+
* unityLoader.onload = () => {
|
|
98
|
+
* createUnityInstance(document.querySelector("#unity-canvas"), {
|
|
99
|
+
* dataUrl: "./Build/webgl.data",
|
|
100
|
+
* frameworkUrl: "./Build/webgl.framework.js",
|
|
101
|
+
* codeUrl: "./Build/webgl.wasm",
|
|
102
|
+
* })
|
|
103
|
+
* .then((unityInstance) => {
|
|
104
|
+
* console.log('✅ Unity 게임 로드 완료');
|
|
105
|
+
*
|
|
106
|
+
* // Unity 인스턴스를 SDK에 연결
|
|
107
|
+
* TudadaGameSDK.connectUnity(unityInstance);
|
|
108
|
+
* console.log('✅ Unity 인스턴스 연결 완료');
|
|
109
|
+
* });
|
|
110
|
+
* };
|
|
111
|
+
* document.body.appendChild(unityLoader);
|
|
112
|
+
* })
|
|
113
|
+
* .catch((error) => {
|
|
114
|
+
* console.error('❌ SDK 초기화 실패:', error);
|
|
115
|
+
* });
|
|
116
|
+
* </script>
|
|
117
|
+
* </body>
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @packageDocumentation
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
// ============================================
|
|
124
|
+
// 공통 타입
|
|
125
|
+
// ============================================
|
|
126
|
+
|
|
127
|
+
/** API 호환을 위해 남겨둔 필드 (고정값 반환) */
|
|
128
|
+
export type Mock<T> = T;
|
|
129
|
+
|
|
130
|
+
/** 일반 콜백 결과 */
|
|
131
|
+
export interface GeneralCallbackResult {
|
|
132
|
+
/** 에러 메시지 */
|
|
133
|
+
errMsg: string;
|
|
134
|
+
/** 에러 코드 */
|
|
135
|
+
errCode?: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ============================================
|
|
139
|
+
// Storage API 타입
|
|
140
|
+
// ============================================
|
|
141
|
+
|
|
142
|
+
/** 스토리지 설정 옵션 */
|
|
143
|
+
export interface SetStorageOption {
|
|
144
|
+
/** 스토리지 키 */
|
|
145
|
+
key: string;
|
|
146
|
+
/**
|
|
147
|
+
* 저장할 데이터
|
|
148
|
+
*
|
|
149
|
+
* JSON으로 직렬화 가능한 데이터만 지원됩니다.
|
|
150
|
+
* `Blob`, `File`, `Map`, `Set` 등 JSON.stringify()로 직렬화할 수 없는 타입은
|
|
151
|
+
* 데이터가 손실되거나 에러가 발생할 수 있습니다.
|
|
152
|
+
*/
|
|
153
|
+
data: any;
|
|
154
|
+
/** 암호화 사용 여부 (미지원) */
|
|
155
|
+
encrypt?: boolean;
|
|
156
|
+
/** 성공 콜백 */
|
|
157
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
158
|
+
/** 실패 콜백 */
|
|
159
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
160
|
+
/** 완료 콜백 */
|
|
161
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** 스토리지 조회 결과 */
|
|
165
|
+
export interface GetStorageSuccessResult {
|
|
166
|
+
/** 에러 메시지 */
|
|
167
|
+
errMsg: string;
|
|
168
|
+
/** 에러 코드 */
|
|
169
|
+
errCode?: number;
|
|
170
|
+
/** 조회된 데이터 */
|
|
171
|
+
data: any;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** 스토리지 조회 옵션 */
|
|
175
|
+
export interface GetStorageOption {
|
|
176
|
+
/** 스토리지 키 */
|
|
177
|
+
key: string;
|
|
178
|
+
/** 암호화 사용 여부 (미지원) */
|
|
179
|
+
encrypt?: boolean;
|
|
180
|
+
/** 성공 콜백 */
|
|
181
|
+
success?: (res: GetStorageSuccessResult) => void;
|
|
182
|
+
/** 실패 콜백 */
|
|
183
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
184
|
+
/** 완료 콜백 */
|
|
185
|
+
complete?: (res: GetStorageSuccessResult | GeneralCallbackResult) => void;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** 스토리지 삭제 옵션 */
|
|
189
|
+
export interface RemoveStorageOption {
|
|
190
|
+
/** 스토리지 키 */
|
|
191
|
+
key: string;
|
|
192
|
+
/** 성공 콜백 */
|
|
193
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
194
|
+
/** 실패 콜백 */
|
|
195
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
196
|
+
/** 완료 콜백 */
|
|
197
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** 스토리지 전체 삭제 옵션 */
|
|
201
|
+
export interface ClearStorageOption {
|
|
202
|
+
/** 성공 콜백 */
|
|
203
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
204
|
+
/** 실패 콜백 */
|
|
205
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
206
|
+
/** 완료 콜백 */
|
|
207
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 스토리지 정보
|
|
212
|
+
*
|
|
213
|
+
* getStorageInfoSync() 함수의 반환 타입입니다.
|
|
214
|
+
*/
|
|
215
|
+
export interface StorageInfo {
|
|
216
|
+
/** 저장된 모든 키 목록 (접두사 제외) */
|
|
217
|
+
keys: string[];
|
|
218
|
+
/** 현재 사용 용량 (KB 단위) */
|
|
219
|
+
currentSize: number;
|
|
220
|
+
/** 최대 용량 (KB 단위, 10240KB = 10MB) */
|
|
221
|
+
limitSize: number;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ============================================
|
|
225
|
+
// TudadaStore API 타입
|
|
226
|
+
// ============================================
|
|
227
|
+
|
|
228
|
+
/** TudadaStore get 성공 결과 */
|
|
229
|
+
export interface TudadaStoreGetSuccessResult {
|
|
230
|
+
/** 에러 메시지 */
|
|
231
|
+
errMsg: string;
|
|
232
|
+
/** 조회된 값 (없으면 null) */
|
|
233
|
+
value: string | null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** TudadaStore get 옵션 */
|
|
237
|
+
export interface TudadaStoreGetOption {
|
|
238
|
+
/** 조회할 키 */
|
|
239
|
+
key: string;
|
|
240
|
+
/** 성공 콜백 */
|
|
241
|
+
success?: (res: TudadaStoreGetSuccessResult) => void;
|
|
242
|
+
/** 실패 콜백 */
|
|
243
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
244
|
+
/** 완료 콜백 */
|
|
245
|
+
complete?: (res: TudadaStoreGetSuccessResult | GeneralCallbackResult) => void;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* TudadaStore save 옵션
|
|
250
|
+
*
|
|
251
|
+
* ## 용량 제한
|
|
252
|
+
* - value 최대 크기: **2KB**
|
|
253
|
+
* - 2KB를 초과하면 fail 콜백이 호출됩니다.
|
|
254
|
+
* - 에러 메시지: `tudadaStore.save:fail value exceeds maximum size limit (2KB)`
|
|
255
|
+
*/
|
|
256
|
+
export interface TudadaStoreSaveOption {
|
|
257
|
+
/** 저장할 키 */
|
|
258
|
+
key: string;
|
|
259
|
+
/**
|
|
260
|
+
* 저장할 값
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* 최대 2KB까지 저장 가능합니다.
|
|
264
|
+
* 용량을 초과하면 fail 콜백이 호출됩니다.
|
|
265
|
+
*/
|
|
266
|
+
value: string;
|
|
267
|
+
/** 성공 콜백 */
|
|
268
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
269
|
+
/** 실패 콜백 */
|
|
270
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
271
|
+
/** 완료 콜백 */
|
|
272
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** TudadaStore 인터페이스 */
|
|
276
|
+
export interface TudadaStore {
|
|
277
|
+
/**
|
|
278
|
+
* 키로 값 조회
|
|
279
|
+
*
|
|
280
|
+
* @param options - 조회 옵션
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* const store = getTudadaStore();
|
|
285
|
+
* store.get({
|
|
286
|
+
* key: 'userScore',
|
|
287
|
+
* success: (res) => {
|
|
288
|
+
* console.log('Value:', res.value); // null 또는 string
|
|
289
|
+
* },
|
|
290
|
+
* fail: (err) => console.error('Failed:', err.errMsg),
|
|
291
|
+
* });
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
get(options: TudadaStoreGetOption): void;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* 키와 값 저장
|
|
298
|
+
*
|
|
299
|
+
* ## 용량 제한
|
|
300
|
+
* value는 최대 **2KB**까지 저장 가능합니다.
|
|
301
|
+
* 초과 시 fail 콜백이 호출됩니다.
|
|
302
|
+
*
|
|
303
|
+
* @param options - 저장 옵션
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* const store = getTudadaStore();
|
|
308
|
+
* store.save({
|
|
309
|
+
* key: 'userScore',
|
|
310
|
+
* value: '1000',
|
|
311
|
+
* success: () => console.log('Saved successfully'),
|
|
312
|
+
* fail: (err) => console.error('Failed:', err.errMsg),
|
|
313
|
+
* });
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
save(options: TudadaStoreSaveOption): void;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ============================================
|
|
320
|
+
// Device API 타입
|
|
321
|
+
// ============================================
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* 진동 강도 타입
|
|
325
|
+
*
|
|
326
|
+
* @remarks
|
|
327
|
+
* 현재는 플랫폼에서 지원하지 않지만, 향후 확장을 위해 파라미터로 받을 수 있습니다.
|
|
328
|
+
* - `heavy`: 강한 진동
|
|
329
|
+
* - `medium`: 중간 진동 (기본값)
|
|
330
|
+
* - `light`: 약한 진동
|
|
331
|
+
*
|
|
332
|
+
* @defaultValue 'medium'
|
|
333
|
+
*/
|
|
334
|
+
export type VibrateType = 'heavy' | 'medium' | 'light';
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* vibrateShort 옵션
|
|
338
|
+
*
|
|
339
|
+
* 짧은 진동(15ms)을 실행하기 위한 옵션입니다.
|
|
340
|
+
*/
|
|
341
|
+
export interface VibrateShortOption {
|
|
342
|
+
/**
|
|
343
|
+
* 진동 강도 타입
|
|
344
|
+
*
|
|
345
|
+
* @remarks
|
|
346
|
+
* 현재는 플랫폼에서 지원하지 않지만, 파라미터로 받을 수 있습니다.
|
|
347
|
+
* 향후 플랫폼 업데이트 시 지원될 예정입니다.
|
|
348
|
+
*
|
|
349
|
+
* @defaultValue 'medium'
|
|
350
|
+
*/
|
|
351
|
+
type?: VibrateType;
|
|
352
|
+
/** 성공 콜백 */
|
|
353
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
354
|
+
/** 실패 콜백 */
|
|
355
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
356
|
+
/** 완료 콜백 */
|
|
357
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* vibrateLong 옵션
|
|
362
|
+
*
|
|
363
|
+
* 긴 진동(400ms)을 실행하기 위한 옵션입니다.
|
|
364
|
+
*/
|
|
365
|
+
export interface VibrateLongOption {
|
|
366
|
+
/** 성공 콜백 */
|
|
367
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
368
|
+
/** 실패 콜백 */
|
|
369
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
370
|
+
/** 완료 콜백 */
|
|
371
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* showKeyboard 옵션
|
|
376
|
+
*
|
|
377
|
+
* 키보드를 표시하기 위한 옵션입니다.
|
|
378
|
+
*/
|
|
379
|
+
export interface ShowKeyboardOption {
|
|
380
|
+
/** 키보드 입력 필드의 기본값 */
|
|
381
|
+
defaultValue?: string;
|
|
382
|
+
/** 키보드 텍스트의 최대 길이 */
|
|
383
|
+
maxLength?: number;
|
|
384
|
+
/** 여러 줄 입력 여부 */
|
|
385
|
+
multiple?: boolean;
|
|
386
|
+
/** 완료 버튼 클릭 시 키보드 유지 여부 */
|
|
387
|
+
confirmHold?: boolean;
|
|
388
|
+
/** 키보드 우측 하단 버튼 텍스트 */
|
|
389
|
+
confirmType?: 'done' | 'next' | 'search' | 'go' | 'send';
|
|
390
|
+
/** 성공 콜백 */
|
|
391
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
392
|
+
/** 실패 콜백 */
|
|
393
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
394
|
+
/** 완료 콜백 */
|
|
395
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* hideKeyboard 옵션
|
|
400
|
+
*
|
|
401
|
+
* 키보드를 숨기기 위한 옵션입니다.
|
|
402
|
+
*/
|
|
403
|
+
export interface HideKeyboardOption {
|
|
404
|
+
/** 성공 콜백 */
|
|
405
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
406
|
+
/** 실패 콜백 */
|
|
407
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
408
|
+
/** 완료 콜백 */
|
|
409
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* 키보드 입력 이벤트 결과
|
|
414
|
+
*/
|
|
415
|
+
export interface OnKeyboardInputCallbackResult {
|
|
416
|
+
/** 키보드 입력의 현재 값 */
|
|
417
|
+
value: string;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* 키보드 입력 이벤트 콜백
|
|
422
|
+
*/
|
|
423
|
+
export type OnKeyboardInputCallback = (res: OnKeyboardInputCallbackResult) => void;
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* 키보드 확인 버튼 클릭 이벤트 결과
|
|
427
|
+
*/
|
|
428
|
+
export interface OnKeyboardConfirmCallbackResult {
|
|
429
|
+
/** 키보드 입력의 현재 값 */
|
|
430
|
+
value: string;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 키보드 확인 버튼 클릭 이벤트 콜백
|
|
435
|
+
*/
|
|
436
|
+
export type OnKeyboardConfirmCallback = (res: OnKeyboardConfirmCallbackResult) => void;
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* 키보드 입력 완료 이벤트 결과
|
|
440
|
+
*/
|
|
441
|
+
export interface OnKeyboardCompleteCallbackResult {
|
|
442
|
+
/** 키보드 입력의 현재 값 */
|
|
443
|
+
value: string;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* 키보드 입력 완료 이벤트 콜백
|
|
448
|
+
*/
|
|
449
|
+
export type OnKeyboardCompleteCallback = (res: OnKeyboardCompleteCallbackResult) => void;
|
|
450
|
+
|
|
451
|
+
// ============================================
|
|
452
|
+
// Clipboard API 타입
|
|
453
|
+
// ============================================
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* setClipboardData 옵션
|
|
457
|
+
*
|
|
458
|
+
* 클립보드에 데이터를 저장하기 위한 옵션입니다.
|
|
459
|
+
*/
|
|
460
|
+
export interface SetClipboardDataOption {
|
|
461
|
+
/** 클립보드에 저장할 데이터 */
|
|
462
|
+
data: string;
|
|
463
|
+
/** 성공 콜백 */
|
|
464
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
465
|
+
/** 실패 콜백 */
|
|
466
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
467
|
+
/** 완료 콜백 */
|
|
468
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* getClipboardData 성공 결과
|
|
473
|
+
*/
|
|
474
|
+
export interface GetClipboardDataSuccessResult {
|
|
475
|
+
/** 에러 메시지 */
|
|
476
|
+
errMsg: string;
|
|
477
|
+
/** 에러 코드 */
|
|
478
|
+
errCode?: number;
|
|
479
|
+
/** 클립보드의 데이터 */
|
|
480
|
+
data: string;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* getClipboardData 옵션
|
|
485
|
+
*
|
|
486
|
+
* 클립보드에서 데이터를 가져오기 위한 옵션입니다.
|
|
487
|
+
*/
|
|
488
|
+
export interface GetClipboardDataOption {
|
|
489
|
+
/** 성공 콜백 */
|
|
490
|
+
success?: (res: GetClipboardDataSuccessResult) => void;
|
|
491
|
+
/** 실패 콜백 */
|
|
492
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
493
|
+
/** 완료 콜백 */
|
|
494
|
+
complete?: (res: GetClipboardDataSuccessResult | GeneralCallbackResult) => void;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ============================================
|
|
498
|
+
// System API 타입
|
|
499
|
+
// ============================================
|
|
500
|
+
|
|
501
|
+
/** 플랫폼 타입 */
|
|
502
|
+
export type Platform = 'ios' | 'android' | 'windows' | 'mac' | 'devtools';
|
|
503
|
+
|
|
504
|
+
/** 안전 영역 정보 */
|
|
505
|
+
export interface SafeArea {
|
|
506
|
+
/** 안전 영역 좌상단 X 좌표 */
|
|
507
|
+
left: number;
|
|
508
|
+
/** 안전 영역 우하단 X 좌표 */
|
|
509
|
+
right: number;
|
|
510
|
+
/** 안전 영역 좌상단 Y 좌표 */
|
|
511
|
+
top: number;
|
|
512
|
+
/** 안전 영역 우하단 Y 좌표 */
|
|
513
|
+
bottom: number;
|
|
514
|
+
/** 안전 영역 너비 (논리 픽셀) */
|
|
515
|
+
width: number;
|
|
516
|
+
/** 안전 영역 높이 (논리 픽셀) */
|
|
517
|
+
height: number;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
/** 시스템 정보 */
|
|
522
|
+
export interface SystemInfo {
|
|
523
|
+
/** 기초 라이브러리 버전 */
|
|
524
|
+
SDKVersion: string;
|
|
525
|
+
/** Tudada 서비스 버전 */
|
|
526
|
+
version: string;
|
|
527
|
+
/** 디버그 모드 활성화 여부 - 호환용 */
|
|
528
|
+
enableDebug: boolean;
|
|
529
|
+
/** 사용자 글꼴 크기 설정 (px) - 호환용 */
|
|
530
|
+
fontSizeSetting: Mock<16>;
|
|
531
|
+
/** 호스트 앱 정보 */
|
|
532
|
+
host: { appId: string };
|
|
533
|
+
/** 디바이스 픽셀 비율 */
|
|
534
|
+
pixelRatio: number;
|
|
535
|
+
/** 화면 너비 (px) */
|
|
536
|
+
screenWidth: number;
|
|
537
|
+
/** 화면 높이 (px) */
|
|
538
|
+
screenHeight: number;
|
|
539
|
+
/** 사용 가능한 창 너비 (px) */
|
|
540
|
+
windowWidth: number;
|
|
541
|
+
/** 사용 가능한 창 높이 (px) */
|
|
542
|
+
windowHeight: number;
|
|
543
|
+
/** 상태바 높이 (px) - 호환용 */
|
|
544
|
+
statusBarHeight: number;
|
|
545
|
+
/** 안전 영역 정보 */
|
|
546
|
+
safeArea: SafeArea;
|
|
547
|
+
/** 디바이스 브랜드 */
|
|
548
|
+
brand: string;
|
|
549
|
+
/** 디바이스 모델 */
|
|
550
|
+
model: string;
|
|
551
|
+
/** OS 및 버전 */
|
|
552
|
+
system: string;
|
|
553
|
+
/** 디바이스 성능 등급 (Android 전용) */
|
|
554
|
+
benchmarkLevel: number;
|
|
555
|
+
/** 언어 설정 */
|
|
556
|
+
language: string;
|
|
557
|
+
/** 테마 (light/dark) */
|
|
558
|
+
theme: 'light' | 'dark';
|
|
559
|
+
/** 디바이스 방향 */
|
|
560
|
+
deviceOrientation: 'portrait' | 'landscape';
|
|
561
|
+
/** 플랫폼 */
|
|
562
|
+
platform: Platform;
|
|
563
|
+
/** 앨범 접근 권한 (iOS 전용) - 호환용 */
|
|
564
|
+
albumAuthorized: Mock<false>;
|
|
565
|
+
/** 카메라 접근 권한 - 호환용 */
|
|
566
|
+
cameraAuthorized: Mock<false>;
|
|
567
|
+
/** 위치 정보 접근 권한 - 호환용 */
|
|
568
|
+
locationAuthorized: Mock<false>;
|
|
569
|
+
/** 마이크 접근 권한 - 호환용 */
|
|
570
|
+
microphoneAuthorized: Mock<false>;
|
|
571
|
+
/** 알림 권한 - 호환용 */
|
|
572
|
+
notificationAuthorized: Mock<false>;
|
|
573
|
+
/** 알림 알림창 권한 (iOS 전용) - 호환용 */
|
|
574
|
+
notificationAlertAuthorized: Mock<false>;
|
|
575
|
+
/** 알림 뱃지 권한 (iOS 전용) - 호환용 */
|
|
576
|
+
notificationBadgeAuthorized: Mock<false>;
|
|
577
|
+
/** 알림 소리 권한 (iOS 전용) - 호환용 */
|
|
578
|
+
notificationSoundAuthorized: Mock<false>;
|
|
579
|
+
/** 캘린더 접근 권한 - 호환용 */
|
|
580
|
+
phoneCalendarAuthorized: Mock<false>;
|
|
581
|
+
/** 블루투스 활성화 상태 - 호환용 */
|
|
582
|
+
bluetoothEnabled: Mock<false>;
|
|
583
|
+
/** 위치 서비스 활성화 상태 - 호환용 */
|
|
584
|
+
locationEnabled: Mock<false>;
|
|
585
|
+
/** Wi-Fi 활성화 상태 - 호환용 */
|
|
586
|
+
wifiEnabled: Mock<false>;
|
|
587
|
+
/** 정밀도 낮은 위치 사용 여부 - 호환용 */
|
|
588
|
+
locationReducedAccuracy?: Mock<false>;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** getSystemInfo 옵션 */
|
|
592
|
+
export interface GetSystemInfoOption {
|
|
593
|
+
/** 성공 콜백 */
|
|
594
|
+
success?: (res: SystemInfo & GeneralCallbackResult) => void;
|
|
595
|
+
/** 실패 콜백 */
|
|
596
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
597
|
+
/** 완료 콜백 */
|
|
598
|
+
complete?: (res: (SystemInfo & GeneralCallbackResult) | GeneralCallbackResult) => void;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/** 창 정보 */
|
|
602
|
+
export interface WindowInfo {
|
|
603
|
+
/** 디바이스 픽셀 비율 */
|
|
604
|
+
pixelRatio: number;
|
|
605
|
+
/** 화면 너비 (px) */
|
|
606
|
+
screenWidth: number;
|
|
607
|
+
/** 화면 높이 (px) */
|
|
608
|
+
screenHeight: number;
|
|
609
|
+
/** 사용 가능한 창 너비 (px) */
|
|
610
|
+
windowWidth: number;
|
|
611
|
+
/** 사용 가능한 창 높이 (px) */
|
|
612
|
+
windowHeight: number;
|
|
613
|
+
/** 상태바 높이 (px) - 호환용 */
|
|
614
|
+
statusBarHeight: number;
|
|
615
|
+
/** 안전 영역 정보 */
|
|
616
|
+
safeArea: SafeArea;
|
|
617
|
+
/** 창 상단 Y 값 */
|
|
618
|
+
screenTop: number;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/** getWindowInfo 옵션 */
|
|
622
|
+
export interface GetWindowInfoOption {
|
|
623
|
+
/** 성공 콜백 */
|
|
624
|
+
success?: (res: WindowInfo & GeneralCallbackResult) => void;
|
|
625
|
+
/** 실패 콜백 */
|
|
626
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
627
|
+
/** 완료 콜백 */
|
|
628
|
+
complete?: (res: (WindowInfo & GeneralCallbackResult) | GeneralCallbackResult) => void;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/** 앱 기본 정보 */
|
|
632
|
+
export interface AppBaseInfo {
|
|
633
|
+
/** 기초 라이브러리 버전 */
|
|
634
|
+
SDKVersion: string;
|
|
635
|
+
/** Tudada 서비스 버전 */
|
|
636
|
+
version: string;
|
|
637
|
+
/** 디버그 모드 활성화 여부 - 호환용 */
|
|
638
|
+
enableDebug: boolean;
|
|
639
|
+
/** 사용자 글꼴 크기 설정 (px) - 호환용 */
|
|
640
|
+
fontSizeSetting: Mock<16>;
|
|
641
|
+
/** 호스트 앱 정보 */
|
|
642
|
+
host: { appId: string };
|
|
643
|
+
/** 글꼴 크기 확대 비율 - 호환용 */
|
|
644
|
+
fontSizeScaleFactor: Mock<1>;
|
|
645
|
+
/** 사용자 설정 언어 - 호환용 */
|
|
646
|
+
language: Mock<'KO'>;
|
|
647
|
+
/** 테마 설정 */
|
|
648
|
+
theme?: 'light' | 'dark';
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/** getAppBaseInfo 옵션 */
|
|
652
|
+
export interface GetAppBaseInfoOption {
|
|
653
|
+
/** 성공 콜백 */
|
|
654
|
+
success?: (res: AppBaseInfo & GeneralCallbackResult) => void;
|
|
655
|
+
/** 실패 콜백 */
|
|
656
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
657
|
+
/** 완료 콜백 */
|
|
658
|
+
complete?: (res: (AppBaseInfo & GeneralCallbackResult) | GeneralCallbackResult) => void;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/** 디바이스 정보 */
|
|
662
|
+
export interface DeviceInfo {
|
|
663
|
+
/** 디바이스 브랜드 */
|
|
664
|
+
brand: string;
|
|
665
|
+
/** 디바이스 모델 */
|
|
666
|
+
model: string;
|
|
667
|
+
/** OS 및 버전 */
|
|
668
|
+
system: string;
|
|
669
|
+
/** 디바이스 성능 등급 (Android 전용) */
|
|
670
|
+
benchmarkLevel: number;
|
|
671
|
+
/** 앱 바이너리 인터페이스 타입 (Android 전용) - 호환용 */
|
|
672
|
+
abi: Mock<''>;
|
|
673
|
+
/** 기기 CPU 타입 (Android 전용) - 호환용 */
|
|
674
|
+
cpuType: Mock<''>;
|
|
675
|
+
/** 기기 바이너리 인터페이스 타입 (Android 전용) - 호환용 */
|
|
676
|
+
deviceAbi: Mock<''>;
|
|
677
|
+
/** 기기 메모리 크기 - 호환용 */
|
|
678
|
+
memorySize: Mock<''>;
|
|
679
|
+
/** 클라이언트 플랫폼 */
|
|
680
|
+
platform: Platform;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/** getDeviceInfo 옵션 */
|
|
684
|
+
export interface GetDeviceInfoOption {
|
|
685
|
+
/** 성공 콜백 */
|
|
686
|
+
success?: (res: DeviceInfo & GeneralCallbackResult) => void;
|
|
687
|
+
/** 실패 콜백 */
|
|
688
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
689
|
+
/** 완료 콜백 */
|
|
690
|
+
complete?: (res: (DeviceInfo & GeneralCallbackResult) | GeneralCallbackResult) => void;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// ============================================
|
|
694
|
+
// UI API 타입
|
|
695
|
+
// ============================================
|
|
696
|
+
|
|
697
|
+
/** 메뉴 버튼 위치 정보 */
|
|
698
|
+
export interface MenuButtonBoundingClientRect {
|
|
699
|
+
/** 너비 (px) */
|
|
700
|
+
width: number;
|
|
701
|
+
/** 높이 (px) */
|
|
702
|
+
height: number;
|
|
703
|
+
/** 상단 좌표 (px) */
|
|
704
|
+
top: number;
|
|
705
|
+
/** 우측 좌표 (px) */
|
|
706
|
+
right: number;
|
|
707
|
+
/** 하단 좌표 (px) */
|
|
708
|
+
bottom: number;
|
|
709
|
+
/** 좌측 좌표 (px) */
|
|
710
|
+
left: number;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// ============================================
|
|
714
|
+
// Auth API 타입
|
|
715
|
+
// ============================================
|
|
716
|
+
|
|
717
|
+
/** 로그인 성공 결과 */
|
|
718
|
+
export interface LoginSuccessResult {
|
|
719
|
+
/** 에러 메시지 */
|
|
720
|
+
errMsg: string;
|
|
721
|
+
/** 에러 코드 */
|
|
722
|
+
errCode?: number;
|
|
723
|
+
/** 사용자 로그인 코드 */
|
|
724
|
+
code: string;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/** 로그인 옵션 */
|
|
728
|
+
export interface LoginOption {
|
|
729
|
+
/** 타임아웃 (ms) */
|
|
730
|
+
timeout?: number;
|
|
731
|
+
/** 성공 콜백 */
|
|
732
|
+
success?: (res: LoginSuccessResult) => void;
|
|
733
|
+
/** 실패 콜백 */
|
|
734
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
735
|
+
/** 완료 콜백 */
|
|
736
|
+
complete?: (res: LoginSuccessResult | GeneralCallbackResult) => void;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/** 세션 확인 옵션 */
|
|
740
|
+
export interface CheckSessionOption {
|
|
741
|
+
/** 성공 콜백 */
|
|
742
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
743
|
+
/** 실패 콜백 */
|
|
744
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
745
|
+
/** 완료 콜백 */
|
|
746
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/** 사용자 정보 */
|
|
750
|
+
export interface UserInfo {
|
|
751
|
+
/** 사용자 닉네임 */
|
|
752
|
+
nickName: string;
|
|
753
|
+
/** 사용자 아바타 이미지 URL */
|
|
754
|
+
avatarUrl: string;
|
|
755
|
+
/** 사용자 언어 설정 - 호환용 */
|
|
756
|
+
language: Mock<'KO'>;
|
|
757
|
+
/** 성별 (0: 알 수 없음) - 호환용 */
|
|
758
|
+
gender: Mock<0>;
|
|
759
|
+
/** 국가 코드 - 호환용 */
|
|
760
|
+
country: Mock<''>;
|
|
761
|
+
/** 도시 - 호환용 */
|
|
762
|
+
city: Mock<''>;
|
|
763
|
+
/** 지역/도 - 호환용 */
|
|
764
|
+
province: Mock<''>;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/** 사용자 정보 조회 성공 결과 */
|
|
768
|
+
export interface GetUserInfoSuccessResult {
|
|
769
|
+
/** 에러 메시지 */
|
|
770
|
+
errMsg: string;
|
|
771
|
+
/** 에러 코드 */
|
|
772
|
+
errCode?: number;
|
|
773
|
+
/** 사용자 정보 객체 */
|
|
774
|
+
userInfo: UserInfo;
|
|
775
|
+
/** 암호화된 데이터 (withCredentials가 true인 경우) */
|
|
776
|
+
encryptedData: string;
|
|
777
|
+
/** 암호화 초기 벡터 (withCredentials가 true인 경우) */
|
|
778
|
+
iv: string;
|
|
779
|
+
/** 데이터 서명 (withCredentials가 true인 경우) */
|
|
780
|
+
signature: string;
|
|
781
|
+
/** 원시 데이터 문자열 (withCredentials가 true인 경우) */
|
|
782
|
+
rawData: string;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/** 사용자 정보 조회 옵션 */
|
|
786
|
+
export interface GetUserInfoOption {
|
|
787
|
+
/** 암호화 데이터 포함 여부 */
|
|
788
|
+
withCredentials?: boolean;
|
|
789
|
+
/** 반환되는 사용자 정보의 언어 */
|
|
790
|
+
lang?: 'KO';
|
|
791
|
+
/** 성공 콜백 */
|
|
792
|
+
success?: (res: GetUserInfoSuccessResult) => void;
|
|
793
|
+
/** 실패 콜백 */
|
|
794
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
795
|
+
/** 완료 콜백 */
|
|
796
|
+
complete?: (res: GetUserInfoSuccessResult | GeneralCallbackResult) => void;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// ============================================
|
|
800
|
+
// Ad API 타입
|
|
801
|
+
// ============================================
|
|
802
|
+
|
|
803
|
+
/** 보상형 비디오 광고 생성 옵션 */
|
|
804
|
+
export interface CreateRewardedVideoAdOption {
|
|
805
|
+
/** 광고 단위 ID */
|
|
806
|
+
adUnitId: string;
|
|
807
|
+
/** 다중 인스턴스 모드 사용 여부 */
|
|
808
|
+
multiton?: boolean;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/** 보상형 비디오 광고 인스턴스 */
|
|
812
|
+
export interface RewardedVideoAd {
|
|
813
|
+
/** 광고 로드 */
|
|
814
|
+
load(): Promise<void>;
|
|
815
|
+
/** 광고 표시 */
|
|
816
|
+
show(): Promise<void>;
|
|
817
|
+
/** 광고 파괴 */
|
|
818
|
+
destroy(): void;
|
|
819
|
+
/** 로드 완료 이벤트 */
|
|
820
|
+
onLoad(callback: () => void): void;
|
|
821
|
+
/** 에러 이벤트 */
|
|
822
|
+
onError(callback: (res: { errMsg: string; errCode: number }) => void): void;
|
|
823
|
+
/** 닫기 버튼 클릭 이벤트 */
|
|
824
|
+
onClose(callback: (res: { isEnded: boolean }) => void): void;
|
|
825
|
+
/** 로드 이벤트 리스너 해제 */
|
|
826
|
+
offLoad(callback?: () => void): void;
|
|
827
|
+
/** 에러 이벤트 리스너 해제 */
|
|
828
|
+
offError(callback?: (res: { errMsg: string; errCode: number }) => void): void;
|
|
829
|
+
/** 닫기 이벤트 리스너 해제 */
|
|
830
|
+
offClose(callback?: (res: { isEnded: boolean }) => void): void;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
// ============================================
|
|
834
|
+
// Lifecycle API 타입
|
|
835
|
+
// ============================================
|
|
836
|
+
|
|
837
|
+
/** onShow 콜백 결과 */
|
|
838
|
+
export interface OnShowCallbackResult {
|
|
839
|
+
/** 앱이 표시된 시각 */
|
|
840
|
+
timestamp: number;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/** onHide 콜백 결과 */
|
|
844
|
+
export interface OnHideCallbackResult {
|
|
845
|
+
/** 앱이 숨겨진 시각 */
|
|
846
|
+
timestamp: number;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** onShow 콜백 함수 타입 */
|
|
850
|
+
export type OnShowCallback = (res: OnShowCallbackResult) => void;
|
|
851
|
+
|
|
852
|
+
/** onHide 콜백 함수 타입 */
|
|
853
|
+
export type OnHideCallback = (res?: OnHideCallbackResult) => void;
|
|
854
|
+
|
|
855
|
+
/** exitMiniProgram 옵션 */
|
|
856
|
+
export interface ExitMiniProgramOption {
|
|
857
|
+
/** 성공 콜백 */
|
|
858
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
859
|
+
/** 실패 콜백 */
|
|
860
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
861
|
+
/** 완료 콜백 */
|
|
862
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/** restartMiniProgram 옵션 */
|
|
866
|
+
export interface RestartMiniProgramOption {
|
|
867
|
+
/** 성공 콜백 */
|
|
868
|
+
success?: (res: GeneralCallbackResult) => void;
|
|
869
|
+
/** 실패 콜백 */
|
|
870
|
+
fail?: (res: GeneralCallbackResult) => void;
|
|
871
|
+
/** 완료 콜백 */
|
|
872
|
+
complete?: (res: GeneralCallbackResult) => void;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// ============================================
|
|
876
|
+
// TudadaSDK 인터페이스
|
|
877
|
+
// ============================================
|
|
878
|
+
|
|
879
|
+
/** TudadaSDK 인터페이스 */
|
|
880
|
+
export interface ITudadaSDK {
|
|
881
|
+
// ============================================
|
|
882
|
+
// Auth API
|
|
883
|
+
// ============================================
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* 사용자 로그인
|
|
887
|
+
*
|
|
888
|
+
* @example
|
|
889
|
+
* ```typescript
|
|
890
|
+
* TudadaSDK.login({
|
|
891
|
+
* success: (res) => console.log('로그인 코드:', res.code),
|
|
892
|
+
* fail: (res) => console.error('로그인 실패:', res.errMsg),
|
|
893
|
+
* });
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
login(options: LoginOption): void;
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* 세션 유효성 확인
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```typescript
|
|
903
|
+
* TudadaSDK.checkSession({
|
|
904
|
+
* success: () => console.log('세션 유효'),
|
|
905
|
+
* fail: () => console.log('세션 만료, 재로그인 필요'),
|
|
906
|
+
* });
|
|
907
|
+
* ```
|
|
908
|
+
*/
|
|
909
|
+
checkSession(options: CheckSessionOption): void;
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* 사용자 정보 조회
|
|
913
|
+
*
|
|
914
|
+
* @example
|
|
915
|
+
* ```typescript
|
|
916
|
+
* TudadaSDK.getUserInfo({
|
|
917
|
+
* success: (res) => {
|
|
918
|
+
* console.log('닉네임:', res.userInfo.nickName);
|
|
919
|
+
* console.log('아바타:', res.userInfo.avatarUrl);
|
|
920
|
+
* },
|
|
921
|
+
* fail: (res) => console.error('사용자 정보 조회 실패:', res.errMsg),
|
|
922
|
+
* });
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
getUserInfo(options: GetUserInfoOption): void;
|
|
926
|
+
|
|
927
|
+
// ============================================
|
|
928
|
+
// Storage API
|
|
929
|
+
// ============================================
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* 데이터를 로컬 스토리지에 저장 (비동기)
|
|
933
|
+
*/
|
|
934
|
+
setStorage(options: SetStorageOption): void;
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* 데이터를 로컬 스토리지에 저장 (동기)
|
|
938
|
+
*/
|
|
939
|
+
setStorageSync(key: string, data: any): void;
|
|
940
|
+
setStorageSync(options: { key: string; data: any }): void;
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* 로컬 스토리지에서 데이터 조회 (비동기)
|
|
944
|
+
*/
|
|
945
|
+
getStorage(options: GetStorageOption): void;
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* 로컬 스토리지에서 데이터 조회 (동기)
|
|
949
|
+
*/
|
|
950
|
+
getStorageSync(key: string): any;
|
|
951
|
+
getStorageSync(options: { key: string }): any;
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* 로컬 스토리지에서 데이터 삭제 (비동기)
|
|
955
|
+
*/
|
|
956
|
+
removeStorage(options: RemoveStorageOption): void;
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* 로컬 스토리지에서 데이터 삭제 (동기)
|
|
960
|
+
*/
|
|
961
|
+
removeStorageSync(key: string): void;
|
|
962
|
+
removeStorageSync(options: { key: string }): void;
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* 로컬 스토리지 전체 삭제 (비동기)
|
|
966
|
+
*/
|
|
967
|
+
clearStorage(options?: ClearStorageOption): void;
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* 로컬 스토리지 전체 삭제 (동기)
|
|
971
|
+
*/
|
|
972
|
+
clearStorageSync(): void;
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* 스토리지 정보 조회 (동기)
|
|
976
|
+
*/
|
|
977
|
+
getStorageInfoSync(): StorageInfo;
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* TudadaStore 인스턴스 획득
|
|
981
|
+
*/
|
|
982
|
+
getTudadaStore(): TudadaStore;
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* TudadaStore에서 값 조회 (Unity Bridge용)
|
|
986
|
+
*/
|
|
987
|
+
tudadaStoreGet(options: TudadaStoreGetOption): void;
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* TudadaStore에 값 저장 (Unity Bridge용)
|
|
991
|
+
*/
|
|
992
|
+
tudadaStoreSave(options: TudadaStoreSaveOption): void;
|
|
993
|
+
|
|
994
|
+
// ============================================
|
|
995
|
+
// System API
|
|
996
|
+
// ============================================
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* 시스템 정보 조회 (비동기)
|
|
1000
|
+
*/
|
|
1001
|
+
getSystemInfo(options?: GetSystemInfoOption): void;
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* 시스템 정보 조회 (동기)
|
|
1005
|
+
*/
|
|
1006
|
+
getSystemInfoSync(): SystemInfo;
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* 창 정보 조회 (동기)
|
|
1010
|
+
*/
|
|
1011
|
+
getWindowInfo(): WindowInfo;
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* 창 정보 조회 (비동기)
|
|
1015
|
+
*/
|
|
1016
|
+
getWindowInfoAsync(options?: GetWindowInfoOption): void;
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* 앱 기본 정보 조회 (동기)
|
|
1020
|
+
*/
|
|
1021
|
+
getAppBaseInfo(): AppBaseInfo;
|
|
1022
|
+
|
|
1023
|
+
/**
|
|
1024
|
+
* 앱 기본 정보 조회 (비동기)
|
|
1025
|
+
*/
|
|
1026
|
+
getAppBaseInfoAsync(options?: GetAppBaseInfoOption): void;
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* 디바이스 정보 조회 (동기)
|
|
1030
|
+
*/
|
|
1031
|
+
getDeviceInfo(): DeviceInfo;
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* 디바이스 정보 조회 (비동기)
|
|
1035
|
+
*/
|
|
1036
|
+
getDeviceInfoAsync(options?: GetDeviceInfoOption): void;
|
|
1037
|
+
|
|
1038
|
+
// ============================================
|
|
1039
|
+
// UI API
|
|
1040
|
+
// ============================================
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* 메뉴 버튼 위치 정보 조회
|
|
1044
|
+
*/
|
|
1045
|
+
getMenuButtonBoundingClientRect(): MenuButtonBoundingClientRect;
|
|
1046
|
+
|
|
1047
|
+
// ============================================
|
|
1048
|
+
// Device API
|
|
1049
|
+
// ============================================
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* 짧은 진동 실행
|
|
1053
|
+
*/
|
|
1054
|
+
vibrateShort(options?: VibrateShortOption): void;
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* 긴 진동 실행
|
|
1058
|
+
*/
|
|
1059
|
+
vibrateLong(options?: VibrateLongOption): void;
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* 키보드 표시
|
|
1063
|
+
*/
|
|
1064
|
+
showKeyboard(options?: ShowKeyboardOption): void;
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* 키보드 숨김
|
|
1068
|
+
*/
|
|
1069
|
+
hideKeyboard(options?: HideKeyboardOption): void;
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* 키보드 입력 이벤트 리스너 등록
|
|
1073
|
+
*/
|
|
1074
|
+
onKeyboardInput(callback: OnKeyboardInputCallback): void;
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* 키보드 입력 이벤트 리스너 제거
|
|
1078
|
+
*/
|
|
1079
|
+
offKeyboardInput(callback?: OnKeyboardInputCallback): void;
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* 키보드 확인 버튼 클릭 이벤트 리스너 등록
|
|
1083
|
+
*/
|
|
1084
|
+
onKeyboardConfirm(callback: OnKeyboardConfirmCallback): void;
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* 키보드 확인 버튼 클릭 이벤트 리스너 제거
|
|
1088
|
+
*/
|
|
1089
|
+
offKeyboardConfirm(callback?: OnKeyboardConfirmCallback): void;
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* 키보드 입력 완료 이벤트 리스너 등록
|
|
1093
|
+
*/
|
|
1094
|
+
onKeyboardComplete(callback: OnKeyboardCompleteCallback): void;
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* 키보드 입력 완료 이벤트 리스너 제거
|
|
1098
|
+
*/
|
|
1099
|
+
offKeyboardComplete(callback?: OnKeyboardCompleteCallback): void;
|
|
1100
|
+
|
|
1101
|
+
// ============================================
|
|
1102
|
+
// Clipboard API
|
|
1103
|
+
// ============================================
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* 클립보드에 데이터 저장
|
|
1107
|
+
*/
|
|
1108
|
+
setClipboardData(options: SetClipboardDataOption): void;
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* 클립보드에서 데이터 가져오기
|
|
1112
|
+
*/
|
|
1113
|
+
getClipboardData(options?: GetClipboardDataOption): void;
|
|
1114
|
+
|
|
1115
|
+
// ============================================
|
|
1116
|
+
// Ad API
|
|
1117
|
+
// ============================================
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* 보상형 비디오 광고 인스턴스 생성
|
|
1121
|
+
*/
|
|
1122
|
+
createRewardedVideoAd(options: CreateRewardedVideoAdOption): RewardedVideoAd;
|
|
1123
|
+
|
|
1124
|
+
// ============================================
|
|
1125
|
+
// Lifecycle API
|
|
1126
|
+
// ============================================
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* 앱이 포어그라운드로 전환될 때 실행할 콜백 등록
|
|
1130
|
+
*/
|
|
1131
|
+
onShow(callback: OnShowCallback): void;
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* onShow 콜백 해제
|
|
1135
|
+
*/
|
|
1136
|
+
offShow(callback?: OnShowCallback): void;
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* 앱이 백그라운드로 전환될 때 실행할 콜백 등록
|
|
1140
|
+
*/
|
|
1141
|
+
onHide(callback: OnHideCallback): void;
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* onHide 콜백 해제
|
|
1145
|
+
*/
|
|
1146
|
+
offHide(callback?: OnHideCallback): void;
|
|
1147
|
+
|
|
1148
|
+
/**
|
|
1149
|
+
* 미니프로그램 종료
|
|
1150
|
+
*/
|
|
1151
|
+
exitMiniProgram(options?: ExitMiniProgramOption): void;
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* 미니프로그램 재시작
|
|
1155
|
+
*/
|
|
1156
|
+
restartMiniProgram(options?: RestartMiniProgramOption): void;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
// ============================================
|
|
1160
|
+
// 글로벌 선언
|
|
1161
|
+
// ============================================
|
|
1162
|
+
|
|
1163
|
+
declare global {
|
|
1164
|
+
/** TudadaSDK 글로벌 인스턴스 */
|
|
1165
|
+
const TudadaSDK: ITudadaSDK;
|
|
1166
|
+
/** TudadaSDK 글로벌 인스턴스 (별칭) */
|
|
1167
|
+
const tudadaSDK: ITudadaSDK;
|
|
1168
|
+
|
|
1169
|
+
interface Window {
|
|
1170
|
+
TudadaSDK: ITudadaSDK;
|
|
1171
|
+
tudadaSDK: ITudadaSDK;
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tudada-sdk-types",
|
|
3
|
+
"version": "0.0.1-2",
|
|
4
|
+
"description": "TypeScript type definitions for TudadaSDK - H5 web game SDK for Tudada platform",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tudada",
|
|
7
|
+
"sdk",
|
|
8
|
+
"types",
|
|
9
|
+
"typescript",
|
|
10
|
+
"h5",
|
|
11
|
+
"game",
|
|
12
|
+
"wechat",
|
|
13
|
+
"minigame"
|
|
14
|
+
],
|
|
15
|
+
"author": "Tudada",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/tudada/tudada-sdk-types"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/tudada/tudada-sdk-types#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/tudada/tudada-sdk-types/issues"
|
|
24
|
+
},
|
|
25
|
+
"main": "",
|
|
26
|
+
"types": "index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"index.d.ts",
|
|
29
|
+
"global.d.ts",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|