@react-native-kakao/user 3.0.0 → 3.1.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import { is } from '@mj-studio/js-util';
2
2
  import { kAssert } from '@react-native-kakao/core';
3
3
 
4
4
  import Native from './spec/NativeKakaoUser';
5
+ import { validateShippingAddressOptions } from './validateShippingAddressOptions';
5
6
 
6
7
  export interface KakaoLoginToken {
7
8
  accessToken: string;
@@ -14,6 +15,16 @@ export interface KakaoLoginToken {
14
15
  refreshTokenExpiresIn: number;
15
16
  scopes: string[];
16
17
  }
18
+ export type KakaoCodeTokenOptions = {
19
+ code: string;
20
+ codeVerifier?: string;
21
+ redirectUri?: string;
22
+ web?: { clientSecret?: string };
23
+ };
24
+
25
+ const minActivityRequestCode = -2147483648;
26
+ const maxActivityRequestCode = 2147483647;
27
+
17
28
  export interface KakaoScopeInfo {
18
29
  id: string;
19
30
  agreed: boolean;
@@ -30,6 +41,10 @@ export interface KakaoServiceTerms {
30
41
  required: boolean;
31
42
  revocable: boolean;
32
43
  }
44
+ export type KakaoRevokedServiceTerms = {
45
+ tag: string;
46
+ agreed: boolean;
47
+ };
33
48
  export interface KakaoAppServiceTerms {
34
49
  tag: string;
35
50
  createdAt: number;
@@ -56,15 +71,20 @@ export interface KakaoShippingAddress {
56
71
  }
57
72
  export interface KakaoUser {
58
73
  id: number;
74
+ hasSignedUp?: boolean | null;
75
+ uuid?: string | null;
76
+ groupUserToken?: string | null;
59
77
  email: string;
60
78
  name?: string | null;
61
79
  nickname: string;
62
80
  profileImageUrl: string;
63
81
  thumbnailImageUrl: string;
82
+ isDefaultImage?: boolean | null;
64
83
  phoneNumber?: string | null;
65
84
  ageRange?: string | null;
66
85
  birthday?: string | null;
67
86
  birthdayType?: string | null;
87
+ isLeapMonth?: boolean | null;
68
88
  birthyear?: string | null;
69
89
  gender?: string | null;
70
90
  isEmailValid: boolean;
@@ -81,7 +101,12 @@ export interface KakaoUser {
81
101
  nameNeedsAgreement?: boolean;
82
102
  profileImageNeedsAgreement?: boolean;
83
103
  profileNicknameNeedsAgreement?: boolean;
104
+ legalName?: string | null;
105
+ legalNameNeedsAgreement?: boolean | null;
106
+ legalBirthDate?: string | null;
84
107
  legalBirthDateNeedsAgreement?: boolean;
108
+ legalGender?: 'female' | 'male' | null;
109
+ legalGenderNeedsAgreement?: boolean | null;
85
110
  connectedAt?: number;
86
111
  synchedAt?: number;
87
112
  }
@@ -96,12 +121,18 @@ export function login({
96
121
  useKakaoAccountLogin,
97
122
  scopes,
98
123
  nonce,
124
+ loginHint,
125
+ channelPublicIds,
126
+ android,
99
127
  }: {
100
128
  serviceTerms?: string[];
101
129
  prompts?: ('Login' | 'Create' | 'Cert' | 'SelectAccount')[];
102
130
  scopes?: string[];
103
131
  useKakaoAccountLogin?: boolean;
104
132
  nonce?: string;
133
+ loginHint?: string;
134
+ channelPublicIds?: string[];
135
+ android?: { requestCode?: number };
105
136
  web?: {
106
137
  redirectUri: string;
107
138
  scope?: string[];
@@ -113,14 +144,35 @@ export function login({
113
144
  nonce?: string;
114
145
  };
115
146
  } = {}): Promise<KakaoLoginToken> {
147
+ const requestCode = android?.requestCode;
148
+ kAssert(
149
+ requestCode == null ||
150
+ (Number.isInteger(requestCode) &&
151
+ requestCode >= minActivityRequestCode &&
152
+ requestCode <= maxActivityRequestCode),
153
+ `[login] android.requestCode must be an integer from ${minActivityRequestCode} to ${maxActivityRequestCode}`,
154
+ );
155
+
116
156
  kAssert(
117
157
  !useKakaoAccountLogin ? !is.notEmptyArray(prompts) && !is.notEmptyArray(scopes) : true,
118
158
  '[login] `prompts` and `scopes` cannot be passed if useKakaoAccountLogin is false.',
119
159
  );
120
160
 
121
161
  kAssert(
122
- is.notEmptyArray(scopes) ? !is.notEmptyArray(prompts) && !is.notEmptyArray(serviceTerms) : true,
123
- '[login] `scopes` cannot be passed with `prompts` or `serviceTerms`',
162
+ is.notEmptyArray(scopes)
163
+ ? !is.notEmptyArray(prompts) &&
164
+ !is.notEmptyArray(serviceTerms) &&
165
+ !is.notEmptyArray(channelPublicIds)
166
+ : true,
167
+ '[login] `scopes` cannot be passed with `prompts`, `serviceTerms`, or `channelPublicIds`',
168
+ );
169
+
170
+ kAssert(
171
+ loginHint == null ||
172
+ (!is.notEmptyArray(scopes) &&
173
+ !is.notEmptyArray(serviceTerms) &&
174
+ !is.notEmptyArray(channelPublicIds)),
175
+ '[login] `loginHint` cannot be passed with `scopes`, `serviceTerms`, or `channelPublicIds` on native platforms.',
124
176
  );
125
177
 
126
178
  return Native.login(
@@ -129,7 +181,87 @@ export function login({
129
181
  useKakaoAccountLogin ?? false,
130
182
  scopes ?? [],
131
183
  nonce,
184
+ loginHint,
185
+ channelPublicIds ?? [],
186
+ requestCode,
187
+ );
188
+ }
189
+
190
+ export async function signup({ properties }: { properties?: Record<string, string> } = {}) {
191
+ await Native.signup(properties);
192
+ }
193
+
194
+ export function loginWithKakao({
195
+ uiMode = 'auto',
196
+ prompts,
197
+ loginHint,
198
+ nonce,
199
+ channelPublicIds,
200
+ serviceTerms,
201
+ ios,
202
+ }: {
203
+ uiMode?: 'auto' | 'light' | 'dark';
204
+ prompts?: ('Login' | 'Create' | 'Cert' | 'SelectAccount')[];
205
+ loginHint?: string;
206
+ nonce?: string;
207
+ channelPublicIds?: string[];
208
+ serviceTerms?: string[];
209
+ ios?: {
210
+ orientation?: 'auto' | 'portrait' | 'landscape';
211
+ launchMethod?: 'UniversalLink' | 'CustomScheme';
212
+ };
213
+ } = {}): Promise<KakaoLoginToken> {
214
+ return Native.loginWithKakao(
215
+ uiMode,
216
+ ios?.orientation ?? 'auto',
217
+ ios?.launchMethod ?? 'UniversalLink',
218
+ prompts ?? [],
219
+ loginHint,
220
+ nonce,
221
+ channelPublicIds ?? [],
222
+ serviceTerms ?? [],
223
+ );
224
+ }
225
+
226
+ export function refreshToken({
227
+ token,
228
+ ios,
229
+ }: {
230
+ token?: KakaoLoginToken;
231
+ ios?: { loggingEnabled?: boolean };
232
+ } = {}): Promise<KakaoLoginToken> {
233
+ kAssert(
234
+ ios?.loggingEnabled == null || typeof ios.loggingEnabled === 'boolean',
235
+ '[refreshToken] ios.loggingEnabled must be a boolean',
132
236
  );
237
+
238
+ if (token !== undefined) {
239
+ kAssert(
240
+ token != null &&
241
+ is.string(token.accessToken) &&
242
+ token.accessToken.length > 0 &&
243
+ is.string(token.refreshToken) &&
244
+ token.refreshToken.length > 0,
245
+ '[refreshToken] token must contain non-empty accessToken and refreshToken strings',
246
+ );
247
+
248
+ kAssert(
249
+ [token.accessTokenExpiresAt, token.refreshTokenExpiresAt].every(
250
+ (value) => Number.isFinite(value) && !Number.isNaN(new Date(value * 1000).getTime()),
251
+ ) && [token.accessTokenExpiresIn, token.refreshTokenExpiresIn].every(Number.isFinite),
252
+ '[refreshToken] token expiry timestamps must be valid Unix seconds and lifetimes must be finite',
253
+ );
254
+
255
+ kAssert(
256
+ (token.tokenType == null || is.string(token.tokenType)) &&
257
+ (token.idToken == null || is.string(token.idToken)) &&
258
+ Array.isArray(token.scopes) &&
259
+ token.scopes.every((scope) => is.string(scope)),
260
+ '[refreshToken] tokenType and idToken must be strings when present, and scopes must be strings',
261
+ );
262
+ }
263
+
264
+ return Native.refreshToken(token, ios?.loggingEnabled ?? true);
133
265
  }
134
266
 
135
267
  export function logout() {
@@ -144,6 +276,8 @@ export function isLogined() {
144
276
  return Native.isLogined();
145
277
  }
146
278
 
279
+ export const hasToken = Native.hasToken;
280
+
147
281
  export function isKakaoTalkLoginAvailable(): Promise<boolean> {
148
282
  return Native.isKakaoTalkLoginAvailable();
149
283
  }
@@ -156,22 +290,66 @@ export function revokeScopes(scopes: string[]): Promise<void> {
156
290
  return Native.revokeScopes(scopes);
157
291
  }
158
292
 
159
- export function serviceTerms(): Promise<KakaoServiceTerms[]> {
160
- return Native.serviceTerms();
293
+ export function serviceTerms({
294
+ result,
295
+ tags,
296
+ }: {
297
+ result?: 'agreed_service_terms' | 'app_service_terms';
298
+ tags?: string[];
299
+ } = {}): Promise<KakaoServiceTerms[]> {
300
+ return Native.serviceTerms(result, tags);
301
+ }
302
+
303
+ export async function shippingAddresses({
304
+ addressId,
305
+ fromUpdatedAt,
306
+ pageSize,
307
+ }: {
308
+ addressId?: number;
309
+ fromUpdatedAt?: number;
310
+ pageSize?: number;
311
+ } = {}): Promise<KakaoShippingAddressResult> {
312
+ validateShippingAddressOptions({ addressId, fromUpdatedAt, pageSize });
313
+
314
+ return Native.shippingAddresses(addressId, fromUpdatedAt, pageSize);
315
+ }
316
+
317
+ export function revokeServiceTerms(tags: string[]): Promise<KakaoRevokedServiceTerms[]> {
318
+ return Native.revokeServiceTerms(tags);
161
319
  }
162
320
 
163
- export function shippingAddresses(): Promise<KakaoShippingAddressResult> {
164
- return Native.shippingAddresses();
321
+ export function selectShippingAddress(): Promise<number> {
322
+ return Native.selectShippingAddress();
165
323
  }
166
324
 
167
- export function me(): Promise<KakaoUser> {
168
- return Native.me();
325
+ export function me({
326
+ secureResource = true,
327
+ }: { secureResource?: boolean } = {}): Promise<KakaoUser> {
328
+ return Native.me(secureResource);
329
+ }
330
+
331
+ export async function issueAccessTokenWithCode({
332
+ code,
333
+ codeVerifier,
334
+ redirectUri,
335
+ }: KakaoCodeTokenOptions): Promise<KakaoLoginToken> {
336
+ kAssert(is.string(code) && code.length > 0, '[issueAccessTokenWithCode] code is required');
337
+
338
+ return Native.issueAccessTokenWithCode(code, codeVerifier, redirectUri);
169
339
  }
170
340
 
171
341
  export function getAccessToken(): Promise<KakaoAccessTokenInfo> {
172
342
  return Native.getAccessToken();
173
343
  }
174
344
 
345
+ export function updateProfile({
346
+ properties,
347
+ }: {
348
+ properties: Record<string, string>;
349
+ }): Promise<void> {
350
+ return Native.updateProfile(properties);
351
+ }
352
+
175
353
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
176
354
  export function setAccessTokenWeb(token: string) {}
177
355
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -179,6 +357,7 @@ export async function issueAccessTokenWithCodeWeb(params: {
179
357
  redirectUri: string;
180
358
  clientSecret?: string;
181
359
  code: string;
360
+ codeVerifier?: string;
182
361
  }): Promise<{
183
362
  tokenType: string;
184
363
  accessToken: string;
@@ -193,15 +372,23 @@ export async function issueAccessTokenWithCodeWeb(params: {
193
372
 
194
373
  const KakaoUser = {
195
374
  login,
375
+ loginWithKakao,
376
+ refreshToken,
377
+ issueAccessTokenWithCode,
378
+ signup,
196
379
  logout,
197
380
  unlink,
198
381
  isLogined,
382
+ hasToken,
199
383
  isKakaoTalkLoginAvailable,
200
384
  scopes,
201
385
  revokeScopes,
202
386
  serviceTerms,
387
+ revokeServiceTerms,
203
388
  shippingAddresses,
389
+ selectShippingAddress,
204
390
  me,
391
+ updateProfile,
205
392
  getAccessToken,
206
393
  setAccessTokenWeb,
207
394
  issueAccessTokenWithCodeWeb,