@apps-in-toss/native-modules 2.5.1 → 2.6.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.
@@ -95,6 +95,14 @@
95
95
  "identifier": "saveBase64Data",
96
96
  "dts": "export interface SaveBase64DataParams {\n\tdata: string;\n\tfileName: string;\n\tmimeType: string;\n}\n/**\n * @public\n * @category 데이터\n * @name saveBase64Data\n * @description 문자열로 인코딩된 Base64 데이터를 지정한 파일 이름과 MIME 타입으로 사용자 기기에 저장해요. 이미지, 텍스트, PDF 등 다양한 형식의 데이터를 저장할 수 있어요.\n * @param {SaveBase64DataParams} params - 저장할 데이터와 파일 정보를 담은 객체예요.\n * @param {string} params.data - Base64 형식으로 인코딩된 데이터 문자열이에요.\n * @param {string} params.fileName - 저장할 파일 이름이에요. 확장자도 같이 붙여줘야해요. 예를 들어, 'example.png'로 저장할 수 있어요.\n * @param {string} params.mimeType - 저장할 파일의 MIME 타입이에요. 예를 들어 'image/png' 로 지정하면 이미지, 'application/pdf'는 PDF 파일이에요. 자세한 내용은 [MIME 문서](https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/MIME_types)를 참고해주세요.\n *\n * @example\n * ### Base64 이미지 데이터를 사용자 기기에 저장하기\n *\n * ```tsx\n * import { Button } from 'react-native';\n * import { saveBase64Data } from '@apps-in-toss/framework';\n *\n * // '저장' 버튼을 누르면 이미지가 사용자 기기에 저장돼요.\n * function SaveButton() {\n * const handleSave = async () => {\n * try {\n * await saveBase64Data({\n * data: 'iVBORw0KGgo...',\n * fileName: 'some-photo.png',\n * mimeType: 'image/png',\n * });\n * } catch (error) {\n * console.error('데이터 저장에 실패했어요:', error);\n * }\n * };\n *\n * return <Button title=\"저장\" onPress={handleSave} />;\n * }\n * ```\n */\nexport declare function saveBase64Data(params: SaveBase64DataParams): Promise<void>;\n\nexport {};\n"
97
97
  },
98
+ {
99
+ "identifier": "openPDFViewer",
100
+ "dts": "/**\n * @public\n * @category PDF\n * @name OpenPDFViewerParams\n * @description PDF 뷰어를 열 때 필요한 파라미터예요.\n * @property {string} data - Base64 형식으로 인코딩된 PDF 데이터 문자열이에요.\n * @property {string} [filename] - PDF 파일 이름이에요.\n */\nexport interface OpenPDFViewerParams {\n\tdata: string;\n\tfilename?: string;\n}\n/**\n * @public\n * @category PDF\n * @name OpenPDFViewerResult\n * @description PDF 뷰어가 닫혔을 때 반환되는 결과예요.\n */\nexport type OpenPDFViewerResult = \"CLOSE\";\n/**\n * @public\n * @category PDF\n * @name openPDFViewer\n * @description Base64로 인코딩된 PDF 데이터를 네이티브 PDF 뷰어로 열어요. 사용자가 뷰어를 닫으면 `'CLOSE'`를 반환해요.\n *\n * @param {OpenPDFViewerParams} params - PDF 데이터와 파일 이름을 담은 객체예요.\n * @returns {Promise<OpenPDFViewerResult>} PDF 뷰어가 닫히면 `'CLOSE'`를 반환해요.\n *\n * @throws\n * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때\n * - {code: `INVALID_DATA`}: PDF 데이터가 유효하지 않을 때\n * - {code: `PDF_VIEWER_ERROR`}: PDF 뷰어를 여는 과정에서 오류가 발생했을 때\n * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때\n *\n * @example\n * ```tsx\n * import { openPDFViewer } from '@apps-in-toss/framework';\n *\n * async function showPdf() {\n * try {\n * const result = await openPDFViewer({\n * data: 'JVBERi0xLjQK...',\n * filename: 'document.pdf',\n * });\n *\n * if (result === 'CLOSE') {\n * console.log('PDF 뷰어가 닫혔어요.');\n * }\n * } catch (error) {\n * console.error('PDF 뷰어 오류:', error);\n * }\n * }\n * ```\n */\nexport declare function openPDFViewer(params: OpenPDFViewerParams): Promise<OpenPDFViewerResult>;\n\nexport {};\n"
101
+ },
102
+ {
103
+ "identifier": "fetchAlbumItems",
104
+ "dts": "/**\n * @public\n * @category 앨범\n * @name AlbumItemType\n * @description 앨범에서 가져올 미디어 유형이에요.\n */\nexport type AlbumItemType = \"PHOTO\" | \"VIDEO\";\n/**\n * @public\n * @category 앨범\n * @name FetchAlbumItemsOptions\n * @description 앨범에서 사진·동영상을 선택할 때 사용하는 옵션이에요.\n * @property {Array<\"PHOTO\" | \"VIDEO\">} [types] - 가져올 미디어 유형 목록이에요. 지정하지 않으면 사진만 가져와요.\n * @property {number} [maxCount] - 가져올 항목의 최대 개수예요. 기본값은 10이에요.\n * @property {number} [maxWidth] - 이미지의 최대 폭이에요. 단위는 픽셀이에요. 기본값은 1024이에요.\n * @property {boolean} [base64] - 이미지의 `dataUri`를 Base64 문자열로 반환할지 여부예요. 기본값은 `false`이에요.\n */\nexport interface FetchAlbumItemsOptions {\n\ttypes?: AlbumItemType[];\n\tmaxCount?: number;\n\tmaxWidth?: number;\n\tbase64?: boolean;\n}\n/**\n * @public\n * @category 앨범\n * @name AlbumItemResponse\n * @description 앨범에서 선택한 미디어 항목이에요.\n * @property {string} id - 항목의 고유 ID예요.\n * @property {string} dataUri - 미디어 데이터 URI예요. `type`이 `PHOTO`면서 `base64` 옵션이 `true`이면 Base64 문자열로 반환돼요.\n * @property {\"PHOTO\" | \"VIDEO\"} type - 미디어 유형이에요.\n */\nexport interface AlbumItemResponse {\n\tid: string;\n\tdataUri: string;\n\ttype: AlbumItemType;\n}\n/**\n * @public\n * @category 앨범\n * @name fetchAlbumItems\n * @description 사용자 앨범에서 사진·동영상을 선택해 가져와요. 사용자가 선택을 취소하면 빈 배열 `[]`을 반환해요.\n *\n * @param {FetchAlbumItemsOptions} [options] - 조회 옵션을 담은 객체예요.\n * @returns {Promise<AlbumItemResponse[]>} 선택한 미디어 목록을 반환해요. 취소 시 빈 배열을 반환해요.\n *\n * @throws 다음 에러 코드가 발생할 수 있어요.\n * - {code: `NOT_ALLOWED`}: 앨범 접근이 허용되지 않았을 때\n * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때\n * - {code: `INVALID_DATA`}: 미디어 데이터가 유효하지 않을 때\n * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때\n *\n * @example\n * ```tsx\n * import { fetchAlbumItems, FetchAlbumItemsError } from '@apps-in-toss/framework';\n *\n * async function pickMedia() {\n * try {\n * const items = await fetchAlbumItems({\n * types: ['PHOTO', 'VIDEO'],\n * maxCount: 5,\n * base64: true,\n * });\n *\n * if (items.length === 0) {\n * console.log('선택이 취소되었어요.');\n * return;\n * }\n *\n * items.forEach((item) => {\n * console.log(item.type, item.id);\n * });\n * } catch (error) {\n * console.error('앨범 조회 오류:', error.code);\n * }\n * }\n * ```\n */\nexport declare function fetchAlbumItems(options?: FetchAlbumItemsOptions): Promise<AlbumItemResponse[]>;\n\nexport {};\n"
105
+ },
98
106
  {
99
107
  "identifier": "appsInTossSignTossCert",
100
108
  "dts": "export interface AppsInTossSignTossCertParams {\n\ttxId: string;\n}\n/**\n * @public\n * @category 토스인증\n * @name appsInTossSignTossCert\n * @description 토스 인증서를 사용해 서명하는 기능을 제공해요. 이 함수를 사용하면 앱인토스에서 제공하는 인증서를 활용해 서명을 할 수 있어요.\n *\n * @param {AppsInTossSignTossCertParams} params - 서명에 필요한 파라미터를 포함하는 객체예요.\n * @param {string} params.txId - 토스인증서를 사용한 본인확인이나 간편인증, 전자서명에서 사용하는 Transaction Id예요.\n *\n * @example\n * ```tsx\n * import { appsInTossSignTossCert } from '@apps-in-toss/framework';\n *\n * // 서명에 필요한 파라미터를 정의해요.\n * const params = {\n * txId: \"f2e1a6df...\"\n * };\n *\n * appsInTossSignTossCert(params)\n * .then(() => {\n * console.log('서명 작업이 성공적으로 완료되었어요.');\n * })\n * .catch((error) => {\n * console.error('서명 작업 중 에러가 발생했어요:', error);\n * });\n * ```\n */\nexport declare function appsInTossSignTossCert(params: AppsInTossSignTossCertParams): Promise<void>;\n\nexport {};\n"
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  closeView: () => closeView,
35
35
  contactsViral: () => contactsViral,
36
36
  eventLog: () => eventLog,
37
+ fetchAlbumItems: () => fetchAlbumItems,
37
38
  fetchAlbumPhotos: () => fetchAlbumPhotos,
38
39
  fetchContacts: () => fetchContacts,
39
40
  generateHapticFeedback: () => generateHapticFeedback,
@@ -60,6 +61,7 @@ __export(index_exports, {
60
61
  onVisibilityChangedByTransparentServiceWeb: () => onVisibilityChangedByTransparentServiceWeb,
61
62
  openCamera: () => openCamera,
62
63
  openGameCenterLeaderboard: () => openGameCenterLeaderboard,
64
+ openPDFViewer: () => openPDFViewer,
63
65
  openURL: () => openURL2,
64
66
  processProductGrant: () => processProductGrant,
65
67
  requestNotificationAgreement: () => requestNotificationAgreement,
@@ -862,6 +864,34 @@ async function saveBase64Data(params) {
862
864
  await safePostMessage("saveBase64Data", params);
863
865
  }
864
866
 
867
+ // src/MiniAppModule/native-modules/openPDFViewer.ts
868
+ async function openPDFViewer(params) {
869
+ const isSupported = isMinVersionSupported({
870
+ android: "5.261.0",
871
+ ios: "5.261.0"
872
+ });
873
+ if (!isSupported) {
874
+ const error = new Error("\uD1A0\uC2A4\uC571 5.261.0 \uBC84\uC804 \uC774\uC0C1\uC774 \uD544\uC694\uD574\uC694.");
875
+ error.code = "UNSUPPORTED_APP_VERSION";
876
+ throw error;
877
+ }
878
+ return safePostMessage("openPDFViewer", params);
879
+ }
880
+
881
+ // src/MiniAppModule/native-modules/fetchAlbumItems.ts
882
+ async function fetchAlbumItems(options) {
883
+ const isSupported = isMinVersionSupported({
884
+ android: "5.261.0",
885
+ ios: "5.261.0"
886
+ });
887
+ if (!isSupported) {
888
+ const error = new Error("\uD1A0\uC2A4\uC571 5.261.0 \uBC84\uC804 \uC774\uC0C1\uC774 \uD544\uC694\uD574\uC694.");
889
+ error.code = "UNSUPPORTED_APP_VERSION";
890
+ throw error;
891
+ }
892
+ return safePostMessage("fetchAlbumItems", options ?? {});
893
+ }
894
+
865
895
  // src/MiniAppModule/native-modules/setDeviceOrientation.ts
866
896
  async function setDeviceOrientation(options) {
867
897
  const isSupported = isMinVersionSupported({
@@ -1241,6 +1271,7 @@ var INTERNAL__module = {
1241
1271
  closeView,
1242
1272
  contactsViral,
1243
1273
  eventLog,
1274
+ fetchAlbumItems,
1244
1275
  fetchAlbumPhotos,
1245
1276
  fetchContacts,
1246
1277
  generateHapticFeedback,
@@ -1267,6 +1298,7 @@ var INTERNAL__module = {
1267
1298
  onVisibilityChangedByTransparentServiceWeb,
1268
1299
  openCamera,
1269
1300
  openGameCenterLeaderboard,
1301
+ openPDFViewer,
1270
1302
  openURL,
1271
1303
  processProductGrant,
1272
1304
  requestNotificationAgreement,
package/dist/index.d.cts CHANGED
@@ -112,6 +112,86 @@ declare function checkoutPayment(options: {
112
112
  params: CheckoutPaymentOptions;
113
113
  }): Promise<CheckoutPaymentResult>;
114
114
 
115
+ /**
116
+ * @public
117
+ * @category 앨범
118
+ * @name AlbumItemType
119
+ * @description 앨범에서 가져올 미디어 유형이에요.
120
+ */
121
+ type AlbumItemType = 'PHOTO' | 'VIDEO';
122
+ /**
123
+ * @public
124
+ * @category 앨범
125
+ * @name FetchAlbumItemsOptions
126
+ * @description 앨범에서 사진·동영상을 선택할 때 사용하는 옵션이에요.
127
+ * @property {Array<"PHOTO" | "VIDEO">} [types] - 가져올 미디어 유형 목록이에요. 지정하지 않으면 사진만 가져와요.
128
+ * @property {number} [maxCount] - 가져올 항목의 최대 개수예요. 기본값은 10이에요.
129
+ * @property {number} [maxWidth] - 이미지의 최대 폭이에요. 단위는 픽셀이에요. 기본값은 1024이에요.
130
+ * @property {boolean} [base64] - 이미지의 `dataUri`를 Base64 문자열로 반환할지 여부예요. 기본값은 `false`이에요.
131
+ */
132
+ interface FetchAlbumItemsOptions {
133
+ types?: AlbumItemType[];
134
+ maxCount?: number;
135
+ maxWidth?: number;
136
+ base64?: boolean;
137
+ }
138
+ /**
139
+ * @public
140
+ * @category 앨범
141
+ * @name AlbumItemResponse
142
+ * @description 앨범에서 선택한 미디어 항목이에요.
143
+ * @property {string} id - 항목의 고유 ID예요.
144
+ * @property {string} dataUri - 미디어 데이터 URI예요. `type`이 `PHOTO`면서 `base64` 옵션이 `true`이면 Base64 문자열로 반환돼요.
145
+ * @property {"PHOTO" | "VIDEO"} type - 미디어 유형이에요.
146
+ */
147
+ interface AlbumItemResponse {
148
+ id: string;
149
+ dataUri: string;
150
+ type: AlbumItemType;
151
+ }
152
+ /**
153
+ * @public
154
+ * @category 앨범
155
+ * @name fetchAlbumItems
156
+ * @description 사용자 앨범에서 사진·동영상을 선택해 가져와요. 사용자가 선택을 취소하면 빈 배열 `[]`을 반환해요.
157
+ *
158
+ * @param {FetchAlbumItemsOptions} [options] - 조회 옵션을 담은 객체예요.
159
+ * @returns {Promise<AlbumItemResponse[]>} 선택한 미디어 목록을 반환해요. 취소 시 빈 배열을 반환해요.
160
+ *
161
+ * @throws 다음 에러 코드가 발생할 수 있어요.
162
+ * - {code: `NOT_ALLOWED`}: 앨범 접근이 허용되지 않았을 때
163
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
164
+ * - {code: `INVALID_DATA`}: 미디어 데이터가 유효하지 않을 때
165
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * import { fetchAlbumItems, FetchAlbumItemsError } from '@apps-in-toss/framework';
170
+ *
171
+ * async function pickMedia() {
172
+ * try {
173
+ * const items = await fetchAlbumItems({
174
+ * types: ['PHOTO', 'VIDEO'],
175
+ * maxCount: 5,
176
+ * base64: true,
177
+ * });
178
+ *
179
+ * if (items.length === 0) {
180
+ * console.log('선택이 취소되었어요.');
181
+ * return;
182
+ * }
183
+ *
184
+ * items.forEach((item) => {
185
+ * console.log(item.type, item.id);
186
+ * });
187
+ * } catch (error) {
188
+ * console.error('앨범 조회 오류:', error.code);
189
+ * }
190
+ * }
191
+ * ```
192
+ */
193
+ declare function fetchAlbumItems(options?: FetchAlbumItemsOptions): Promise<AlbumItemResponse[]>;
194
+
115
195
  interface GetAnonymousKeySuccessResponse {
116
196
  hash: string;
117
197
  type: 'HASH';
@@ -902,6 +982,62 @@ declare const IAP: {
902
982
  getSubscriptionInfo: typeof getSubscriptionInfo;
903
983
  };
904
984
 
985
+ /**
986
+ * @public
987
+ * @category PDF
988
+ * @name OpenPDFViewerParams
989
+ * @description PDF 뷰어를 열 때 필요한 파라미터예요.
990
+ * @property {string} data - Base64 형식으로 인코딩된 PDF 데이터 문자열이에요.
991
+ * @property {string} [filename] - PDF 파일 이름이에요.
992
+ */
993
+ interface OpenPDFViewerParams {
994
+ data: string;
995
+ filename?: string;
996
+ }
997
+ /**
998
+ * @public
999
+ * @category PDF
1000
+ * @name OpenPDFViewerResult
1001
+ * @description PDF 뷰어가 닫혔을 때 반환되는 결과예요.
1002
+ */
1003
+ type OpenPDFViewerResult = 'CLOSE';
1004
+ /**
1005
+ * @public
1006
+ * @category PDF
1007
+ * @name openPDFViewer
1008
+ * @description Base64로 인코딩된 PDF 데이터를 네이티브 PDF 뷰어로 열어요. 사용자가 뷰어를 닫으면 `'CLOSE'`를 반환해요.
1009
+ *
1010
+ * @param {OpenPDFViewerParams} params - PDF 데이터와 파일 이름을 담은 객체예요.
1011
+ * @returns {Promise<OpenPDFViewerResult>} PDF 뷰어가 닫히면 `'CLOSE'`를 반환해요.
1012
+ *
1013
+ * @throws
1014
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
1015
+ * - {code: `INVALID_DATA`}: PDF 데이터가 유효하지 않을 때
1016
+ * - {code: `PDF_VIEWER_ERROR`}: PDF 뷰어를 여는 과정에서 오류가 발생했을 때
1017
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
1018
+ *
1019
+ * @example
1020
+ * ```tsx
1021
+ * import { openPDFViewer } from '@apps-in-toss/framework';
1022
+ *
1023
+ * async function showPdf() {
1024
+ * try {
1025
+ * const result = await openPDFViewer({
1026
+ * data: 'JVBERi0xLjQK...',
1027
+ * filename: 'document.pdf',
1028
+ * });
1029
+ *
1030
+ * if (result === 'CLOSE') {
1031
+ * console.log('PDF 뷰어가 닫혔어요.');
1032
+ * }
1033
+ * } catch (error) {
1034
+ * console.error('PDF 뷰어 오류:', error);
1035
+ * }
1036
+ * }
1037
+ * ```
1038
+ */
1039
+ declare function openPDFViewer(params: OpenPDFViewerParams): Promise<OpenPDFViewerResult>;
1040
+
905
1041
  /**
906
1042
  * @public
907
1043
  * @category 알림
@@ -1178,6 +1314,7 @@ interface AsyncMethodsMap {
1178
1314
  maxCount?: number;
1179
1315
  maxWidth?: number;
1180
1316
  }) => Promise<ImageResponse[]>;
1317
+ fetchAlbumItems: (params: FetchAlbumItemsOptions) => Promise<AlbumItemResponse[]>;
1181
1318
  openCamera: (params: {
1182
1319
  base64?: boolean;
1183
1320
  maxWidth?: number;
@@ -1237,6 +1374,7 @@ interface AsyncMethodsMap {
1237
1374
  type: 'portrait' | 'landscape';
1238
1375
  }) => Promise<void>;
1239
1376
  saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
1377
+ openPDFViewer: (params: OpenPDFViewerParams) => Promise<OpenPDFViewerResult>;
1240
1378
  appsInTossSignTossCert: (params: AppsInTossSignTossCertParams) => Promise<void>;
1241
1379
  getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse | undefined>;
1242
1380
  getUserKeyForGame: (params: CompatiblePlaceholderArgument) => Promise<GetUserKeyForGameResponse | undefined>;
@@ -3450,4 +3588,4 @@ declare const INTERNAL__module: {
3450
3588
  tossCoreEventLog: typeof tossCoreEventLog;
3451
3589
  };
3452
3590
 
3453
- export { type AppsInTossSignTossCertParams, type CheckoutPaymentOptions, type CheckoutPaymentResult, type CompletedOrRefundedOrdersResult, type ConsumableProductListItem, type ContactsViralParams, type CreateSubscriptionPurchaseOrderOptions, type EventLogParams, type GameCenterGameProfileResponse, type GetAnonymousKeyResponse, type GetAnonymousKeySuccessResponse, type GetUserKeyForGameErrorResponse, type GetUserKeyForGameResponse, type GetUserKeyForGameSuccessResponse, GoogleAdMob, type GrantPromotionRewardErrorResponse, type GrantPromotionRewardErrorResult, type GrantPromotionRewardForGameErrorResponse, type GrantPromotionRewardForGameErrorResult, type GrantPromotionRewardForGameResponse, type GrantPromotionRewardForGameSuccessResponse, type GrantPromotionRewardResponse, type GrantPromotionRewardSuccessResponse, type HapticFeedbackType, IAP, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapCreateSubscriptionPurchaseOrderResult, type IapProductListItem, type IapSubscriptionInfoResult, type NetworkStatus, type NonConsumableProductListItem, type NotificationAgreementResult, type Primitive, type RequestNotificationAgreementOptions, type RequestTossPayPaysBillingOptions, type RequestTossPayPaysBillingResult, type SaveBase64DataParams, Storage, type SubmitGameCenterLeaderBoardScoreResponse, type SubscriptionProductListItem, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, appsInTossSignTossCert, checkoutPayment, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, grantPromotionReward, grantPromotionRewardForGame, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, processProductGrant, requestNotificationAgreement, requestOneTimePurchase, requestReview, requestTossPayPaysBilling, safePostMessage, safeSyncPostMessage, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareWithScheme, startUpdateLocation, submitGameCenterLeaderBoardScore };
3591
+ export { type AlbumItemResponse, type AlbumItemType, type AppsInTossSignTossCertParams, type CheckoutPaymentOptions, type CheckoutPaymentResult, type CompletedOrRefundedOrdersResult, type ConsumableProductListItem, type ContactsViralParams, type CreateSubscriptionPurchaseOrderOptions, type EventLogParams, type FetchAlbumItemsOptions, type GameCenterGameProfileResponse, type GetAnonymousKeyResponse, type GetAnonymousKeySuccessResponse, type GetUserKeyForGameErrorResponse, type GetUserKeyForGameResponse, type GetUserKeyForGameSuccessResponse, GoogleAdMob, type GrantPromotionRewardErrorResponse, type GrantPromotionRewardErrorResult, type GrantPromotionRewardForGameErrorResponse, type GrantPromotionRewardForGameErrorResult, type GrantPromotionRewardForGameResponse, type GrantPromotionRewardForGameSuccessResponse, type GrantPromotionRewardResponse, type GrantPromotionRewardSuccessResponse, type HapticFeedbackType, IAP, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapCreateSubscriptionPurchaseOrderResult, type IapProductListItem, type IapSubscriptionInfoResult, type NetworkStatus, type NonConsumableProductListItem, type NotificationAgreementResult, type OpenPDFViewerParams, type OpenPDFViewerResult, type Primitive, type RequestNotificationAgreementOptions, type RequestTossPayPaysBillingOptions, type RequestTossPayPaysBillingResult, type SaveBase64DataParams, Storage, type SubmitGameCenterLeaderBoardScoreResponse, type SubscriptionProductListItem, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, appsInTossSignTossCert, checkoutPayment, closeView, contactsViral, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, grantPromotionReward, grantPromotionRewardForGame, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openURL, processProductGrant, requestNotificationAgreement, requestOneTimePurchase, requestReview, requestTossPayPaysBilling, safePostMessage, safeSyncPostMessage, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareWithScheme, startUpdateLocation, submitGameCenterLeaderBoardScore };
package/dist/index.d.ts CHANGED
@@ -112,6 +112,86 @@ declare function checkoutPayment(options: {
112
112
  params: CheckoutPaymentOptions;
113
113
  }): Promise<CheckoutPaymentResult>;
114
114
 
115
+ /**
116
+ * @public
117
+ * @category 앨범
118
+ * @name AlbumItemType
119
+ * @description 앨범에서 가져올 미디어 유형이에요.
120
+ */
121
+ type AlbumItemType = 'PHOTO' | 'VIDEO';
122
+ /**
123
+ * @public
124
+ * @category 앨범
125
+ * @name FetchAlbumItemsOptions
126
+ * @description 앨범에서 사진·동영상을 선택할 때 사용하는 옵션이에요.
127
+ * @property {Array<"PHOTO" | "VIDEO">} [types] - 가져올 미디어 유형 목록이에요. 지정하지 않으면 사진만 가져와요.
128
+ * @property {number} [maxCount] - 가져올 항목의 최대 개수예요. 기본값은 10이에요.
129
+ * @property {number} [maxWidth] - 이미지의 최대 폭이에요. 단위는 픽셀이에요. 기본값은 1024이에요.
130
+ * @property {boolean} [base64] - 이미지의 `dataUri`를 Base64 문자열로 반환할지 여부예요. 기본값은 `false`이에요.
131
+ */
132
+ interface FetchAlbumItemsOptions {
133
+ types?: AlbumItemType[];
134
+ maxCount?: number;
135
+ maxWidth?: number;
136
+ base64?: boolean;
137
+ }
138
+ /**
139
+ * @public
140
+ * @category 앨범
141
+ * @name AlbumItemResponse
142
+ * @description 앨범에서 선택한 미디어 항목이에요.
143
+ * @property {string} id - 항목의 고유 ID예요.
144
+ * @property {string} dataUri - 미디어 데이터 URI예요. `type`이 `PHOTO`면서 `base64` 옵션이 `true`이면 Base64 문자열로 반환돼요.
145
+ * @property {"PHOTO" | "VIDEO"} type - 미디어 유형이에요.
146
+ */
147
+ interface AlbumItemResponse {
148
+ id: string;
149
+ dataUri: string;
150
+ type: AlbumItemType;
151
+ }
152
+ /**
153
+ * @public
154
+ * @category 앨범
155
+ * @name fetchAlbumItems
156
+ * @description 사용자 앨범에서 사진·동영상을 선택해 가져와요. 사용자가 선택을 취소하면 빈 배열 `[]`을 반환해요.
157
+ *
158
+ * @param {FetchAlbumItemsOptions} [options] - 조회 옵션을 담은 객체예요.
159
+ * @returns {Promise<AlbumItemResponse[]>} 선택한 미디어 목록을 반환해요. 취소 시 빈 배열을 반환해요.
160
+ *
161
+ * @throws 다음 에러 코드가 발생할 수 있어요.
162
+ * - {code: `NOT_ALLOWED`}: 앨범 접근이 허용되지 않았을 때
163
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
164
+ * - {code: `INVALID_DATA`}: 미디어 데이터가 유효하지 않을 때
165
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * import { fetchAlbumItems, FetchAlbumItemsError } from '@apps-in-toss/framework';
170
+ *
171
+ * async function pickMedia() {
172
+ * try {
173
+ * const items = await fetchAlbumItems({
174
+ * types: ['PHOTO', 'VIDEO'],
175
+ * maxCount: 5,
176
+ * base64: true,
177
+ * });
178
+ *
179
+ * if (items.length === 0) {
180
+ * console.log('선택이 취소되었어요.');
181
+ * return;
182
+ * }
183
+ *
184
+ * items.forEach((item) => {
185
+ * console.log(item.type, item.id);
186
+ * });
187
+ * } catch (error) {
188
+ * console.error('앨범 조회 오류:', error.code);
189
+ * }
190
+ * }
191
+ * ```
192
+ */
193
+ declare function fetchAlbumItems(options?: FetchAlbumItemsOptions): Promise<AlbumItemResponse[]>;
194
+
115
195
  interface GetAnonymousKeySuccessResponse {
116
196
  hash: string;
117
197
  type: 'HASH';
@@ -902,6 +982,62 @@ declare const IAP: {
902
982
  getSubscriptionInfo: typeof getSubscriptionInfo;
903
983
  };
904
984
 
985
+ /**
986
+ * @public
987
+ * @category PDF
988
+ * @name OpenPDFViewerParams
989
+ * @description PDF 뷰어를 열 때 필요한 파라미터예요.
990
+ * @property {string} data - Base64 형식으로 인코딩된 PDF 데이터 문자열이에요.
991
+ * @property {string} [filename] - PDF 파일 이름이에요.
992
+ */
993
+ interface OpenPDFViewerParams {
994
+ data: string;
995
+ filename?: string;
996
+ }
997
+ /**
998
+ * @public
999
+ * @category PDF
1000
+ * @name OpenPDFViewerResult
1001
+ * @description PDF 뷰어가 닫혔을 때 반환되는 결과예요.
1002
+ */
1003
+ type OpenPDFViewerResult = 'CLOSE';
1004
+ /**
1005
+ * @public
1006
+ * @category PDF
1007
+ * @name openPDFViewer
1008
+ * @description Base64로 인코딩된 PDF 데이터를 네이티브 PDF 뷰어로 열어요. 사용자가 뷰어를 닫으면 `'CLOSE'`를 반환해요.
1009
+ *
1010
+ * @param {OpenPDFViewerParams} params - PDF 데이터와 파일 이름을 담은 객체예요.
1011
+ * @returns {Promise<OpenPDFViewerResult>} PDF 뷰어가 닫히면 `'CLOSE'`를 반환해요.
1012
+ *
1013
+ * @throws
1014
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
1015
+ * - {code: `INVALID_DATA`}: PDF 데이터가 유효하지 않을 때
1016
+ * - {code: `PDF_VIEWER_ERROR`}: PDF 뷰어를 여는 과정에서 오류가 발생했을 때
1017
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
1018
+ *
1019
+ * @example
1020
+ * ```tsx
1021
+ * import { openPDFViewer } from '@apps-in-toss/framework';
1022
+ *
1023
+ * async function showPdf() {
1024
+ * try {
1025
+ * const result = await openPDFViewer({
1026
+ * data: 'JVBERi0xLjQK...',
1027
+ * filename: 'document.pdf',
1028
+ * });
1029
+ *
1030
+ * if (result === 'CLOSE') {
1031
+ * console.log('PDF 뷰어가 닫혔어요.');
1032
+ * }
1033
+ * } catch (error) {
1034
+ * console.error('PDF 뷰어 오류:', error);
1035
+ * }
1036
+ * }
1037
+ * ```
1038
+ */
1039
+ declare function openPDFViewer(params: OpenPDFViewerParams): Promise<OpenPDFViewerResult>;
1040
+
905
1041
  /**
906
1042
  * @public
907
1043
  * @category 알림
@@ -1178,6 +1314,7 @@ interface AsyncMethodsMap {
1178
1314
  maxCount?: number;
1179
1315
  maxWidth?: number;
1180
1316
  }) => Promise<ImageResponse[]>;
1317
+ fetchAlbumItems: (params: FetchAlbumItemsOptions) => Promise<AlbumItemResponse[]>;
1181
1318
  openCamera: (params: {
1182
1319
  base64?: boolean;
1183
1320
  maxWidth?: number;
@@ -1237,6 +1374,7 @@ interface AsyncMethodsMap {
1237
1374
  type: 'portrait' | 'landscape';
1238
1375
  }) => Promise<void>;
1239
1376
  saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
1377
+ openPDFViewer: (params: OpenPDFViewerParams) => Promise<OpenPDFViewerResult>;
1240
1378
  appsInTossSignTossCert: (params: AppsInTossSignTossCertParams) => Promise<void>;
1241
1379
  getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse | undefined>;
1242
1380
  getUserKeyForGame: (params: CompatiblePlaceholderArgument) => Promise<GetUserKeyForGameResponse | undefined>;
@@ -3450,4 +3588,4 @@ declare const INTERNAL__module: {
3450
3588
  tossCoreEventLog: typeof tossCoreEventLog;
3451
3589
  };
3452
3590
 
3453
- export { type AppsInTossSignTossCertParams, type CheckoutPaymentOptions, type CheckoutPaymentResult, type CompletedOrRefundedOrdersResult, type ConsumableProductListItem, type ContactsViralParams, type CreateSubscriptionPurchaseOrderOptions, type EventLogParams, type GameCenterGameProfileResponse, type GetAnonymousKeyResponse, type GetAnonymousKeySuccessResponse, type GetUserKeyForGameErrorResponse, type GetUserKeyForGameResponse, type GetUserKeyForGameSuccessResponse, GoogleAdMob, type GrantPromotionRewardErrorResponse, type GrantPromotionRewardErrorResult, type GrantPromotionRewardForGameErrorResponse, type GrantPromotionRewardForGameErrorResult, type GrantPromotionRewardForGameResponse, type GrantPromotionRewardForGameSuccessResponse, type GrantPromotionRewardResponse, type GrantPromotionRewardSuccessResponse, type HapticFeedbackType, IAP, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapCreateSubscriptionPurchaseOrderResult, type IapProductListItem, type IapSubscriptionInfoResult, type NetworkStatus, type NonConsumableProductListItem, type NotificationAgreementResult, type Primitive, type RequestNotificationAgreementOptions, type RequestTossPayPaysBillingOptions, type RequestTossPayPaysBillingResult, type SaveBase64DataParams, Storage, type SubmitGameCenterLeaderBoardScoreResponse, type SubscriptionProductListItem, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, appsInTossSignTossCert, checkoutPayment, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, grantPromotionReward, grantPromotionRewardForGame, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, processProductGrant, requestNotificationAgreement, requestOneTimePurchase, requestReview, requestTossPayPaysBilling, safePostMessage, safeSyncPostMessage, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareWithScheme, startUpdateLocation, submitGameCenterLeaderBoardScore };
3591
+ export { type AlbumItemResponse, type AlbumItemType, type AppsInTossSignTossCertParams, type CheckoutPaymentOptions, type CheckoutPaymentResult, type CompletedOrRefundedOrdersResult, type ConsumableProductListItem, type ContactsViralParams, type CreateSubscriptionPurchaseOrderOptions, type EventLogParams, type FetchAlbumItemsOptions, type GameCenterGameProfileResponse, type GetAnonymousKeyResponse, type GetAnonymousKeySuccessResponse, type GetUserKeyForGameErrorResponse, type GetUserKeyForGameResponse, type GetUserKeyForGameSuccessResponse, GoogleAdMob, type GrantPromotionRewardErrorResponse, type GrantPromotionRewardErrorResult, type GrantPromotionRewardForGameErrorResponse, type GrantPromotionRewardForGameErrorResult, type GrantPromotionRewardForGameResponse, type GrantPromotionRewardForGameSuccessResponse, type GrantPromotionRewardResponse, type GrantPromotionRewardSuccessResponse, type HapticFeedbackType, IAP, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapCreateSubscriptionPurchaseOrderResult, type IapProductListItem, type IapSubscriptionInfoResult, type NetworkStatus, type NonConsumableProductListItem, type NotificationAgreementResult, type OpenPDFViewerParams, type OpenPDFViewerResult, type Primitive, type RequestNotificationAgreementOptions, type RequestTossPayPaysBillingOptions, type RequestTossPayPaysBillingResult, type SaveBase64DataParams, Storage, type SubmitGameCenterLeaderBoardScoreResponse, type SubscriptionProductListItem, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, appsInTossSignTossCert, checkoutPayment, closeView, contactsViral, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, grantPromotionReward, grantPromotionRewardForGame, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openURL, processProductGrant, requestNotificationAgreement, requestOneTimePurchase, requestReview, requestTossPayPaysBilling, safePostMessage, safeSyncPostMessage, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareWithScheme, startUpdateLocation, submitGameCenterLeaderBoardScore };
package/dist/index.js CHANGED
@@ -779,6 +779,34 @@ async function saveBase64Data(params) {
779
779
  await safePostMessage("saveBase64Data", params);
780
780
  }
781
781
 
782
+ // src/MiniAppModule/native-modules/openPDFViewer.ts
783
+ async function openPDFViewer(params) {
784
+ const isSupported = isMinVersionSupported({
785
+ android: "5.261.0",
786
+ ios: "5.261.0"
787
+ });
788
+ if (!isSupported) {
789
+ const error = new Error("\uD1A0\uC2A4\uC571 5.261.0 \uBC84\uC804 \uC774\uC0C1\uC774 \uD544\uC694\uD574\uC694.");
790
+ error.code = "UNSUPPORTED_APP_VERSION";
791
+ throw error;
792
+ }
793
+ return safePostMessage("openPDFViewer", params);
794
+ }
795
+
796
+ // src/MiniAppModule/native-modules/fetchAlbumItems.ts
797
+ async function fetchAlbumItems(options) {
798
+ const isSupported = isMinVersionSupported({
799
+ android: "5.261.0",
800
+ ios: "5.261.0"
801
+ });
802
+ if (!isSupported) {
803
+ const error = new Error("\uD1A0\uC2A4\uC571 5.261.0 \uBC84\uC804 \uC774\uC0C1\uC774 \uD544\uC694\uD574\uC694.");
804
+ error.code = "UNSUPPORTED_APP_VERSION";
805
+ throw error;
806
+ }
807
+ return safePostMessage("fetchAlbumItems", options ?? {});
808
+ }
809
+
782
810
  // src/MiniAppModule/native-modules/setDeviceOrientation.ts
783
811
  async function setDeviceOrientation(options) {
784
812
  const isSupported = isMinVersionSupported({
@@ -1157,6 +1185,7 @@ export {
1157
1185
  closeView,
1158
1186
  contactsViral,
1159
1187
  eventLog,
1188
+ fetchAlbumItems,
1160
1189
  fetchAlbumPhotos,
1161
1190
  fetchContacts,
1162
1191
  generateHapticFeedback,
@@ -1183,6 +1212,7 @@ export {
1183
1212
  onVisibilityChangedByTransparentServiceWeb,
1184
1213
  openCamera,
1185
1214
  openGameCenterLeaderboard,
1215
+ openPDFViewer,
1186
1216
  openURL2 as openURL,
1187
1217
  processProductGrant,
1188
1218
  requestNotificationAgreement,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@apps-in-toss/native-modules",
3
3
  "type": "module",
4
- "version": "2.5.1",
4
+ "version": "2.6.0",
5
5
  "description": "Native Modules for Apps In Toss",
6
6
  "scripts": {
7
7
  "typecheck": "tsc --noEmit",
@@ -42,7 +42,7 @@
42
42
  "vitest": "^3.2.4"
43
43
  },
44
44
  "dependencies": {
45
- "@apps-in-toss/types": "2.5.1",
45
+ "@apps-in-toss/types": "2.6.0",
46
46
  "brick-module": "0.5.2",
47
47
  "es-toolkit": "^1.39.3"
48
48
  },
@@ -0,0 +1,98 @@
1
+ import { isMinVersionSupported } from './isMinVersionSupported';
2
+ import { safePostMessage } from '../../natives';
3
+
4
+ /**
5
+ * @public
6
+ * @category 앨범
7
+ * @name AlbumItemType
8
+ * @description 앨범에서 가져올 미디어 유형이에요.
9
+ */
10
+ export type AlbumItemType = 'PHOTO' | 'VIDEO';
11
+
12
+ /**
13
+ * @public
14
+ * @category 앨범
15
+ * @name FetchAlbumItemsOptions
16
+ * @description 앨범에서 사진·동영상을 선택할 때 사용하는 옵션이에요.
17
+ * @property {Array<"PHOTO" | "VIDEO">} [types] - 가져올 미디어 유형 목록이에요. 지정하지 않으면 사진만 가져와요.
18
+ * @property {number} [maxCount] - 가져올 항목의 최대 개수예요. 기본값은 10이에요.
19
+ * @property {number} [maxWidth] - 이미지의 최대 폭이에요. 단위는 픽셀이에요. 기본값은 1024이에요.
20
+ * @property {boolean} [base64] - 이미지의 `dataUri`를 Base64 문자열로 반환할지 여부예요. 기본값은 `false`이에요.
21
+ */
22
+ export interface FetchAlbumItemsOptions {
23
+ types?: AlbumItemType[];
24
+ maxCount?: number;
25
+ maxWidth?: number;
26
+ base64?: boolean;
27
+ }
28
+
29
+ /**
30
+ * @public
31
+ * @category 앨범
32
+ * @name AlbumItemResponse
33
+ * @description 앨범에서 선택한 미디어 항목이에요.
34
+ * @property {string} id - 항목의 고유 ID예요.
35
+ * @property {string} dataUri - 미디어 데이터 URI예요. `type`이 `PHOTO`면서 `base64` 옵션이 `true`이면 Base64 문자열로 반환돼요.
36
+ * @property {"PHOTO" | "VIDEO"} type - 미디어 유형이에요.
37
+ */
38
+ export interface AlbumItemResponse {
39
+ id: string;
40
+ dataUri: string;
41
+ type: AlbumItemType;
42
+ }
43
+
44
+ /**
45
+ * @public
46
+ * @category 앨범
47
+ * @name fetchAlbumItems
48
+ * @description 사용자 앨범에서 사진·동영상을 선택해 가져와요. 사용자가 선택을 취소하면 빈 배열 `[]`을 반환해요.
49
+ *
50
+ * @param {FetchAlbumItemsOptions} [options] - 조회 옵션을 담은 객체예요.
51
+ * @returns {Promise<AlbumItemResponse[]>} 선택한 미디어 목록을 반환해요. 취소 시 빈 배열을 반환해요.
52
+ *
53
+ * @throws 다음 에러 코드가 발생할 수 있어요.
54
+ * - {code: `NOT_ALLOWED`}: 앨범 접근이 허용되지 않았을 때
55
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
56
+ * - {code: `INVALID_DATA`}: 미디어 데이터가 유효하지 않을 때
57
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * import { fetchAlbumItems, FetchAlbumItemsError } from '@apps-in-toss/framework';
62
+ *
63
+ * async function pickMedia() {
64
+ * try {
65
+ * const items = await fetchAlbumItems({
66
+ * types: ['PHOTO', 'VIDEO'],
67
+ * maxCount: 5,
68
+ * base64: true,
69
+ * });
70
+ *
71
+ * if (items.length === 0) {
72
+ * console.log('선택이 취소되었어요.');
73
+ * return;
74
+ * }
75
+ *
76
+ * items.forEach((item) => {
77
+ * console.log(item.type, item.id);
78
+ * });
79
+ * } catch (error) {
80
+ * console.error('앨범 조회 오류:', error.code);
81
+ * }
82
+ * }
83
+ * ```
84
+ */
85
+ export async function fetchAlbumItems(options?: FetchAlbumItemsOptions): Promise<AlbumItemResponse[]> {
86
+ const isSupported = isMinVersionSupported({
87
+ android: '5.261.0',
88
+ ios: '5.261.0',
89
+ });
90
+
91
+ if (!isSupported) {
92
+ const error = new Error('토스앱 5.261.0 버전 이상이 필요해요.');
93
+ (error as any).code = 'UNSUPPORTED_APP_VERSION';
94
+ throw error;
95
+ }
96
+
97
+ return safePostMessage('fetchAlbumItems', options ?? {});
98
+ }
@@ -37,6 +37,8 @@ export * from './getTossShareLink';
37
37
  export * from './iap';
38
38
  export * from './isMinVersionSupported';
39
39
  export * from './saveBase64Data';
40
+ export * from './openPDFViewer';
41
+ export * from './fetchAlbumItems';
40
42
  export * from './setDeviceOrientation';
41
43
  export * from './storage';
42
44
  export * from './openGameCenterLeaderboard';
@@ -0,0 +1,73 @@
1
+ import { isMinVersionSupported } from './isMinVersionSupported';
2
+ import { safePostMessage } from '../../natives';
3
+
4
+ /**
5
+ * @public
6
+ * @category PDF
7
+ * @name OpenPDFViewerParams
8
+ * @description PDF 뷰어를 열 때 필요한 파라미터예요.
9
+ * @property {string} data - Base64 형식으로 인코딩된 PDF 데이터 문자열이에요.
10
+ * @property {string} [filename] - PDF 파일 이름이에요.
11
+ */
12
+ export interface OpenPDFViewerParams {
13
+ data: string;
14
+ filename?: string;
15
+ }
16
+
17
+ /**
18
+ * @public
19
+ * @category PDF
20
+ * @name OpenPDFViewerResult
21
+ * @description PDF 뷰어가 닫혔을 때 반환되는 결과예요.
22
+ */
23
+ export type OpenPDFViewerResult = 'CLOSE';
24
+
25
+ /**
26
+ * @public
27
+ * @category PDF
28
+ * @name openPDFViewer
29
+ * @description Base64로 인코딩된 PDF 데이터를 네이티브 PDF 뷰어로 열어요. 사용자가 뷰어를 닫으면 `'CLOSE'`를 반환해요.
30
+ *
31
+ * @param {OpenPDFViewerParams} params - PDF 데이터와 파일 이름을 담은 객체예요.
32
+ * @returns {Promise<OpenPDFViewerResult>} PDF 뷰어가 닫히면 `'CLOSE'`를 반환해요.
33
+ *
34
+ * @throws
35
+ * - {code: `INVALID_REQUEST`}: 요청 파라미터가 올바르지 않을 때
36
+ * - {code: `INVALID_DATA`}: PDF 데이터가 유효하지 않을 때
37
+ * - {code: `PDF_VIEWER_ERROR`}: PDF 뷰어를 여는 과정에서 오류가 발생했을 때
38
+ * - {code: `UNSUPPORTED_APP_VERSION`}: 토스앱 버전이 5.261.0보다 낮을 때
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * import { openPDFViewer } from '@apps-in-toss/framework';
43
+ *
44
+ * async function showPdf() {
45
+ * try {
46
+ * const result = await openPDFViewer({
47
+ * data: 'JVBERi0xLjQK...',
48
+ * filename: 'document.pdf',
49
+ * });
50
+ *
51
+ * if (result === 'CLOSE') {
52
+ * console.log('PDF 뷰어가 닫혔어요.');
53
+ * }
54
+ * } catch (error) {
55
+ * console.error('PDF 뷰어 오류:', error);
56
+ * }
57
+ * }
58
+ * ```
59
+ */
60
+ export async function openPDFViewer(params: OpenPDFViewerParams): Promise<OpenPDFViewerResult> {
61
+ const isSupported = isMinVersionSupported({
62
+ android: '5.261.0',
63
+ ios: '5.261.0',
64
+ });
65
+
66
+ if (!isSupported) {
67
+ const error = new Error('토스앱 5.261.0 버전 이상이 필요해요.');
68
+ (error as any).code = 'UNSUPPORTED_APP_VERSION';
69
+ throw error;
70
+ }
71
+
72
+ return safePostMessage('openPDFViewer', params);
73
+ }
@@ -9,11 +9,13 @@ import type {
9
9
  } from '@apps-in-toss/types';
10
10
  import type { AppsInTossSignTossCertParams } from './native-modules/appsInTossSignTossCert';
11
11
  import type { CheckoutPaymentOptions, CheckoutPaymentResult } from './native-modules/checkoutPayment';
12
+ import type { AlbumItemResponse, FetchAlbumItemsOptions } from './native-modules/fetchAlbumItems';
12
13
  import type { GetAnonymousKeyResponse } from './native-modules/getAnonymousKey';
13
14
  import type { GameCenterGameProfileResponse } from './native-modules/getGameCenterGameProfile';
14
15
  import type { GetUserKeyForGameResponse } from './native-modules/getUserKeyForGame';
15
16
  import type { GrantPromotionRewardForGameResponse } from './native-modules/grantPromotionRewardForGame';
16
17
  import type { IapCreateOneTimePurchaseOrderResult, IapSubscriptionInfoResult } from './native-modules/iap';
18
+ import type { OpenPDFViewerParams, OpenPDFViewerResult } from './native-modules/openPDFViewer';
17
19
  import type { RequestNotificationAgreementOptions } from './native-modules/requestNotificationAgreement';
18
20
  import type {
19
21
  RequestTossPayPaysBillingOptions,
@@ -45,6 +47,7 @@ export interface AsyncMethodsMap {
45
47
  // Contacts & Photos (3)
46
48
  fetchContacts: (params: { size: number; offset: number; query?: { contains?: string } }) => Promise<ContactResult>;
47
49
  fetchAlbumPhotos: (params: { base64?: boolean; maxCount?: number; maxWidth?: number }) => Promise<ImageResponse[]>;
50
+ fetchAlbumItems: (params: FetchAlbumItemsOptions) => Promise<AlbumItemResponse[]>;
48
51
  openCamera: (params: { base64?: boolean; maxWidth?: number }) => Promise<ImageResponse>;
49
52
 
50
53
  // Location (1)
@@ -74,6 +77,7 @@ export interface AsyncMethodsMap {
74
77
  requestTossPayPaysBilling: (params: RequestTossPayPaysBillingOptions) => Promise<RequestTossPayPaysBillingResult>;
75
78
  setDeviceOrientation: (params: { type: 'portrait' | 'landscape' }) => Promise<void>;
76
79
  saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
80
+ openPDFViewer: (params: OpenPDFViewerParams) => Promise<OpenPDFViewerResult>;
77
81
  appsInTossSignTossCert: (params: AppsInTossSignTossCertParams) => Promise<void>;
78
82
  getGameCenterGameProfile: (
79
83
  params: CompatiblePlaceholderArgument
@@ -25,6 +25,8 @@ export * from './MiniAppModule/native-modules/setDeviceOrientation';
25
25
  export * from './MiniAppModule/native-modules/checkoutPayment';
26
26
  export * from './MiniAppModule/native-modules/requestTossPayPaysBilling';
27
27
  export * from './MiniAppModule/native-modules/saveBase64Data';
28
+ export * from './MiniAppModule/native-modules/openPDFViewer';
29
+ export * from './MiniAppModule/native-modules/fetchAlbumItems';
28
30
  export * from './MiniAppModule/native-modules/appsInTossSignTossCert';
29
31
  export * from './MiniAppModule/native-modules/getGameCenterGameProfile';
30
32
  export * from './MiniAppModule/native-modules/openGameCenterLeaderboard';