@ait-kit/sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +110 -0
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/platform-loader.d.ts +16 -0
  5. package/dist/platform-loader.d.ts.map +1 -0
  6. package/dist/platform-loader.js +35 -0
  7. package/dist/promotion/adapter.d.ts +3 -0
  8. package/dist/promotion/adapter.d.ts.map +1 -0
  9. package/dist/promotion/adapter.js +128 -0
  10. package/dist/promotion/platform-contract.d.ts +37 -0
  11. package/dist/promotion/platform-contract.d.ts.map +1 -0
  12. package/dist/promotion/platform-contract.js +1 -0
  13. package/dist/review/adapter.d.ts +3 -0
  14. package/dist/review/adapter.d.ts.map +1 -0
  15. package/dist/review/adapter.js +33 -0
  16. package/dist/review/platform-contract.d.ts +21 -0
  17. package/dist/review/platform-contract.d.ts.map +1 -0
  18. package/dist/review/platform-contract.js +1 -0
  19. package/dist/rn/ads.d.ts.map +1 -1
  20. package/dist/rn/ads.js +2 -7
  21. package/dist/rn/framework-loader.d.ts.map +1 -1
  22. package/dist/rn/framework-loader.js +6 -17
  23. package/dist/rn/iap.d.ts.map +1 -1
  24. package/dist/rn/iap.js +9 -28
  25. package/dist/rn/identity.d.ts.map +1 -1
  26. package/dist/rn/identity.js +4 -21
  27. package/dist/rn/index.d.ts +2 -0
  28. package/dist/rn/index.d.ts.map +1 -1
  29. package/dist/rn/index.js +2 -0
  30. package/dist/rn/notify-share.d.ts.map +1 -1
  31. package/dist/rn/notify-share.js +6 -48
  32. package/dist/rn/official-module.d.ts +16 -0
  33. package/dist/rn/official-module.d.ts.map +1 -1
  34. package/dist/rn/official-module.js +20 -0
  35. package/dist/rn/platform-loader.d.ts +4 -0
  36. package/dist/rn/platform-loader.d.ts.map +1 -0
  37. package/dist/rn/platform-loader.js +5 -0
  38. package/dist/rn/promotion.d.ts +9 -0
  39. package/dist/rn/promotion.d.ts.map +1 -0
  40. package/dist/rn/promotion.js +11 -0
  41. package/dist/rn/review.d.ts +7 -0
  42. package/dist/rn/review.d.ts.map +1 -0
  43. package/dist/rn/review.js +10 -0
  44. package/dist/rn/storage.d.ts.map +1 -1
  45. package/dist/rn/storage.js +4 -24
  46. package/dist/web/framework-loader.d.ts.map +1 -1
  47. package/dist/web/framework-loader.js +7 -23
  48. package/dist/web/identity.d.ts.map +1 -1
  49. package/dist/web/identity.js +6 -50
  50. package/dist/web/index.d.ts +2 -0
  51. package/dist/web/index.d.ts.map +1 -1
  52. package/dist/web/index.js +4 -5
  53. package/dist/web/notify-share.d.ts.map +1 -1
  54. package/dist/web/notify-share.js +6 -50
  55. package/dist/web/platform-loader.d.ts +4 -0
  56. package/dist/web/platform-loader.d.ts.map +1 -0
  57. package/dist/web/platform-loader.js +5 -0
  58. package/dist/web/promotion.d.ts +9 -0
  59. package/dist/web/promotion.d.ts.map +1 -0
  60. package/dist/web/promotion.js +10 -0
  61. package/dist/web/review.d.ts +7 -0
  62. package/dist/web/review.d.ts.map +1 -0
  63. package/dist/web/review.js +9 -0
  64. package/package.json +1 -1
package/README.md CHANGED
@@ -293,3 +293,113 @@ resolving `undefined` (installed app below the feature's minimum version)
293
293
  now rejects with `SdkError("UNSUPPORTED")` instead of
294
294
  `INVALID_ANONYMOUS_KEY`; the `"ERROR"` sentinel still rejects with
295
295
  `INVALID_ANONYMOUS_KEY`.
296
+
297
+ ## Review requests
298
+
299
+ ```ts
300
+ import { createReactNativeReview } from "@ait-kit/sdk/rn";
301
+ // Web: import { createWebReview } from "@ait-kit/sdk/web";
302
+ const review = createReactNativeReview(); // share one instance across screens
303
+ if (await review.isSupported()) await review.request();
304
+ ```
305
+
306
+ `ReviewAdapter` is a runtime-neutral root type. Factories accept `framework`
307
+ (shared `Review.request` contract or async loader), like the existing adapters.
308
+ RN translates the official `requestReview()` export; Web calls `Review.request()`.
309
+ The official SDK loads only on use. Missing features/support checkers return
310
+ `false`; import failure throws `SDK_UNAVAILABLE`; support-check exceptions propagate.
311
+ `request()` rechecks support and throws `UNSUPPORTED` when unavailable.
312
+ Concurrent requests on one instance share one Promise, cleared after success or
313
+ failure. There is no retry or timeout.
314
+
315
+ `Promise<void>` completion does not establish whether UI appeared or a review
316
+ was written. Never grant rewards, unlock features, or block navigation on review
317
+ completion. Complete and persist the core action first, then start a separately
318
+ error-handled review request without awaiting it in the core flow. The consumer
319
+ owns request timing, session limits, cooldowns and storage. Do not log raw SDK
320
+ errors by default.
321
+
322
+ Official reference: [Review.request](https://developers-apps-in-toss.toss.im/documentation/sdk/domains-api/review/review.request.md)
323
+ (Android/iOS Toss 5.253.0+, checked by the SDK). Verified package surfaces:
324
+ RN 2.10.10 and Web 3.4.0. Device UI behavior requires separate manual verification;
325
+ unit/tarball tests use injected SDKs or a stubbed native bridge.
326
+
327
+ ## Explicit direct promotion rewards
328
+
329
+ ```ts
330
+ import { createReactNativePromotion } from "@ait-kit/sdk/rn";
331
+ // Web: import { createWebPromotion } from "@ait-kit/sdk/web";
332
+ const promotion = createReactNativePromotion({ timeoutMs: 15_000 });
333
+ const support = await promotion.getSupport();
334
+ // RN 2.10.10 exposes no support checker: support is "unknown", not "supported".
335
+ // Opt into direct grants explicitly, with app-specific eligibility/budget checks.
336
+ ```
337
+
338
+ `PromotionAdapter`, `PromotionSupport`, `PromotionGrantInput` and
339
+ `PromotionGrantResult` are runtime-neutral root types. Both factories accept
340
+ `framework` (shared `Promotion.grantReward` contract or async loader).
341
+ RN calls `grantPromotionReward({ params: { promotionCode, amount } })`;
342
+ Web calls only `Promotion.grantReward({ promotionCode, amount })`.
343
+ There is no legacy Web fallback or fallback to/from server payment flows.
344
+
345
+ `getSupport()` reports `unsupported` for missing functions or an explicit false
346
+ check, `supported` for a true check, and `unknown` when a function has no checker.
347
+ Import failures throw `SDK_UNAVAILABLE`; support-check exceptions propagate.
348
+ Every grant rechecks support. RN's documented `undefined` and the provider's
349
+ `UNSUPPORTED_APP_VERSION` throw `UNSUPPORTED`; malformed Web responses stay unknown.
350
+
351
+ Input errors throw `INVALID_PROMOTION_INPUT` before loading/calling the SDK:
352
+ `promotionCode` must be non-empty without surrounding whitespace (never trimmed
353
+ into a different code), and `amount` must be a positive safe integer. Campaign
354
+ eligibility, maximum amounts and budgets remain the consumer's responsibility.
355
+
356
+ Results:
357
+
358
+ - `granted` has a non-empty `rewardKey` and means only that the SDK reported success.
359
+ - `rejected` carries an explicit documented refusal code: `4100`, `4104`, `4105`,
360
+ `4108`, `4109`, `4110`, `4112`, or `4114`.
361
+ - `unknown` means confirmation is required: SDK exceptions/sentinels, malformed or
362
+ contradictory responses, deadlines, `UNKNOWN_ERROR`, `4113`, or new provider
363
+ codes. `4113` never becomes an inferred already-granted ledger state.
364
+
365
+ Provider messages and raw errors are not included in grant results. Provider codes
366
+ are retained only as bounded uppercase alphanumeric/underscore tokens; do not log
367
+ reward keys, promotion codes or whole SDK responses.
368
+
369
+ Share one adapter instance. A concurrent grant throws `PROMOTION_IN_PROGRESS`;
370
+ completed results are never cached as idempotent payments. `timeoutMs` defaults to
371
+ 0 (disabled), accepts integers through 2147483647, and covers loading and the SDK
372
+ call. Elapsed time is checked before dispatch and when the SDK settles, so delayed
373
+ timer callbacks cannot start an overdue payment or turn a late result into success.
374
+ After timeout the result is unknown, but the instance stays locked until the
375
+ actual operation settles. A loader finishing after timeout never starts payment.
376
+ A late success/failure cannot change the returned timeout result. There is no
377
+ cancellation, automatic retry, or protection across instances/devices/restarts.
378
+
379
+ Consumer UI pattern (all callbacks are supplied by the app):
380
+
381
+ ```ts
382
+ async function grantOnce(input, ui) {
383
+ ui.disableGrantAction();
384
+ try {
385
+ const result = await promotion.grantReward(input);
386
+ if (result.status === "unknown") {
387
+ ui.showConfirmationRequired(); // keep disabled; never retry automatically
388
+ return;
389
+ }
390
+ ui.showSdkResult(result); // client report only; not a server ledger receipt
391
+ } catch {
392
+ ui.showConfirmationRequired(); // do not dump raw exceptions or auto-reenable
393
+ }
394
+ }
395
+ ```
396
+
397
+ Posting a client result to a server is not independent payment verification.
398
+ Consumers requiring a server ledger must keep their existing three-stage server
399
+ payment path. This API does not require client-side mTLS certificates/proxy tokens
400
+ and does not replace TrailBase claims or owned-currency accounting.
401
+
402
+ Official reference: [Promotion.grantReward](https://developers-apps-in-toss.toss.im/documentation/sdk/domains-api/promotion/promotion.grantreward.md).
403
+ Contracts are checked against RN 2.10.10 and Web 3.4.0 published types/code with
404
+ synthetic bridge fixtures. Device checks and official test-promotion calls remain
405
+ manual; no real promotion is invoked by tests.
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export type AdShowResult = {
28
28
  reason?: string;
29
29
  };
30
30
  /** Stable error codes for SDK adapter failures. */
31
- export type SdkErrorCode = "SDK_UNAVAILABLE" | "UNSUPPORTED" | "AD_NOT_LOADED" | "AD_ALREADY_SHOWING" | "AD_LOAD_FAILED" | "AD_LOAD_TIMEOUT" | "INVALID_LOGIN_RESULT" | "INVALID_ANONYMOUS_KEY" | "INVALID_SHARE_PATH";
31
+ export type SdkErrorCode = "SDK_UNAVAILABLE" | "UNSUPPORTED" | "AD_NOT_LOADED" | "AD_ALREADY_SHOWING" | "AD_LOAD_FAILED" | "AD_LOAD_TIMEOUT" | "INVALID_LOGIN_RESULT" | "INVALID_ANONYMOUS_KEY" | "INVALID_PROMOTION_INPUT" | "PROMOTION_IN_PROGRESS" | "INVALID_SHARE_PATH";
32
32
  /** Terminal agreement outcomes delivered by the platform event. */
33
33
  export type SdkNotificationAgreementType = "newAgreement" | "alreadyAgreed" | "agreementRejected";
34
34
  /**
@@ -214,4 +214,6 @@ export declare class SdkError extends Error {
214
214
  cause?: unknown;
215
215
  });
216
216
  }
217
+ export type { ReviewAdapter } from "./review/platform-contract.js";
218
+ export type { PromotionAdapter, PromotionSupport, PromotionGrantInput, PromotionGrantResult } from "./promotion/platform-contract.js";
217
219
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Internal runtime-neutral loader primitives; no official SDK is imported here. */
2
+ export type PlatformLoadResult<T> = {
3
+ available: true;
4
+ module: T;
5
+ } | {
6
+ available: false;
7
+ reason: string;
8
+ };
9
+ export type PlatformLoader<T> = () => Promise<PlatformLoadResult<T>>;
10
+ /** Preserve injected loaders verbatim and construct defaults only when needed. */
11
+ export declare function resolvePlatformLoader<T>(framework: T | PlatformLoader<T> | undefined, createDefault: () => PlatformLoader<T>): PlatformLoader<T>;
12
+ /** Cache only successful selections; unavailable results and thrown loads retry. */
13
+ export declare function createCachedPlatformLoader<T>(load: PlatformLoader<T>, errorReason: (error: unknown) => string): PlatformLoader<T>;
14
+ /** Preserve existing diagnostic detail policies chosen by each adapter. */
15
+ export declare function frameworkImportError(packageName: string, error: unknown, includeDetails: boolean): string;
16
+ //# sourceMappingURL=platform-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-loader.d.ts","sourceRoot":"","sources":["../src/platform-loader.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAC9B;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACzC,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,SAAS,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,EAC5C,aAAa,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,GACrC,cAAc,CAAC,CAAC,CAAC,CAInB;AAED,oFAAoF;AACpF,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GACtC,cAAc,CAAC,CAAC,CAAC,CAcnB;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,GAAG,MAAM,CAKzG"}
@@ -0,0 +1,35 @@
1
+ /** Preserve injected loaders verbatim and construct defaults only when needed. */
2
+ export function resolvePlatformLoader(framework, createDefault) {
3
+ if (!framework)
4
+ return createDefault();
5
+ if (typeof framework === "function")
6
+ return framework;
7
+ return async () => ({ available: true, module: framework });
8
+ }
9
+ /** Cache only successful selections; unavailable results and thrown loads retry. */
10
+ export function createCachedPlatformLoader(load, errorReason) {
11
+ let cached;
12
+ return async () => {
13
+ if (cached)
14
+ return { available: true, module: cached.module };
15
+ try {
16
+ const result = await load();
17
+ // Keep the cache independent from the mutable result envelope returned
18
+ // to callers, as the original per-adapter loaders did.
19
+ if (result.available)
20
+ cached = { available: true, module: result.module };
21
+ return result;
22
+ }
23
+ catch (error) {
24
+ return { available: false, reason: errorReason(error) };
25
+ }
26
+ };
27
+ }
28
+ /** Preserve existing diagnostic detail policies chosen by each adapter. */
29
+ export function frameworkImportError(packageName, error, includeDetails) {
30
+ const prefix = `failed to import ${packageName}`;
31
+ if (!includeDetails)
32
+ return prefix;
33
+ const message = error instanceof Error ? error.message : String(error);
34
+ return `${prefix}: ${message}`;
35
+ }
@@ -0,0 +1,3 @@
1
+ import type { PromotionAdapter, PromotionPlatformLoader } from "./platform-contract.js";
2
+ export declare function createPromotionAdapter(loader: PromotionPlatformLoader, timeoutMs?: number): PromotionAdapter;
3
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/promotion/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAiDhC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,uBAAuB,EAAE,SAAS,SAAI,GAAG,gBAAgB,CA+DvG"}
@@ -0,0 +1,128 @@
1
+ import { SdkError } from "../index.js";
2
+ // Official Promotion.grantReward documentation (RN 2.10.10 / Web 3.4.0).
3
+ // 4113 is intentionally absent: it cannot establish this attempt's outcome.
4
+ const REJECTION_CODES = new Set(["4100", "4104", "4105", "4108", "4109", "4110", "4112", "4114"]);
5
+ function unknown(reason, providerCode) {
6
+ return providerCode === undefined ? { status: "unknown", reason } : { status: "unknown", reason, providerCode };
7
+ }
8
+ function normalize(value, thrown) {
9
+ if (typeof value !== "object" || value === null) {
10
+ return unknown(thrown || value === "ERROR" ? "sdk_error" : "invalid_response");
11
+ }
12
+ const data = value;
13
+ const rawCode = data.errorCode ?? data.code;
14
+ const code = typeof rawCode === "string" && /^[A-Z0-9_]{1,64}$/.test(rawCode) ? rawCode : undefined;
15
+ const hasError = "errorCode" in data || "code" in data || "error" in data || "message" in data;
16
+ if (("key" in data && (thrown || hasError)) ||
17
+ (data.code !== undefined && data.errorCode !== undefined && data.code !== data.errorCode)) {
18
+ return unknown("invalid_response", code);
19
+ }
20
+ if (!thrown && typeof data.key === "string" && data.key.trim().length > 0) {
21
+ return { status: "granted", rewardKey: data.key };
22
+ }
23
+ if ("key" in data)
24
+ return unknown("invalid_response", code);
25
+ if (code === "UNSUPPORTED_APP_VERSION") {
26
+ throw new SdkError("UNSUPPORTED", "direct promotion rewards are not supported on this app version");
27
+ }
28
+ if (code && REJECTION_CODES.has(code))
29
+ return { status: "rejected", providerCode: code };
30
+ return unknown(code ? "ambiguous_provider_error" : thrown ? "sdk_error" : "invalid_response", code);
31
+ }
32
+ function support(platform) {
33
+ const grant = platform.Promotion?.grantReward;
34
+ if (typeof grant !== "function")
35
+ return "unsupported";
36
+ if (typeof grant.isSupported !== "function")
37
+ return "unknown";
38
+ return grant.isSupported() ? "supported" : "unsupported";
39
+ }
40
+ function validate(input) {
41
+ if (!input || typeof input.promotionCode !== "string" || !input.promotionCode.trim() ||
42
+ input.promotionCode !== input.promotionCode.trim() || !Number.isSafeInteger(input.amount) || input.amount <= 0) {
43
+ throw new SdkError("INVALID_PROMOTION_INPUT", "promotionCode must be non-empty without surrounding whitespace and amount must be a positive safe integer");
44
+ }
45
+ // Snapshot before loading; callers cannot change the pending payment input.
46
+ return { promotionCode: input.promotionCode, amount: input.amount };
47
+ }
48
+ export function createPromotionAdapter(loader, timeoutMs = 0) {
49
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647) {
50
+ throw new SdkError("INVALID_PROMOTION_INPUT", "timeoutMs must be an integer from 0 to 2147483647");
51
+ }
52
+ let inFlight = false;
53
+ const load = async () => {
54
+ const result = await loader();
55
+ if (!result.available)
56
+ throw new SdkError("SDK_UNAVAILABLE", result.reason);
57
+ return result.module;
58
+ };
59
+ return {
60
+ async getSupport() { return support(await load()); },
61
+ grantReward(input) {
62
+ let validated;
63
+ try {
64
+ validated = validate(input);
65
+ }
66
+ catch (error) {
67
+ return Promise.reject(error);
68
+ }
69
+ if (inFlight)
70
+ return Promise.reject(new SdkError("PROMOTION_IN_PROGRESS", "a direct promotion request is still in progress"));
71
+ inFlight = true;
72
+ const now = typeof performance !== "undefined" && typeof performance.now === "function"
73
+ ? performance.now.bind(performance)
74
+ : Date.now;
75
+ const startedAt = now();
76
+ let expired = false;
77
+ // Timers cannot run while JS is blocked or draining microtasks. Check the
78
+ // elapsed budget too, using one clock source for the entire request.
79
+ const hasExpired = () => expired || (timeoutMs > 0 && now() - startedAt >= timeoutMs);
80
+ let timer;
81
+ const work = Promise.resolve().then(async () => {
82
+ if (hasExpired())
83
+ return unknown("timeout");
84
+ const platform = await load();
85
+ // A loading timeout must not launch a new payment later.
86
+ if (hasExpired())
87
+ return unknown("timeout");
88
+ const availability = support(platform);
89
+ if (hasExpired())
90
+ return unknown("timeout");
91
+ if (availability === "unsupported") {
92
+ throw new SdkError("UNSUPPORTED", "the installed SDK or app does not support direct promotion rewards");
93
+ }
94
+ let response;
95
+ try {
96
+ response = await platform.Promotion.grantReward(validated);
97
+ }
98
+ catch (error) {
99
+ if (hasExpired())
100
+ return unknown("timeout");
101
+ // The RN conversion uses this only for the documented undefined result.
102
+ if (error instanceof SdkError && error.code === "UNSUPPORTED")
103
+ throw error;
104
+ return normalize(error, true);
105
+ }
106
+ if (hasExpired())
107
+ return unknown("timeout");
108
+ return normalize(response, false);
109
+ }).catch((error) => {
110
+ // A delayed loader/support failure must not beat an elapsed deadline.
111
+ if (hasExpired())
112
+ return unknown("timeout");
113
+ throw error;
114
+ }).finally(() => {
115
+ inFlight = false;
116
+ if (timer !== undefined)
117
+ clearTimeout(timer);
118
+ });
119
+ if (timeoutMs === 0)
120
+ return work;
121
+ const deadline = new Promise(resolve => {
122
+ timer = setTimeout(() => { expired = true; resolve(unknown("timeout")); }, timeoutMs);
123
+ });
124
+ // Only actual SDK/load settlement releases the lock, not this race.
125
+ return Promise.race([work, deadline]);
126
+ }
127
+ };
128
+ }
@@ -0,0 +1,37 @@
1
+ export type PromotionSupport = "supported" | "unsupported" | "unknown";
2
+ export interface PromotionGrantInput {
3
+ promotionCode: string;
4
+ amount: number;
5
+ }
6
+ export type PromotionGrantResult = {
7
+ status: "granted";
8
+ rewardKey: string;
9
+ } | {
10
+ status: "rejected";
11
+ providerCode: string;
12
+ } | {
13
+ status: "unknown";
14
+ reason: "sdk_error" | "timeout" | "invalid_response" | "ambiguous_provider_error";
15
+ providerCode?: string;
16
+ };
17
+ /** Client SDK reports are not independently verified server ledger evidence. */
18
+ export interface PromotionAdapter {
19
+ getSupport(): Promise<PromotionSupport>;
20
+ grantReward(input: PromotionGrantInput): Promise<PromotionGrantResult>;
21
+ }
22
+ /** Injected results are untrusted, just like the native bridge response. */
23
+ export interface PromotionPlatformSdk {
24
+ Promotion?: {
25
+ grantReward?: ((input: PromotionGrantInput) => Promise<unknown>) & {
26
+ isSupported?: () => boolean;
27
+ };
28
+ };
29
+ }
30
+ export type PromotionPlatformLoader = () => Promise<{
31
+ available: true;
32
+ module: PromotionPlatformSdk;
33
+ } | {
34
+ available: false;
35
+ reason: string;
36
+ }>;
37
+ //# sourceMappingURL=platform-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-contract.d.ts","sourceRoot":"","sources":["../../src/promotion/platform-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5C;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,kBAAkB,GAAG,0BAA0B,CAAC;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACxE;AAED,4EAA4E;AAC5E,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG;YACjE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;SAC7B,CAAC;KACH,CAAC;CACH;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,CAC/C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GACjD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACvC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { ReviewAdapter, ReviewPlatformLoader } from "./platform-contract.js";
2
+ export declare function createReviewAdapter(loader: ReviewPlatformLoader): ReviewAdapter;
3
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/review/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAqB,MAAM,wBAAwB,CAAC;AAErG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CA6B/E"}
@@ -0,0 +1,33 @@
1
+ import { SdkError } from "../index.js";
2
+ export function createReviewAdapter(loader) {
3
+ let inFlight;
4
+ const load = async () => {
5
+ const result = await loader();
6
+ if (!result.available)
7
+ throw new SdkError("SDK_UNAVAILABLE", result.reason);
8
+ return result.module;
9
+ };
10
+ const supported = (platform) => {
11
+ const request = platform.Review?.request;
12
+ return typeof request === "function" &&
13
+ typeof request.isSupported === "function" && request.isSupported() === true;
14
+ };
15
+ return {
16
+ async isSupported() {
17
+ return supported(await load());
18
+ },
19
+ request() {
20
+ if (inFlight)
21
+ return inFlight;
22
+ // Schedule loading after publishing the lock, including reentrant loaders.
23
+ inFlight = Promise.resolve().then(async () => {
24
+ const platform = await load();
25
+ if (!supported(platform)) {
26
+ throw new SdkError("UNSUPPORTED", "review requests are not supported on this app version");
27
+ }
28
+ await platform.Review.request();
29
+ }).finally(() => { inFlight = undefined; });
30
+ return inFlight;
31
+ }
32
+ };
33
+ }
@@ -0,0 +1,21 @@
1
+ /** Minimal injectable shape shared by the platform adapters. */
2
+ export interface ReviewPlatformSdk {
3
+ Review?: {
4
+ request?: (() => Promise<void>) & {
5
+ isSupported?: () => boolean;
6
+ };
7
+ };
8
+ }
9
+ export type ReviewPlatformLoader = () => Promise<{
10
+ available: true;
11
+ module: ReviewPlatformSdk;
12
+ } | {
13
+ available: false;
14
+ reason: string;
15
+ }>;
16
+ /** Completion only means the SDK call settled, never that a review was written. */
17
+ export interface ReviewAdapter {
18
+ isSupported(): Promise<boolean>;
19
+ request(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=platform-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-contract.d.ts","sourceRoot":"","sources":["../../src/review/platform-contract.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG;YAAE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAA;SAAE,CAAC;KACnE,CAAC;CACH;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAC5C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAC9C;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACvC,CAAC;AAEF,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/rn/ads.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAyB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAE/B,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,GAAG,mBAAmB,CAAC;IAClD,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5D;AAmED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAqKxF"}
1
+ {"version":3,"file":"ads.d.ts","sourceRoot":"","sources":["../../src/rn/ads.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAyB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAE/B,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,GAAG,mBAAmB,CAAC;IAClD,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5D;AAmED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAqKxF"}
package/dist/rn/ads.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
1
2
  // Relative import: the package ships per-file output (no bundling), so
2
3
  // the /rn entry and the root entry share one SdkError constructor and
3
4
  // `instanceof` holds for consumers importing either entry.
@@ -222,11 +223,5 @@ function errorMessage(error) {
222
223
  return error instanceof Error ? error.message : String(error);
223
224
  }
224
225
  function normalizeLoader(framework) {
225
- if (!framework) {
226
- return createDefaultFrameworkLoader();
227
- }
228
- if (typeof framework === "function") {
229
- return framework;
230
- }
231
- return async () => ({ available: true, module: framework });
226
+ return resolvePlatformLoader(framework, createDefaultFrameworkLoader);
232
227
  }
@@ -1 +1 @@
1
- {"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAkB9D"}
1
+ {"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAO9D"}
@@ -1,3 +1,4 @@
1
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
2
  /**
2
3
  * Default lazy loader: imports `@apps-in-toss/framework` only when an ad
3
4
  * operation needs it. A failed import is never cached, so a later call
@@ -5,22 +6,10 @@
5
6
  * successful loads are cached.
6
7
  */
7
8
  export function createDefaultFrameworkLoader() {
8
- let cached;
9
- return async () => {
10
- if (cached) {
11
- return { available: true, module: cached };
9
+ return createRnPlatformLoader((module) => {
10
+ if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
11
+ return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
12
12
  }
13
- try {
14
- const module = (await import("@apps-in-toss/framework"));
15
- if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
16
- return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
17
- }
18
- cached = module;
19
- return { available: true, module: cached };
20
- }
21
- catch (error) {
22
- const message = error instanceof Error ? error.message : String(error);
23
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
24
- }
25
- };
13
+ return { available: true, module: module };
14
+ });
26
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE5F;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC9E;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,0CAOlE"}
1
+ {"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE5F;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC9E;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,0CAGlE"}
package/dist/rn/iap.js CHANGED
@@ -1,35 +1,16 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
2
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
3
  import { createIapAdapter } from "../iap/adapter.js";
2
4
  export function createReactNativeIap(options) {
3
- const loader = !options.framework
4
- ? createDefaultRnIapLoader()
5
- : typeof options.framework === "function"
6
- ? options.framework
7
- : async () => ({ available: true, module: options.framework });
5
+ const loader = resolvePlatformLoader(options.framework, createDefaultRnIapLoader);
8
6
  return createIapAdapter({ ...options, loader });
9
7
  }
10
8
  function createDefaultRnIapLoader() {
11
- let cached;
12
- return async () => {
13
- if (cached) {
14
- return { available: true, module: cached };
9
+ return createRnPlatformLoader((framework) => {
10
+ const iap = framework.IAP;
11
+ if (typeof iap !== "object" || iap === null) {
12
+ return { available: false, reason: "@apps-in-toss/framework does not expose an IAP domain" };
15
13
  }
16
- try {
17
- const framework = (await import("@apps-in-toss/framework"));
18
- const iap = framework.IAP;
19
- if (typeof iap !== "object" || iap === null) {
20
- return {
21
- available: false,
22
- reason: "@apps-in-toss/framework does not expose an IAP domain"
23
- };
24
- }
25
- // Per-operation capability is validated at each call site: an
26
- // installed version may expose some IAP functions but not others.
27
- cached = iap;
28
- return { available: true, module: cached };
29
- }
30
- catch (error) {
31
- const message = error instanceof Error ? error.message : String(error);
32
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
33
- }
34
- };
14
+ return { available: true, module: iap };
15
+ });
35
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mBAAmB,GAAG,sBAAsB,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CAavG;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,GACjD,sBAAsB,CAQxB"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mBAAmB,GAAG,sBAAsB,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CAavG;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,GACjD,sBAAsB,CAExB"}
@@ -1,3 +1,5 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
2
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
3
  import { SdkError } from "../index.js";
2
4
  import { runSdkGetAnonymousKey, runSdkLogin } from "../identity/platform-contract.js";
3
5
  import { adaptOfficialRnIdentity } from "./official-module.js";
@@ -16,13 +18,7 @@ export function createReactNativeIdentity(options = {}) {
16
18
  };
17
19
  }
18
20
  export function normalizeIdentityLoader(framework) {
19
- if (!framework) {
20
- return createDefaultRnIdentityLoader();
21
- }
22
- if (typeof framework === "function") {
23
- return framework;
24
- }
25
- return async () => ({ available: true, module: framework });
21
+ return resolvePlatformLoader(framework, createDefaultRnIdentityLoader);
26
22
  }
27
23
  /**
28
24
  * Default loader: imports the official `@apps-in-toss/framework` lazily and
@@ -31,18 +27,5 @@ export function normalizeIdentityLoader(framework) {
31
27
  * retries); successful loads cache the converted module.
32
28
  */
33
29
  function createDefaultRnIdentityLoader() {
34
- let cached;
35
- return async () => {
36
- if (cached) {
37
- return { available: true, module: cached };
38
- }
39
- try {
40
- cached = adaptOfficialRnIdentity(await import("@apps-in-toss/framework"));
41
- return { available: true, module: cached };
42
- }
43
- catch (error) {
44
- const message = error instanceof Error ? error.message : String(error);
45
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
46
- }
47
- };
30
+ return createRnPlatformLoader(module => ({ available: true, module: adaptOfficialRnIdentity(module) }));
48
31
  }
@@ -24,4 +24,6 @@ export { createReactNativeStorage, type ReactNativeStorageOptions } from "./stor
24
24
  export { createReactNativeNotification, createReactNativeShare, type ReactNativeNotification, type ReactNativeNotificationOptions, type ReactNativeShare, type ReactNativeShareOptions } from "./notify-share.js";
25
25
  export { createDefaultFrameworkLoader, type FrameworkLoader } from "./framework-loader.js";
26
26
  export type { FullScreenAdShowEvent, FullScreenAdSupport, LoadFullScreenAdParams, ShowFullScreenAdParams } from "./framework-contract.js";
27
+ export { createReactNativeReview, type ReactNativeReviewOptions } from "./review.js";
28
+ export { createReactNativePromotion, type ReactNativePromotionOptions } from "./promotion.js";
27
29
  //# sourceMappingURL=index.d.ts.map