@smpx/koa-request 0.5.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/Request.js +97 -155
  2. package/package.json +1 -1
package/Request.js CHANGED
@@ -22,7 +22,6 @@ const TEN_YEARS = 10 * ONE_YEAR;
22
22
 
23
23
  const PLATFORM_PARAM = 'platform';
24
24
  const PLATFORM_COOKIE = 'platform';
25
- const PLATFORM_COOKIE_DURATION = 4 * ONE_HOUR;
26
25
  const APPINFO_PARAM = 'sm_app';
27
26
  const APPINFO_COOKIE = 'sm_app';
28
27
  const APPINFO_HEADER = 'sm-app';
@@ -399,7 +398,6 @@ class Request {
399
398
  this.ctx.set('Content-Security-Policy', `frame-ancestors https://*.${domain}`);
400
399
  }
401
400
 
402
- this.handlePlatformModification();
403
401
  if (!this.isAjax()) {
404
402
  this.setUTMCookie();
405
403
  this.setAffidCookie();
@@ -653,17 +651,17 @@ class Request {
653
651
  _getAppInfoFromString(infoStr, separator = '#') {
654
652
  if (!infoStr) return null;
655
653
  // eslint-disable-next-line prefer-const
656
- let [platform, appVersion, installId] = infoStr.split(separator);
657
- platform = platform.toLowerCase();
654
+ let [os, appVersion, installId] = infoStr.split(separator);
655
+ os = os.toLowerCase();
658
656
 
659
657
  const appInfo = {
660
- platform,
658
+ os,
661
659
  appVersion,
662
660
  installId,
663
661
  };
664
662
 
665
- if (this.appPlatforms().has(platform)) {
666
- appInfo.isMobileApp = true;
663
+ if (this.appPlatforms().has(os)) {
664
+ appInfo.appType = 'app';
667
665
  }
668
666
 
669
667
  return appInfo;
@@ -693,17 +691,75 @@ class Request {
693
691
  return this._getAppInfoFromString(this.ctx.headers[APPINFO_HEADER]);
694
692
  }
695
693
 
696
- getAppInfo() {
697
- const appInfoHeader = this.getAppInfoFromHeader();
698
- if (appInfoHeader) return appInfoHeader;
694
+ getAppInfoCustom() {
695
+ return null;
696
+ }
697
+
698
+ _getDeviceTypeFromUA() {
699
+ const ua = this.parseUserAgent();
700
+ const deviceType = ua.device?.type;
701
+ if (deviceType === 'mobile') return 'mobile';
702
+ if (deviceType === 'tablet') return 'tablet';
703
+ return 'desktop';
704
+ }
705
+
706
+ _getDeviceType() {
707
+ const secHeader = this.ctx.headers['sec-ch-ua-mobile'];
708
+ if (secHeader) {
709
+ if (secHeader === '?1') return 'mobile';
710
+ return this._getDeviceTypeFromUA();
711
+ }
712
+ const vwCookie = this.cookie(VIEWPORT_WIDTH_COOKIE);
713
+ if (vwCookie) {
714
+ if (Number(vwCookie) <= 750) return 'mobile';
715
+ return this._getDeviceTypeFromUA();
716
+ }
717
+ return this._getDeviceTypeFromUA();
718
+ }
699
719
 
700
- const appInfoParam = this.getAppInfoFromParam();
701
- if (appInfoParam) return appInfoParam;
720
+ computeAppInfo() {
721
+ const ctx = this.ctx;
702
722
 
703
- const appInfoUserAgent = this.getAppInfoFromUserAgent();
704
- if (appInfoUserAgent) return appInfoUserAgent;
723
+ const appInfo1 = this.getAppInfoFromHeader() || {};
724
+ const appInfo2 = this.getAppInfoFromParam() || {};
725
+ const appInfo3 = this.getAppInfoFromUserAgent() || {};
726
+ const appInfo4 = this.getAppInfoCustom() || {};
705
727
 
706
- return {};
728
+ const appInfo = {
729
+ installId: ctx.query.installId,
730
+ appVersion: ctx.query.appVersion,
731
+ ...appInfo4,
732
+ ...appInfo3,
733
+ ...appInfo2,
734
+ ...appInfo1,
735
+ };
736
+
737
+ let xPlatform = (
738
+ ctx.query[PLATFORM_PARAM] ||
739
+ this.cookie(PLATFORM_COOKIE) ||
740
+ ctx.headers['x-sm-platform']
741
+ );
742
+ if (xPlatform) {
743
+ xPlatform = xPlatform.toLowerCase();
744
+ if (xPlatform === 'mobile_app') {
745
+ if (!appInfo.deviceType) appInfo.deviceType = 'mobile';
746
+ if (!appInfo.appType) appInfo.appType = 'app';
747
+ }
748
+ else {
749
+ const os = xPlatform.match(/android|ios|wp|tizen|jio/i)?.[0];
750
+ if (os) {
751
+ if (!appInfo.deviceType) appInfo.deviceType = 'mobile';
752
+ if (!appInfo.appType) appInfo.appType = 'app';
753
+ if (!appInfo.os) appInfo.os = os.toLowerCase();
754
+ }
755
+ else if (!appInfo.deviceType) {
756
+ appInfo.deviceType = xPlatform.includes('mobile') ? 'mobile' : 'desktop';
757
+ }
758
+ }
759
+ }
760
+ else if (!appInfo.deviceType) {
761
+ appInfo.deviceType = this._getDeviceType();
762
+ }
707
763
  }
708
764
 
709
765
  /*
@@ -711,156 +767,71 @@ class Request {
711
767
  * this means that you can have the url as sm_app=android
712
768
  * and it'll automatically identify it as an android app
713
769
  */
714
- appInfo(param = null) {
770
+ appInfo() {
715
771
  if (!this._appInfo) {
716
- this._appInfo = this.getAppInfo() || {};
772
+ this._appInfo = this.computeAppInfo() || {};
717
773
  }
718
- return param ? this._appInfo[param] : this._appInfo;
774
+ return this._appInfo;
719
775
  }
720
776
 
721
777
  installId() {
722
- return this.appInfo('installId') || this.ctx.query.installId || '';
778
+ return this.appInfo().installId || '';
723
779
  }
724
780
 
725
781
  appVersion() {
726
- return this.appInfo('appVersion') || this.ctx.query.appVersion || '';
782
+ return this.appInfo().appVersion || '';
783
+ }
784
+
785
+ isApp() {
786
+ return this.appInfo().type === 'app';
727
787
  }
728
788
 
729
789
  isAndroidApp() {
730
- return this.appInfo('platform') === 'android';
790
+ return this.isApp() && this.appInfo().os === 'android';
731
791
  }
732
792
 
733
793
  isIOSApp() {
734
- return this.appInfo('platform') === 'ios';
794
+ return this.isApp() && this.appInfo().os === 'ios';
735
795
  }
736
796
 
737
797
  isWPApp() {
738
- return this.appInfo('platform') === 'wp';
798
+ return this.isApp() && this.appInfo().os === 'wp';
739
799
  }
740
800
 
741
801
  isTizenApp() {
742
- return this.appInfo('platform') === 'tizen';
802
+ return this.isApp() && this.appInfo().os === 'tizen';
743
803
  }
744
804
 
745
805
  isJIOApp() {
746
- return this.appInfo('platform') === 'jio';
806
+ return this.isApp() && this.appInfo().os === 'jio';
747
807
  }
748
808
 
749
809
  isMobileApp() {
750
- // for setPlatform cases
751
- const platform = this._platform;
752
- if (platform) {
753
- if (platform === 'mobile_app') return true;
754
- return false;
755
- }
756
-
757
- return !!this.appInfo('isMobileApp');
810
+ return this.isApp() && this.isMobile();
758
811
  }
759
812
 
760
813
  isMobileWeb() {
761
- // for setPlatform cases
762
- const platform = this._platform;
763
- if (platform) {
764
- if (platform === 'mobile_web') return true;
765
- return false;
766
- }
767
-
768
- if (this._isMobileWeb == null) {
769
- const secHeader = this.ctx.headers['sec-ch-ua-mobile'];
770
- if (secHeader) {
771
- this._isMobileWeb = secHeader === '?1';
772
- }
773
- else {
774
- const vwCookie = this.cookie(VIEWPORT_WIDTH_COOKIE);
775
- if (vwCookie) {
776
- this._isMobileWeb = Number(vwCookie) <= 750;
777
- }
778
- else {
779
- const ua = this.parseUserAgent();
780
- this._isMobileWeb = (ua && ua.device && ua.device.type === 'mobile') || false;
781
- }
782
- }
783
- }
784
- return this._isMobileWeb;
814
+ return this.isMobile() && !this.isApp();
785
815
  }
786
816
 
787
- isMobile() {
788
- return this.isMobileApp() || this.isMobileWeb();
817
+ deviceType() {
818
+ return this.appInfo().deviceType || 'desktop';
789
819
  }
790
820
 
791
- isAPI() {
792
- return false;
793
- }
794
-
795
- platform() {
796
- if (!this._platform) {
797
- if (this.isMobileApp()) {
798
- this._platform = 'mobile_app';
799
- }
800
- else if (this.isMobileWeb()) {
801
- this._platform = 'mobile_web';
802
- }
803
- else if (this.isAPI()) {
804
- this._platform = 'api';
805
- }
806
- else {
807
- this._platform = 'desktop';
808
- }
809
- }
810
-
811
- return this._platform;
821
+ isMobile() {
822
+ return this.appInfo().deviceType === 'mobile';
812
823
  }
813
824
 
814
- setPlatform(platform) {
815
- if (!platform) return false;
816
- platform = handleArray(platform);
817
- const appPlatform = platform.replace('_app', '');
818
-
819
- if (this.appPlatforms().has(appPlatform)) {
820
- this._platform = 'mobile_app';
821
- this._subPlatform = `${appPlatform}_app`;
822
- return false;
823
- }
824
-
825
- switch (platform) {
826
- case 'mobile':
827
- case 'mobile_web':
828
- this._platform = 'mobile_web';
829
- return true;
830
- case 'www':
831
- case 'desktop':
832
- this._platform = 'desktop';
833
- return true;
834
- case 'mobile_app':
835
- this._platform = 'mobile_app';
836
- return true;
837
- default:
838
- return false;
839
- }
840
- }
841
-
842
- subPlatform() {
843
- if (!this._subPlatform) {
844
- const appPlatform = this.appInfo('platform');
845
- if (appPlatform && this.isMobileApp()) {
846
- this._subPlatform = `${appPlatform}_app`;
847
- }
848
- else {
849
- this._subPlatform = this.platform();
850
- }
851
- }
852
- return this._subPlatform;
825
+ isTablet() {
826
+ return this.appInfo().deviceType === 'tablet';
853
827
  }
854
828
 
855
829
  isDesktop() {
856
- // for setPlatform cases
857
- const platform = this._platform;
858
- if (platform) {
859
- if (platform === 'desktop') return true;
860
- return false;
861
- }
830
+ return !this.isMobile();
831
+ }
862
832
 
863
- return this.platform() === 'desktop';
833
+ isAPI() {
834
+ return false;
864
835
  }
865
836
 
866
837
  /**
@@ -1152,14 +1123,6 @@ class Request {
1152
1123
  return '/signup?next=' + encodeURIComponent(this.nextUrl());
1153
1124
  }
1154
1125
 
1155
- mobileUrl() {
1156
- return addQuery(this.ctx.url, {[PLATFORM_PARAM]: 'mobile'});
1157
- }
1158
-
1159
- desktopUrl() {
1160
- return addQuery(this.ctx.url, {[PLATFORM_PARAM]: 'desktop'});
1161
- }
1162
-
1163
1126
  redirect(url, qs = true) {
1164
1127
  if (qs === true) {
1165
1128
  url = addQuery(url, this.ctx.querystring);
@@ -1402,27 +1365,6 @@ class Request {
1402
1365
  }
1403
1366
  }
1404
1367
 
1405
- handlePlatformModification() {
1406
- let setPlatformCookie = false;
1407
- if (!this.isMobileApp() && !this.isAjax()) {
1408
- // don't change platform in mobile apps (and ajax requests) from query or cookie
1409
- const platform = this.ctx.query[PLATFORM_PARAM] || this.cookie(PLATFORM_COOKIE);
1410
- setPlatformCookie = this.setPlatform(platform);
1411
- if (setPlatformCookie) {
1412
- this.cookie(PLATFORM_COOKIE, platform, {
1413
- maxAge: PLATFORM_COOKIE_DURATION,
1414
- domain: '*',
1415
- });
1416
- }
1417
- }
1418
- if (!setPlatformCookie) {
1419
- const smPlatform = this.header('x-sm-platform');
1420
- if (smPlatform) {
1421
- this._platform = smPlatform;
1422
- }
1423
- }
1424
- }
1425
-
1426
1368
  geoipLoc() {
1427
1369
  if (this._giploc === undefined) {
1428
1370
  this._giploc = GeoIP.getSync(this.ip()) || {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smpx/koa-request",
3
- "version": "0.5.0",
3
+ "version": "1.0.0",
4
4
  "description": "Handle basic tasks for koajs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",