@sendoracloud/sdk-react-native 0.8.0 → 0.9.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.
- package/dist/index.cjs +124 -0
- package/dist/index.d.cts +43 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +124 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -355,6 +355,59 @@ var Auth = class {
|
|
|
355
355
|
return parsed.data.user;
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Verify an IdP-issued credential (authorization code OR id_token)
|
|
360
|
+
* and mint a Sendora session. Customer's app handles the IdP
|
|
361
|
+
* dance — typically via expo-auth-session / react-native-app-auth
|
|
362
|
+
* — then hands the result here. See web SDK for full provider
|
|
363
|
+
* matrix; mirrors that surface 1:1.
|
|
364
|
+
*/
|
|
365
|
+
loginSocial(input) {
|
|
366
|
+
return this.serialize(async () => {
|
|
367
|
+
if (this.user !== null) await this.wipeLocalIdentity();
|
|
368
|
+
const res = await post(
|
|
369
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
370
|
+
"/api/v1/auth-service/login/social",
|
|
371
|
+
input
|
|
372
|
+
);
|
|
373
|
+
if (!res) throw new AuthError("NETWORK_ERROR", "Network request failed");
|
|
374
|
+
let parsed;
|
|
375
|
+
try {
|
|
376
|
+
parsed = await res.json();
|
|
377
|
+
} catch {
|
|
378
|
+
throw new AuthError("PARSE_ERROR", `HTTP ${res.status}`);
|
|
379
|
+
}
|
|
380
|
+
if (!res.ok || !parsed.success || !isAuthApiResponse(parsed.data)) {
|
|
381
|
+
throw new AuthError(
|
|
382
|
+
parsed.error?.code ?? "SOCIAL_LOGIN_FAILED",
|
|
383
|
+
parsed.error?.message ?? "Social login failed"
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
this.persist(parsed.data);
|
|
387
|
+
return parsed.data.user;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
signInWithGoogle(code, redirectUri) {
|
|
391
|
+
return this.loginSocial({ provider: "google", code, redirectUri });
|
|
392
|
+
}
|
|
393
|
+
signInWithGitHub(code, redirectUri) {
|
|
394
|
+
return this.loginSocial({ provider: "github", code, redirectUri });
|
|
395
|
+
}
|
|
396
|
+
signInWithApple(input) {
|
|
397
|
+
return this.loginSocial({ provider: "apple", ...input });
|
|
398
|
+
}
|
|
399
|
+
signInWithMicrosoft(code, redirectUri) {
|
|
400
|
+
return this.loginSocial({ provider: "microsoft", code, redirectUri });
|
|
401
|
+
}
|
|
402
|
+
signInWithLinkedIn(code, redirectUri) {
|
|
403
|
+
return this.loginSocial({ provider: "linkedin", code, redirectUri });
|
|
404
|
+
}
|
|
405
|
+
signInWithFacebook(code, redirectUri) {
|
|
406
|
+
return this.loginSocial({ provider: "facebook", code, redirectUri });
|
|
407
|
+
}
|
|
408
|
+
signInWithDiscord(code, redirectUri) {
|
|
409
|
+
return this.loginSocial({ provider: "discord", code, redirectUri });
|
|
410
|
+
}
|
|
358
411
|
/**
|
|
359
412
|
* Exchange the MFA challenge token from `signIn` for a real session
|
|
360
413
|
* by submitting a TOTP or recovery code from the user's authenticator.
|
|
@@ -391,6 +444,77 @@ var Auth = class {
|
|
|
391
444
|
});
|
|
392
445
|
}
|
|
393
446
|
// ============================================================
|
|
447
|
+
// EMAIL OTP (6-digit cross-device code)
|
|
448
|
+
// ============================================================
|
|
449
|
+
async sendEmailOtp(email) {
|
|
450
|
+
const res = await post(
|
|
451
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
452
|
+
"/api/v1/auth-service/email-otp/request",
|
|
453
|
+
{ email }
|
|
454
|
+
);
|
|
455
|
+
if (!res || !res.ok) {
|
|
456
|
+
throw new AuthError("EMAIL_OTP_REQUEST_FAILED", "Failed to send code");
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
verifyEmailOtp(email, code) {
|
|
460
|
+
return this.serialize(async () => {
|
|
461
|
+
if (this.user !== null) await this.wipeLocalIdentity();
|
|
462
|
+
const data = await this.callAuth("/api/v1/auth-service/email-otp/verify", { email, code });
|
|
463
|
+
this.persist(data);
|
|
464
|
+
return data.user;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
// ============================================================
|
|
468
|
+
// PASSWORD RESET + EMAIL VERIFICATION
|
|
469
|
+
// ============================================================
|
|
470
|
+
/** Trigger password-reset email. Resolves on 204 even when address is unknown (anti-enumeration). */
|
|
471
|
+
async requestPasswordReset(email) {
|
|
472
|
+
const res = await post(
|
|
473
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
474
|
+
"/api/v1/auth-service/password/forgot",
|
|
475
|
+
{ email }
|
|
476
|
+
);
|
|
477
|
+
if (!res || !res.ok) {
|
|
478
|
+
throw new AuthError("PASSWORD_RESET_REQUEST_FAILED", "Failed to send reset email");
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/** Pair the reset-email token with the new password to complete the reset. */
|
|
482
|
+
async resetPassword(token, newPassword) {
|
|
483
|
+
const res = await post(
|
|
484
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
485
|
+
"/api/v1/auth-service/password/reset",
|
|
486
|
+
{ token, newPassword }
|
|
487
|
+
);
|
|
488
|
+
if (!res || !res.ok) {
|
|
489
|
+
throw new AuthError("PASSWORD_RESET_FAILED", "Reset failed");
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/** Verify the email-address token from the link Sendora sent on signup. */
|
|
493
|
+
async verifyEmail(token) {
|
|
494
|
+
const res = await post(
|
|
495
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
496
|
+
"/api/v1/auth-service/email/verify",
|
|
497
|
+
{ token }
|
|
498
|
+
);
|
|
499
|
+
if (!res || !res.ok) {
|
|
500
|
+
throw new AuthError("EMAIL_VERIFICATION_FAILED", "Verification failed");
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
/** Re-send the email-verification email for the currently-signed-in user. */
|
|
504
|
+
async sendVerificationEmail() {
|
|
505
|
+
const headers = this.bearerHeaders();
|
|
506
|
+
if (!headers) throw new AuthError("UNAUTHORIZED", "Sign in before requesting a verification email");
|
|
507
|
+
const res = await post(
|
|
508
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
509
|
+
"/api/v1/auth-service/email/verify/resend",
|
|
510
|
+
{},
|
|
511
|
+
headers
|
|
512
|
+
);
|
|
513
|
+
if (!res || !res.ok) {
|
|
514
|
+
throw new AuthError("VERIFICATION_RESEND_FAILED", "Failed to send verification email");
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
// ============================================================
|
|
394
518
|
// TOTP MFA — enrollment management (Bearer-authenticated)
|
|
395
519
|
// ============================================================
|
|
396
520
|
async enrollMfa() {
|
package/dist/index.d.cts
CHANGED
|
@@ -137,6 +137,39 @@ declare class Auth {
|
|
|
137
137
|
mfaChallengeToken: string;
|
|
138
138
|
userId: string;
|
|
139
139
|
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Verify an IdP-issued credential (authorization code OR id_token)
|
|
142
|
+
* and mint a Sendora session. Customer's app handles the IdP
|
|
143
|
+
* dance — typically via expo-auth-session / react-native-app-auth
|
|
144
|
+
* — then hands the result here. See web SDK for full provider
|
|
145
|
+
* matrix; mirrors that surface 1:1.
|
|
146
|
+
*/
|
|
147
|
+
loginSocial(input: {
|
|
148
|
+
provider: "google" | "github" | "apple" | "microsoft" | "linkedin" | "facebook" | "twitter" | "discord";
|
|
149
|
+
code?: string;
|
|
150
|
+
idToken?: string;
|
|
151
|
+
redirectUri?: string;
|
|
152
|
+
codeVerifier?: string;
|
|
153
|
+
appleName?: {
|
|
154
|
+
firstName?: string;
|
|
155
|
+
lastName?: string;
|
|
156
|
+
};
|
|
157
|
+
}): Promise<AuthUser>;
|
|
158
|
+
signInWithGoogle(code: string, redirectUri: string): Promise<AuthUser>;
|
|
159
|
+
signInWithGitHub(code: string, redirectUri: string): Promise<AuthUser>;
|
|
160
|
+
signInWithApple(input: {
|
|
161
|
+
idToken?: string;
|
|
162
|
+
code?: string;
|
|
163
|
+
redirectUri?: string;
|
|
164
|
+
appleName?: {
|
|
165
|
+
firstName?: string;
|
|
166
|
+
lastName?: string;
|
|
167
|
+
};
|
|
168
|
+
}): Promise<AuthUser>;
|
|
169
|
+
signInWithMicrosoft(code: string, redirectUri: string): Promise<AuthUser>;
|
|
170
|
+
signInWithLinkedIn(code: string, redirectUri: string): Promise<AuthUser>;
|
|
171
|
+
signInWithFacebook(code: string, redirectUri: string): Promise<AuthUser>;
|
|
172
|
+
signInWithDiscord(code: string, redirectUri: string): Promise<AuthUser>;
|
|
140
173
|
/**
|
|
141
174
|
* Exchange the MFA challenge token from `signIn` for a real session
|
|
142
175
|
* by submitting a TOTP or recovery code from the user's authenticator.
|
|
@@ -144,6 +177,16 @@ declare class Auth {
|
|
|
144
177
|
challengeMfa(mfaChallengeToken: string, code: string): Promise<AuthUser>;
|
|
145
178
|
sendMagicLink(email: string): Promise<void>;
|
|
146
179
|
verifyMagicLink(token: string): Promise<AuthUser>;
|
|
180
|
+
sendEmailOtp(email: string): Promise<void>;
|
|
181
|
+
verifyEmailOtp(email: string, code: string): Promise<AuthUser>;
|
|
182
|
+
/** Trigger password-reset email. Resolves on 204 even when address is unknown (anti-enumeration). */
|
|
183
|
+
requestPasswordReset(email: string): Promise<void>;
|
|
184
|
+
/** Pair the reset-email token with the new password to complete the reset. */
|
|
185
|
+
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
186
|
+
/** Verify the email-address token from the link Sendora sent on signup. */
|
|
187
|
+
verifyEmail(token: string): Promise<void>;
|
|
188
|
+
/** Re-send the email-verification email for the currently-signed-in user. */
|
|
189
|
+
sendVerificationEmail(): Promise<void>;
|
|
147
190
|
enrollMfa(): Promise<{
|
|
148
191
|
secret: string;
|
|
149
192
|
otpauthUrl: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -137,6 +137,39 @@ declare class Auth {
|
|
|
137
137
|
mfaChallengeToken: string;
|
|
138
138
|
userId: string;
|
|
139
139
|
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Verify an IdP-issued credential (authorization code OR id_token)
|
|
142
|
+
* and mint a Sendora session. Customer's app handles the IdP
|
|
143
|
+
* dance — typically via expo-auth-session / react-native-app-auth
|
|
144
|
+
* — then hands the result here. See web SDK for full provider
|
|
145
|
+
* matrix; mirrors that surface 1:1.
|
|
146
|
+
*/
|
|
147
|
+
loginSocial(input: {
|
|
148
|
+
provider: "google" | "github" | "apple" | "microsoft" | "linkedin" | "facebook" | "twitter" | "discord";
|
|
149
|
+
code?: string;
|
|
150
|
+
idToken?: string;
|
|
151
|
+
redirectUri?: string;
|
|
152
|
+
codeVerifier?: string;
|
|
153
|
+
appleName?: {
|
|
154
|
+
firstName?: string;
|
|
155
|
+
lastName?: string;
|
|
156
|
+
};
|
|
157
|
+
}): Promise<AuthUser>;
|
|
158
|
+
signInWithGoogle(code: string, redirectUri: string): Promise<AuthUser>;
|
|
159
|
+
signInWithGitHub(code: string, redirectUri: string): Promise<AuthUser>;
|
|
160
|
+
signInWithApple(input: {
|
|
161
|
+
idToken?: string;
|
|
162
|
+
code?: string;
|
|
163
|
+
redirectUri?: string;
|
|
164
|
+
appleName?: {
|
|
165
|
+
firstName?: string;
|
|
166
|
+
lastName?: string;
|
|
167
|
+
};
|
|
168
|
+
}): Promise<AuthUser>;
|
|
169
|
+
signInWithMicrosoft(code: string, redirectUri: string): Promise<AuthUser>;
|
|
170
|
+
signInWithLinkedIn(code: string, redirectUri: string): Promise<AuthUser>;
|
|
171
|
+
signInWithFacebook(code: string, redirectUri: string): Promise<AuthUser>;
|
|
172
|
+
signInWithDiscord(code: string, redirectUri: string): Promise<AuthUser>;
|
|
140
173
|
/**
|
|
141
174
|
* Exchange the MFA challenge token from `signIn` for a real session
|
|
142
175
|
* by submitting a TOTP or recovery code from the user's authenticator.
|
|
@@ -144,6 +177,16 @@ declare class Auth {
|
|
|
144
177
|
challengeMfa(mfaChallengeToken: string, code: string): Promise<AuthUser>;
|
|
145
178
|
sendMagicLink(email: string): Promise<void>;
|
|
146
179
|
verifyMagicLink(token: string): Promise<AuthUser>;
|
|
180
|
+
sendEmailOtp(email: string): Promise<void>;
|
|
181
|
+
verifyEmailOtp(email: string, code: string): Promise<AuthUser>;
|
|
182
|
+
/** Trigger password-reset email. Resolves on 204 even when address is unknown (anti-enumeration). */
|
|
183
|
+
requestPasswordReset(email: string): Promise<void>;
|
|
184
|
+
/** Pair the reset-email token with the new password to complete the reset. */
|
|
185
|
+
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
186
|
+
/** Verify the email-address token from the link Sendora sent on signup. */
|
|
187
|
+
verifyEmail(token: string): Promise<void>;
|
|
188
|
+
/** Re-send the email-verification email for the currently-signed-in user. */
|
|
189
|
+
sendVerificationEmail(): Promise<void>;
|
|
147
190
|
enrollMfa(): Promise<{
|
|
148
191
|
secret: string;
|
|
149
192
|
otpauthUrl: string;
|
package/dist/index.js
CHANGED
|
@@ -315,6 +315,59 @@ var Auth = class {
|
|
|
315
315
|
return parsed.data.user;
|
|
316
316
|
});
|
|
317
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Verify an IdP-issued credential (authorization code OR id_token)
|
|
320
|
+
* and mint a Sendora session. Customer's app handles the IdP
|
|
321
|
+
* dance — typically via expo-auth-session / react-native-app-auth
|
|
322
|
+
* — then hands the result here. See web SDK for full provider
|
|
323
|
+
* matrix; mirrors that surface 1:1.
|
|
324
|
+
*/
|
|
325
|
+
loginSocial(input) {
|
|
326
|
+
return this.serialize(async () => {
|
|
327
|
+
if (this.user !== null) await this.wipeLocalIdentity();
|
|
328
|
+
const res = await post(
|
|
329
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
330
|
+
"/api/v1/auth-service/login/social",
|
|
331
|
+
input
|
|
332
|
+
);
|
|
333
|
+
if (!res) throw new AuthError("NETWORK_ERROR", "Network request failed");
|
|
334
|
+
let parsed;
|
|
335
|
+
try {
|
|
336
|
+
parsed = await res.json();
|
|
337
|
+
} catch {
|
|
338
|
+
throw new AuthError("PARSE_ERROR", `HTTP ${res.status}`);
|
|
339
|
+
}
|
|
340
|
+
if (!res.ok || !parsed.success || !isAuthApiResponse(parsed.data)) {
|
|
341
|
+
throw new AuthError(
|
|
342
|
+
parsed.error?.code ?? "SOCIAL_LOGIN_FAILED",
|
|
343
|
+
parsed.error?.message ?? "Social login failed"
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
this.persist(parsed.data);
|
|
347
|
+
return parsed.data.user;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
signInWithGoogle(code, redirectUri) {
|
|
351
|
+
return this.loginSocial({ provider: "google", code, redirectUri });
|
|
352
|
+
}
|
|
353
|
+
signInWithGitHub(code, redirectUri) {
|
|
354
|
+
return this.loginSocial({ provider: "github", code, redirectUri });
|
|
355
|
+
}
|
|
356
|
+
signInWithApple(input) {
|
|
357
|
+
return this.loginSocial({ provider: "apple", ...input });
|
|
358
|
+
}
|
|
359
|
+
signInWithMicrosoft(code, redirectUri) {
|
|
360
|
+
return this.loginSocial({ provider: "microsoft", code, redirectUri });
|
|
361
|
+
}
|
|
362
|
+
signInWithLinkedIn(code, redirectUri) {
|
|
363
|
+
return this.loginSocial({ provider: "linkedin", code, redirectUri });
|
|
364
|
+
}
|
|
365
|
+
signInWithFacebook(code, redirectUri) {
|
|
366
|
+
return this.loginSocial({ provider: "facebook", code, redirectUri });
|
|
367
|
+
}
|
|
368
|
+
signInWithDiscord(code, redirectUri) {
|
|
369
|
+
return this.loginSocial({ provider: "discord", code, redirectUri });
|
|
370
|
+
}
|
|
318
371
|
/**
|
|
319
372
|
* Exchange the MFA challenge token from `signIn` for a real session
|
|
320
373
|
* by submitting a TOTP or recovery code from the user's authenticator.
|
|
@@ -351,6 +404,77 @@ var Auth = class {
|
|
|
351
404
|
});
|
|
352
405
|
}
|
|
353
406
|
// ============================================================
|
|
407
|
+
// EMAIL OTP (6-digit cross-device code)
|
|
408
|
+
// ============================================================
|
|
409
|
+
async sendEmailOtp(email) {
|
|
410
|
+
const res = await post(
|
|
411
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
412
|
+
"/api/v1/auth-service/email-otp/request",
|
|
413
|
+
{ email }
|
|
414
|
+
);
|
|
415
|
+
if (!res || !res.ok) {
|
|
416
|
+
throw new AuthError("EMAIL_OTP_REQUEST_FAILED", "Failed to send code");
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
verifyEmailOtp(email, code) {
|
|
420
|
+
return this.serialize(async () => {
|
|
421
|
+
if (this.user !== null) await this.wipeLocalIdentity();
|
|
422
|
+
const data = await this.callAuth("/api/v1/auth-service/email-otp/verify", { email, code });
|
|
423
|
+
this.persist(data);
|
|
424
|
+
return data.user;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
// ============================================================
|
|
428
|
+
// PASSWORD RESET + EMAIL VERIFICATION
|
|
429
|
+
// ============================================================
|
|
430
|
+
/** Trigger password-reset email. Resolves on 204 even when address is unknown (anti-enumeration). */
|
|
431
|
+
async requestPasswordReset(email) {
|
|
432
|
+
const res = await post(
|
|
433
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
434
|
+
"/api/v1/auth-service/password/forgot",
|
|
435
|
+
{ email }
|
|
436
|
+
);
|
|
437
|
+
if (!res || !res.ok) {
|
|
438
|
+
throw new AuthError("PASSWORD_RESET_REQUEST_FAILED", "Failed to send reset email");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/** Pair the reset-email token with the new password to complete the reset. */
|
|
442
|
+
async resetPassword(token, newPassword) {
|
|
443
|
+
const res = await post(
|
|
444
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
445
|
+
"/api/v1/auth-service/password/reset",
|
|
446
|
+
{ token, newPassword }
|
|
447
|
+
);
|
|
448
|
+
if (!res || !res.ok) {
|
|
449
|
+
throw new AuthError("PASSWORD_RESET_FAILED", "Reset failed");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/** Verify the email-address token from the link Sendora sent on signup. */
|
|
453
|
+
async verifyEmail(token) {
|
|
454
|
+
const res = await post(
|
|
455
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
456
|
+
"/api/v1/auth-service/email/verify",
|
|
457
|
+
{ token }
|
|
458
|
+
);
|
|
459
|
+
if (!res || !res.ok) {
|
|
460
|
+
throw new AuthError("EMAIL_VERIFICATION_FAILED", "Verification failed");
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/** Re-send the email-verification email for the currently-signed-in user. */
|
|
464
|
+
async sendVerificationEmail() {
|
|
465
|
+
const headers = this.bearerHeaders();
|
|
466
|
+
if (!headers) throw new AuthError("UNAUTHORIZED", "Sign in before requesting a verification email");
|
|
467
|
+
const res = await post(
|
|
468
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
469
|
+
"/api/v1/auth-service/email/verify/resend",
|
|
470
|
+
{},
|
|
471
|
+
headers
|
|
472
|
+
);
|
|
473
|
+
if (!res || !res.ok) {
|
|
474
|
+
throw new AuthError("VERIFICATION_RESEND_FAILED", "Failed to send verification email");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// ============================================================
|
|
354
478
|
// TOTP MFA — enrollment management (Bearer-authenticated)
|
|
355
479
|
// ============================================================
|
|
356
480
|
async enrollMfa() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendoracloud/sdk-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth. Expo Go compatible, no native modules beyond AsyncStorage.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|