@goodgamestudios/cxf-webshop 7.0.0-qa.1 → 7.0.0-qa.11
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/dist/webshop-cxf.js +1 -1
- package/dist/webshop-cxf.js.map +4 -4
- package/esbuild.serve.webshop.js +25 -0
- package/package.json +10 -9
- package/.eslintrc.js +0 -25
- package/.prettierignore +0 -6
- package/.prettierrc.js +0 -10
- package/REFACTORING_README.md +0 -265
- package/TEST_MIGRATION.md +0 -441
- package/TYPES_REFACTORING.md +0 -308
- package/esbuild.build.js +0 -14
- package/esbuild.serve.js +0 -25
- package/src_old/@types/global.d.ts +0 -2
- package/src_old/ArgumentNullError.ts +0 -6
- package/src_old/app.ts +0 -30
- package/src_old/combineReaders.ts +0 -8
- package/src_old/common.ts +0 -35
- package/src_old/config.ts +0 -42
- package/src_old/cxf.ts +0 -32
- package/src_old/dialog.ts +0 -25
- package/src_old/env.ts +0 -127
- package/src_old/fetch.ts +0 -46
- package/src_old/handlers/eventHandlers.ts +0 -43
- package/src_old/handlers/postMessageHandlers.ts +0 -43
- package/src_old/handlers/pushHandlers.ts +0 -95
- package/src_old/handlers/reducers.ts +0 -207
- package/src_old/helpers.ts +0 -143
- package/src_old/index.ts +0 -35
- package/src_old/messages/IShopMessageBus.ts +0 -3
- package/src_old/messages/ShopMessageBus.ts +0 -10
- package/src_old/messages/TestShopMessageBus.ts +0 -8
- package/src_old/ping.ts +0 -15
- package/src_old/preFetch.ts +0 -43
- package/src_old/storage.ts +0 -32
- package/src_old/store.ts +0 -82
- package/src_old/track.ts +0 -59
- package/src_old/url.ts +0 -95
- package/src_old/utils.ts +0 -64
package/src_old/preFetch.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { DIReader } from './common'
|
|
2
|
-
import { inject } from 'readuz'
|
|
3
|
-
|
|
4
|
-
type LemonstandConfig = {
|
|
5
|
-
css: string
|
|
6
|
-
js: string
|
|
7
|
-
unreadOfferNotifsCountUrl: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type PreFetch = (...parameter: any[]) => void
|
|
11
|
-
|
|
12
|
-
export const preResolveConfig: DIReader<PreFetch> = inject(
|
|
13
|
-
(environment) => environment.log,
|
|
14
|
-
(environment) => environment.setStore,
|
|
15
|
-
(environment) => environment.createCustomizationUrl,
|
|
16
|
-
(log, setStore, getCustomizationUrl) => () => {
|
|
17
|
-
if (typeof fetch !== 'function') {
|
|
18
|
-
return
|
|
19
|
-
}
|
|
20
|
-
const originalCustomUrl = getCustomizationUrl()
|
|
21
|
-
let resolvedUrl = ''
|
|
22
|
-
fetch(originalCustomUrl)
|
|
23
|
-
.then((resp) => {
|
|
24
|
-
const currentCustomUrl = getCustomizationUrl()
|
|
25
|
-
if (currentCustomUrl === originalCustomUrl) {
|
|
26
|
-
// this is the latest, we keep it
|
|
27
|
-
resolvedUrl = resp.url
|
|
28
|
-
log('parsed customization url is ' + resolvedUrl)
|
|
29
|
-
setStore({
|
|
30
|
-
resolvedCustomizationUrl: resolvedUrl,
|
|
31
|
-
})
|
|
32
|
-
return resp.json()
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
.then((config: LemonstandConfig | undefined) => {
|
|
36
|
-
if (config) {
|
|
37
|
-
setStore({
|
|
38
|
-
unreadOfferNotifsCountUrl: config.unreadOfferNotifsCountUrl || '',
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
)
|
package/src_old/storage.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { IDictionary } from './common'
|
|
2
|
-
|
|
3
|
-
export interface IStorageData {
|
|
4
|
-
growthFund: {
|
|
5
|
-
lastPopup: IDictionary<number>
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type GetStorageData = () => IStorageData
|
|
10
|
-
export const getStorageData: GetStorageData = () => {
|
|
11
|
-
const restoreData = () => JSON.parse(localStorage.getItem('webshop') as string) as IStorageData
|
|
12
|
-
|
|
13
|
-
if (localStorage.getItem('webshop')) {
|
|
14
|
-
return restoreData()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
localStorage.setItem(
|
|
18
|
-
'webshop',
|
|
19
|
-
JSON.stringify({
|
|
20
|
-
growthFund: {
|
|
21
|
-
lastPopup: {},
|
|
22
|
-
},
|
|
23
|
-
} as IStorageData)
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
return restoreData()
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export type SetStorageData = (data: IStorageData) => void
|
|
30
|
-
export const setStorageData: SetStorageData = (data: IStorageData) => {
|
|
31
|
-
localStorage.setItem('webshop', JSON.stringify(data))
|
|
32
|
-
}
|
package/src_old/store.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { DIReader, IDictionary } from './common'
|
|
2
|
-
import { inject } from 'readuz'
|
|
3
|
-
import { CountryCode, IGameEvent } from '@goodgamestudios/cxf-events'
|
|
4
|
-
import { ICXF, IGameApi } from './cxf'
|
|
5
|
-
|
|
6
|
-
export interface IStore {
|
|
7
|
-
playerId?: string
|
|
8
|
-
instanceId: string
|
|
9
|
-
networkId: string
|
|
10
|
-
gameId: string
|
|
11
|
-
gameApi: IGameApi
|
|
12
|
-
language?: string
|
|
13
|
-
token?: string
|
|
14
|
-
zoneId?: string
|
|
15
|
-
xp: number
|
|
16
|
-
level: number
|
|
17
|
-
gameEvents: IGameEvent[]
|
|
18
|
-
countryCode: CountryCode
|
|
19
|
-
lastPurchaseTab: string
|
|
20
|
-
legendLevel?: number
|
|
21
|
-
subscriptionDisabled: boolean
|
|
22
|
-
isTempServer: boolean
|
|
23
|
-
customizationSuffix: string
|
|
24
|
-
resolvedCustomizationUrl?: string
|
|
25
|
-
sourceId: string
|
|
26
|
-
unreadOfferNotifsCountUrl: string
|
|
27
|
-
adStatus?: Record<string, any>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function defaultStore(cxf: ICXF): IStore {
|
|
31
|
-
return {
|
|
32
|
-
playerId: cxf.playerId,
|
|
33
|
-
instanceId: cxf.instanceId,
|
|
34
|
-
networkId: cxf.networkId,
|
|
35
|
-
gameId: cxf.gameId,
|
|
36
|
-
gameApi: cxf.gameApi,
|
|
37
|
-
language: cxf.language,
|
|
38
|
-
token: cxf.token,
|
|
39
|
-
zoneId: cxf.zoneId,
|
|
40
|
-
gameEvents: [],
|
|
41
|
-
xp: 0,
|
|
42
|
-
level: 0,
|
|
43
|
-
legendLevel: undefined,
|
|
44
|
-
countryCode: '',
|
|
45
|
-
lastPurchaseTab: '',
|
|
46
|
-
subscriptionDisabled: false,
|
|
47
|
-
isTempServer: false,
|
|
48
|
-
customizationSuffix: '',
|
|
49
|
-
resolvedCustomizationUrl: '',
|
|
50
|
-
sourceId: 'unknown',
|
|
51
|
-
unreadOfferNotifsCountUrl: '',
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export type GetStore = () => IStore
|
|
56
|
-
export const getStore: DIReader<GetStore> = inject(
|
|
57
|
-
(environment) => environment.log,
|
|
58
|
-
(environment) => environment.store,
|
|
59
|
-
(log, store) => () => {
|
|
60
|
-
return store.get() as IStore
|
|
61
|
-
}
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
export type SetStore = (data: Partial<IStore>) => void
|
|
65
|
-
export const setStore: DIReader<SetStore> = inject(
|
|
66
|
-
(environment) => environment.log,
|
|
67
|
-
(environment) => environment.store,
|
|
68
|
-
(log, store) => (data) => {
|
|
69
|
-
const state = store.get() as IStore
|
|
70
|
-
store.set({
|
|
71
|
-
...state,
|
|
72
|
-
...data,
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
export function criteriaSelector({ legendLevel, level }: IStore): IDictionary<any> {
|
|
78
|
-
return {
|
|
79
|
-
legendLevel,
|
|
80
|
-
level,
|
|
81
|
-
}
|
|
82
|
-
}
|
package/src_old/track.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { inject } from 'readuz'
|
|
2
|
-
import { DIReader, IDictionary } from './common'
|
|
3
|
-
import { msToSec } from './utils'
|
|
4
|
-
import { getCxf, getTokenAndLanguage } from './helpers'
|
|
5
|
-
|
|
6
|
-
export type IRanchWebShopCallProperties = {
|
|
7
|
-
eventId: number
|
|
8
|
-
gameId: number
|
|
9
|
-
playerId: number
|
|
10
|
-
instanceId: number
|
|
11
|
-
zoneId: number
|
|
12
|
-
networkId: number
|
|
13
|
-
sessionId: string
|
|
14
|
-
date: number
|
|
15
|
-
unixtimeMS: number
|
|
16
|
-
sourceId: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type TrackOpenAction = (sid: string) => void
|
|
20
|
-
export const trackOpenAction: DIReader<TrackOpenAction> = inject(
|
|
21
|
-
(environment) => environment.config,
|
|
22
|
-
(environment) => environment.trackAction,
|
|
23
|
-
(environment) => environment.getStore,
|
|
24
|
-
({ WEB_SHOP_CALL_TRACK_ID }, trackUserAction, getStore) =>
|
|
25
|
-
(sid) => {
|
|
26
|
-
const now = Date.now()
|
|
27
|
-
const parameters = getTokenAndLanguage(getStore())
|
|
28
|
-
const { zoneId } = parameters
|
|
29
|
-
const sessionId = sid
|
|
30
|
-
const { playerId, gameId, networkId, instanceId, sourceId } = getStore()
|
|
31
|
-
trackUserAction({
|
|
32
|
-
eventId: WEB_SHOP_CALL_TRACK_ID,
|
|
33
|
-
date: msToSec(now),
|
|
34
|
-
unixtimeMS: now,
|
|
35
|
-
sessionId,
|
|
36
|
-
zoneId: zoneId ? Number.parseInt(zoneId, 10) : undefined,
|
|
37
|
-
playerId: Number.parseInt(playerId as string, 10),
|
|
38
|
-
gameId: Number.parseInt(gameId, 10),
|
|
39
|
-
networkId: Number.parseInt(networkId, 10),
|
|
40
|
-
instanceId: Number.parseInt(instanceId, 10),
|
|
41
|
-
sourceId,
|
|
42
|
-
} as IRanchWebShopCallProperties)
|
|
43
|
-
}
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
export interface ITrackPayload extends IDictionary<string | number> {
|
|
47
|
-
eventId: number
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type TrackAction = (payload: ITrackPayload) => void
|
|
51
|
-
export const trackAction: DIReader<TrackAction> = inject(
|
|
52
|
-
(environment) => environment.config,
|
|
53
|
-
(environment) => environment.cxfProvider,
|
|
54
|
-
({ CXF_TRACK_MSG }, cxfProvider) =>
|
|
55
|
-
(payload) => {
|
|
56
|
-
const cxf = getCxf(cxfProvider)
|
|
57
|
-
cxf.emit(CXF_TRACK_MSG, payload)
|
|
58
|
-
}
|
|
59
|
-
)
|
package/src_old/url.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { inject } from 'readuz'
|
|
2
|
-
import { DIReader } from './common'
|
|
3
|
-
import { getCxf, createSessionId, formatQueryString, getTokenAndLanguage } from './helpers'
|
|
4
|
-
import { validateForNull } from './utils'
|
|
5
|
-
import { criteriaSelector } from './store'
|
|
6
|
-
import { acronym } from '@goodgamestudios/game-alias'
|
|
7
|
-
|
|
8
|
-
export interface ICreateCatalogUrlProperties {
|
|
9
|
-
sid?: string
|
|
10
|
-
page?: string
|
|
11
|
-
route?: string
|
|
12
|
-
config?: Record<string, any>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type CreateIframeUrl = (properties: ICreateCatalogUrlProperties) => string
|
|
16
|
-
export const createIframeUrl: DIReader<CreateIframeUrl> = inject(
|
|
17
|
-
(environment) => environment.config,
|
|
18
|
-
(environment) => environment.log,
|
|
19
|
-
(environment) => environment.getStore,
|
|
20
|
-
(environment) => environment.getDomain,
|
|
21
|
-
(environment) => environment.ggsGetQueryParams,
|
|
22
|
-
(environment) => environment.ggsGetReferrerValue,
|
|
23
|
-
(environment) => environment.createCustomizationUrl,
|
|
24
|
-
(config, log, getStore, getDomain, ggsGetQueryParameters, ggsGetReferrerValue, getCustomizationUrl) =>
|
|
25
|
-
({ page, route, sid, config: igsConfig = {} }: ICreateCatalogUrlProperties) => {
|
|
26
|
-
const store = getStore()
|
|
27
|
-
|
|
28
|
-
const { token, zoneId, locale } = getTokenAndLanguage(store)
|
|
29
|
-
const parameters = {
|
|
30
|
-
token,
|
|
31
|
-
zoneId,
|
|
32
|
-
locale,
|
|
33
|
-
sid: sid || createSessionId(),
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (Object.keys(igsConfig).length > 0) {
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
parameters.config = JSON.stringify(igsConfig)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
validateForNull(parameters)
|
|
42
|
-
|
|
43
|
-
const urlParameters = new URLSearchParams(ggsGetQueryParameters())
|
|
44
|
-
const queryParameters = {
|
|
45
|
-
...parameters,
|
|
46
|
-
'lemonstand.customization.url': store.resolvedCustomizationUrl || getCustomizationUrl(),
|
|
47
|
-
domain: getDomain(ggsGetReferrerValue()),
|
|
48
|
-
websiteId: urlParameters.get('w'),
|
|
49
|
-
criteria: JSON.stringify(criteriaSelector(store)),
|
|
50
|
-
level: store.level,
|
|
51
|
-
}
|
|
52
|
-
// <editor-fold desc="SPIL integration">
|
|
53
|
-
/* In case of SPIL integration the game can be launched
|
|
54
|
-
with additional params 'network=xx&usekeybaselogin=false'
|
|
55
|
-
in this case it needs to pass the network parameter to iframe url */
|
|
56
|
-
const network = urlParameters.get('network')
|
|
57
|
-
if (urlParameters.get('usekeybaselogin') === 'false' && Number(network) > 0) {
|
|
58
|
-
// @ts-ignore
|
|
59
|
-
queryParameters.network = network
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (store.adStatus?.areBannersAvailable) {
|
|
63
|
-
// @ts-ignore
|
|
64
|
-
queryParameters.ads = true
|
|
65
|
-
}
|
|
66
|
-
// </editor-fold>
|
|
67
|
-
|
|
68
|
-
log('createIframeUrl params', queryParameters)
|
|
69
|
-
return `${config.BASE_URL}/?${formatQueryString(queryParameters)}${page ? `#${page}` : ''}${
|
|
70
|
-
route ? `--${route}--${Date.now()}` : ''
|
|
71
|
-
}`
|
|
72
|
-
}
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
export type CreateCustomizationUrl = () => string
|
|
76
|
-
export const createCustomizationUrl: DIReader<CreateCustomizationUrl> = inject(
|
|
77
|
-
(environment) => environment.config,
|
|
78
|
-
(environment) => environment.getStore,
|
|
79
|
-
(environment) => environment.cxfProvider,
|
|
80
|
-
(config, getStore, cxfProvider) => () => {
|
|
81
|
-
const store = getStore()
|
|
82
|
-
const configBase = acronym(store.gameId)
|
|
83
|
-
const configVariance = store.customizationSuffix ? `-${store.customizationSuffix}` : ''
|
|
84
|
-
const configBranch = `${configBase}${configVariance}`
|
|
85
|
-
const cxf = getCxf(cxfProvider)
|
|
86
|
-
|
|
87
|
-
if (cxf.env === 'test') {
|
|
88
|
-
const configVersion = new URLSearchParams(window.location.search).get('configGGS')
|
|
89
|
-
if (configVersion !== null) {
|
|
90
|
-
return config.CUSTOMIZATION_URL_TEMPLATE.replace('{0}', configBranch).replace('{1}', configVersion)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return config.CUSTOMIZATION_URL.replace('{0}', configBranch)
|
|
94
|
-
}
|
|
95
|
-
)
|
package/src_old/utils.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { AnyVoidFn as AnyVoidFunction, IDictionary, PromiseFn as PromiseFunction } from './common'
|
|
2
|
-
import { ArgumentNullError } from './ArgumentNullError'
|
|
3
|
-
|
|
4
|
-
const startTimer = (function_: AnyVoidFunction, time: number) => {
|
|
5
|
-
const id = setTimeout(function_, time)
|
|
6
|
-
return () => clearTimeout(id)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const timeout =
|
|
10
|
-
<A, B>(function_: PromiseFunction<A, B>, time: number): PromiseFunction<A, B> =>
|
|
11
|
-
(a) => {
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
const stopTimer = startTimer(() => {
|
|
14
|
-
reject(new Error(`Timeout has exceeded ${time}`))
|
|
15
|
-
}, time)
|
|
16
|
-
|
|
17
|
-
function_(a)
|
|
18
|
-
.then((value) => {
|
|
19
|
-
resolve(value)
|
|
20
|
-
stopTimer()
|
|
21
|
-
})
|
|
22
|
-
.catch(reject)
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const validateForNull = (properties: IDictionary<any>) => {
|
|
27
|
-
for (const key of Object.keys(properties)) {
|
|
28
|
-
const value = properties[key]
|
|
29
|
-
if (value === undefined || value === null || Number.isNaN(value)) {
|
|
30
|
-
throw new ArgumentNullError(key, value)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function msToSec(value: number): number {
|
|
36
|
-
return Math.floor(value / 1000)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function decodePayload<T>(data: string): T {
|
|
40
|
-
return JSON.parse(atob(data))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function diffHours(d1: Date, d2: Date): number {
|
|
44
|
-
const diff = (d1.getTime() - d2.getTime()) / 1000
|
|
45
|
-
return Math.abs(Math.round(diff / (60 * 60)))
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function timestampToHours(value: number): number {
|
|
49
|
-
return Math.abs(Math.round(value / 1000 / (60 * 60)))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const parentDomain = (referrer: string) => {
|
|
53
|
-
const matches = referrer.match(/^https?:\/\/([^#/?]+)(?:[#/?]|$)/i)
|
|
54
|
-
if (!matches || !matches[1]) {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const result = matches[1].match(/[^.]+\.[^.]+$/)
|
|
59
|
-
if (!result) {
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return result[0]
|
|
64
|
-
}
|