box-content-preview 3.78.0 → 3.79.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![Mergify Status](https://img.shields.io/endpoint.svg?url=https://gh.mergify.io/badges/box/box-content-preview&style=flat)](https://mergify.io)
3
3
  [![Styled With Prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
4
4
  [![build status](https://img.shields.io/travis/box/box-content-preview/master.svg?style=flat-square)](https://travis-ci.org/box/box-content-preview)
5
- [![version](https://img.shields.io/badge/version-v3.78.0-blue.svg?style=flat-square)](https://github.com/box/box-content-preview)
5
+ [![version](https://img.shields.io/badge/version-v3.79.0-blue.svg?style=flat-square)](https://github.com/box/box-content-preview)
6
6
  [![npm version](https://img.shields.io/npm/v/box-ui-elements.svg?style=flat-square)](https://www.npmjs.com/package/box-ui-elements)
7
7
 
8
8
  # [Box Content Preview](https://developer.box.com/docs/box-content-preview)
@@ -22,11 +22,11 @@ We encourage all users to update their applications to utilize modern browsers f
22
22
 
23
23
  ## Current Version
24
24
 
25
- - Version: v3.78.0
25
+ - Version: v3.79.0
26
26
  - Locale: en-US
27
27
 
28
- https://cdn01.boxcdn.net/platform/preview/3.78.0/en-US/preview.js
29
- https://cdn01.boxcdn.net/platform/preview/3.78.0/en-US/preview.css
28
+ https://cdn01.boxcdn.net/platform/preview/3.79.0/en-US/preview.js
29
+ https://cdn01.boxcdn.net/platform/preview/3.79.0/en-US/preview.css
30
30
 
31
31
  ## Supported Locales
32
32
 
@@ -52,10 +52,10 @@ You can self-host the Box Content Preview library or reference the versions avai
52
52
  <title>Box Content Preview Demo</title>
53
53
 
54
54
  <!-- Latest version of Preview SDK for your locale -->
55
- <script src="https://cdn01.boxcdn.net/platform/preview/3.78.0/en-US/preview.js"></script>
55
+ <script src="https://cdn01.boxcdn.net/platform/preview/3.79.0/en-US/preview.js"></script>
56
56
  <link
57
57
  rel="stylesheet"
58
- href="https://cdn01.boxcdn.net/platform/preview/3.78.0/en-US/preview.css"
58
+ href="https://cdn01.boxcdn.net/platform/preview/3.79.0/en-US/preview.css"
59
59
  />
60
60
  </head>
61
61
  <body>
@@ -76,7 +76,7 @@ To self-host the Box Content Preview library, follow these steps:
76
76
 
77
77
  1. Either fork the repo and check out the version you want to host or download the specific version as a zip:
78
78
 
79
- - Check out a specific version with `git checkout v3.78.0`
79
+ - Check out a specific version with `git checkout v3.79.0`
80
80
  - Download a specific version as a zip from https://github.com/box/box-content-preview/releases
81
81
 
82
82
  2. Install dependencies and build the library with `yarn install && yarn build:i18n && yarn build:prod`
package/dist/lib/index.js CHANGED
@@ -15388,7 +15388,7 @@ function util_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var
15388
15388
  const CLIENT_NAME = "box-content-preview"; // eslint-disable-line no-undef
15389
15389
  const CLIENT_NAME_KEY = 'box_client_name';
15390
15390
  const CLIENT_VERSION_KEY = 'box_client_version';
15391
- const CLIENT_VERSION = "3.78.0"; // eslint-disable-line no-undef
15391
+ const CLIENT_VERSION = "3.79.0"; // eslint-disable-line no-undef
15392
15392
  const HEADER_CLIENT_NAME = 'X-Box-Client-Name';
15393
15393
  const HEADER_CLIENT_VERSION = 'X-Box-Client-Version';
15394
15394
  const PROMISE_MAP = {};
@@ -17085,7 +17085,7 @@ class Browser {
17085
17085
  ;// ./src/lib/Logger.js
17086
17086
  /* eslint-disable no-undef */
17087
17087
  const Logger_CLIENT_NAME = "box-content-preview";
17088
- const Logger_CLIENT_VERSION = "3.78.0";
17088
+ const Logger_CLIENT_VERSION = "3.79.0";
17089
17089
  /* eslint-enable no-undef */
17090
17090
 
17091
17091
  class Logger {
@@ -17813,8 +17813,7 @@ class RepStatus extends (events_default()) {
17813
17813
  sharedLink,
17814
17814
  sharedLinkPassword,
17815
17815
  logger,
17816
- fileId,
17817
- migrateAccessTokenToHeader = false
17816
+ fileId
17818
17817
  }) {
17819
17818
  super();
17820
17819
  /** @property {Api} - Api used for XHR calls */
@@ -17826,12 +17825,8 @@ class RepStatus extends (events_default()) {
17826
17825
 
17827
17826
  // Some representations (e.g. ORIGINAL) may not have an info url
17828
17827
  const repInfo = this.representation.info;
17829
- if (migrateAccessTokenToHeader) {
17830
- this.infoUrl = repInfo ? appendAuthParamsV2(repInfo.url, sharedLink, sharedLinkPassword) : '';
17831
- this.headers = getHeaders({}, token);
17832
- } else {
17833
- this.infoUrl = repInfo ? appendAuthParams(repInfo.url, token, sharedLink, sharedLinkPassword) : '';
17834
- }
17828
+ this.infoUrl = repInfo ? appendAuthParamsV2(repInfo.url, sharedLink, sharedLinkPassword) : '';
17829
+ this.headers = getHeaders({}, token);
17835
17830
  this.promise = new Promise((resolve, reject) => {
17836
17831
  this.resolve = resolve;
17837
17832
  this.reject = reject;
@@ -18569,15 +18564,11 @@ class BaseViewer extends (events_default()) {
18569
18564
  template = this.api.reachability.constructor.replaceDownloadHostWithDefault(template);
18570
18565
  }
18571
18566
 
18572
- // Cache-buster only needed when auth is header-based; the in-URL token otherwise
18573
- // varies the cache key on its own.
18574
- const resolveCacheBuster = this.featureEnabled('migrateAccessTokenToHeader');
18575
-
18576
- // Append optional query params
18567
+ // Auth is header-based, so re-resolve the cache-buster per request.
18577
18568
  const {
18578
18569
  queryParams
18579
18570
  } = this.options;
18580
- return appendQueryParams(createContentUrl(template, asset, resolveCacheBuster), queryParams);
18571
+ return appendQueryParams(createContentUrl(template, asset, true), queryParams);
18581
18572
  }
18582
18573
 
18583
18574
  /**
@@ -18591,13 +18582,7 @@ class BaseViewer extends (events_default()) {
18591
18582
  * @return {string} content url
18592
18583
  */
18593
18584
  createContentUrlWithAuthParams(template, asset) {
18594
- const urlWithAuthParams = this.appendAuthParams(this.createContentUrl(template, asset));
18595
-
18596
- // Append optional query params
18597
- const {
18598
- queryParams
18599
- } = this.options;
18600
- return appendQueryParams(urlWithAuthParams, queryParams);
18585
+ return this.createContentUrlV2(template, asset);
18601
18586
  }
18602
18587
 
18603
18588
  /**
@@ -19034,9 +19019,7 @@ class BaseViewer extends (events_default()) {
19034
19019
  sharedLink,
19035
19020
  sharedLinkPassword,
19036
19021
  fileId: file.id,
19037
- logger: representation ? null : logger,
19038
- // Do not log to main preview status if rep is passed in
19039
- migrateAccessTokenToHeader: this.featureEnabled('migrateAccessTokenToHeader')
19022
+ logger: representation ? null : logger // Do not log to main preview status if rep is passed in
19040
19023
  });
19041
19024
 
19042
19025
  // Don't time out while conversion is pending
@@ -19615,14 +19598,10 @@ class ArchiveViewer extends viewers_BaseViewer {
19615
19598
  } = this.options;
19616
19599
  const template = get_default()(representation, 'content.url_template');
19617
19600
  this.startLoadTimer();
19618
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
19619
- const contentUrl = this.createContentUrlV2(template);
19620
- return this.api.get(contentUrl, {
19621
- headers: this.appendAuthHeader()
19622
- });
19623
- }
19624
- const contentUrl = this.createContentUrlWithAuthParams(template);
19625
- return this.api.get(contentUrl);
19601
+ const contentUrl = this.createContentUrlV2(template);
19602
+ return this.api.get(contentUrl, {
19603
+ headers: this.appendAuthHeader()
19604
+ });
19626
19605
  }).then(this.finishLoading).catch(this.handleAssetError);
19627
19606
  }
19628
19607
  }
@@ -21335,8 +21314,7 @@ class ImageViewer extends image_ImageBaseViewer {
21335
21314
  this.removeListener('zoom', this.handleZoomEvent);
21336
21315
  }
21337
21316
 
21338
- // Auth header migration uses blob URLs for images (XHR fetch + createObjectURL).
21339
- // Revoke to free the memory since blobs persist until explicitly released.
21317
+ // Blob URLs stay allocated until revoked.
21340
21318
  if (this.imageEl && this.imageEl.src && this.imageEl.src.startsWith('blob:')) {
21341
21319
  URL.revokeObjectURL(this.imageEl.src);
21342
21320
  }
@@ -21382,23 +21360,21 @@ class ImageViewer extends image_ImageBaseViewer {
21382
21360
  } = this.options;
21383
21361
  const template = representation.content.url_template;
21384
21362
  this.bindDOMListeners();
21385
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
21386
- const contentUrl = this.createContentUrlV2(template, viewer.ASSET);
21387
- return this.getRepStatus().getPromise().then(() => {
21388
- this.startLoadTimer();
21389
- // Reuse prefetched blob URL if available, otherwise fetch now
21390
- return this.prefetchedBlobUrlPromise || this.fetchContentAsBlobUrl(contentUrl);
21391
- }).then(blobUrl => {
21392
- this.prefetchedBlobUrlPromise = null;
21393
- this.imageEl.src = blobUrl;
21394
- if (this.imageEl.complete) {
21395
- this.finishLoading();
21396
- }
21397
- super.handleAssetAndRepLoad();
21398
- }).catch(this.handleAssetError);
21399
- }
21400
- const downloadUrl = this.createContentUrlWithAuthParams(template, viewer.ASSET);
21401
- return this.getRepStatus().getPromise().then(() => this.handleAssetAndRepLoad(downloadUrl)).catch(this.handleAssetError);
21363
+ const contentUrl = this.createContentUrlV2(template, viewer.ASSET);
21364
+ return this.getRepStatus().getPromise().then(() => {
21365
+ this.startLoadTimer();
21366
+ return this.fetchContentAsBlobUrl(contentUrl);
21367
+ }).then(blobUrl => {
21368
+ if (this.isDestroyed()) {
21369
+ URL.revokeObjectURL(blobUrl);
21370
+ return;
21371
+ }
21372
+ this.imageEl.src = blobUrl;
21373
+ if (this.imageEl.complete) {
21374
+ this.finishLoading();
21375
+ }
21376
+ super.handleAssetAndRepLoad();
21377
+ }).catch(this.handleAssetError);
21402
21378
  }
21403
21379
 
21404
21380
  /**
@@ -21442,9 +21418,6 @@ class ImageViewer extends image_ImageBaseViewer {
21442
21418
  this.firstRenderEmitted = true;
21443
21419
  }
21444
21420
  }
21445
- prefetchFinishedLoading(event) {
21446
- document.body.removeChild(event?.currentTarget);
21447
- }
21448
21421
 
21449
21422
  /**
21450
21423
  * Prefetches assets for an image.
@@ -21464,16 +21437,13 @@ class ImageViewer extends image_ImageBaseViewer {
21464
21437
  const isWatermarked = file && file.watermark_info && file.watermark_info.is_watermarked;
21465
21438
  if ((content || preload) && !isWatermarked && this.isRepresentationReady(representation)) {
21466
21439
  const template = representation.content.url_template;
21467
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
21468
- const contentUrl = this.createContentUrlV2(template, viewer.ASSET);
21469
- this.prefetchedBlobUrlPromise = this.fetchContentAsBlobUrl(contentUrl);
21470
- } else {
21471
- const preFetchedImg = document.createElement('img');
21472
- preFetchedImg.addEventListener('load', this.prefetchFinishedLoading);
21473
- preFetchedImg.classList.add(CLASS_PREFETCHED_IMAGE);
21474
- document.body.appendChild(preFetchedImg);
21475
- preFetchedImg.src = this.createContentUrlWithAuthParams(template, viewer.ASSET);
21476
- }
21440
+ const contentUrl = this.createContentUrlV2(template, viewer.ASSET);
21441
+ this.api.get(contentUrl, {
21442
+ type: 'blob',
21443
+ headers: this.appendAuthHeader()
21444
+ }).catch(err => {
21445
+ console.warn('Image prefetch failed', err); // eslint-disable-line no-console
21446
+ });
21477
21447
  }
21478
21448
  }
21479
21449
 
@@ -22138,8 +22108,7 @@ class MultiImageViewer extends image_ImageBaseViewer {
22138
22108
  */
22139
22109
  destroy() {
22140
22110
  if (this.singleImageEls && this.singleImageEls.length > 0) {
22141
- // Auth header migration uses blob URLs for images (XHR fetch + createObjectURL).
22142
- // Revoke to free the memory since blobs persist until explicitly released.
22111
+ // Blob URLs stay allocated until revoked.
22143
22112
  this.singleImageEls.forEach((el, index) => {
22144
22113
  if (el.src && el.src.startsWith('blob:')) {
22145
22114
  URL.revokeObjectURL(el.src);
@@ -22210,8 +22179,7 @@ class MultiImageViewer extends image_ImageBaseViewer {
22210
22179
  } = representation;
22211
22180
  const asset = viewer.ASSET;
22212
22181
  this.pagesCount = metadata.pages;
22213
- const useHeaders = this.featureEnabled('migrateAccessTokenToHeader');
22214
- const urlBase = useHeaders ? this.createContentUrlV2(template, asset) : this.createContentUrlWithAuthParams(template, asset);
22182
+ const urlBase = this.createContentUrlV2(template, asset);
22215
22183
  const urls = [];
22216
22184
  for (let pageNum = 1; pageNum <= this.pagesCount; pageNum += 1) {
22217
22185
  urls.push(urlBase.replace('{page}', pageNum));
@@ -22236,13 +22204,13 @@ class MultiImageViewer extends image_ImageBaseViewer {
22236
22204
  // Set page number. Page is index + 1.
22237
22205
  this.singleImageEls[index].setAttribute('data-page-number', index + 1);
22238
22206
  this.singleImageEls[index].classList.add(CLASS_MULTI_IMAGE_PAGE);
22239
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
22240
- this.fetchContentAsBlobUrl(imageUrl).then(blobUrl => {
22241
- this.singleImageEls[index].src = blobUrl;
22242
- });
22243
- } else {
22244
- this.singleImageEls[index].src = imageUrl;
22245
- }
22207
+ this.fetchContentAsBlobUrl(imageUrl).then(blobUrl => {
22208
+ if (this.isDestroyed()) {
22209
+ URL.revokeObjectURL(blobUrl);
22210
+ return;
22211
+ }
22212
+ this.singleImageEls[index].src = blobUrl;
22213
+ }).catch(this.handleMultiImageDownloadError);
22246
22214
  }
22247
22215
 
22248
22216
  /**
@@ -24710,15 +24678,17 @@ class SWFViewer extends viewers_BaseViewer {
24710
24678
  /* global swfobject */
24711
24679
  const template = this.options.representation.content.url_template;
24712
24680
  this.startLoadTimer();
24713
-
24714
- /* istanbul ignore next */
24715
- swfobject.embedSWF(this.createContentUrlWithAuthParams(template), this.playerEl.id, '100%', '100%', '9', null, null, SWF_PARAMS, null, () => {
24716
- if (this.isDestroyed()) {
24717
- return;
24718
- }
24719
- this.loaded = true;
24720
- this.emit(VIEWER_EVENT.load);
24721
- });
24681
+ const contentUrl = this.createContentUrlV2(template);
24682
+ return this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
24683
+ /* istanbul ignore next */
24684
+ swfobject.embedSWF(blobUrl, this.playerEl.id, '100%', '100%', '9', null, null, SWF_PARAMS, null, () => {
24685
+ if (this.isDestroyed()) {
24686
+ return;
24687
+ }
24688
+ this.loaded = true;
24689
+ this.emit(VIEWER_EVENT.load);
24690
+ });
24691
+ }).catch(this.handleAssetError);
24722
24692
  });
24723
24693
  }
24724
24694
  /**
@@ -25687,13 +25657,8 @@ class PlainTextViewer extends text_TextBaseViewer {
25687
25657
  const headers = this.truncated ? {
25688
25658
  Range: `bytes=0-${SIZE_LIMIT_BYTES}`
25689
25659
  } : {};
25690
- let contentUrl;
25691
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
25692
- contentUrl = this.createContentUrlV2(template);
25693
- PlainTextViewer_extends(headers, this.appendAuthHeader());
25694
- } else {
25695
- contentUrl = this.createContentUrlWithAuthParams(template);
25696
- }
25660
+ const contentUrl = this.createContentUrlV2(template);
25661
+ PlainTextViewer_extends(headers, this.appendAuthHeader());
25697
25662
  this.startLoadTimer();
25698
25663
  return this.api.get(contentUrl, {
25699
25664
  headers,
@@ -25764,17 +25729,11 @@ class PlainTextViewer extends text_TextBaseViewer {
25764
25729
  } = this.options;
25765
25730
  if (content && this.isRepresentationReady(representation)) {
25766
25731
  const template = representation.content.url_template;
25767
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
25768
- const contentUrl = this.createContentUrlV2(template);
25769
- this.api.get(contentUrl, {
25770
- type: 'document',
25771
- headers: this.appendAuthHeader()
25772
- });
25773
- } else {
25774
- this.api.get(this.createContentUrlWithAuthParams(template), {
25775
- type: 'document'
25776
- });
25777
- }
25732
+ const contentUrl = this.createContentUrlV2(template);
25733
+ this.api.get(contentUrl, {
25734
+ type: 'document',
25735
+ headers: this.appendAuthHeader()
25736
+ });
25778
25737
  }
25779
25738
  }
25780
25739
 
@@ -26243,15 +26202,11 @@ class CSVViewer extends text_TextBaseViewer {
26243
26202
  worker: true
26244
26203
  });
26245
26204
  };
26246
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
26247
- const contentUrl = this.createContentUrlV2(template);
26248
- return this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
26249
- this.blobUrl = blobUrl;
26250
- parseCSV(blobUrl);
26251
- });
26252
- }
26253
- parseCSV(this.createContentUrlWithAuthParams(template));
26254
- return undefined;
26205
+ const contentUrl = this.createContentUrlV2(template);
26206
+ return this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
26207
+ this.blobUrl = blobUrl;
26208
+ parseCSV(blobUrl);
26209
+ });
26255
26210
  }).catch(this.handleAssetError);
26256
26211
  }
26257
26212
 
@@ -26302,17 +26257,11 @@ class CSVViewer extends text_TextBaseViewer {
26302
26257
  } = this.options;
26303
26258
  if (content && this.isRepresentationReady(representation)) {
26304
26259
  const template = representation.content.url_template;
26305
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
26306
- const contentUrl = this.createContentUrlV2(template);
26307
- this.api.get(contentUrl, {
26308
- type: 'document',
26309
- headers: this.appendAuthHeader()
26310
- });
26311
- } else {
26312
- this.api.get(this.createContentUrlWithAuthParams(template), {
26313
- type: 'document'
26314
- });
26315
- }
26260
+ const contentUrl = this.createContentUrlV2(template);
26261
+ this.api.get(contentUrl, {
26262
+ type: 'document',
26263
+ headers: this.appendAuthHeader()
26264
+ });
26316
26265
  }
26317
26266
  }
26318
26267
 
@@ -28563,21 +28512,14 @@ class MediaBaseViewer extends viewers_BaseViewer {
28563
28512
  // https://webkit.org/blog/6784/new-video-policies-for-ios/
28564
28513
  this.mediaEl.autoplay = true;
28565
28514
  }
28566
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
28567
- const contentUrl = this.createContentUrlV2(template);
28568
- return this.getRepStatus().getPromise().then(() => {
28569
- this.startLoadTimer();
28570
- return this.fetchContentAsBlobUrl(contentUrl);
28571
- }).then(blobUrl => {
28572
- this.mediaBlobUrl = blobUrl;
28573
- this.mediaUrl = blobUrl;
28574
- this.mediaEl.src = blobUrl;
28575
- }).catch(this.handleAssetError);
28576
- }
28577
- this.mediaUrl = this.createContentUrlWithAuthParams(template);
28515
+ const contentUrl = this.createContentUrlV2(template);
28578
28516
  return this.getRepStatus().getPromise().then(() => {
28579
28517
  this.startLoadTimer();
28580
- this.mediaEl.src = this.mediaUrl;
28518
+ return this.fetchContentAsBlobUrl(contentUrl);
28519
+ }).then(blobUrl => {
28520
+ this.mediaBlobUrl = blobUrl;
28521
+ this.mediaUrl = blobUrl;
28522
+ this.mediaEl.src = blobUrl;
28581
28523
  }).catch(this.handleAssetError);
28582
28524
  }
28583
28525
 
@@ -28677,20 +28619,15 @@ class MediaBaseViewer extends viewers_BaseViewer {
28677
28619
  } = this.mediaEl;
28678
28620
  this.currentTime = currentTime;
28679
28621
  this.options.token = newToken;
28680
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
28681
- if (this.mediaBlobUrl) {
28682
- URL.revokeObjectURL(this.mediaBlobUrl);
28683
- }
28684
- const contentUrl = this.createContentUrlV2(this.options.representation.content.url_template);
28685
- this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
28686
- this.mediaBlobUrl = blobUrl;
28687
- this.mediaUrl = blobUrl;
28688
- this.mediaEl.src = blobUrl;
28689
- }).catch(this.handleAssetError);
28690
- return;
28622
+ if (this.mediaBlobUrl) {
28623
+ URL.revokeObjectURL(this.mediaBlobUrl);
28691
28624
  }
28692
- this.mediaUrl = this.createContentUrlWithAuthParams(this.options.representation.content.url_template);
28693
- this.mediaEl.src = this.mediaUrl;
28625
+ const contentUrl = this.createContentUrlV2(this.options.representation.content.url_template);
28626
+ this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
28627
+ this.mediaBlobUrl = blobUrl;
28628
+ this.mediaUrl = blobUrl;
28629
+ this.mediaEl.src = blobUrl;
28630
+ }).catch(this.handleAssetError);
28694
28631
  }
28695
28632
 
28696
28633
  /**
@@ -32659,19 +32596,22 @@ class VideoBaseViewer extends media_MediaBaseViewer {
32659
32596
  height: this.wrapperEl.clientHeight - controlsHeight
32660
32597
  };
32661
32598
  }
32662
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
32663
- const contentUrl = this.createContentUrlV2(template);
32664
- if (this.preloadBlobUrl) {
32665
- URL.revokeObjectURL(this.preloadBlobUrl);
32666
- }
32667
- this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
32668
- this.preloadBlobUrl = blobUrl;
32669
- this.preloader.showPreload(blobUrl, this.mediaContainerEl, options);
32670
- }).catch(this.handleAssetError);
32671
- } else {
32672
- const preloadUrlWithAuth = this.createContentUrlWithAuthParams(template);
32673
- this.preloader.showPreload(preloadUrlWithAuth, this.mediaContainerEl, options);
32599
+ const contentUrl = this.createContentUrlV2(template);
32600
+ if (this.preloadBlobUrl) {
32601
+ URL.revokeObjectURL(this.preloadBlobUrl);
32674
32602
  }
32603
+ this.fetchContentAsBlobUrl(contentUrl).then(blobUrl => {
32604
+ if (this.isDestroyed()) {
32605
+ URL.revokeObjectURL(blobUrl);
32606
+ return;
32607
+ }
32608
+ this.preloadBlobUrl = blobUrl;
32609
+ this.preloader.showPreload(blobUrl, this.mediaContainerEl, options);
32610
+ }).catch(err => {
32611
+ // Poster is a non-critical first-frame enhancement.
32612
+ // Warn so prod 401s leave a breadcrumb in DevTools.
32613
+ console.warn('Video preload failed', err); // eslint-disable-line no-console
32614
+ });
32675
32615
  this.mediaEl.classList.add(CLASS_INVISIBLE);
32676
32616
  }
32677
32617
 
@@ -32712,18 +32652,13 @@ class VideoBaseViewer extends media_MediaBaseViewer {
32712
32652
  if (!preloadRep || !this.isRepresentationReady(preloadRep) || !preloadRep.content?.url_template) {
32713
32653
  return;
32714
32654
  }
32715
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
32716
- const contentUrl = this.createContentUrlV2(preloadRep.content.url_template);
32717
- this.api.get(contentUrl, {
32718
- type: 'blob',
32719
- headers: this.appendAuthHeader()
32720
- }).catch(() => {});
32721
- } else {
32722
- const preloadUrlWithAuth = this.createContentUrlWithAuthParams(preloadRep.content.url_template);
32723
- this.api.get(preloadUrlWithAuth, {
32724
- type: 'blob'
32725
- }).catch(() => {});
32726
- }
32655
+ const contentUrl = this.createContentUrlV2(preloadRep.content.url_template);
32656
+ this.api.get(contentUrl, {
32657
+ type: 'blob',
32658
+ headers: this.appendAuthHeader()
32659
+ }).catch(err => {
32660
+ console.warn('Video preload prefetch failed', err); // eslint-disable-line no-console
32661
+ });
32727
32662
  }
32728
32663
  buildPlayButtonWithSeekButtons() {
32729
32664
  this.playContainerEl = this.mediaContainerEl.appendChild(document.createElement('div'));
@@ -34807,7 +34742,7 @@ class DashViewer extends media_VideoBaseViewer {
34807
34742
  this.filmstripStatus.destroy();
34808
34743
  }
34809
34744
 
34810
- // Release blob: URL allocated for the filmstrip when migrateAccessTokenToHeader is on
34745
+ // Release blob: URL allocated for the filmstrip
34811
34746
  if (this.filmstripUrl && this.filmstripUrl.startsWith('blob:')) {
34812
34747
  URL.revokeObjectURL(this.filmstripUrl);
34813
34748
  }
@@ -34885,17 +34820,11 @@ class DashViewer extends media_VideoBaseViewer {
34885
34820
  } = this.options;
34886
34821
  if (content && this.isRepresentationReady(representation)) {
34887
34822
  const template = representation.content.url_template;
34888
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
34889
- const contentUrl = this.createContentUrlV2(template, MANIFEST);
34890
- this.api.get(contentUrl, {
34891
- type: 'document',
34892
- headers: this.appendAuthHeader()
34893
- });
34894
- } else {
34895
- this.api.get(this.createContentUrlWithAuthParams(template, MANIFEST), {
34896
- type: 'document'
34897
- });
34898
- }
34823
+ const contentUrl = this.createContentUrlV2(template, MANIFEST);
34824
+ this.api.get(contentUrl, {
34825
+ type: 'document',
34826
+ headers: this.appendAuthHeader()
34827
+ });
34899
34828
  }
34900
34829
  }
34901
34830
 
@@ -35021,7 +34950,7 @@ class DashViewer extends media_VideoBaseViewer {
35021
34950
  }
35022
34951
 
35023
34952
  /**
35024
- * A networking filter to append representation URLs with tokens
34953
+ * Rewrites representation URIs without an access token and attaches Authorization headers.
35025
34954
  * Manifest type will use an asset name. Segments will not.
35026
34955
  *
35027
34956
  * @private
@@ -35032,28 +34961,16 @@ class DashViewer extends media_VideoBaseViewer {
35032
34961
  requestFilter(type, request) {
35033
34962
  const asset = type === shaka.net.NetworkingEngine.RequestType.MANIFEST ? MANIFEST : undefined;
35034
34963
  /* eslint-disable no-param-reassign */
35035
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
35036
- request.uris = request.uris.map(uri => {
35037
- let newUri = this.createContentUrlV2(uri, asset);
35038
- if (asset !== MANIFEST && this.options.file.watermark_info.is_watermarked) {
35039
- newUri = appendQueryParams(newUri, {
35040
- watermark_content: this.watermarkCacheBust
35041
- });
35042
- }
35043
- return newUri;
35044
- });
35045
- DashViewer_extends(request.headers, this.appendAuthHeader());
35046
- } else {
35047
- request.uris = request.uris.map(uri => {
35048
- let newUri = this.createContentUrlWithAuthParams(uri, asset);
35049
- if (asset !== MANIFEST && this.options.file.watermark_info.is_watermarked) {
35050
- newUri = appendQueryParams(newUri, {
35051
- watermark_content: this.watermarkCacheBust
35052
- });
35053
- }
35054
- return newUri;
35055
- });
35056
- }
34964
+ request.uris = request.uris.map(uri => {
34965
+ let newUri = this.createContentUrlV2(uri, asset);
34966
+ if (asset !== MANIFEST && this.options.file.watermark_info.is_watermarked) {
34967
+ newUri = appendQueryParams(newUri, {
34968
+ watermark_content: this.watermarkCacheBust
34969
+ });
34970
+ }
34971
+ return newUri;
34972
+ });
34973
+ request.headers = DashViewer_extends(request.headers || {}, this.appendAuthHeader());
35057
34974
  /* eslint-enable no-param-reassign */
35058
34975
  }
35059
34976
 
@@ -35616,29 +35533,14 @@ class DashViewer extends media_VideoBaseViewer {
35616
35533
  const filmstrip = getRepresentation(this.options.file, 'filmstrip');
35617
35534
  const filmstripInterval = filmstrip && filmstrip.metadata && filmstrip.metadata.interval;
35618
35535
  if (filmstripInterval > 0) {
35619
- const useHeaders = this.featureEnabled('migrateAccessTokenToHeader');
35620
35536
  const useReactControls = this.useReactControls();
35621
- const url = useHeaders ? this.createContentUrlV2(filmstrip.content.url_template) : this.createContentUrlWithAuthParams(filmstrip.content.url_template);
35537
+ const url = this.createContentUrlV2(filmstrip.content.url_template);
35622
35538
  this.filmstripInterval = filmstripInterval;
35623
35539
  this.filmstripStatus = this.getRepStatus(filmstrip);
35624
- // When useHeaders is on, the URL has no token and would 401 if rendered as <img src>.
35625
- // Defer setting filmstripUrl until the blob: URL is ready below.
35626
- this.filmstripUrl = useHeaders ? null : url;
35627
-
35628
- // Legacy controls have a synchronous init path when the URL already carries a token.
35629
- if (!useHeaders && !useReactControls) {
35630
- this.mediaControls.initFilmstrip(url, this.filmstripStatus, this.aspect, filmstripInterval);
35631
- return;
35632
- }
35633
- this.filmstripStatus.getPromise().then(() => useHeaders ? this.fetchContentAsBlobUrl(url) : url).then(filmstripUrl => {
35634
- // <img src> can't carry an Authorization header, so when the access-token has
35635
- // been migrated out of the URL we expose the rep as a blob: URL instead.
35636
- // If the viewer was destroyed while we were fetching, release the blob now —
35637
- // destroy() can't see it because filmstripUrl was still null when it ran.
35540
+ this.filmstripUrl = null;
35541
+ this.filmstripStatus.getPromise().then(() => this.fetchContentAsBlobUrl(url)).then(filmstripUrl => {
35638
35542
  if (this.destroyed) {
35639
- if (useHeaders) {
35640
- URL.revokeObjectURL(filmstripUrl);
35641
- }
35543
+ URL.revokeObjectURL(filmstripUrl);
35642
35544
  return;
35643
35545
  }
35644
35546
  this.filmstripUrl = filmstripUrl;
@@ -35648,9 +35550,8 @@ class DashViewer extends media_VideoBaseViewer {
35648
35550
  this.mediaControls.initFilmstrip(filmstripUrl, this.filmstripStatus, this.aspect, filmstripInterval);
35649
35551
  }
35650
35552
  })
35651
- // Filmstrip is a non-critical scrubbing-preview enhancement, so any failure
35652
- // (rep status reject, blob fetch reject) is swallowed rather than failing
35653
- // the whole viewer. Warn so prod 401s leave a breadcrumb in DevTools.
35553
+ // Filmstrip is a non-critical scrubbing-preview enhancement.
35554
+ // Warn so prod 401s leave a breadcrumb in DevTools.
35654
35555
  .catch(err => {
35655
35556
  console.warn('Filmstrip load failed', err); // eslint-disable-line no-console
35656
35557
  });
@@ -35671,7 +35572,7 @@ class DashViewer extends media_VideoBaseViewer {
35671
35572
  if (!extractedText?.content?.url_template) {
35672
35573
  return;
35673
35574
  }
35674
- const transcriptionUrl = this.featureEnabled('migrateAccessTokenToHeader') ? this.createContentUrlV2(extractedText.content.url_template) : this.createContentUrlWithAuthParams(extractedText.content.url_template);
35575
+ const transcriptionUrl = this.createContentUrlV2(extractedText.content.url_template);
35675
35576
  this.transcriptionStatus = this.getRepStatus(extractedText);
35676
35577
  try {
35677
35578
  await this.transcriptionStatus.getPromise();
@@ -40671,15 +40572,14 @@ class DocBaseViewer extends viewers_BaseViewer {
40671
40572
  const pagedWebpRepReady = pagedWebpRep && this.isRepresentationReady(pagedWebpRep) && pagedWebpRep.content?.url_template;
40672
40573
  const jpegRepReady = jpegPreloadRep && this.isRepresentationReady(jpegPreloadRep) && jpegPreloadRep.content?.url_template;
40673
40574
  const onlyJpegRepAvailable = jpegRepReady && !pagedWebpRepReady;
40674
- const useHeaders = this.featureEnabled('migrateAccessTokenToHeader');
40675
- const headersOption = useHeaders ? {
40575
+ const headersOption = {
40676
40576
  headers: this.appendAuthHeader()
40677
- } : {};
40577
+ };
40678
40578
  if (onlyJpegRepAvailable) {
40679
40579
  const {
40680
40580
  url_template: jpegUrlTemplate = ''
40681
40581
  } = jpegPreloadRep.content;
40682
- const jpegUrlAuthTemplate = useHeaders ? this.createContentUrlV2(jpegUrlTemplate) : this.createContentUrlWithAuthParams(jpegUrlTemplate);
40582
+ const jpegUrlAuthTemplate = this.createContentUrlV2(jpegUrlTemplate);
40683
40583
  const promises = getPreloadImageRequestPromises(this.api, jpegUrlAuthTemplate, 1, '', headersOption);
40684
40584
  Promise.all(promises).then(() => {
40685
40585
  this.preloaderImagesPrefetched = true;
@@ -40690,7 +40590,7 @@ class DocBaseViewer extends viewers_BaseViewer {
40690
40590
  } = pagedWebpRep.content;
40691
40591
  const pageCount = pagedWebpRep.metadata?.pages || 8;
40692
40592
  const newPagedUrlTemplate = pagedUrlTemplate.replace(/\{.*\}/, DocBaseViewer_PAGED_URL_TEMPLATE_PAGE_NUMBER_HOLDER);
40693
- const pagedUrlAuthTemplate = useHeaders ? this.createContentUrlV2(newPagedUrlTemplate) : this.createContentUrlWithAuthParams(newPagedUrlTemplate);
40593
+ const pagedUrlAuthTemplate = this.createContentUrlV2(newPagedUrlTemplate);
40694
40594
  if (docFirstPagesConfig && docFirstPagesConfig.priorityPages) {
40695
40595
  const {
40696
40596
  priorityPages,
@@ -40755,19 +40655,11 @@ class DocBaseViewer extends viewers_BaseViewer {
40755
40655
  const {
40756
40656
  url_template: template
40757
40657
  } = preloadRep.content;
40758
-
40759
- // Prefetch as blob since preload needs to load image as a blob
40760
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
40761
- const contentUrl = this.createContentUrlV2(template);
40762
- this.api.get(contentUrl, {
40763
- type: 'blob',
40764
- headers: this.appendAuthHeader()
40765
- });
40766
- } else {
40767
- this.api.get(this.createContentUrlWithAuthParams(template), {
40768
- type: 'blob'
40769
- });
40770
- }
40658
+ const contentUrl = this.createContentUrlV2(template);
40659
+ this.api.get(contentUrl, {
40660
+ type: 'blob',
40661
+ headers: this.appendAuthHeader()
40662
+ });
40771
40663
  }
40772
40664
  } else {
40773
40665
  this.prefetchPreloaderImages(file);
@@ -40777,17 +40669,11 @@ class DocBaseViewer extends viewers_BaseViewer {
40777
40669
  const {
40778
40670
  url_template: template
40779
40671
  } = representation.content;
40780
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
40781
- const contentUrl = this.createContentUrlV2(template);
40782
- this.api.get(contentUrl, {
40783
- type: 'document',
40784
- headers: this.appendAuthHeader()
40785
- });
40786
- } else {
40787
- this.api.get(this.createContentUrlWithAuthParams(template), {
40788
- type: 'document'
40789
- });
40790
- }
40672
+ const contentUrl = this.createContentUrlV2(template);
40673
+ this.api.get(contentUrl, {
40674
+ type: 'document',
40675
+ headers: this.appendAuthHeader()
40676
+ });
40791
40677
  }
40792
40678
  }
40793
40679
 
@@ -40846,11 +40732,10 @@ class DocBaseViewer extends viewers_BaseViewer {
40846
40732
  const {
40847
40733
  url_template: template = ''
40848
40734
  } = preloadRep?.content || {};
40849
- const useHeaders = this.featureEnabled('migrateAccessTokenToHeader');
40850
- const preloadUrl = useHeaders ? this.createContentUrlV2(template) : this.createContentUrlWithAuthParams(template);
40851
- const headersOption = useHeaders ? {
40735
+ const preloadUrl = this.createContentUrlV2(template);
40736
+ const headersOption = {
40852
40737
  headers: this.appendAuthHeader()
40853
- } : {};
40738
+ };
40854
40739
  if (!this.docFirstPagesEnabled) {
40855
40740
  this.startPreloadTimer();
40856
40741
  this.preloader.showPreload(preloadUrl, this.containerEl, headersOption);
@@ -40874,7 +40759,7 @@ class DocBaseViewer extends viewers_BaseViewer {
40874
40759
  url_template: pagedUrlTemplate = ''
40875
40760
  } = preloadRepPaged?.content || {};
40876
40761
  const newPagedUrlTemplate = pagedUrlTemplate.replace(/\{.*\}/, DocBaseViewer_PAGED_URL_TEMPLATE_PAGE_NUMBER_HOLDER);
40877
- const pagedPreLoadUrl = useHeaders ? this.createContentUrlV2(newPagedUrlTemplate) : this.createContentUrlWithAuthParams(newPagedUrlTemplate);
40762
+ const pagedPreLoadUrl = this.createContentUrlV2(newPagedUrlTemplate);
40878
40763
  this.preloader.showPreload(null, this.containerEl, pagedPreLoadUrl, pageCount, this, headersOption);
40879
40764
  }
40880
40765
  }
@@ -40914,11 +40799,7 @@ class DocBaseViewer extends viewers_BaseViewer {
40914
40799
  this.showPreload();
40915
40800
  }
40916
40801
  const template = this.options.representation.content.url_template;
40917
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
40918
- this.pdfUrl = this.createContentUrlV2(template);
40919
- } else {
40920
- this.pdfUrl = this.createContentUrlWithAuthParams(template);
40921
- }
40802
+ this.pdfUrl = this.createContentUrlV2(template);
40922
40803
  let jsAssets;
40923
40804
  let cssAssets;
40924
40805
  const useNpmPdfjs = this.featureEnabled('useNpmPdfjs');
@@ -41317,9 +41198,7 @@ class DocBaseViewer extends viewers_BaseViewer {
41317
41198
  rangeChunkSize,
41318
41199
  url: pdfUrl
41319
41200
  };
41320
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
41321
- pdfDocConfig.httpHeaders = this.appendAuthHeader();
41322
- }
41201
+ pdfDocConfig.httpHeaders = this.appendAuthHeader();
41323
41202
  this.pdfLoadingTask = this.pdfjsLib.getDocument(pdfDocConfig);
41324
41203
  if (this.pageTracker) {
41325
41204
  this.addListener('preview_event_report', this.handlePreviewEventReport);
@@ -41638,13 +41517,10 @@ class DocBaseViewer extends viewers_BaseViewer {
41638
41517
  * @return {Promise} Promise setting print blob
41639
41518
  */
41640
41519
  fetchPrintBlob(pdfUrl) {
41641
- const options = {
41642
- type: 'blob'
41643
- };
41644
- if (this.featureEnabled('migrateAccessTokenToHeader')) {
41645
- options.headers = this.appendAuthHeader();
41646
- }
41647
- return this.api.get(pdfUrl, options).then(blob => {
41520
+ return this.api.get(pdfUrl, {
41521
+ type: 'blob',
41522
+ headers: this.appendAuthHeader()
41523
+ }).then(blob => {
41648
41524
  this.printBlob = blob;
41649
41525
  });
41650
41526
  }
@@ -47341,7 +47217,7 @@ class OfficeViewer extends viewers_BaseViewer {
47341
47217
 
47342
47218
  // This occurs in the case of .xlsb files where no pdf rep exists
47343
47219
  if (template) {
47344
- this.pdfUrl = this.createContentUrlWithAuthParams(template);
47220
+ this.pdfUrl = this.createContentUrlV2(template);
47345
47221
  }
47346
47222
  }
47347
47223
 
@@ -47501,7 +47377,8 @@ class OfficeViewer extends viewers_BaseViewer {
47501
47377
  */
47502
47378
  fetchPrintBlob(pdfUrl) {
47503
47379
  return this.api.get(pdfUrl, {
47504
- type: 'blob'
47380
+ type: 'blob',
47381
+ headers: this.appendAuthHeader()
47505
47382
  }).then(blob => {
47506
47383
  this.printBlob = blob;
47507
47384
  });
@@ -48930,8 +48807,25 @@ class Preview extends (events_default()) {
48930
48807
  const params = Preview_objectSpread({
48931
48808
  response_content_disposition_type: 'attachment'
48932
48809
  }, queryParams);
48933
- const downloadUrl = appendQueryParams(this.viewer.createContentUrlWithAuthParams(contentUrlTemplate, this.viewer.getAssetPath()), params);
48934
- this.api.reachability.downloadWithReachabilityCheck(downloadUrl);
48810
+ const downloadUrl = appendQueryParams(this.viewer.createContentUrlV2(contentUrlTemplate, this.viewer.getAssetPath()), params);
48811
+ this.api.get(downloadUrl, {
48812
+ type: 'blob',
48813
+ headers: this.getRequestHeaders()
48814
+ }).then(data => {
48815
+ const blob = data instanceof Blob ? data : new Blob([data]);
48816
+ const blobUrl = URL.createObjectURL(blob);
48817
+ const anchor = document.createElement('a');
48818
+ anchor.href = blobUrl;
48819
+ anchor.download = this.file && this.file.name || 'download';
48820
+ document.body.appendChild(anchor);
48821
+ anchor.click();
48822
+ document.body.removeChild(anchor);
48823
+ URL.revokeObjectURL(blobUrl);
48824
+ }).catch(error => {
48825
+ const code = getProp(error, 'response.data.code');
48826
+ const msg = code === ERROR_CODE_403_FORBIDDEN_BY_POLICY ? downloadErrorDueToPolicyMsg : downloadErrorMsg;
48827
+ this.ui.showNotification(msg);
48828
+ });
48935
48829
 
48936
48830
  // Otherwise, get the content download URL of the original file and download
48937
48831
  } else {
@@ -49002,8 +48896,7 @@ class Preview extends (events_default()) {
49002
48896
  sharedLinkPassword = '',
49003
48897
  preload = false,
49004
48898
  isDocFirstPrefetchEnabled = false,
49005
- docFirstPagesConfig = null,
49006
- isAccessTokenHeaderEnabled = false
48899
+ docFirstPagesConfig = null
49007
48900
  }) {
49008
48901
  let file;
49009
48902
  let loader;
@@ -49044,9 +48937,6 @@ class Preview extends (events_default()) {
49044
48937
  options.sharedLinkPassword = sharedLinkPassword;
49045
48938
  options.isDocFirstPrefetchEnabled = isDocFirstPrefetchEnabled;
49046
48939
  options.docFirstPagesConfig = docFirstPagesConfig;
49047
- options.features = Preview_objectSpread(Preview_objectSpread({}, this.options.features), {}, {
49048
- migrateAccessTokenToHeader: isAccessTokenHeaderEnabled
49049
- });
49050
48940
  }
49051
48941
  const viewerInstance = new viewer.CONSTRUCTOR(this.createViewerOptions(options));
49052
48942
  if (typeof viewerInstance.prefetch === 'function') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "box-content-preview",
3
- "version": "3.78.0",
3
+ "version": "3.79.0",
4
4
  "description": "Box Content Preview UI Element",
5
5
  "author": "Box (https://www.box.com/)",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -49,7 +49,7 @@
49
49
  "@babel/plugin-proposal-class-properties": "^7.18.6",
50
50
  "@babel/plugin-proposal-object-rest-spread": "^7.18.6",
51
51
  "@babel/plugin-transform-object-assign": "^7.18.6",
52
- "@babel/preset-env": "^7.18.6",
52
+ "@babel/preset-env": "^7.24.7",
53
53
  "@babel/preset-react": "^7.18.6",
54
54
  "@babel/preset-typescript": "^7.18.6",
55
55
  "@box/blueprint-web": "^14.41.0",
@@ -80,8 +80,8 @@
80
80
  "box-ui-elements": "^20.0.0",
81
81
  "chai": "^4.2.0",
82
82
  "classnames": "^2.2.6",
83
- "conventional-changelog-cli": "^2.0.28",
84
- "conventional-github-releaser": "^3.1.3",
83
+ "conventional-changelog": "^8.1.3",
84
+ "conventional-changelog-conventionalcommits": "^10.3.0",
85
85
  "create-react-class": "^15.6.2",
86
86
  "css-loader": "^6.11.0",
87
87
  "css-minimizer-webpack-plugin": "^8.0.0",
@@ -89,7 +89,6 @@
89
89
  "eslint": "^8.43.0",
90
90
  "eslint-config-airbnb": "^18.0.1",
91
91
  "eslint-config-prettier": "^6.7.0",
92
- "eslint-import-resolver-webpack": "^0.11.1",
93
92
  "eslint-plugin-babel": "^5.3.0",
94
93
  "eslint-plugin-chai-friendly": "^0.4.1",
95
94
  "eslint-plugin-cypress": "^2.8.1",
@@ -114,7 +113,6 @@
114
113
  "lodash": "^4.18.1",
115
114
  "mini-css-extract-plugin": "^2.10.2",
116
115
  "mock-local-storage": "^1.1.15",
117
- "mojito-rb-gen": "^0.0.1",
118
116
  "npm-run-all": "^4.1.5",
119
117
  "postcss": "^8.5.18",
120
118
  "postcss-loader": "^8.1.1",
@@ -149,7 +147,7 @@
149
147
  "build": "yarn setup && yarn clean && yarn build:i18n && yarn build:dev",
150
148
  "build:ci": "yarn setup && yarn webpack --progress --config build/webpack.config.js",
151
149
  "build:dev": "BABEL_ENV=dev NODE_ENV=dev yarn webpack --progress --config build/webpack.config.js",
152
- "build:i18n": "mojito-rb-gen -s src/i18n -o src/i18n/json -b en-US.properties",
150
+ "build:i18n": "node build/buildI18n.js",
153
151
  "build:lib": "yarn build:i18n && yarn build:lib:js && yarn build:lib:verify && yarn build:lib:types",
154
152
  "build:lib:verify": "node build/verifyLibBundle.js",
155
153
  "build:lib:js": "BABEL_ENV=production NODE_ENV=production yarn webpack --config build/webpack.config.lib.js",