lupine.web 1.1.3 → 1.1.5
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 +66 -3
- package/jsx-runtime/index.js +14 -14
- package/jsx-runtime/package.json +16 -16
- package/jsx-runtime/src/index.d.ts +2 -2
- package/package.json +53 -52
- package/src/core/bind-attributes.ts +61 -61
- package/src/core/bind-lang.ts +52 -52
- package/src/core/bind-links.ts +26 -16
- package/src/core/bind-meta.tsx +52 -52
- package/src/core/bind-ref.ts +51 -51
- package/src/core/bind-styles.ts +239 -239
- package/src/core/bind-theme.ts +53 -53
- package/src/core/camel-to-hyphens.ts +3 -3
- package/src/core/export-lupine.ts +80 -80
- package/src/core/index.ts +17 -17
- package/src/core/initialize.ts +116 -116
- package/src/core/mount-component.ts +72 -68
- package/src/core/page-loaded-events.ts +16 -16
- package/src/core/page-router.ts +180 -180
- package/src/core/render-component.ts +230 -233
- package/src/core/replace-innerhtml.ts +23 -23
- package/src/core/server-cookie.ts +24 -24
- package/src/global.d.ts +66 -66
- package/src/index.ts +14 -14
- package/src/jsx.ts +1044 -1043
- package/src/lib/cookie.ts +44 -44
- package/src/lib/debug-watch.ts +32 -32
- package/src/lib/index.ts +7 -7
- package/src/lib/is-frontend.ts +3 -3
- package/src/lib/logger.ts +55 -55
- package/src/lib/unique-id.ts +40 -40
- package/src/lib/web-config.ts +79 -77
- package/src/lib/web-env.ts +99 -99
- package/src/models/index.ts +4 -4
- package/src/models/json-props.ts +8 -8
- package/src/models/simple-storage-props.ts +9 -9
- package/src/models/theme-props.ts +7 -7
- package/src/models/to-client-delivery-props.ts +8 -8
- package/src/styles/css-styles.ts +814 -814
- package/src/styles/index.ts +4 -4
- package/tsconfig.json +113 -113
package/src/lib/cookie.ts
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
export const setCookie = (
|
|
2
|
-
name: string,
|
|
3
|
-
value: string,
|
|
4
|
-
expireDays = 365,
|
|
5
|
-
path?: string,
|
|
6
|
-
domain?: string,
|
|
7
|
-
secure?: string
|
|
8
|
-
) => {
|
|
9
|
-
const expires = new Date(new Date().getTime() + expireDays * 24 * 3600000);
|
|
10
|
-
document.cookie =
|
|
11
|
-
name +
|
|
12
|
-
'=' +
|
|
13
|
-
escape(value) +
|
|
14
|
-
';expires=' +
|
|
15
|
-
expires.toUTCString() +
|
|
16
|
-
';path=' +
|
|
17
|
-
(path ? path : '/') +
|
|
18
|
-
(domain ? ';domain=' + domain : '') +
|
|
19
|
-
(secure ? ';secure' : '');
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const getCookie = (key: string) => {
|
|
23
|
-
const cookies = document.cookie.split(';');
|
|
24
|
-
for (let i = 0; i < cookies.length; i++) {
|
|
25
|
-
const c = cookies[i].trim();
|
|
26
|
-
if (c.substring(0, key.length + 1) == key + '=') {
|
|
27
|
-
return unescape(c.substring(key.length + 1));
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return null;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export const clearCookie = (name: string, path?: string, domain?: string, secure?: string) => {
|
|
34
|
-
document.cookie =
|
|
35
|
-
name +
|
|
36
|
-
'=;expires=Fri, 02-Jan-1970 00:00:00 GMT' +
|
|
37
|
-
';path=' +
|
|
38
|
-
(path ? path : '/') +
|
|
39
|
-
(domain ? ';domain=' + domain : '') +
|
|
40
|
-
(secure ? ';secure' : '');
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// convinent but not good for tree-shaking
|
|
44
|
-
export const cookie = { set: setCookie, get: getCookie, clear: clearCookie };
|
|
1
|
+
export const setCookie = (
|
|
2
|
+
name: string,
|
|
3
|
+
value: string,
|
|
4
|
+
expireDays = 365,
|
|
5
|
+
path?: string,
|
|
6
|
+
domain?: string,
|
|
7
|
+
secure?: string
|
|
8
|
+
) => {
|
|
9
|
+
const expires = new Date(new Date().getTime() + expireDays * 24 * 3600000);
|
|
10
|
+
document.cookie =
|
|
11
|
+
name +
|
|
12
|
+
'=' +
|
|
13
|
+
escape(value) +
|
|
14
|
+
';expires=' +
|
|
15
|
+
expires.toUTCString() +
|
|
16
|
+
';path=' +
|
|
17
|
+
(path ? path : '/') +
|
|
18
|
+
(domain ? ';domain=' + domain : '') +
|
|
19
|
+
(secure ? ';secure' : '');
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getCookie = (key: string) => {
|
|
23
|
+
const cookies = document.cookie.split(';');
|
|
24
|
+
for (let i = 0; i < cookies.length; i++) {
|
|
25
|
+
const c = cookies[i].trim();
|
|
26
|
+
if (c.substring(0, key.length + 1) == key + '=') {
|
|
27
|
+
return unescape(c.substring(key.length + 1));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const clearCookie = (name: string, path?: string, domain?: string, secure?: string) => {
|
|
34
|
+
document.cookie =
|
|
35
|
+
name +
|
|
36
|
+
'=;expires=Fri, 02-Jan-1970 00:00:00 GMT' +
|
|
37
|
+
';path=' +
|
|
38
|
+
(path ? path : '/') +
|
|
39
|
+
(domain ? ';domain=' + domain : '') +
|
|
40
|
+
(secure ? ';secure' : '');
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// convinent but not good for tree-shaking
|
|
44
|
+
export const cookie = { set: setCookie, get: getCookie, clear: clearCookie };
|
package/src/lib/debug-watch.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
let flag = 0;
|
|
2
|
-
export const debugWatch = (port: number) => {
|
|
3
|
-
console.log('Creating debug-watch socket');
|
|
4
|
-
const protocol = location.protocol ===
|
|
5
|
-
const socket = new WebSocket(`${protocol}//${location.host}/debug/client`);
|
|
6
|
-
window.addEventListener('beforeunload', () => {
|
|
7
|
-
socket.close();
|
|
8
|
-
});
|
|
9
|
-
socket.onopen = () => {
|
|
10
|
-
// console.log('Socket open.');
|
|
11
|
-
socket.send(JSON.stringify({ message: 'get-flag' }));
|
|
12
|
-
};
|
|
13
|
-
socket.onmessage = (message) => {
|
|
14
|
-
try {
|
|
15
|
-
const jsonData = JSON.parse(message.data);
|
|
16
|
-
console.log('Debug socket message:', jsonData);
|
|
17
|
-
if (jsonData && jsonData.flag) {
|
|
18
|
-
if (!flag) {
|
|
19
|
-
flag = jsonData.flag;
|
|
20
|
-
} else if (flag !== jsonData.flag) {
|
|
21
|
-
document.location.reload();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
} catch {}
|
|
25
|
-
};
|
|
26
|
-
socket.onclose = () => {
|
|
27
|
-
console.log('Debug socket close.');
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
debugWatch(port);
|
|
30
|
-
}, 3000);
|
|
31
|
-
};
|
|
32
|
-
};
|
|
1
|
+
let flag = 0;
|
|
2
|
+
export const debugWatch = (port: number) => {
|
|
3
|
+
console.log('Creating debug-watch socket');
|
|
4
|
+
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
5
|
+
const socket = new WebSocket(`${protocol}//${location.host}/debug/client`);
|
|
6
|
+
window.addEventListener('beforeunload', () => {
|
|
7
|
+
socket.close();
|
|
8
|
+
});
|
|
9
|
+
socket.onopen = () => {
|
|
10
|
+
// console.log('Socket open.');
|
|
11
|
+
socket.send(JSON.stringify({ message: 'get-flag' }));
|
|
12
|
+
};
|
|
13
|
+
socket.onmessage = (message) => {
|
|
14
|
+
try {
|
|
15
|
+
const jsonData = JSON.parse(message.data);
|
|
16
|
+
console.log('Debug socket message:', jsonData);
|
|
17
|
+
if (jsonData && jsonData.flag) {
|
|
18
|
+
if (!flag) {
|
|
19
|
+
flag = jsonData.flag;
|
|
20
|
+
} else if (flag !== jsonData.flag) {
|
|
21
|
+
document.location.reload();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch {}
|
|
25
|
+
};
|
|
26
|
+
socket.onclose = () => {
|
|
27
|
+
console.log('Debug socket close.');
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
debugWatch(port);
|
|
30
|
+
}, 3000);
|
|
31
|
+
};
|
|
32
|
+
};
|
package/src/lib/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './cookie';
|
|
2
|
-
export * from './debug-watch';
|
|
3
|
-
export * from './is-frontend';
|
|
4
|
-
export * from './logger';
|
|
5
|
-
export * from './unique-id';
|
|
6
|
-
export * from './web-config';
|
|
7
|
-
export * from './web-env';
|
|
1
|
+
export * from './cookie';
|
|
2
|
+
export * from './debug-watch';
|
|
3
|
+
export * from './is-frontend';
|
|
4
|
+
export * from './logger';
|
|
5
|
+
export * from './unique-id';
|
|
6
|
+
export * from './web-config';
|
|
7
|
+
export * from './web-env';
|
package/src/lib/is-frontend.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const isFrontEnd = () => {
|
|
2
|
-
return typeof window === 'object' && typeof document === 'object';
|
|
3
|
-
};
|
|
1
|
+
export const isFrontEnd = () => {
|
|
2
|
+
return typeof window === 'object' && typeof document === 'object';
|
|
3
|
+
};
|
package/src/lib/logger.ts
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
// Colors for console
|
|
2
|
-
export const ConsoleColors = {
|
|
3
|
-
Red: '#f44336',
|
|
4
|
-
Pink: '#e81e63',
|
|
5
|
-
Purple: '#9c27b0',
|
|
6
|
-
DeepPurple: '#673ab7',
|
|
7
|
-
Indigo: '#3f51b5',
|
|
8
|
-
Blue: '#2196f3',
|
|
9
|
-
LightBlue: '#03a9f4',
|
|
10
|
-
Cyan: '#00bcd4',
|
|
11
|
-
Teal: '#009688',
|
|
12
|
-
Green: '#4caf50',
|
|
13
|
-
LightGreen: '#8bc34a',
|
|
14
|
-
Lime: '#cddc39',
|
|
15
|
-
DarkYellow: '#bfa40e',
|
|
16
|
-
Amber: '#ffc107',
|
|
17
|
-
Orange: '#ff9800',
|
|
18
|
-
DeepOrange: '#ff5722',
|
|
19
|
-
Silver: '#c0c0c0',
|
|
20
|
-
Gray: '#808080',
|
|
21
|
-
Black: '#000000',
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export class Logger {
|
|
25
|
-
private static enabled = true;
|
|
26
|
-
private namespace = '';
|
|
27
|
-
private color = '';
|
|
28
|
-
constructor(namespace: string, color?: string) {
|
|
29
|
-
this.namespace = namespace ? `[${namespace}] ` : '';
|
|
30
|
-
if (color) {
|
|
31
|
-
this.color = 'color:' + color;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
static setEnabled(enabled: boolean) {
|
|
36
|
-
enabled && !Logger.enabled && console.log(`Logger is enabled.`);
|
|
37
|
-
Logger.enabled = enabled;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
log(message: string, ...data: (string | object | number | undefined)[]) {
|
|
41
|
-
Logger.enabled && console.log(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
timestamp(date?: Date) {
|
|
45
|
-
return (date || new Date()).toJSON().substring(11, 23);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
warn(message: string, ...data: (string | object | number | undefined)[]) {
|
|
49
|
-
console.warn(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
error(message: string, ...data: (string | object | number | undefined)[]) {
|
|
53
|
-
console.error(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
1
|
+
// Colors for console
|
|
2
|
+
export const ConsoleColors = {
|
|
3
|
+
Red: '#f44336',
|
|
4
|
+
Pink: '#e81e63',
|
|
5
|
+
Purple: '#9c27b0',
|
|
6
|
+
DeepPurple: '#673ab7',
|
|
7
|
+
Indigo: '#3f51b5',
|
|
8
|
+
Blue: '#2196f3',
|
|
9
|
+
LightBlue: '#03a9f4',
|
|
10
|
+
Cyan: '#00bcd4',
|
|
11
|
+
Teal: '#009688',
|
|
12
|
+
Green: '#4caf50',
|
|
13
|
+
LightGreen: '#8bc34a',
|
|
14
|
+
Lime: '#cddc39',
|
|
15
|
+
DarkYellow: '#bfa40e',
|
|
16
|
+
Amber: '#ffc107',
|
|
17
|
+
Orange: '#ff9800',
|
|
18
|
+
DeepOrange: '#ff5722',
|
|
19
|
+
Silver: '#c0c0c0',
|
|
20
|
+
Gray: '#808080',
|
|
21
|
+
Black: '#000000',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export class Logger {
|
|
25
|
+
private static enabled = true;
|
|
26
|
+
private namespace = '';
|
|
27
|
+
private color = '';
|
|
28
|
+
constructor(namespace: string, color?: string) {
|
|
29
|
+
this.namespace = namespace ? `[${namespace}] ` : '';
|
|
30
|
+
if (color) {
|
|
31
|
+
this.color = 'color:' + color;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static setEnabled(enabled: boolean) {
|
|
36
|
+
enabled && !Logger.enabled && console.log(`Logger is enabled.`);
|
|
37
|
+
Logger.enabled = enabled;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
log(message: string, ...data: (string | object | number | undefined)[]) {
|
|
41
|
+
Logger.enabled && console.log(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
timestamp(date?: Date) {
|
|
45
|
+
return (date || new Date()).toJSON().substring(11, 23);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
warn(message: string, ...data: (string | object | number | undefined)[]) {
|
|
49
|
+
console.warn(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
error(message: string, ...data: (string | object | number | undefined)[]) {
|
|
53
|
+
console.error(`%c${this.timestamp()} ${this.namespace}${message}`, this.color, ...data);
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/lib/unique-id.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sample:
|
|
3
|
-
* const domUniqueId = uniqueIdGenerator('lj');
|
|
4
|
-
* const id1 = domUniqueId();
|
|
5
|
-
* const id2 = domUniqueId();
|
|
6
|
-
* @param preKey
|
|
7
|
-
* @returns A function to generate Unique Ids
|
|
8
|
-
*/
|
|
9
|
-
// export function uniqueIdGenerator2(preKey: string) {
|
|
10
|
-
// let count = 0;
|
|
11
|
-
// let diff = '';
|
|
12
|
-
// return function (reset = false): string {
|
|
13
|
-
// if (reset) {
|
|
14
|
-
// count = 0;
|
|
15
|
-
// diff = '';
|
|
16
|
-
// }
|
|
17
|
-
// if (count > 9999999999999999) {
|
|
18
|
-
// count = 0;
|
|
19
|
-
// diff = Math.round(new Date().getTime() / 1000).toString(36) + '-';
|
|
20
|
-
// }
|
|
21
|
-
// count++;
|
|
22
|
-
// return `${preKey}${diff}${count.toString(36)}`;
|
|
23
|
-
// };
|
|
24
|
-
// }
|
|
25
|
-
|
|
26
|
-
export function uniqueIdGenerator(preKey: string) {
|
|
27
|
-
let count = 0;
|
|
28
|
-
const baseTime = Math.round(Date.now() / 1000);
|
|
29
|
-
let lastKey = '';
|
|
30
|
-
return function (): string {
|
|
31
|
-
const key = Math.round(Date.now() / 1000 - baseTime).toString(36);
|
|
32
|
-
if (key !== lastKey) {
|
|
33
|
-
count = 0;
|
|
34
|
-
lastKey = key;
|
|
35
|
-
} else {
|
|
36
|
-
count++;
|
|
37
|
-
}
|
|
38
|
-
return `${preKey}${lastKey}${count.toString(36)}`;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Sample:
|
|
3
|
+
* const domUniqueId = uniqueIdGenerator('lj');
|
|
4
|
+
* const id1 = domUniqueId();
|
|
5
|
+
* const id2 = domUniqueId();
|
|
6
|
+
* @param preKey
|
|
7
|
+
* @returns A function to generate Unique Ids
|
|
8
|
+
*/
|
|
9
|
+
// export function uniqueIdGenerator2(preKey: string) {
|
|
10
|
+
// let count = 0;
|
|
11
|
+
// let diff = '';
|
|
12
|
+
// return function (reset = false): string {
|
|
13
|
+
// if (reset) {
|
|
14
|
+
// count = 0;
|
|
15
|
+
// diff = '';
|
|
16
|
+
// }
|
|
17
|
+
// if (count > 9999999999999999) {
|
|
18
|
+
// count = 0;
|
|
19
|
+
// diff = Math.round(new Date().getTime() / 1000).toString(36) + '-';
|
|
20
|
+
// }
|
|
21
|
+
// count++;
|
|
22
|
+
// return `${preKey}${diff}${count.toString(36)}`;
|
|
23
|
+
// };
|
|
24
|
+
// }
|
|
25
|
+
|
|
26
|
+
export function uniqueIdGenerator(preKey: string) {
|
|
27
|
+
let count = 0;
|
|
28
|
+
const baseTime = Math.round(Date.now() / 1000);
|
|
29
|
+
let lastKey = '';
|
|
30
|
+
return function (): string {
|
|
31
|
+
const key = Math.round(Date.now() / 1000 - baseTime).toString(36);
|
|
32
|
+
if (key !== lastKey) {
|
|
33
|
+
count = 0;
|
|
34
|
+
lastKey = key;
|
|
35
|
+
} else {
|
|
36
|
+
count++;
|
|
37
|
+
}
|
|
38
|
+
return `${preKey}${lastKey}${count.toString(36)}`;
|
|
39
|
+
};
|
|
40
|
+
}
|
package/src/lib/web-config.ts
CHANGED
|
@@ -1,77 +1,79 @@
|
|
|
1
|
-
import { getRenderPageProps } from 'lupine.web';
|
|
2
|
-
|
|
3
|
-
// for mobile app, it needs the url to fetch the config for the first time
|
|
4
|
-
export const bindWebConfigApi = (webConfigApi: string) => {
|
|
5
|
-
WebConfig.webConfigApi = webConfigApi;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export class WebConfig {
|
|
9
|
-
static webConfigApi = '';
|
|
10
|
-
static initialized = false;
|
|
11
|
-
static cfg: { [key: string]: string } = {};
|
|
12
|
-
|
|
13
|
-
// called from generatePage (SSR)
|
|
14
|
-
static initFromData(cfg: { [key: string]: string }) {
|
|
15
|
-
this.initialized = true;
|
|
16
|
-
this.cfg = cfg;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static async init(force?: boolean) {
|
|
20
|
-
if (this.initialized && !force) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
this.initialized = true;
|
|
24
|
-
|
|
25
|
-
// For web, it's injected in the html by SSR, but for mobile, it's fetched from api
|
|
26
|
-
if (typeof document === 'object' && !force) {
|
|
27
|
-
const json = document.querySelector('#web-setting')?.textContent;
|
|
28
|
-
if (json) {
|
|
29
|
-
this.cfg = JSON.parse(json);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!this.webConfigApi) {
|
|
35
|
-
console.error('WebConfig webConfigApi is not set');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const url = getRenderPageProps().renderPageFunctions.baseUrl(this.webConfigApi);
|
|
39
|
-
const data = await getRenderPageProps().renderPageFunctions.fetchData(url);
|
|
40
|
-
if (data && data.json && data.json.status === 'ok') {
|
|
41
|
-
this.cfg = data.json.result;
|
|
42
|
-
} else {
|
|
43
|
-
console.error(data?.json?.message || 'Failed to get web config');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
static async get(key: string, defaultValue: number): Promise<number>;
|
|
48
|
-
static async get(key: string, defaultValue: string): Promise<string>;
|
|
49
|
-
static async get(key: string, defaultValue: boolean): Promise<boolean>;
|
|
50
|
-
static async get(key: string, defaultValue: object): Promise<object>;
|
|
51
|
-
static async get(key: string, defaultValue?: any): Promise<any> {
|
|
52
|
-
await WebConfig.init();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
import { getRenderPageProps } from 'lupine.web';
|
|
2
|
+
|
|
3
|
+
// for mobile app, it needs the url to fetch the config for the first time
|
|
4
|
+
export const bindWebConfigApi = (webConfigApi: string) => {
|
|
5
|
+
WebConfig.webConfigApi = webConfigApi;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export class WebConfig {
|
|
9
|
+
static webConfigApi = '';
|
|
10
|
+
static initialized = false;
|
|
11
|
+
static cfg: { [key: string]: string } = {};
|
|
12
|
+
|
|
13
|
+
// called from generatePage (SSR)
|
|
14
|
+
static initFromData(cfg: { [key: string]: string }) {
|
|
15
|
+
this.initialized = true;
|
|
16
|
+
this.cfg = cfg;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static async init(force?: boolean) {
|
|
20
|
+
if (this.initialized && !force) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.initialized = true;
|
|
24
|
+
|
|
25
|
+
// For web, it's injected in the html by SSR, but for mobile, it's fetched from api
|
|
26
|
+
if (typeof document === 'object' && !force) {
|
|
27
|
+
const json = document.querySelector('#web-setting')?.textContent;
|
|
28
|
+
if (json) {
|
|
29
|
+
this.cfg = JSON.parse(json);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!this.webConfigApi) {
|
|
35
|
+
console.error('WebConfig webConfigApi is not set');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const url = getRenderPageProps().renderPageFunctions.baseUrl(this.webConfigApi);
|
|
39
|
+
const data = await getRenderPageProps().renderPageFunctions.fetchData(url);
|
|
40
|
+
if (data && data.json && data.json.status === 'ok') {
|
|
41
|
+
this.cfg = data.json.result;
|
|
42
|
+
} else {
|
|
43
|
+
console.error(data?.json?.message || 'Failed to get web config');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static async get(key: string, defaultValue: number): Promise<number>;
|
|
48
|
+
static async get(key: string, defaultValue: string): Promise<string>;
|
|
49
|
+
static async get(key: string, defaultValue: boolean): Promise<boolean>;
|
|
50
|
+
static async get(key: string, defaultValue: object): Promise<object>;
|
|
51
|
+
static async get(key: string, defaultValue?: any): Promise<any> {
|
|
52
|
+
await WebConfig.init();
|
|
53
|
+
|
|
54
|
+
const v = WebConfig.cfg[key];
|
|
55
|
+
if (typeof v === 'undefined') {
|
|
56
|
+
return defaultValue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (typeof defaultValue === 'number') {
|
|
60
|
+
return Number.parseInt(v!);
|
|
61
|
+
}
|
|
62
|
+
if (typeof defaultValue === 'boolean') {
|
|
63
|
+
return v!.toLocaleLowerCase() === 'true' || v === '1';
|
|
64
|
+
}
|
|
65
|
+
if (typeof defaultValue === 'object') {
|
|
66
|
+
if (typeof v === 'object') {
|
|
67
|
+
return v;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(v!);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(`WebConfig JSON.parse error: `, error);
|
|
73
|
+
}
|
|
74
|
+
return defaultValue;
|
|
75
|
+
}
|
|
76
|
+
// if empty, then return default value
|
|
77
|
+
return v || defaultValue;
|
|
78
|
+
}
|
|
79
|
+
}
|