@etsoo/appscript 1.2.47 → 1.2.51

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.
@@ -83,6 +83,22 @@ export interface RefreshTokenProps<D extends {}> {
83
83
  showLoading?: boolean;
84
84
  }
85
85
 
86
+ /**
87
+ * App fields
88
+ */
89
+ const appFields = [
90
+ 'headerToken',
91
+ 'serversideDeviceId',
92
+ 'deviceId',
93
+ 'devices',
94
+ 'devicePassphrase'
95
+ ] as const;
96
+
97
+ /**
98
+ * Basic type template
99
+ */
100
+ export type IAppFields = { [key in typeof appFields[number]]: string };
101
+
86
102
  /**
87
103
  * Core application interface
88
104
  */
@@ -96,6 +112,11 @@ export interface ICoreApp<
96
112
  */
97
113
  readonly settings: S;
98
114
 
115
+ /**
116
+ * Fields
117
+ */
118
+ readonly fields: IAppFields;
119
+
99
120
  /**
100
121
  * API
101
122
  */
@@ -502,6 +523,11 @@ export abstract class CoreApp<
502
523
  */
503
524
  readonly settings: S;
504
525
 
526
+ /**
527
+ * Fields
528
+ */
529
+ readonly fields: IAppFields;
530
+
505
531
  /**
506
532
  * API
507
533
  */
@@ -632,10 +658,10 @@ export abstract class CoreApp<
632
658
  */
633
659
  protected get persistedFields() {
634
660
  return [
635
- this.addIdentifier(CoreApp.deviceIdField),
636
- this.addIdentifier(CoreApp.devicePassphraseField),
637
- this.addIdentifier(CoreApp.serversideDeviceIdField),
638
- this.addIdentifier(CoreApp.headerTokenField)
661
+ this.fields.deviceId,
662
+ this.fields.devicePassphrase,
663
+ this.fields.serversideDeviceId,
664
+ this.fields.headerToken
639
665
  ];
640
666
  }
641
667
 
@@ -660,12 +686,15 @@ export abstract class CoreApp<
660
686
  this.storage = storage;
661
687
  this.name = name;
662
688
 
663
- // Device id
664
- this._deviceId = storage.getData(
665
- this.addIdentifier(CoreApp.deviceIdField),
666
- ''
689
+ // Fields, attach with the name identifier
690
+ this.fields = appFields.reduce(
691
+ (a, v) => ({ ...a, [v]: 'smarterp-' + v + '-' + name }),
692
+ {} as any
667
693
  );
668
694
 
695
+ // Device id
696
+ this._deviceId = storage.getData(this.fields.deviceId, '');
697
+
669
698
  // Restore
670
699
  this.restore();
671
700
 
@@ -687,22 +716,31 @@ export abstract class CoreApp<
687
716
  private resetKeys() {
688
717
  this.storage.clear(
689
718
  [
690
- this.addIdentifier(CoreApp.devicePassphraseField),
691
- this.addIdentifier(CoreApp.headerTokenField),
692
- this.addIdentifier(CoreApp.serversideDeviceIdField)
719
+ this.fields.devicePassphrase,
720
+ this.fields.headerToken,
721
+ this.fields.serversideDeviceId
693
722
  ],
694
723
  false
695
724
  );
696
725
  this.passphrase = '';
697
726
  }
698
727
 
728
+ /**
729
+ * Add app name as identifier
730
+ * @param field Field
731
+ * @returns Result
732
+ */
733
+ protected addIdentifier(field: string) {
734
+ return field + '-' + this.name;
735
+ }
736
+
699
737
  /**
700
738
  * Restore settings from persisted source
701
739
  */
702
740
  protected restore() {
703
741
  // Devices
704
742
  const devices = this.storage.getPersistedData<string[]>(
705
- CoreApp.devicesField,
743
+ this.fields.devices,
706
744
  []
707
745
  );
708
746
 
@@ -711,10 +749,7 @@ export abstract class CoreApp<
711
749
  this.storage.copyFrom(this.persistedFields, false);
712
750
 
713
751
  // Reset device id
714
- this._deviceId = this.storage.getData(
715
- this.addIdentifier(CoreApp.deviceIdField),
716
- ''
717
- );
752
+ this._deviceId = this.storage.getData(this.fields.deviceId, '');
718
753
 
719
754
  // Totally new, no data restored
720
755
  if (this._deviceId === '') return false;
@@ -731,7 +766,7 @@ export abstract class CoreApp<
731
766
 
732
767
  // this.name to identifier different app's secret
733
768
  const passphraseEncrypted = this.storage.getData<string>(
734
- this.addIdentifier(CoreApp.devicePassphraseField)
769
+ this.fields.devicePassphrase
735
770
  );
736
771
  if (passphraseEncrypted) {
737
772
  const passphraseDecrypted = this.decrypt(
@@ -741,7 +776,7 @@ export abstract class CoreApp<
741
776
  if (passphraseDecrypted != null) {
742
777
  // Add the device to the list
743
778
  devices.push(d);
744
- this.storage.setPersistedData(CoreApp.devicesField, devices);
779
+ this.storage.setPersistedData(this.fields.devices, devices);
745
780
 
746
781
  this.passphrase = passphraseDecrypted;
747
782
 
@@ -761,14 +796,14 @@ export abstract class CoreApp<
761
796
  persist() {
762
797
  // Devices
763
798
  const devices = this.storage.getPersistedData<string[]>(
764
- CoreApp.devicesField
799
+ this.fields.devices
765
800
  );
766
801
  if (devices != null) {
767
802
  const index = devices.indexOf(this.getDeviceId());
768
803
  if (index !== -1) {
769
804
  // Remove current device from the list
770
805
  devices.splice(index, 1);
771
- this.storage.setPersistedData(CoreApp.devicesField, devices);
806
+ this.storage.setPersistedData(this.fields.devices, devices);
772
807
  }
773
808
  }
774
809
 
@@ -776,15 +811,6 @@ export abstract class CoreApp<
776
811
  this.storage.copyTo(this.persistedFields);
777
812
  }
778
813
 
779
- /**
780
- * Add app name as identifier
781
- * @param field Field
782
- * @returns Result
783
- */
784
- protected addIdentifier(field: string) {
785
- return field + '-' + this.name;
786
- }
787
-
788
814
  /**
789
815
  * Setup Api
790
816
  * @param api Api
@@ -845,7 +871,7 @@ export abstract class CoreApp<
845
871
 
846
872
  // Serverside encrypted device id
847
873
  const identifier = this.storage.getData<string>(
848
- this.addIdentifier(CoreApp.serversideDeviceIdField)
874
+ this.fields.serversideDeviceId
849
875
  );
850
876
 
851
877
  // Timestamp
@@ -890,10 +916,7 @@ export abstract class CoreApp<
890
916
  if (callback) callback(false);
891
917
 
892
918
  // Clear device id
893
- this.storage.setData(
894
- this.addIdentifier(CoreApp.deviceIdField),
895
- undefined
896
- );
919
+ this.storage.setData(this.fields.deviceId, undefined);
897
920
 
898
921
  return;
899
922
  }
@@ -919,23 +942,20 @@ export abstract class CoreApp<
919
942
 
920
943
  // Update device id and cache it
921
944
  this._deviceId = data.deviceId;
922
- this.storage.setData(
923
- this.addIdentifier(CoreApp.deviceIdField),
924
- this._deviceId
925
- );
945
+ this.storage.setData(this.fields.deviceId, this._deviceId);
926
946
 
927
947
  // Devices
928
948
  const devices = this.storage.getPersistedData<string[]>(
929
- CoreApp.devicesField,
949
+ this.fields.devices,
930
950
  []
931
951
  );
932
952
  devices.push(this.getDeviceId());
933
- this.storage.setPersistedData(CoreApp.devicesField, devices);
953
+ this.storage.setPersistedData(this.fields.devices, devices);
934
954
 
935
955
  // Current passphrase
936
956
  this.passphrase = passphrase;
937
957
  this.storage.setData(
938
- this.addIdentifier(CoreApp.devicePassphraseField),
958
+ this.fields.devicePassphrase,
939
959
  this.encrypt(passphrase, this.name)
940
960
  );
941
961
 
@@ -981,7 +1001,7 @@ export abstract class CoreApp<
981
1001
  * @returns Fields
982
1002
  */
983
1003
  protected initCallEncryptedUpdateFields(): string[] {
984
- return [this.addIdentifier(CoreApp.headerTokenField)];
1004
+ return [this.fields.headerToken];
985
1005
  }
986
1006
 
987
1007
  /**
@@ -1009,10 +1029,7 @@ export abstract class CoreApp<
1009
1029
  // Cover the current value
1010
1030
  if (refreshToken !== '') {
1011
1031
  if (refreshToken != null) refreshToken = this.encrypt(refreshToken);
1012
- this.storage.setData(
1013
- this.addIdentifier(CoreApp.headerTokenField),
1014
- refreshToken
1015
- );
1032
+ this.storage.setData(this.fields.headerToken, refreshToken);
1016
1033
  }
1017
1034
 
1018
1035
  // Reset tryLogin state
@@ -1100,10 +1117,7 @@ export abstract class CoreApp<
1100
1117
  */
1101
1118
  clearCacheData() {
1102
1119
  this.clearCacheToken();
1103
- this.storage.setData(
1104
- this.addIdentifier(CoreApp.devicePassphraseField),
1105
- undefined
1106
- );
1120
+ this.storage.setData(this.fields.devicePassphrase, undefined);
1107
1121
  }
1108
1122
 
1109
1123
  /**
@@ -1111,10 +1125,7 @@ export abstract class CoreApp<
1111
1125
  */
1112
1126
  clearCacheToken() {
1113
1127
  this.cachedRefreshToken = undefined;
1114
- this.storage.setPersistedData(
1115
- this.addIdentifier(CoreApp.headerTokenField),
1116
- undefined
1117
- );
1128
+ this.storage.setPersistedData(this.fields.headerToken, undefined);
1118
1129
  }
1119
1130
 
1120
1131
  /**
@@ -1426,9 +1437,7 @@ export abstract class CoreApp<
1426
1437
  getCacheToken(): string | undefined {
1427
1438
  // Temp refresh token
1428
1439
  if (this.cachedRefreshToken) return this.cachedRefreshToken;
1429
- return this.storage.getData<string>(
1430
- this.addIdentifier(CoreApp.headerTokenField)
1431
- );
1440
+ return this.storage.getData<string>(this.fields.headerToken);
1432
1441
  }
1433
1442
 
1434
1443
  /**
@@ -1462,7 +1471,7 @@ export abstract class CoreApp<
1462
1471
  const response = this.api.transformResponse(rawResponse);
1463
1472
  return this.api.getHeaderValue(
1464
1473
  response.headers,
1465
- CoreApp.headerTokenField
1474
+ 'SmartERPRefreshToken'
1466
1475
  );
1467
1476
  }
1468
1477
 
@@ -1697,8 +1706,9 @@ export abstract class CoreApp<
1697
1706
  * Try login, returning false means is loading
1698
1707
  * UI get involved while refreshToken not intended
1699
1708
  * @param data Additional request data
1709
+ * @param showLoading Show loading bar or not during call
1700
1710
  */
1701
- async tryLogin<D extends {} = {}>(_data?: D) {
1711
+ async tryLogin<D extends {} = {}>(_data?: D, _showLoading?: boolean) {
1702
1712
  if (this._isTryingLogin) return false;
1703
1713
  this._isTryingLogin = true;
1704
1714
  return true;
@@ -1714,10 +1724,7 @@ export abstract class CoreApp<
1714
1724
  this.userData = user;
1715
1725
 
1716
1726
  // Cache the encrypted serverside device id
1717
- this.storage.setData(
1718
- this.addIdentifier(CoreApp.serversideDeviceIdField),
1719
- user.deviceId
1720
- );
1727
+ this.storage.setData(this.fields.serversideDeviceId, user.deviceId);
1721
1728
 
1722
1729
  if (keep) {
1723
1730
  this.authorize(user.token, refreshToken);
@@ -1764,30 +1771,3 @@ export abstract class CoreApp<
1764
1771
  );
1765
1772
  }
1766
1773
  }
1767
-
1768
- export namespace CoreApp {
1769
- /**
1770
- * Response token header field name
1771
- */
1772
- export const headerTokenField = 'SmartERPRefreshToken';
1773
-
1774
- /**
1775
- * Serverside device id encrypted field name
1776
- */
1777
- export const serversideDeviceIdField = 'SmartERPServersideDeviceId';
1778
-
1779
- /**
1780
- * Device id field name
1781
- */
1782
- export const deviceIdField = 'SmartERPDeviceId';
1783
-
1784
- /**
1785
- * Devices field name
1786
- */
1787
- export const devicesField = 'SmartERPDevices';
1788
-
1789
- /**
1790
- * Device passphrase field name
1791
- */
1792
- export const devicePassphraseField = 'SmartERPDevicePassphrase';
1793
- }
@@ -1,48 +1,19 @@
1
+ import { FlutterHost } from './FlutterHost';
1
2
  import { IBridgeHost } from './IBridgeHost';
2
3
 
3
4
  /**
4
5
  * Bridge utils
5
6
  */
6
7
  export namespace BridgeUtils {
7
- /**
8
- * Is electron client
9
- * @returns Result
10
- */
11
- export function isElectronClient() {
12
- // Renderer process
13
- if (
14
- typeof window !== 'undefined' &&
15
- typeof window.process === 'object' &&
16
- (window.process as any).type === 'renderer'
17
- ) {
18
- return true;
19
- }
20
-
21
- // Main process
22
- if (
23
- typeof process !== 'undefined' &&
24
- typeof process.versions === 'object' &&
25
- !!process.versions.electron
26
- ) {
27
- return true;
28
- }
29
-
30
- // Detect the user agent when the `nodeIntegration` option is set to true
31
- if (
32
- typeof navigator === 'object' &&
33
- typeof navigator.userAgent === 'string' &&
34
- navigator.userAgent.indexOf('Electron') >= 0
35
- ) {
36
- return true;
37
- }
38
-
39
- return false;
40
- }
8
+ const g: any = globalThis;
41
9
 
42
10
  /**
43
11
  * Bridge host
44
12
  */
45
- export const host = isElectronClient()
46
- ? ((globalThis as any).electron as IBridgeHost)
47
- : undefined;
13
+ export const host =
14
+ typeof g.flutter_inappwebview?.callHandler === 'function'
15
+ ? new FlutterHost(g.flutter_inappwebview.callHandler)
16
+ : typeof g.electron === 'object'
17
+ ? (g.electron as IBridgeHost)
18
+ : undefined;
48
19
  }
@@ -0,0 +1,40 @@
1
+ import { IBridgeHost } from './IBridgeHost';
2
+
3
+ /**
4
+ * Flutter JavaScript Host
5
+ * https://inappwebview.dev/docs/javascript/communication/
6
+ */
7
+ export class FlutterHost implements IBridgeHost {
8
+ /**
9
+ * Start Url
10
+ */
11
+ private startUrl: string | null | undefined;
12
+
13
+ /**
14
+ * Constructor
15
+ * @param callHandler Call handler
16
+ */
17
+ constructor(
18
+ public callHandler: (
19
+ name: string,
20
+ ...args: unknown[]
21
+ ) => PromiseLike<{} | void>
22
+ ) {}
23
+
24
+ changeCulture(locale: string): void {
25
+ this.callHandler('changeCulture', locale);
26
+ }
27
+
28
+ exit(): void {
29
+ this.callHandler('exit');
30
+ }
31
+
32
+ getStartUrl(): string | null | undefined {
33
+ return this.startUrl;
34
+ }
35
+
36
+ loadApp(name: string, startUrl?: string): void {
37
+ this.startUrl = startUrl;
38
+ this.callHandler('loadApp', name, startUrl);
39
+ }
40
+ }
@@ -13,10 +13,15 @@ export interface IBridgeHost {
13
13
  */
14
14
  exit(): void;
15
15
 
16
+ /**
17
+ * Get app start Url / router Url
18
+ */
19
+ getStartUrl(): string | undefined | null;
20
+
16
21
  /**
17
22
  * Load application
18
23
  * @param name App name
19
- * @param startUrl Start Url
24
+ * @param startUrl Start Url / router Url
20
25
  */
21
26
  loadApp(name: string, startUrl?: string): void;
22
27
  }
@@ -56,6 +56,26 @@ export namespace BusinessUtils {
56
56
  });
57
57
  }
58
58
 
59
+ /**
60
+ * Get 12-month items
61
+ * @param monthLabels Month labels
62
+ * @param startMonth Start month, 0 as Jan.
63
+ * @returns 12 months
64
+ */
65
+ export function getMonths(monthLabels: string[], startMonth: number = 0) {
66
+ const months: DataTypes.IdLabelItem[] = [];
67
+
68
+ for (let i = 0; i < 12; i++) {
69
+ if (startMonth >= 12) startMonth = 0;
70
+
71
+ months.push({ id: startMonth, label: monthLabels[startMonth] });
72
+
73
+ startMonth++;
74
+ }
75
+
76
+ return months;
77
+ }
78
+
59
79
  /**
60
80
  * Get product unit's label
61
81
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
@@ -50,6 +50,20 @@
50
50
  "message": "Message",
51
51
  "mobile": "Mobile number",
52
52
  "mobilePhones": "Mobile numbers",
53
+ "months": [
54
+ "Jan.",
55
+ "Feb.",
56
+ "Mar.",
57
+ "Apr.",
58
+ "May.",
59
+ "Jun.",
60
+ "Jul.",
61
+ "Aug.",
62
+ "Sep.",
63
+ "Oct.",
64
+ "Nov.",
65
+ "Dec."
66
+ ],
53
67
  "more": "More",
54
68
  "moreTag": "{0} more",
55
69
  "name": "Name",
@@ -67,6 +81,7 @@
67
81
  "pageNotFound": "Page Not Found",
68
82
  "prompt": "Input",
69
83
  "pullToRefresh": "Pull down to refresh",
84
+ "quarters": ["Q1", "Q2", "Q3", "Q4"],
70
85
  "record": "Record",
71
86
  "refresh": "Refresh",
72
87
  "refreshing": "Refreshing",
@@ -50,6 +50,20 @@
50
50
  "message": "留言",
51
51
  "mobile": "手机号码",
52
52
  "mobilePhones": "手机号码",
53
+ "months": [
54
+ "1月",
55
+ "2月",
56
+ "3月",
57
+ "4月",
58
+ "5月",
59
+ "6月",
60
+ "7月",
61
+ "8月",
62
+ "9月",
63
+ "10月",
64
+ "11月",
65
+ "12月"
66
+ ],
53
67
  "more": "更多",
54
68
  "moreTag": "({0}+)",
55
69
  "name": "姓名",
@@ -67,6 +81,7 @@
67
81
  "pageNotFound": "找不到页面",
68
82
  "prompt": "输入",
69
83
  "pullToRefresh": "下拉刷新",
84
+ "quarters": ["一季度", "二季度", "三季度", "四季度"],
70
85
  "record": "记录",
71
86
  "refresh": "刷新",
72
87
  "refreshing": "正在刷新",
@@ -50,6 +50,20 @@
50
50
  "message": "留言",
51
51
  "mobilePhone": "手機號碼",
52
52
  "mobilePhones": "手機號碼",
53
+ "months": [
54
+ "1月",
55
+ "2月",
56
+ "3月",
57
+ "4月",
58
+ "5月",
59
+ "6月",
60
+ "7月",
61
+ "8月",
62
+ "9月",
63
+ "10月",
64
+ "11月",
65
+ "12月"
66
+ ],
53
67
  "more": "更多",
54
68
  "moreTag": "({0}+)",
55
69
  "name": "姓名",
@@ -67,6 +81,7 @@
67
81
  "pageNotFound": "找不到頁面",
68
82
  "prompt": "輸入",
69
83
  "pullToRefresh": "下拉刷新",
84
+ "quarters": ["一季度", "二季度", "三季度", "四季度"],
70
85
  "record": "記錄",
71
86
  "refresh": "刷新",
72
87
  "refreshing": "正在刷新",