glitch-javascript-sdk 3.10.7 → 3.15.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/cjs/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var require$$1 = require('util');
4
6
  var stream = require('stream');
5
7
  var require$$1$1 = require('path');
@@ -15442,7 +15444,7 @@ var transitionalDefaults = {
15442
15444
  validateStatusUndefinedResolves: true,
15443
15445
  };
15444
15446
 
15445
- var URLSearchParams = require$$5.URLSearchParams;
15447
+ var URLSearchParams$1 = require$$5.URLSearchParams;
15446
15448
 
15447
15449
  const ALPHA = 'abcdefghijklmnopqrstuvwxyz';
15448
15450
 
@@ -15469,7 +15471,7 @@ const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
15469
15471
  var platform$1 = {
15470
15472
  isNode: true,
15471
15473
  classes: {
15472
- URLSearchParams,
15474
+ URLSearchParams: URLSearchParams$1,
15473
15475
  FormData: FormData$2,
15474
15476
  Blob: (typeof Blob !== 'undefined' && Blob) || null,
15475
15477
  },
@@ -23524,7 +23526,7 @@ var Requests = /** @class */ (function () {
23524
23526
  }
23525
23527
  return Requests.request('DELETE', url);
23526
23528
  };
23527
- Requests.uploadFile = function (url, filename, file, data, params, onUploadProgress) {
23529
+ Requests.uploadFile = function (url, filename, file, data, params, onUploadProgress, options) {
23528
23530
  // Process URL and params
23529
23531
  if (params && Object.keys(params).length > 0) {
23530
23532
  var queryString = Object.entries(params)
@@ -23558,6 +23560,8 @@ var Requests = /** @class */ (function () {
23558
23560
  data: formData,
23559
23561
  headers: headers,
23560
23562
  onUploadProgress: onUploadProgress,
23563
+ signal: options === null || options === void 0 ? void 0 : options.signal,
23564
+ timeout: options === null || options === void 0 ? void 0 : options.timeout,
23561
23565
  });
23562
23566
  };
23563
23567
  Requests.postFormData = function (url, formData, params, onUploadProgress) {
@@ -23699,13 +23703,22 @@ var Requests = /** @class */ (function () {
23699
23703
  });
23700
23704
  });
23701
23705
  };
23702
- Requests.processRoute = function (route, data, routeReplace, params) {
23706
+ Requests.processRoute = function (route, data, routeReplace, params, options) {
23703
23707
  var url = route.url;
23704
23708
  if (routeReplace) {
23705
23709
  for (var key in routeReplace) {
23706
23710
  url = url.replace("{" + key + "}", routeReplace[key]);
23707
23711
  }
23708
23712
  }
23713
+ if (options) {
23714
+ var query = __assign(__assign({}, params), (Requests.community_id && !options.excludeCommunityContext ? { community_id: Requests.community_id } : {}));
23715
+ return axios({
23716
+ method: route.method, url: Requests.buildUrl(url, query),
23717
+ data: data,
23718
+ headers: __assign(__assign({ 'Content-Type': 'application/json' }, (Requests.authToken ? { Authorization: "Bearer ".concat(Requests.authToken) } : {})), options.headers),
23719
+ signal: options.signal, timeout: options.timeout,
23720
+ });
23721
+ }
23709
23722
  if (route.method == HTTP_METHODS.GET) {
23710
23723
  return Requests.get(url, params);
23711
23724
  }
@@ -32642,7 +32655,10 @@ var Messages = /** @class */ (function () {
32642
32655
  return Requests.processRoute(MessagesRoute.routes.listMessageThreads, undefined, undefined, params);
32643
32656
  };
32644
32657
  /**
32645
- * Send a new message that will be added to a thread
32658
+ * Send a new message that will be added to a thread. Festival-scoped threads
32659
+ * enforce current admission, blocking and read-only state server-side.
32660
+ * Include an optional client_message_id UUID and reuse it when retrying a
32661
+ * timed-out request to prevent duplicate messages and notifications.
32646
32662
  *
32647
32663
  * @see https://api.glitch.fun/api/documentation#/Messages/storeMessage
32648
32664
  *
@@ -33126,6 +33142,7 @@ var GameShowsRoute = /** @class */ (function () {
33126
33142
  registrationQuestionReports: { url: '/gameshows/{show_id}/registration-form/reports', method: HTTP_METHODS.GET },
33127
33143
  listTitles: { url: '/gameshows/{show_id}/titles', method: HTTP_METHODS.GET },
33128
33144
  addTitle: { url: '/gameshows/{show_id}/addTitle', method: HTTP_METHODS.POST },
33145
+ searchTitleCandidates: { url: '/gameshows/{show_id}/title-candidates', method: HTTP_METHODS.GET },
33129
33146
  // External registration file preview/import endpoints.
33130
33147
  previewExternalTitles: { url: '/gameshows/{show_id}/external-titles/preview', method: HTTP_METHODS.POST },
33131
33148
  importExternalTitles: { url: '/gameshows/{show_id}/external-titles/import', method: HTTP_METHODS.POST },
@@ -33375,6 +33392,10 @@ var GameShows = /** @class */ (function () {
33375
33392
  GameShows.addTitle = function (show_id, data, params) {
33376
33393
  return Requests.processRoute(GameShowsRoute.routes.addTitle, data, { show_id: show_id }, params);
33377
33394
  };
33395
+ /** Search privacy-safe registered Glitch games that an organizer may attach to a festival. */
33396
+ GameShows.searchTitleCandidates = function (show_id, params) {
33397
+ return Requests.processRoute(GameShowsRoute.routes.searchTitleCandidates, {}, { show_id: show_id }, params);
33398
+ };
33378
33399
  /** Preview CSV/TSV/TXT/ZIP registrations without writing showcase data. */
33379
33400
  GameShows.previewExternalTitles = function (show_id, file, data, params) {
33380
33401
  // Multipart helpers require the concrete URL before uploading.
@@ -39666,6 +39687,847 @@ var GameDesign = /** @class */ (function () {
39666
39687
  return GameDesign;
39667
39688
  }());
39668
39689
 
39690
+ /** Participant-only festival networking; all access checks are enforced by the API. */
39691
+ var FestivalNetworkingRoute = /** @class */ (function () {
39692
+ function FestivalNetworkingRoute() {
39693
+ }
39694
+ FestivalNetworkingRoute.routes = {
39695
+ settings: { url: '/gameshows/{show_id}/networking/settings', method: HTTP_METHODS.GET },
39696
+ updateSettings: { url: '/gameshows/{show_id}/networking/settings', method: HTTP_METHODS.PUT },
39697
+ listPosts: { url: '/gameshows/{show_id}/networking/posts', method: HTTP_METHODS.GET },
39698
+ createPost: { url: '/gameshows/{show_id}/networking/posts', method: HTTP_METHODS.POST },
39699
+ getPost: { url: '/gameshows/{show_id}/networking/posts/{post_id}', method: HTTP_METHODS.GET },
39700
+ updatePost: { url: '/gameshows/{show_id}/networking/posts/{post_id}', method: HTTP_METHODS.PUT },
39701
+ listComments: { url: '/gameshows/{show_id}/networking/posts/{post_id}/comments', method: HTTP_METHODS.GET },
39702
+ createComment: { url: '/gameshows/{show_id}/networking/posts/{post_id}/comments', method: HTTP_METHODS.POST },
39703
+ setInteraction: { url: '/gameshows/{show_id}/networking/posts/{post_id}/interaction', method: HTTP_METHODS.PUT },
39704
+ apply: { url: '/gameshows/{show_id}/networking/posts/{post_id}/apply', method: HTTP_METHODS.POST },
39705
+ matches: { url: '/gameshows/{show_id}/networking/posts/{post_id}/matches', method: HTTP_METHODS.GET },
39706
+ report: { url: '/gameshows/{show_id}/networking/posts/{post_id}/report', method: HTTP_METHODS.POST },
39707
+ applications: { url: '/gameshows/{show_id}/networking/applications', method: HTTP_METHODS.GET },
39708
+ updateApplication: { url: '/gameshows/{show_id}/networking/applications/{application_id}', method: HTTP_METHODS.PUT },
39709
+ conversation: { url: '/gameshows/{show_id}/networking/applications/{application_id}/conversation', method: HTTP_METHODS.POST },
39710
+ moderation: { url: '/gameshows/{show_id}/networking/moderation', method: HTTP_METHODS.GET },
39711
+ moderatePost: { url: '/gameshows/{show_id}/networking/moderation/posts/{post_id}', method: HTTP_METHODS.PUT },
39712
+ resolveReport: { url: '/gameshows/{show_id}/networking/moderation/{report_id}', method: HTTP_METHODS.PUT },
39713
+ restrictMember: { url: '/gameshows/{show_id}/networking/members/{user_id}', method: HTTP_METHODS.PUT },
39714
+ preferences: { url: '/gameshows/{show_id}/networking/preferences', method: HTTP_METHODS.GET },
39715
+ updatePreferences: { url: '/gameshows/{show_id}/networking/preferences', method: HTTP_METHODS.PUT },
39716
+ media: { url: '/gameshows/{show_id}/networking/media', method: HTTP_METHODS.GET },
39717
+ uploadMedia: { url: '/gameshows/{show_id}/networking/media', method: HTTP_METHODS.POST },
39718
+ organizations: { url: '/gameshows/{show_id}/networking/organizations', method: HTTP_METHODS.GET },
39719
+ analytics: { url: '/gameshows/{show_id}/networking/analytics', method: HTTP_METHODS.GET },
39720
+ };
39721
+ return FestivalNetworkingRoute;
39722
+ }());
39723
+
39724
+ /** Festival-scoped discussions, talent, jobs, moderation and new owned media uploads. */
39725
+ var FestivalNetworking = /** @class */ (function () {
39726
+ function FestivalNetworking() {
39727
+ }
39728
+ FestivalNetworking.request = function (name, show_id, data, ids, params, options) {
39729
+ if (ids === void 0) { ids = {}; }
39730
+ var replacements = Object.fromEntries(Object.entries(__assign({ show_id: show_id }, ids)).map(function (_a) {
39731
+ var key = _a[0], id = _a[1];
39732
+ return [key, encodeURIComponent(id)];
39733
+ }));
39734
+ return Requests.processRoute(FestivalNetworkingRoute.routes[name], data, replacements, params, options);
39735
+ };
39736
+ /** Read enabled tools and the current account's registration/ticket access. */
39737
+ FestivalNetworking.settings = function (id, options) { return this.request('settings', id, undefined, {}, undefined, options); };
39738
+ /** Organizer-only settings update; admission remains mandatory. */
39739
+ FestivalNetworking.updateSettings = function (id, data) { return this.request('updateSettings', id, data); };
39740
+ /** Search posts; compensation comparisons require currency and period. */
39741
+ FestivalNetworking.listPosts = function (id, params, options) { return this.request('listPosts', id, undefined, {}, params, options); };
39742
+ /** Create a post with rich HTML and optional newly uploaded UserMedia IDs. */
39743
+ FestivalNetworking.createPost = function (id, data) { return this.request('createPost', id, data); };
39744
+ /** Direct links still require admission and content visibility permission. */
39745
+ FestivalNetworking.getPost = function (id, post_id, options) { return this.request('getPost', id, undefined, { post_id: post_id }, undefined, options); };
39746
+ /** Edit or soft-delete via state; omit media_ids to preserve current attachments. */
39747
+ FestivalNetworking.updatePost = function (id, post_id, data) { return this.request('updatePost', id, data, { post_id: post_id }); };
39748
+ /** Paginated direct replies; fetch children to expand a thread. */
39749
+ FestivalNetworking.listComments = function (id, post_id, params, options) { return this.request('listComments', id, undefined, { post_id: post_id }, params, options); };
39750
+ /** Add a rich-text reply, subject to locking and five-level nesting. */
39751
+ FestivalNetworking.createComment = function (id, post_id, data) { return this.request('createComment', id, data, { post_id: post_id }); };
39752
+ /** Set, replace, or remove a vote/save/hide idempotently. */
39753
+ FestivalNetworking.setInteraction = function (id, post_id, data) { return this.request('setInteraction', id, data, { post_id: post_id }); };
39754
+ /** Apply or express interest once; the original listing is snapshotted. */
39755
+ FestivalNetworking.apply = function (id, post_id, data) { return this.request('apply', id, data, { post_id: post_id }); };
39756
+ /** Discovery matches for the current user's own job/talent listing. */
39757
+ FestivalNetworking.matches = function (id, post_id, params, options) { return this.request('matches', id, undefined, { post_id: post_id }, params, options); };
39758
+ /** Report suspicious content privately to festival moderators. */
39759
+ FestivalNetworking.report = function (id, post_id, data) { return this.request('report', id, data, { post_id: post_id }); };
39760
+ /** Only the applicant and listing owner receive application records. */
39761
+ FestivalNetworking.applications = function (id, params, options) { return this.request('applications', id, undefined, {}, params, options); };
39762
+ /** Applicant withdrawal or owner-managed status changes. */
39763
+ FestivalNetworking.updateApplication = function (id, application_id, data) { return this.request('updateApplication', id, data, { application_id: application_id }); };
39764
+ /** Open the application/talent inquiry's private shared-inbox conversation, creating it once for legacy applications. Only the applicant and original listing owner may call this. Use Messages.getThread/sendMessage for subsequent conversation activity. */
39765
+ FestivalNetworking.conversation = function (id, application_id) { return this.request('conversation', id, {}, { application_id: application_id }); };
39766
+ /** Moderator-only report queue and audit history. */
39767
+ FestivalNetworking.moderation = function (id, params, options) { return this.request('moderation', id, undefined, {}, params, options); };
39768
+ /** Moderation remains available even while the board is disabled. */
39769
+ FestivalNetworking.moderatePost = function (id, post_id, data) { return this.request('moderatePost', id, data, { post_id: post_id }); };
39770
+ /** Resolve, dismiss or begin reviewing a report. */
39771
+ FestivalNetworking.resolveReport = function (id, report_id, data) { return this.request('resolveReport', id, data, { report_id: report_id }); };
39772
+ /** Moderator-only participant restrictions. */
39773
+ FestivalNetworking.restrictMember = function (id, user_id, data) { return this.request('restrictMember', id, data, { user_id: user_id }); };
39774
+ /** Current user's privacy and notification preferences. */
39775
+ FestivalNetworking.preferences = function (id, options) { return this.request('preferences', id, undefined, {}, undefined, options); };
39776
+ /** Set notification opt-out and blocked participants/companies. */
39777
+ FestivalNetworking.updatePreferences = function (id, data) { return this.request('updatePreferences', id, data); };
39778
+ /** Uploaded festival attachments only; not the gameplay clip library. */
39779
+ FestivalNetworking.media = function (id, params, options) { return this.request('media', id, undefined, {}, params, options); };
39780
+ /**
39781
+ * Upload a new image (10 MB max) or video (100 MB max), using the existing media pipeline.
39782
+ * The response ID is an owned UserMedia ID for createPost/updatePost media_ids.
39783
+ * @param file New file selected by the attendee; supported images exclude SVG.
39784
+ * @param data Which enabled board the upload is for.
39785
+ * @param onUploadProgress Transfer progress; 100% may still require conversion before completion.
39786
+ */
39787
+ FestivalNetworking.uploadMedia = function (id, file, data, onUploadProgress, options) {
39788
+ return Requests.uploadFile(FestivalNetworkingRoute.routes.uploadMedia.url.replace('{show_id}', encodeURIComponent(id)), 'media', file, data, undefined, onUploadProgress, options);
39789
+ };
39790
+ /** Organizations the authenticated user is authorized to represent. */
39791
+ FestivalNetworking.organizations = function (id, options) { return this.request('organizations', id, undefined, {}, undefined, options); };
39792
+ /** Organizer-only aggregate participation metrics. */
39793
+ FestivalNetworking.analytics = function (id, options) { return this.request('analytics', id, undefined, {}, undefined, options); };
39794
+ return FestivalNetworking;
39795
+ }());
39796
+
39797
+ /** Consumer-facing commerce routes. Signed provider webhooks are deliberately not client APIs. */
39798
+ var MicrotransactionsRoute = /** @class */ (function () {
39799
+ function MicrotransactionsRoute() {
39800
+ }
39801
+ MicrotransactionsRoute.routes = {
39802
+ uploadMedia: { url: '/titles/{title_id}/microtransactions/media', method: HTTP_METHODS.POST },
39803
+ mcpUploadMedia: { url: '/mcp/v1/titles/{title_id}/microtransactions/media', method: HTTP_METHODS.POST },
39804
+ settings: { url: '/titles/{title_id}/microtransactions/settings', method: HTTP_METHODS.GET },
39805
+ updateSettings: { url: '/titles/{title_id}/microtransactions/settings', method: HTTP_METHODS.PUT },
39806
+ readiness: { url: '/titles/{title_id}/microtransactions/readiness', method: HTTP_METHODS.GET },
39807
+ products: { url: '/titles/{title_id}/microtransactions/products', method: HTTP_METHODS.GET },
39808
+ createProduct: { url: '/titles/{title_id}/microtransactions/products', method: HTTP_METHODS.POST },
39809
+ updateProduct: { url: '/titles/{title_id}/microtransactions/products/{product_id}', method: HTTP_METHODS.PUT },
39810
+ archiveProduct: { url: '/titles/{title_id}/microtransactions/products/{product_id}/archive', method: HTTP_METHODS.POST },
39811
+ providers: { url: '/titles/{title_id}/microtransactions/providers', method: HTTP_METHODS.GET },
39812
+ earnings: { url: '/titles/{title_id}/microtransactions/earnings', method: HTTP_METHODS.GET },
39813
+ orders: { url: '/titles/{title_id}/microtransactions/orders', method: HTTP_METHODS.GET },
39814
+ order: { url: '/titles/{title_id}/microtransactions/orders/{order_id}', method: HTTP_METHODS.GET },
39815
+ refund: { url: '/titles/{title_id}/microtransactions/orders/{order_id}/refund', method: HTTP_METHODS.POST },
39816
+ replayDelivery: { url: '/titles/{title_id}/microtransactions/deliveries/{delivery_id}/replay', method: HTTP_METHODS.POST },
39817
+ catalog: { url: '/titles/{title_id}/microtransactions/catalog', method: HTTP_METHODS.GET },
39818
+ createQuote: { url: '/titles/{title_id}/microtransactions/quotes', method: HTTP_METHODS.POST },
39819
+ createCheckoutSession: { url: '/titles/{title_id}/microtransactions/checkout-sessions', method: HTTP_METHODS.POST },
39820
+ createRestoreSession: { url: '/titles/{title_id}/microtransactions/restore-sessions', method: HTTP_METHODS.POST },
39821
+ checkoutSession: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}', method: HTTP_METHODS.GET },
39822
+ checkoutFramePolicy: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}/frame-policy', method: HTTP_METHODS.GET },
39823
+ framePolicy: { url: '/titles/{title_id}/microtransactions/frame-policy', method: HTTP_METHODS.GET },
39824
+ authenticateCheckoutSession: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}/authenticate', method: HTTP_METHODS.POST },
39825
+ checkout: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}/checkout', method: HTTP_METHODS.POST },
39826
+ reconcileCheckout: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}/reconcile', method: HTTP_METHODS.POST },
39827
+ createHandoff: { url: '/titles/{title_id}/microtransactions/checkout-sessions/{session_id}/handoff', method: HTTP_METHODS.POST },
39828
+ claimHandoff: { url: '/titles/{title_id}/microtransactions/handoffs/claim', method: HTTP_METHODS.POST },
39829
+ restoreHandoff: { url: '/titles/{title_id}/microtransactions/handoffs/restore', method: HTTP_METHODS.POST },
39830
+ verifyIntegration: { url: '/titles/{title_id}/microtransactions/integration/verify', method: HTTP_METHODS.POST },
39831
+ entitlements: { url: '/titles/{title_id}/microtransactions/entitlements', method: HTTP_METHODS.GET },
39832
+ myPurchases: { url: '/titles/{title_id}/microtransactions/me/purchases', method: HTTP_METHODS.GET },
39833
+ consume: { url: '/titles/{title_id}/microtransactions/consume', method: HTTP_METHODS.POST },
39834
+ requestRefund: { url: '/titles/{title_id}/microtransactions/refund-requests', method: HTTP_METHODS.POST },
39835
+ acknowledgeDelivery: { url: '/titles/{title_id}/microtransactions/deliveries/{delivery_id}/acknowledge', method: HTTP_METHODS.POST },
39836
+ mcpCapabilities: { url: '/mcp/v1/titles/{title_id}/microtransactions/capabilities', method: HTTP_METHODS.GET },
39837
+ mcpOperation: { url: '/mcp/v1/titles/{title_id}/microtransactions/operations/{operation}', method: HTTP_METHODS.POST },
39838
+ };
39839
+ return MicrotransactionsRoute;
39840
+ }());
39841
+
39842
+ /**
39843
+ * Provider-neutral, title-scoped commerce. Configure with user JWT; purchases
39844
+ * use a recoverable user account and limited checkout capability. Install/title
39845
+ * tokens cannot authorize money, ownership, refunds, or catalog changes.
39846
+ *
39847
+ * Each result preserves payment versus fulfillment versus settlement. Redirects
39848
+ * and postMessage events only trigger an authoritative refresh. A timeout is
39849
+ * unknown; reconcile the original attempt instead of charging another provider.
39850
+ */
39851
+ var Microtransactions = /** @class */ (function () {
39852
+ function Microtransactions() {
39853
+ }
39854
+ /**
39855
+ * Upload an image/video through existing Glitch Media processing with title
39856
+ * and actor ownership. Attach its returned Media ID to products/branding.
39857
+ * Does not create a social-library post, scheduler, or new payment product.
39858
+ */
39859
+ Microtransactions.uploadMedia = function (title_id, media, onUploadProgress, options) {
39860
+ if (!/^[A-Za-z0-9_:-]+$/.test(title_id))
39861
+ throw new Error('Invalid commerce title identifier.');
39862
+ return Requests.uploadFile(MicrotransactionsRoute.routes.uploadMedia.url.replace('{title_id}', encodeURIComponent(title_id)), 'media', media, {}, undefined, onUploadProgress, options);
39863
+ };
39864
+ /** Same title-authorized Media pipeline using the caller's MCP credential and commerce:write ability. */
39865
+ Microtransactions.mcpUploadMedia = function (title_id, media, onUploadProgress, options) {
39866
+ if (!/^[A-Za-z0-9_:-]+$/.test(title_id))
39867
+ throw new Error('Invalid commerce title identifier.');
39868
+ return Requests.uploadFile(MicrotransactionsRoute.routes.mcpUploadMedia.url.replace('{title_id}', encodeURIComponent(title_id)), 'media', media, {}, undefined, onUploadProgress, options);
39869
+ };
39870
+ /** Admin settings, including immutable 1200bp commission and readiness blockers. */
39871
+ Microtransactions.settings = function (title_id, options) { return this.call('settings', title_id, undefined, {}, undefined, options); };
39872
+ /** Atomic policy update. Sandbox/off by default. Cannot disable the final working revenue model. */
39873
+ Microtransactions.updateSettings = function (title_id, data, options) { return this.call('updateSettings', title_id, data, {}, undefined, options); };
39874
+ /** Read-only country/provider/approval readiness; never enables a provider. */
39875
+ Microtransactions.readiness = function (title_id, options) { return this.call('readiness', title_id, undefined, {}, undefined, options); };
39876
+ /** Admin list includes drafts and archives. Player clients should use catalog(). */
39877
+ Microtransactions.listProducts = function (title_id, options) { return this.call('products', title_id, undefined, {}, undefined, options); };
39878
+ /** Save a catalog product. Prices use integer minor units and attached media must belong to the title. */
39879
+ Microtransactions.createProduct = function (title_id, data, options) { return this.call('createProduct', title_id, data, {}, undefined, options); };
39880
+ /** Update a product version. Existing order snapshots remain unchanged. */
39881
+ Microtransactions.updateProduct = function (title_id, product_id, data, options) { return this.call('updateProduct', title_id, data, { product_id: product_id }, undefined, options); };
39882
+ /** Archive, never delete financial history. Requires explicit confirmation. */
39883
+ Microtransactions.archiveProduct = function (title_id, product_id, data, options) { return this.call('archiveProduct', title_id, data, { product_id: product_id }, undefined, options); };
39884
+ /** Public provider metadata only. Credentials and commercial approvals are platform-managed. */
39885
+ Microtransactions.providers = function (title_id, options) { return this.call('providers', title_id, undefined, {}, undefined, options); };
39886
+ /** Admin read of separate-currency balances; pending is not withdrawable revenue. */
39887
+ Microtransactions.earnings = function (title_id, params, options) { return this.call('earnings', title_id, undefined, {}, params, options); };
39888
+ /** Admin list, bounded to the server's most recent 100 redacted orders. */
39889
+ Microtransactions.listOrders = function (title_id, params, options) { return this.call('orders', title_id, undefined, {}, params, options); };
39890
+ /** Owner JWT/scoped player token or title admin. An arbitrary order UUID grants no access. */
39891
+ Microtransactions.getOrder = function (title_id, order_id, options) { return this.call('order', title_id, undefined, { order_id: order_id }, undefined, options); };
39892
+ /** Financial admin only; original provider and human approval. Omit amount_minor for remaining full refund; partial amounts are bounded and allocated pro rata. */
39893
+ Microtransactions.refundOrder = function (title_id, order_id, data, options) { return this.call('refund', title_id, data, { order_id: order_id }, undefined, options); };
39894
+ /** Replay the same immutable event. Receiver must deduplicate event_id. This cannot mint goods. */
39895
+ Microtransactions.replayDelivery = function (title_id, delivery_id, data, options) { return this.call('replayDelivery', title_id, data, { delivery_id: delivery_id }, undefined, options); };
39896
+ /** Public eligible catalog. Sandbox is restricted by backend environment/admin policy. */
39897
+ Microtransactions.catalog = function (title_id, params, options) { return this.call('catalog', title_id, undefined, {}, params, options); };
39898
+ /** User-authenticated quote. Clients select product/quantity, never monetary values or seller accounts. */
39899
+ Microtransactions.createQuote = function (title_id, data, options) { return this.call('createQuote', title_id, data, {}, undefined, options); };
39900
+ /** Anonymous-safe opening step only. The hosted UI creates/logs into an account before payment. */
39901
+ Microtransactions.createCheckoutSession = function (title_id, data, options) { return this.call('createCheckoutSession', title_id, data, {}, undefined, options); };
39902
+ /** Anonymous-safe inventory recovery. Opens an in-game hosted sign-in overlay, never creates a charge or requires the game's account JWT. */
39903
+ Microtransactions.createRestoreSession = function (title_id, data, options) { return this.call('createRestoreSession', title_id, data, {}, undefined, options); };
39904
+ /** Read the session using its limited capability. Cannot mutate user identity or declare payment. */
39905
+ Microtransactions.getCheckoutSession = function (title_id, session_id, options) { return this.call('checkoutSession', title_id, undefined, { session_id: session_id }, undefined, options); };
39906
+ /** Anonymous, read-only embedding policy: server-approved frame ancestors only, no player/session capability data. */
39907
+ Microtransactions.getCheckoutFramePolicy = function (title_id, session_id, options) { return this.call('checkoutFramePolicy', title_id, undefined, { session_id: session_id }, undefined, options); };
39908
+ /** Anonymous title-wide approved embedding policy for trusted hosted account pages; no player data. */
39909
+ Microtransactions.getFramePolicy = function (title_id, options) { return this.call('framePolicy', title_id, undefined, {}, undefined, options); };
39910
+ /** Bind once to the existing authenticated account. Cannot reassign another player's purchase. */
39911
+ Microtransactions.authenticateCheckoutSession = function (title_id, session_id, options) { return this.call('authenticateCheckoutSession', title_id, {}, { session_id: session_id }, undefined, options); };
39912
+ /** Bound-user JWT + session capability. Reuse the idempotency key after a network timeout. */
39913
+ Microtransactions.checkout = function (title_id, session_id, data, options) { return this.call('checkout', title_id, data, { session_id: session_id }, undefined, options); };
39914
+ /** Query original provider; never creates another charge. Pending/unknown remains non-terminal. */
39915
+ Microtransactions.reconcileCheckoutSession = function (title_id, session_id, options) { return this.call('reconcileCheckout', title_id, {}, { session_id: session_id }, undefined, options); };
39916
+ /** Hosted checkout only. Server issues an expiring one-time game handoff after verified fulfillment. */
39917
+ Microtransactions.createHandoff = function (title_id, session_id, options) { return this.call('createHandoff', title_id, {}, { session_id: session_id }, undefined, options); };
39918
+ /** Game exchanges a verified popup code. Browser Origin must match return_origin; code is consumed once. */
39919
+ Microtransactions.claimHandoff = function (title_id, data, options) { return this.call('claimHandoff', title_id, data, {}, undefined, options); };
39920
+ /**
39921
+ * Authenticated hosted Glitch account only: restore a previous purchase into a
39922
+ * NEW nonce-bound session/handoff after the game's 15-minute token expires or
39923
+ * storage is cleared. Does not create another payment. Return to the game via
39924
+ * verified source/origin and a new bridge bound to event.checkout_session_id.
39925
+ */
39926
+ Microtransactions.restoreHandoff = function (title_id, data, options) { return this.call('restoreHandoff', title_id, data, {}, undefined, options); };
39927
+ /** Record integration proof from a genuinely paid, fulfilled sandbox order with a claimed game handoff. */
39928
+ Microtransactions.verifyIntegration = function (title_id, data, options) { return this.call('verifyIntegration', title_id, data, {}, undefined, options); };
39929
+ /** Restore authoritative durable ownership/current consumable balances, never mutable cloud-save balances. */
39930
+ Microtransactions.listEntitlements = function (title_id, params, options) { return this.call('entitlements', title_id, undefined, {}, params, options); };
39931
+ /**
39932
+ * Optional self-only purchase/usage history. A user JWT selects that user; a
39933
+ * scoped playerToken selects its bound title/player/environment and requires
39934
+ * the exact approved game Origin. No MCP/install token or caller-selected
39935
+ * user_id/player_id is accepted. JWT environment defaults to live; scoped
39936
+ * tokens default to their bound environment. Admin listOrders stays separate.
39937
+ *
39938
+ * Read response.data.data.purchases and .pagination. Use grant_usage for lot
39939
+ * consumption/refund/expiry status, listEntitlements for current aggregate
39940
+ * inventory, and consume for explicit gameplay spending. History never grants
39941
+ * inventory and durable/pass is_used is null rather than a guessed boolean.
39942
+ */
39943
+ Microtransactions.listMyPurchases = function (title_id, filters, options) {
39944
+ if (filters === void 0) { filters = {}; }
39945
+ var allowed = ['environment', 'page', 'per_page'];
39946
+ if (Object.keys(filters).some(function (key) { return !allowed.includes(key); }))
39947
+ throw new Error('Own purchase history supports only environment, page and per_page; identity cannot be selected.');
39948
+ if (filters.environment !== undefined && !['sandbox', 'live'].includes(filters.environment))
39949
+ throw new Error('Invalid purchase-history environment.');
39950
+ if (filters.page !== undefined && (!Number.isInteger(filters.page) || filters.page < 1 || filters.page > 10000))
39951
+ throw new Error('Purchase-history page must be an integer from 1 to 10000.');
39952
+ if (filters.per_page !== undefined && (!Number.isInteger(filters.per_page) || filters.per_page < 1 || filters.per_page > 100))
39953
+ throw new Error('Purchase-history per_page must be an integer from 1 to 100.');
39954
+ return this.call('myPurchases', title_id, undefined, {}, filters, options);
39955
+ };
39956
+ /** Atomic tracked spending. Reuse action_id for retries; a new gameplay action needs a new ID. */
39957
+ Microtransactions.consume = function (title_id, data, options) { return this.call('consume', title_id, data, {}, undefined, options); };
39958
+ /** Owning user asks support to review a refund. This does not execute payment reversal. */
39959
+ Microtransactions.requestRefund = function (title_id, data, options) { return this.call('requestRefund', title_id, data, {}, undefined, options); };
39960
+ /** Trusted title server with commerce:fulfill or admin JWT acknowledges the immutable event. */
39961
+ Microtransactions.acknowledgeDelivery = function (title_id, delivery_id, data, options) { return this.call('acknowledgeDelivery', title_id, data, { delivery_id: delivery_id }, undefined, options); };
39962
+ /** Title MCP token, never a runtime install token. Describes every argument/schema/ability/approval gate. */
39963
+ Microtransactions.mcpCapabilities = function (title_id, options) { return this.call('mcpCapabilities', title_id, undefined, {}, undefined, options); };
39964
+ /** Execute only an operation discovered in mcpCapabilities. confirm is not financial approval. */
39965
+ Microtransactions.mcpOperation = function (title_id, operation, data, options) { return this.call('mcpOperation', title_id, data, { operation: operation }, undefined, options); };
39966
+ Microtransactions.call = function (route, title_id, data, ids, params, options) {
39967
+ if (ids === void 0) { ids = {}; }
39968
+ var replacements = {};
39969
+ for (var _i = 0, _a = Object.entries(__assign({ title_id: title_id }, ids)); _i < _a.length; _i++) {
39970
+ var _b = _a[_i], key = _b[0], value = _b[1];
39971
+ if (!value || !/^[A-Za-z0-9_.:-]+$/.test(value) || value === '.' || value === '..')
39972
+ throw new Error("Invalid commerce route identifier: ".concat(key));
39973
+ replacements[key] = encodeURIComponent(value);
39974
+ }
39975
+ var headers = {};
39976
+ if (options === null || options === void 0 ? void 0 : options.playerToken)
39977
+ headers.Authorization = "Bearer ".concat(options.playerToken);
39978
+ if (options && 'checkoutToken' in options) {
39979
+ if (!options.checkoutToken)
39980
+ throw new Error('A checkout capability is required.');
39981
+ headers['X-Checkout-Token'] = options.checkoutToken;
39982
+ }
39983
+ return Requests.processRoute(MicrotransactionsRoute.routes[route], data, replacements, params, {
39984
+ signal: options === null || options === void 0 ? void 0 : options.signal, timeout: options === null || options === void 0 ? void 0 : options.timeout,
39985
+ headers: headers,
39986
+ // Self-history accepts only its explicit filters, not global community scope.
39987
+ excludeCommunityContext: route === 'myPurchases',
39988
+ });
39989
+ };
39990
+ return Microtransactions;
39991
+ }());
39992
+
39993
+ /** Generate a 256-bit browser nonce. Fails closed without secure Web Crypto. */
39994
+ function createMicrotransactionNonce() {
39995
+ var _a;
39996
+ if (typeof ((_a = globalThis.crypto) === null || _a === void 0 ? void 0 : _a.getRandomValues) !== 'function') {
39997
+ throw new Error('Secure Web Crypto is required for a checkout nonce.');
39998
+ }
39999
+ var bytes = new Uint8Array(32);
40000
+ globalThis.crypto.getRandomValues(bytes);
40001
+ return Array.from(bytes, function (value) { return value.toString(16).padStart(2, '0'); }).join('');
40002
+ }
40003
+ /**
40004
+ * Listen for Glitch-hosted, game-branded checkout changes with strict origin,
40005
+ * source, title, session, and nonce binding. Message data cannot grant an item.
40006
+ * The caller always verifies the session at Glitch before updating inventory.
40007
+ *
40008
+ * Prefer openMicrotransactionOverlay with the exact server-returned URL. The
40009
+ * game stays mounted; no top-level navigation fallback is permitted. If an
40010
+ * embedded flow is unavailable, show retry/close and preserve the game state.
40011
+ * refresh() requires an already verified claim. Keep
40012
+ * secrets in memory/session storage or a URL fragment, never query parameters.
40013
+ * Dispose on game unmount/account change. Reconnect restores ownership through
40014
+ * the authenticated entitlement API, not a saved "purchase successful" flag.
40015
+ */
40016
+ function createMicrotransactionBridge(options) {
40017
+ if (!options.checkoutSessionId)
40018
+ throw new Error('The original checkout session is required.');
40019
+ return createBridge(options, options.checkoutSessionId);
40020
+ }
40021
+ /**
40022
+ * Restore-only bridge for /games/:titleId/purchases/restore. Pin the prior order,
40023
+ * fresh nonce, exact Glitch origin and opened window. The hosted signed-in page
40024
+ * creates a NEW session; the server-verified claim must match that new session
40025
+ * and the pinned order. This does not relax purchase-session binding.
40026
+ *
40027
+ * Open the hosted restore page, never request the account JWT in the game.
40028
+ * verify(message) exchanges the code using message.checkout_session_id. All
40029
+ * duplicate-code, expiry and same-player refresh safeguards still apply.
40030
+ */
40031
+ function createMicrotransactionRestoreBridge(options) {
40032
+ if (!/^[A-Za-z0-9_:-]{1,160}$/.test(options.orderId))
40033
+ throw new Error('The original verified order is required for restore.');
40034
+ return createBridge(options, undefined, options.orderId);
40035
+ }
40036
+ function createBridge(options, checkoutSessionId, expectedOrderId) {
40037
+ var _this = this;
40038
+ var _a;
40039
+ var origin = new URL(options.checkoutOrigin);
40040
+ var local = ['localhost', '127.0.0.1', '[::1]'].includes(origin.hostname) || origin.hostname.endsWith('.test') || (origin.hostname === 'www.glitch.local' && origin.port === '3000');
40041
+ if (origin.origin !== options.checkoutOrigin || origin.username || origin.password ||
40042
+ (origin.protocol !== 'https:' && !(options.allowLocalDevelopment && local && origin.protocol === 'http:'))) {
40043
+ throw new Error('Checkout requires an exact trusted HTTPS origin.');
40044
+ }
40045
+ if (!options.checkoutWindow || !options.titleId ||
40046
+ !/^[A-Za-z0-9_-]{22,128}$/.test(options.nonce)) {
40047
+ throw new Error('Checkout window, title, session, and secure nonce are required.');
40048
+ }
40049
+ var target = (_a = options.eventTarget) !== null && _a !== void 0 ? _a : window;
40050
+ var disposed = false;
40051
+ var inFlight;
40052
+ var verified;
40053
+ var attemptedCodes = new Set();
40054
+ var accept = function (result, orderId, sessionId) { return __awaiter$1(_this, void 0, void 0, function () {
40055
+ return __generator(this, function (_a) {
40056
+ switch (_a.label) {
40057
+ case 0:
40058
+ if (disposed)
40059
+ return [2 /*return*/];
40060
+ if (result.title_id !== options.titleId || result.checkout_session_id !== sessionId || result.order_id !== orderId ||
40061
+ (verified && verified.player_id !== result.player_id) ||
40062
+ typeof result.player_id !== 'string' || !result.player_id || typeof result.player_token !== 'string' || !result.player_token ||
40063
+ !Array.isArray(result.entitlements) || !Number.isFinite(Date.parse(result.expires_at)) || Date.parse(result.expires_at) <= Date.now()) {
40064
+ throw new Error('Checkout verification returned an invalid or differently bound claim.');
40065
+ }
40066
+ verified = result;
40067
+ return [4 /*yield*/, options.onVerified(result)];
40068
+ case 1:
40069
+ _a.sent();
40070
+ return [2 /*return*/];
40071
+ }
40072
+ });
40073
+ }); };
40074
+ var refresh = function () {
40075
+ if (disposed)
40076
+ return Promise.resolve();
40077
+ if (inFlight)
40078
+ return inFlight;
40079
+ if (!verified || !options.refresh)
40080
+ return Promise.reject(new Error('A verified claim and scoped-token refresh callback are required.'));
40081
+ var previous = verified;
40082
+ inFlight = Promise.resolve().then(function () { return options.refresh(previous); }).then(function (result) { return accept(result, previous.order_id, previous.checkout_session_id); }).finally(function () { inFlight = undefined; });
40083
+ return inFlight;
40084
+ };
40085
+ var listener = function (event) {
40086
+ if (disposed || event.origin !== options.checkoutOrigin || event.source !== options.checkoutWindow)
40087
+ return;
40088
+ var value = event.data;
40089
+ if (!value || typeof value !== 'object')
40090
+ return;
40091
+ var message = value;
40092
+ if (message.type !== 'glitch.microtransaction.updated' || message.version !== 1 || message.title_id !== options.titleId ||
40093
+ (checkoutSessionId && message.checkout_session_id !== checkoutSessionId) || message.nonce !== options.nonce ||
40094
+ typeof message.checkout_session_id !== 'string' || !/^[A-Za-z0-9_:-]{1,160}$/.test(message.checkout_session_id) ||
40095
+ (expectedOrderId && message.order_id !== expectedOrderId) ||
40096
+ typeof message.order_id !== 'string' || !/^[A-Za-z0-9_:-]{1,160}$/.test(message.order_id) ||
40097
+ typeof message.claim_code !== 'string' || !/^[A-Za-z0-9_-]{40,128}$/.test(message.claim_code))
40098
+ return;
40099
+ if (inFlight || attemptedCodes.has(message.claim_code) || attemptedCodes.size >= 8)
40100
+ return;
40101
+ if (verified && (verified.order_id !== message.order_id || verified.checkout_session_id !== message.checkout_session_id))
40102
+ return;
40103
+ // Mark BEFORE network I/O. Even a timeout can mean the server consumed it.
40104
+ attemptedCodes.add(message.claim_code);
40105
+ var handoff = message;
40106
+ inFlight = Promise.resolve().then(function () { return options.verify(handoff); }).then(function (result) { return accept(result, handoff.order_id, handoff.checkout_session_id); }).finally(function () { inFlight = undefined; });
40107
+ void inFlight.catch(function (error) {
40108
+ var _a;
40109
+ if (!disposed)
40110
+ (_a = options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
40111
+ });
40112
+ };
40113
+ target.addEventListener('message', listener);
40114
+ return {
40115
+ refresh: refresh,
40116
+ dispose: function () {
40117
+ disposed = true;
40118
+ verified = undefined;
40119
+ attemptedCodes.clear();
40120
+ target.removeEventListener('message', listener);
40121
+ },
40122
+ };
40123
+ }
40124
+
40125
+ var overlaySequence = 0;
40126
+ var activeOverlays = new WeakMap();
40127
+ /**
40128
+ * Mount Glitch checkout IN the running game. The game document, URL and session
40129
+ * stay intact. Uses a modal dialog with focus restore and a sandboxed payment
40130
+ * iframe. No top-navigation permission or top-level/popup-blocked fallback exists.
40131
+ * Only bank/OAuth verification may open a controlled provider window from inside
40132
+ * the frame. If embedding is unavailable, show retry/close instead of navigating.
40133
+ *
40134
+ * Receipt messages must originate from this exact iframe.contentWindow and pass
40135
+ * origin/title/session/nonce checks. The SDK redeems the one-time claim at Glitch
40136
+ * and uses the returned scoped player token only on commerce requests. Closing
40137
+ * does not cancel an uncertain payment, grant goods, or discard the game state.
40138
+ */
40139
+ function openMicrotransactionOverlay(options) {
40140
+ var _this = this;
40141
+ var _a, _b, _c, _d;
40142
+ var doc = (_a = options.document) !== null && _a !== void 0 ? _a : document;
40143
+ var win = doc.defaultView;
40144
+ if (!win || !doc.body)
40145
+ throw new Error('A mounted game document is required.');
40146
+ if (activeOverlays.has(doc))
40147
+ throw new Error('A checkout is already open. Resume or close that same purchase first.');
40148
+ var session = options.session;
40149
+ var parsed = new URL(session.hosted_url);
40150
+ var path = "/games/".concat(encodeURIComponent(options.titleId), "/checkout/").concat(encodeURIComponent(session.id));
40151
+ if (parsed.origin !== options.checkoutOrigin || parsed.pathname !== path || parsed.search || parsed.username || parsed.password ||
40152
+ new URLSearchParams(parsed.hash.slice(1)).get('token') !== session.session_token || !session.session_token ||
40153
+ (session.checkout_session_id && session.checkout_session_id !== session.id)) {
40154
+ throw new Error('The hosted checkout URL does not match its title, session and capability.');
40155
+ }
40156
+ var timeout = Math.min(60000, Math.max(1000, (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 15000));
40157
+ var requestedFrameTimeout = (_c = options.frameLoadTimeoutMs) !== null && _c !== void 0 ? _c : 20000;
40158
+ var frameTimeout = Number.isFinite(requestedFrameTimeout) ? Math.min(60000, Math.max(1000, requestedFrameTimeout)) : 20000;
40159
+ var beforeFocus = doc.activeElement;
40160
+ var beforeOverflow = doc.body.style.overflow;
40161
+ var dialog = doc.createElement('dialog');
40162
+ var id = "glitch-commerce-modal-".concat(++overlaySequence);
40163
+ dialog.id = id;
40164
+ dialog.setAttribute('aria-modal', 'true');
40165
+ dialog.setAttribute('aria-labelledby', "".concat(id, "-title"));
40166
+ dialog.setAttribute('role', 'dialog');
40167
+ dialog.style.cssText = 'position:fixed;inset:16px;margin:auto;padding:0;border:1px solid #cbd5e1;border-radius:16px;width:min(1100px,calc(100vw - 32px));height:min(850px,calc(100dvh - 32px));max-width:none;max-height:none;background:#fff;color:#172033;box-shadow:0 24px 90px #0008;z-index:2147483647;overflow:hidden;';
40168
+ var style = doc.createElement('style');
40169
+ style.textContent = "#".concat(id, "::backdrop{background:rgba(8,16,32,.72)}#").concat(id, " button:focus-visible{outline:3px solid #4263eb;outline-offset:3px}@media(max-width:600px){#").concat(id, "{inset:0!important;width:100vw!important;height:100dvh!important;border-radius:0!important}}");
40170
+ var header = doc.createElement('div');
40171
+ header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:16px;padding:12px 16px;border-bottom:1px solid #e2e8f0;height:56px;box-sizing:border-box;';
40172
+ var heading = doc.createElement('h2');
40173
+ heading.id = "".concat(id, "-title");
40174
+ heading.textContent = options.label || (session.intent === 'restore' ? 'Restore game purchases' : 'Secure game checkout');
40175
+ heading.style.cssText = 'margin:0;font:600 17px/1.3 system-ui,sans-serif;color:#172033;';
40176
+ var closeButton = doc.createElement('button');
40177
+ closeButton.type = 'button';
40178
+ closeButton.textContent = 'Close';
40179
+ closeButton.setAttribute('aria-label', 'Close checkout and return to game');
40180
+ closeButton.style.cssText = 'border:1px solid #cbd5e1;border-radius:8px;padding:7px 14px;background:#fff;color:#172033;font:600 14px system-ui,sans-serif;cursor:pointer;';
40181
+ var retryButton = doc.createElement('button');
40182
+ retryButton.type = 'button';
40183
+ retryButton.textContent = 'Retry';
40184
+ retryButton.setAttribute('aria-label', 'Reload this same checkout without starting another purchase');
40185
+ retryButton.style.cssText = closeButton.style.cssText;
40186
+ var controls = doc.createElement('div');
40187
+ controls.style.cssText = 'display:flex;gap:8px;';
40188
+ controls.append(retryButton, closeButton);
40189
+ header.append(heading, controls);
40190
+ var status = doc.createElement('div');
40191
+ status.setAttribute('role', 'status');
40192
+ status.style.cssText = 'padding:6px 16px;font:12px/1.4 system-ui,sans-serif;background:#f1f5f9;color:#172033;min-height:28px;box-sizing:border-box;';
40193
+ status.textContent = 'Your game stays open. Loading secure checkout…';
40194
+ var iframe = doc.createElement('iframe');
40195
+ iframe.title = heading.textContent;
40196
+ iframe.setAttribute('allow', 'payment');
40197
+ iframe.setAttribute('sandbox', 'allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox');
40198
+ iframe.referrerPolicy = 'no-referrer';
40199
+ iframe.style.cssText = 'display:block;width:100%;height:calc(100% - 84px);border:0;background:#fff;';
40200
+ iframe.src = session.hosted_url;
40201
+ dialog.append(style, header, status, iframe);
40202
+ doc.body.append(dialog);
40203
+ var frameWindow = iframe.contentWindow;
40204
+ if (!frameWindow) {
40205
+ dialog.remove();
40206
+ throw new Error('In-game checkout embedding is unavailable. Your game has not navigated.');
40207
+ }
40208
+ var closed = false;
40209
+ var closing;
40210
+ var verified;
40211
+ var bridge;
40212
+ var frameLoadTimer;
40213
+ var appReadyTimer;
40214
+ var applicationReady = false;
40215
+ var blocked = [];
40216
+ var report = function (error) { var _a; try {
40217
+ (_a = options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
40218
+ }
40219
+ catch ( /* Consumer error handlers cannot prevent modal cleanup. */_b) { /* Consumer error handlers cannot prevent modal cleanup. */ } };
40220
+ var clearWatchdogs = function () {
40221
+ if (frameLoadTimer !== undefined)
40222
+ win.clearTimeout(frameLoadTimer);
40223
+ if (appReadyTimer !== undefined)
40224
+ win.clearTimeout(appReadyTimer);
40225
+ frameLoadTimer = undefined;
40226
+ appReadyTimer = undefined;
40227
+ };
40228
+ var unavailable = function (reason) {
40229
+ if (closed)
40230
+ return;
40231
+ clearWatchdogs();
40232
+ status.setAttribute('role', 'alert');
40233
+ status.textContent = reason === 'ready'
40234
+ ? 'Checkout did not become ready. Retry this same checkout or Close; your game remains open.'
40235
+ : 'Checkout could not load here. Retry this same checkout or Close; your game remains open.';
40236
+ report(new Error(reason === 'ready'
40237
+ ? 'Embedded checkout readiness timed out; no navigation or new payment was attempted.'
40238
+ : 'Embedded checkout loading unavailable; no navigation or new payment was attempted.'));
40239
+ };
40240
+ var markApplicationReady = function () {
40241
+ if (closed)
40242
+ return;
40243
+ applicationReady = true;
40244
+ clearWatchdogs();
40245
+ status.setAttribute('role', 'status');
40246
+ status.textContent = 'Checkout is ready. Your game remains open underneath.';
40247
+ };
40248
+ var armLoadWatchdog = function () {
40249
+ clearWatchdogs();
40250
+ applicationReady = false;
40251
+ frameLoadTimer = win.setTimeout(function () { return unavailable('load'); }, frameTimeout);
40252
+ };
40253
+ var receipt = function () { return __awaiter$1(_this, void 0, void 0, function () {
40254
+ var response, current;
40255
+ var _a;
40256
+ return __generator(this, function (_b) {
40257
+ switch (_b.label) {
40258
+ case 0: return [4 /*yield*/, Microtransactions.getCheckoutSession(options.titleId, session.id, { checkoutToken: session.session_token, timeout: timeout })];
40259
+ case 1:
40260
+ response = _b.sent();
40261
+ current = response.data.data;
40262
+ if (current.id !== session.id || current.title.id !== options.titleId)
40263
+ throw new Error('Checkout status returned a different title or session.');
40264
+ return [4 /*yield*/, ((_a = options.onOrderUpdate) === null || _a === void 0 ? void 0 : _a.call(options, current.order))];
40265
+ case 2:
40266
+ _b.sent();
40267
+ return [2 /*return*/];
40268
+ }
40269
+ });
40270
+ }); };
40271
+ try {
40272
+ bridge = createMicrotransactionBridge({
40273
+ titleId: options.titleId, checkoutSessionId: session.id, checkoutOrigin: options.checkoutOrigin,
40274
+ checkoutWindow: frameWindow, nonce: session.nonce, eventTarget: win,
40275
+ allowLocalDevelopment: options.allowLocalDevelopment,
40276
+ verify: function (message) { return __awaiter$1(_this, void 0, void 0, function () {
40277
+ return __generator(this, function (_a) {
40278
+ switch (_a.label) {
40279
+ case 0: return [4 /*yield*/, Microtransactions.claimHandoff(options.titleId, {
40280
+ claim_code: message.claim_code, checkout_session_id: session.id, nonce: session.nonce, return_origin: win.location.origin,
40281
+ }, { timeout: timeout })];
40282
+ case 1: return [2 /*return*/, (_a.sent()).data.data];
40283
+ }
40284
+ });
40285
+ }); },
40286
+ refresh: function (previous) { return __awaiter$1(_this, void 0, void 0, function () {
40287
+ var auth, order, inventory;
40288
+ var _a;
40289
+ return __generator(this, function (_b) {
40290
+ switch (_b.label) {
40291
+ case 0:
40292
+ auth = { playerToken: previous.player_token, timeout: timeout };
40293
+ return [4 /*yield*/, Microtransactions.getOrder(options.titleId, previous.order_id, auth)];
40294
+ case 1:
40295
+ order = (_b.sent()).data.data;
40296
+ if (order.id !== previous.order_id || order.title_id !== options.titleId)
40297
+ throw new Error('Restored order identity mismatch.');
40298
+ return [4 /*yield*/, Microtransactions.listEntitlements(options.titleId, undefined, auth)];
40299
+ case 2:
40300
+ inventory = (_b.sent()).data.data;
40301
+ return [4 /*yield*/, ((_a = options.onOrderUpdate) === null || _a === void 0 ? void 0 : _a.call(options, order))];
40302
+ case 3:
40303
+ _b.sent();
40304
+ return [2 /*return*/, __assign(__assign({}, previous), { entitlements: inventory.entitlements })];
40305
+ }
40306
+ });
40307
+ }); },
40308
+ onVerified: function (result) { return __awaiter$1(_this, void 0, void 0, function () { return __generator(this, function (_a) {
40309
+ switch (_a.label) {
40310
+ case 0:
40311
+ markApplicationReady();
40312
+ verified = result;
40313
+ return [4 /*yield*/, options.onVerified(result)];
40314
+ case 1:
40315
+ _a.sent();
40316
+ return [2 /*return*/];
40317
+ }
40318
+ }); }); },
40319
+ onError: report,
40320
+ });
40321
+ }
40322
+ catch (error) {
40323
+ dialog.remove();
40324
+ throw error;
40325
+ }
40326
+ var refresh = function () { return __awaiter$1(_this, void 0, void 0, function () {
40327
+ return __generator(this, function (_a) {
40328
+ switch (_a.label) {
40329
+ case 0:
40330
+ if (!verified) return [3 /*break*/, 2];
40331
+ return [4 /*yield*/, bridge.refresh()];
40332
+ case 1:
40333
+ _a.sent();
40334
+ return [3 /*break*/, 4];
40335
+ case 2: return [4 /*yield*/, receipt()];
40336
+ case 3:
40337
+ _a.sent();
40338
+ _a.label = 4;
40339
+ case 4: return [2 /*return*/];
40340
+ }
40341
+ });
40342
+ }); };
40343
+ var onKey = function (event) {
40344
+ if (event.key === 'Escape') {
40345
+ event.preventDefault();
40346
+ void overlay.close();
40347
+ }
40348
+ if (event.key === 'Tab' && !closed) {
40349
+ if (event.shiftKey && doc.activeElement === retryButton) {
40350
+ event.preventDefault();
40351
+ iframe.focus();
40352
+ }
40353
+ else if (!event.shiftKey && doc.activeElement === iframe) {
40354
+ event.preventDefault();
40355
+ retryButton.focus();
40356
+ }
40357
+ }
40358
+ };
40359
+ var onCancel = function (event) { event.preventDefault(); void overlay.close(); };
40360
+ var onCloseMessage = function (event) {
40361
+ if (closed || event.origin !== options.checkoutOrigin || event.source !== frameWindow || !event.data || typeof event.data !== 'object')
40362
+ return;
40363
+ var message = event.data;
40364
+ if (message.version !== 1 || message.title_id !== options.titleId ||
40365
+ message.checkout_session_id !== session.id || message.nonce !== session.nonce)
40366
+ return;
40367
+ if (message.type === 'glitch.microtransaction.ready') {
40368
+ markApplicationReady();
40369
+ return;
40370
+ }
40371
+ if (message.type !== 'glitch.microtransaction.close')
40372
+ return;
40373
+ void overlay.close(verified ? 'completed' : 'dismissed');
40374
+ };
40375
+ var onFrameError = function () { unavailable('error'); };
40376
+ var onFrameLoad = function () {
40377
+ if (closed)
40378
+ return;
40379
+ if (frameLoadTimer !== undefined)
40380
+ win.clearTimeout(frameLoadTimer);
40381
+ frameLoadTimer = undefined;
40382
+ if (applicationReady)
40383
+ return;
40384
+ status.setAttribute('role', 'status');
40385
+ status.textContent = 'Checkout document loaded. Waiting for the secure checkout interface…';
40386
+ // A document load is not proof the app rendered. Repeated loads cannot
40387
+ // indefinitely extend this bounded wait; only explicit Retry resets it.
40388
+ if (appReadyTimer === undefined)
40389
+ appReadyTimer = win.setTimeout(function () { return unavailable('ready'); }, frameTimeout);
40390
+ };
40391
+ var overlay = {
40392
+ element: dialog,
40393
+ iframe: iframe,
40394
+ refresh: refresh,
40395
+ retry: function () {
40396
+ if (closed)
40397
+ return;
40398
+ status.textContent = 'Retrying the same secure checkout. Your game stays open.';
40399
+ status.setAttribute('role', 'status');
40400
+ armLoadWatchdog();
40401
+ iframe.src = session.hosted_url;
40402
+ },
40403
+ close: function (reason) {
40404
+ if (reason === void 0) { reason = 'dismissed'; }
40405
+ if (closing)
40406
+ return closing;
40407
+ if (closed)
40408
+ return Promise.resolve();
40409
+ closed = true;
40410
+ clearWatchdogs();
40411
+ status.textContent = 'Finishing secure purchase verification. Your game stays open.';
40412
+ closing = (function () { return __awaiter$1(_this, void 0, void 0, function () {
40413
+ var error_1, error_2, _i, blocked_1, item, error_3;
40414
+ var _a;
40415
+ return __generator(this, function (_b) {
40416
+ switch (_b.label) {
40417
+ case 0:
40418
+ _b.trys.push([0, 5, 6, 11]);
40419
+ _b.label = 1;
40420
+ case 1:
40421
+ _b.trys.push([1, 3, , 4]);
40422
+ return [4 /*yield*/, bridge.refresh()];
40423
+ case 2:
40424
+ _b.sent();
40425
+ return [3 /*break*/, 4];
40426
+ case 3:
40427
+ error_1 = _b.sent();
40428
+ if (verified)
40429
+ throw error_1;
40430
+ return [3 /*break*/, 4];
40431
+ case 4: return [3 /*break*/, 11];
40432
+ case 5:
40433
+ error_2 = _b.sent();
40434
+ report(error_2);
40435
+ return [3 /*break*/, 11];
40436
+ case 6:
40437
+ win.removeEventListener('keydown', onKey, true);
40438
+ win.removeEventListener('message', onCloseMessage);
40439
+ dialog.removeEventListener('cancel', onCancel);
40440
+ iframe.removeEventListener('load', onFrameLoad);
40441
+ iframe.removeEventListener('error', onFrameError);
40442
+ dialog.remove();
40443
+ doc.body.style.overflow = beforeOverflow;
40444
+ for (_i = 0, blocked_1 = blocked; _i < blocked_1.length; _i++) {
40445
+ item = blocked_1[_i];
40446
+ item.element.inert = item.inert;
40447
+ if (item.ariaHidden === null)
40448
+ item.element.removeAttribute('aria-hidden');
40449
+ else
40450
+ item.element.setAttribute('aria-hidden', item.ariaHidden);
40451
+ }
40452
+ activeOverlays.delete(doc);
40453
+ (beforeFocus === null || beforeFocus === void 0 ? void 0 : beforeFocus.isConnected) && beforeFocus.focus();
40454
+ try {
40455
+ (_a = options.onClose) === null || _a === void 0 ? void 0 : _a.call(options, reason);
40456
+ }
40457
+ catch (error) {
40458
+ report(error);
40459
+ }
40460
+ if (!!verified) return [3 /*break*/, 10];
40461
+ _b.label = 7;
40462
+ case 7:
40463
+ _b.trys.push([7, 9, , 10]);
40464
+ return [4 /*yield*/, receipt()];
40465
+ case 8:
40466
+ _b.sent();
40467
+ return [3 /*break*/, 10];
40468
+ case 9:
40469
+ error_3 = _b.sent();
40470
+ report(error_3);
40471
+ return [3 /*break*/, 10];
40472
+ case 10:
40473
+ bridge.dispose();
40474
+ return [7 /*endfinally*/];
40475
+ case 11: return [2 /*return*/];
40476
+ }
40477
+ });
40478
+ }); })();
40479
+ return closing;
40480
+ },
40481
+ };
40482
+ closeButton.addEventListener('click', function () { void overlay.close(); });
40483
+ retryButton.addEventListener('click', overlay.retry);
40484
+ iframe.addEventListener('error', onFrameError);
40485
+ iframe.addEventListener('load', onFrameLoad);
40486
+ dialog.addEventListener('cancel', onCancel);
40487
+ win.addEventListener('keydown', onKey, true);
40488
+ win.addEventListener('message', onCloseMessage);
40489
+ doc.body.style.overflow = 'hidden';
40490
+ if (typeof dialog.showModal === 'function') {
40491
+ try {
40492
+ dialog.showModal();
40493
+ }
40494
+ catch (error) {
40495
+ void overlay.close('unavailable');
40496
+ throw error;
40497
+ }
40498
+ }
40499
+ else {
40500
+ dialog.setAttribute('open', '');
40501
+ for (var _i = 0, _e = Array.from(doc.body.children); _i < _e.length; _i++) {
40502
+ var child = _e[_i];
40503
+ if (child !== dialog && child instanceof win.HTMLElement) {
40504
+ var element = child;
40505
+ blocked.push({ element: element, inert: element.inert, ariaHidden: element.getAttribute('aria-hidden') });
40506
+ element.inert = true;
40507
+ element.setAttribute('aria-hidden', 'true');
40508
+ }
40509
+ }
40510
+ }
40511
+ activeOverlays.set(doc, overlay);
40512
+ closeButton.focus();
40513
+ try {
40514
+ (_d = options.onOpen) === null || _d === void 0 ? void 0 : _d.call(options);
40515
+ }
40516
+ catch (error) {
40517
+ void overlay.close('unavailable');
40518
+ throw error;
40519
+ }
40520
+ if (!closed)
40521
+ armLoadWatchdog();
40522
+ return overlay;
40523
+ }
40524
+ /** Same in-game modal for anonymous-safe restore sessions; never opens a new payment. */
40525
+ function openMicrotransactionRestoreOverlay(options) {
40526
+ if (options.session.intent !== 'restore')
40527
+ throw new Error('Create a restore session before opening purchase recovery.');
40528
+ return openMicrotransactionOverlay(options);
40529
+ }
40530
+
39669
40531
  var Parser = /** @class */ (function () {
39670
40532
  function Parser() {
39671
40533
  }
@@ -40193,6 +41055,7 @@ var Glitch = /** @class */ (function () {
40193
41055
  Newsletters: Newsletters,
40194
41056
  PlayTests: PlayTests,
40195
41057
  Media: Media,
41058
+ FestivalNetworking: FestivalNetworking,
40196
41059
  Scheduler: Scheduler,
40197
41060
  RedditSubreddits: RedditSubreddits,
40198
41061
  Funnel: Funnel,
@@ -40218,6 +41081,7 @@ var Glitch = /** @class */ (function () {
40218
41081
  GameAdvertising: GameAdvertising,
40219
41082
  Hosting: Hosting,
40220
41083
  GameDesign: GameDesign,
41084
+ Microtransactions: Microtransactions,
40221
41085
  };
40222
41086
  Glitch.util = {
40223
41087
  Requests: Requests,
@@ -40247,5 +41111,11 @@ var Glitch = /** @class */ (function () {
40247
41111
  return Glitch;
40248
41112
  }());
40249
41113
 
40250
- module.exports = Glitch;
41114
+ exports.createMicrotransactionBridge = createMicrotransactionBridge;
41115
+ exports.createMicrotransactionNonce = createMicrotransactionNonce;
41116
+ exports.createMicrotransactionRestoreBridge = createMicrotransactionRestoreBridge;
41117
+ exports.default = Glitch;
41118
+ exports.openMicrotransactionOverlay = openMicrotransactionOverlay;
41119
+ exports.openMicrotransactionRestoreOverlay = openMicrotransactionRestoreOverlay;
41120
+ module.exports = Object.assign(exports.default, exports);
40251
41121
  //# sourceMappingURL=index.js.map