@looplay/sdk 0.8.8 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,7 +35,6 @@ import { LooplayIframeAuth } from '@looplay/sdk';
35
35
 
36
36
  export const looplayAuth = new LooplayIframeAuth({
37
37
  appId: 'YOUR_APP_ID', // from your creator dashboard — required
38
- apiUrl: 'https://api.looplay.gg',
39
38
  });
40
39
  ```
41
40
 
@@ -64,10 +63,11 @@ backward compatibility, but you should set one regardless).
64
63
  import { LooplayIframeAuth } from '@looplay/sdk';
65
64
 
66
65
  // 1. Initialize the SDK
66
+ // apiUrl and parentOrigin are automatically configured:
67
+ // - parentOrigin defaults to import.meta.env.VITE_PARENT_ORIGIN (or document.referrer)
68
+ // - apiUrl defaults to import.meta.env.VITE_API_URL (or 'https://api.looplay.gg')
67
69
  export const looplayAuth = new LooplayIframeAuth({
68
70
  appId: 'YOUR_APP_ID', // from your creator dashboard
69
- apiUrl: 'https://api.looplay.gg', // required for standalone builds; optional inside the iframe
70
- parentOrigin: import.meta.env.VITE_PARENT_ORIGIN, // restrict the accepted postMessage origin
71
71
 
72
72
  // Optional: Auto-request rewarded ads after match activity
73
73
  autoRequestAds: {
@@ -309,7 +309,6 @@ directly, no bundler needed:
309
309
  <script>
310
310
  const looplayAuth = new LooplaySDK.LooplayIframeAuth({
311
311
  appId: 'YOUR_APP_ID',
312
- apiUrl: 'https://api.looplay.gg',
313
312
  });
314
313
  looplayAuth.init();
315
314
  looplayAuth.initLifecycleTracking();
@@ -334,11 +333,13 @@ that's a separate opt-in browser bundle, only needed if you want
334
333
  </script>
335
334
  ```
336
335
 
337
- **Security note**: the origin check relies on `parentOrigin` (explicit option)
338
- or `document.referrer`. Referrer can be stripped by `Referrer-Policy`, browser
339
- privacy settings, or extensions when that happens the check is skipped and
340
- `LooplayIframeAuth` logs a `console.warn`. Always pass `parentOrigin` explicitly
341
- in production embeds instead of relying on the referrer fallback.
336
+ **Security note**: the origin check relies on `parentOrigin` (explicit option
337
+ or `import.meta.env.VITE_PARENT_ORIGIN`), falling back to `document.referrer`.
338
+ Referrer can be stripped by `Referrer-Policy`, browser privacy settings, or
339
+ extensions when that happens and no `parentOrigin` or `VITE_PARENT_ORIGIN` is configured,
340
+ the check is skipped and `LooplayIframeAuth` logs a `console.warn`. Configure
341
+ `VITE_PARENT_ORIGIN` in your environment or pass `parentOrigin` explicitly
342
+ in production embeds instead of relying solely on the referrer fallback.
342
343
 
343
344
  **Lifecycle**: call `dispose()` when tearing down (route change, HMR, test
344
345
  cleanup) to remove the `message` listener and clear subscribers:
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
3
4
  // src/errors.ts
4
5
  var LooplaySDKError = class extends Error {
5
6
  constructor(message) {
@@ -139,8 +140,45 @@ var LooplayAuth = class {
139
140
  }
140
141
  };
141
142
 
143
+ // src/constants.ts
144
+ var DEFAULT_API_URL = "https://miniapp-api.looplay.gg";
145
+ function resolveEnvParentOrigin() {
146
+ try {
147
+ if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('looplay-sdk.cjs.js', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_PARENT_ORIGIN) {
148
+ const val = undefined.VITE_PARENT_ORIGIN;
149
+ if (typeof val === "string" && val.trim().length > 0) return val.trim();
150
+ }
151
+ } catch {
152
+ }
153
+ try {
154
+ if (typeof process !== "undefined" && process.env?.VITE_PARENT_ORIGIN) {
155
+ const val = process.env.VITE_PARENT_ORIGIN;
156
+ if (typeof val === "string" && val.trim().length > 0) return val.trim();
157
+ }
158
+ } catch {
159
+ }
160
+ return void 0;
161
+ }
162
+ function resolveEnvApiUrl() {
163
+ try {
164
+ if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('looplay-sdk.cjs.js', document.baseURI).href)) }) !== "undefined" && undefined) {
165
+ const val = undefined.VITE_API_URL ?? undefined.VITE_LOOPLAY_API_URL;
166
+ if (typeof val === "string" && val.trim().length > 0) return val.trim();
167
+ }
168
+ } catch {
169
+ }
170
+ try {
171
+ if (typeof process !== "undefined" && process.env) {
172
+ const val = process.env.VITE_API_URL ?? process.env.VITE_LOOPLAY_API_URL;
173
+ if (typeof val === "string" && val.trim().length > 0) return val.trim();
174
+ }
175
+ } catch {
176
+ }
177
+ return void 0;
178
+ }
179
+
142
180
  // src/version.ts
143
- var LOOPLAY_SDK_VERSION = "0.8.5";
181
+ var LOOPLAY_SDK_VERSION = "0.8.10";
144
182
 
145
183
  // src/apps/http.ts
146
184
  function getFetchFn(fetchOverride) {
@@ -166,8 +204,9 @@ var HttpClient = class {
166
204
  baseUrl;
167
205
  fetchFn;
168
206
  defaultHeaders;
169
- constructor(options) {
170
- this.baseUrl = options.baseUrl.replace(/\/$/, "");
207
+ constructor(options = {}) {
208
+ const rawBaseUrl = typeof options.baseUrl === "string" && options.baseUrl.trim().length > 0 ? options.baseUrl.trim() : resolveEnvApiUrl() ?? DEFAULT_API_URL;
209
+ this.baseUrl = rawBaseUrl.replace(/\/$/, "");
171
210
  this.fetchFn = getFetchFn(options.fetch);
172
211
  this.defaultHeaders = {
173
212
  "x-looplay-sdk-version": LOOPLAY_SDK_VERSION,
@@ -463,10 +502,11 @@ var ApiClient = class {
463
502
  playSession;
464
503
  playSessionPromiseKey;
465
504
  playSessionPromise;
466
- constructor(options) {
467
- if (!options.baseUrl) throw new MissingBaseUrlError();
505
+ constructor(options = {}) {
506
+ const baseUrl = typeof options.baseUrl === "string" && options.baseUrl.trim().length > 0 ? options.baseUrl.trim() : resolveEnvApiUrl() ?? DEFAULT_API_URL;
507
+ if (!baseUrl) throw new MissingBaseUrlError();
468
508
  this.raw = new ServiceClient({
469
- baseUrl: options.baseUrl,
509
+ baseUrl,
470
510
  fetch: options.fetch,
471
511
  defaultHeaders: options.defaultHeaders
472
512
  });
@@ -691,18 +731,21 @@ var LooplaySDK = class {
691
731
  gameId;
692
732
  initialized = false;
693
733
  constructor(options = {}) {
694
- const { auth, baseUrl, fetch, defaultHeaders } = options;
734
+ const {
735
+ auth,
736
+ fetch,
737
+ defaultHeaders
738
+ } = options;
739
+ const baseUrl = typeof options.baseUrl === "string" && options.baseUrl.trim().length > 0 ? options.baseUrl.trim() : resolveEnvApiUrl() ?? DEFAULT_API_URL;
695
740
  if (auth) {
696
741
  this.auth = new LooplayAuth(auth);
697
742
  }
698
- if (baseUrl) {
699
- this.api = new ApiClient({
700
- baseUrl,
701
- fetch,
702
- defaultHeaders,
703
- getAccessToken: async () => this.auth?.getAccessToken()
704
- });
705
- }
743
+ this.api = new ApiClient({
744
+ baseUrl,
745
+ fetch,
746
+ defaultHeaders,
747
+ getAccessToken: async () => this.auth?.getAccessToken()
748
+ });
706
749
  }
707
750
  async init(params) {
708
751
  this.gameId = params.gameId;
@@ -964,7 +1007,8 @@ var LooplayIframeAuth = class {
964
1007
  return this.state.jwt;
965
1008
  }
966
1009
  getApiUrl() {
967
- return this.state.apiUrl ?? this.options.apiUrl ?? null;
1010
+ const raw = toOptionalString(this.state.apiUrl) ?? toOptionalString(this.options.apiUrl) ?? resolveEnvApiUrl() ?? DEFAULT_API_URL;
1011
+ return raw.trim();
968
1012
  }
969
1013
  /** Resolves to the configured `appId`, falling back to whatever the parent pushed as `gameId`. */
970
1014
  getGameId() {
@@ -1339,7 +1383,12 @@ ${gameId}`;
1339
1383
  }
1340
1384
  }
1341
1385
  resolveParentOrigin() {
1342
- if (this.options.parentOrigin) return this.options.parentOrigin;
1386
+ if (this.options.parentOrigin) {
1387
+ const opt = toOptionalString(this.options.parentOrigin);
1388
+ if (opt) return opt;
1389
+ }
1390
+ const envOrigin = resolveEnvParentOrigin();
1391
+ if (envOrigin) return envOrigin;
1343
1392
  if (typeof document === "undefined" || !document.referrer) return null;
1344
1393
  try {
1345
1394
  return new URL(document.referrer).origin;
@@ -1383,6 +1432,7 @@ ${gameId}`;
1383
1432
 
1384
1433
  exports.ApiClient = ApiClient;
1385
1434
  exports.BrowserLocalStorageAuthStorage = BrowserLocalStorageAuthStorage;
1435
+ exports.DEFAULT_API_URL = DEFAULT_API_URL;
1386
1436
  exports.HttpClient = HttpClient;
1387
1437
  exports.HttpError = HttpError;
1388
1438
  exports.LOOPLAY_SDK_VERSION = LOOPLAY_SDK_VERSION;
@@ -1397,5 +1447,7 @@ exports.NotAuthenticatedError = NotAuthenticatedError;
1397
1447
  exports.NotInitializedError = NotInitializedError;
1398
1448
  exports.ServiceClient = ServiceClient;
1399
1449
  exports.TelegramAuthProvider = TelegramAuthProvider;
1450
+ exports.resolveEnvApiUrl = resolveEnvApiUrl;
1451
+ exports.resolveEnvParentOrigin = resolveEnvParentOrigin;
1400
1452
  //# sourceMappingURL=looplay-sdk.cjs.js.map
1401
1453
  //# sourceMappingURL=looplay-sdk.cjs.js.map