@smpx/koa-request 0.5.0 → 1.0.1

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 +102 -153
  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,78 @@ 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;
821
+ isMobile() {
822
+ return this.appInfo().deviceType === 'mobile';
793
823
  }
794
824
 
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;
825
+ isTablet() {
826
+ return this.appInfo().deviceType === 'tablet';
812
827
  }
813
828
 
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
- }
829
+ isDesktop() {
830
+ return !this.isMobile();
840
831
  }
841
832
 
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;
833
+ isAPI() {
834
+ return false;
853
835
  }
854
836
 
855
- isDesktop() {
856
- // for setPlatform cases
857
- const platform = this._platform;
858
- if (platform) {
859
- if (platform === 'desktop') return true;
860
- return false;
861
- }
862
-
863
- return this.platform() === 'desktop';
837
+ platform() {
838
+ if (this.isApp()) return 'mobile_app';
839
+ if (this.isMobile()) return 'mobile_web';
840
+ if (this.isAPI()) return 'api';
841
+ return 'desktop';
864
842
  }
865
843
 
866
844
  /**
@@ -1152,14 +1130,6 @@ class Request {
1152
1130
  return '/signup?next=' + encodeURIComponent(this.nextUrl());
1153
1131
  }
1154
1132
 
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
1133
  redirect(url, qs = true) {
1164
1134
  if (qs === true) {
1165
1135
  url = addQuery(url, this.ctx.querystring);
@@ -1402,27 +1372,6 @@ class Request {
1402
1372
  }
1403
1373
  }
1404
1374
 
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
1375
  geoipLoc() {
1427
1376
  if (this._giploc === undefined) {
1428
1377
  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.1",
4
4
  "description": "Handle basic tasks for koajs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",