@playdotfun/game-sdk 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.
- package/DEVELOPERS.md +94 -0
- package/index.html +219 -0
- package/package.json +48 -0
- package/src/buffer-shim.ts +3 -0
- package/src/carousel/messages.ts +145 -0
- package/src/config.ts +26 -0
- package/src/dashboard/bridge.ts +8 -0
- package/src/http/client.ts +58 -0
- package/src/index.ts +3 -0
- package/src/scripts/deploy.ts +135 -0
- package/src/sdk/crypto.ts +51 -0
- package/src/sdk/index.ts +1488 -0
- package/src/sdk/messaging.ts +50 -0
- package/src/sdk/obfuscation.ts +74 -0
- package/src/types.ts +67 -0
- package/src/widget/bridge.ts +157 -0
- package/src/widget/messages.ts +45 -0
- package/tsconfig.json +25 -0
- package/tsup.config.ts +77 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SDKEvents } from '@/types';
|
|
2
|
+
|
|
3
|
+
export default (eventHandler: EventTarget) => {
|
|
4
|
+
function emit(evt: SDKEvents | '*', data?: Record<string, any>) {
|
|
5
|
+
const cEvent = new CustomEvent(evt, { detail: data });
|
|
6
|
+
console.debug(`[OpenGameSDK] Dispatching event: ${evt} to SDK handler`);
|
|
7
|
+
eventHandler.dispatchEvent(cEvent);
|
|
8
|
+
|
|
9
|
+
if (window) {
|
|
10
|
+
console.debug(`[OpenGameSDK] Dispatching event: ${evt} to window`);
|
|
11
|
+
window.dispatchEvent(cEvent);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const globalEvent = new CustomEvent('*', {
|
|
15
|
+
detail: {
|
|
16
|
+
name: evt,
|
|
17
|
+
data,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
console.debug(`[OpenGameSDK] Dispatching global event: ${globalEvent.detail} to SDK handler`);
|
|
22
|
+
eventHandler.dispatchEvent(globalEvent);
|
|
23
|
+
if (window) {
|
|
24
|
+
console.debug('[OpenGameSDK] Dispatching global event:', globalEvent.detail, 'to window');
|
|
25
|
+
window.dispatchEvent(globalEvent);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function on(event: SDKEvents, callback: (event: CustomEvent) => void) {
|
|
29
|
+
console.debug('[OpenGameSDK] Adding event listener for event:', event);
|
|
30
|
+
eventHandler.addEventListener(event, (e: Event) => callback(e as CustomEvent));
|
|
31
|
+
}
|
|
32
|
+
function off(event: SDKEvents | '*', callback: (event: CustomEvent) => void) {
|
|
33
|
+
console.debug('[OpenGameSDK] Removing event listener for event:', event);
|
|
34
|
+
eventHandler.removeEventListener(event, callback as EventListener);
|
|
35
|
+
}
|
|
36
|
+
function onAll(callback: (event: SDKEvents, data?: Record<string, any>) => void) {
|
|
37
|
+
console.debug('[OpenGameSDK] Adding event listener for all events');
|
|
38
|
+
eventHandler.addEventListener('*', (e: Event) => {
|
|
39
|
+
const { name, data } = (e as CustomEvent).detail;
|
|
40
|
+
callback(name as SDKEvents, data);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
emit,
|
|
46
|
+
on,
|
|
47
|
+
off,
|
|
48
|
+
onAll,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const k7x = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
2
|
+
function m9q(s: string) {
|
|
3
|
+
let h = 5381;
|
|
4
|
+
for (let i = 0; i < s.length; i++) h = (h * 33) ^ s.charCodeAt(i);
|
|
5
|
+
return h >>> 0;
|
|
6
|
+
}
|
|
7
|
+
function w3r(n: number) {
|
|
8
|
+
let x = n || 2463534242;
|
|
9
|
+
return () => {
|
|
10
|
+
x ^= x << 13;
|
|
11
|
+
x ^= x >>> 17;
|
|
12
|
+
x ^= x << 5;
|
|
13
|
+
return (x >>> 0) / 0x100000000;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function p8t(k: string) {
|
|
17
|
+
const a = k7x.split('');
|
|
18
|
+
const r = w3r(m9q(k));
|
|
19
|
+
for (let i = a.length - 1; i > 0; i--) {
|
|
20
|
+
const j = Math.floor(r() * (i + 1));
|
|
21
|
+
[a[i], a[j]] = [a[j], a[i]];
|
|
22
|
+
}
|
|
23
|
+
return a.join('');
|
|
24
|
+
}
|
|
25
|
+
function l5n(s: string, f: string, t: string) {
|
|
26
|
+
const m = new Map<string, string>();
|
|
27
|
+
for (let i = 0; i < f.length; i++) m.set(f[i], t[i]);
|
|
28
|
+
let o = '';
|
|
29
|
+
for (const c of s) o += m.get(c) ?? c;
|
|
30
|
+
return o;
|
|
31
|
+
}
|
|
32
|
+
function d2v(s: string, z = 6, p = '-') {
|
|
33
|
+
const x = [];
|
|
34
|
+
for (let i = 0; i < s.length; i += z) x.push(s.slice(i, i + z));
|
|
35
|
+
return x.join(p);
|
|
36
|
+
}
|
|
37
|
+
function g6h(s: string, p = '-') {
|
|
38
|
+
return s.split(p).join('');
|
|
39
|
+
}
|
|
40
|
+
function q1u(b: Buffer, k: Buffer) {
|
|
41
|
+
const o = Buffer.allocUnsafe(b.length);
|
|
42
|
+
for (let i = 0; i < b.length; i++) o[i] = b[i] ^ k[i % k.length];
|
|
43
|
+
return o;
|
|
44
|
+
}
|
|
45
|
+
export function encodePointsObf(points: number, key = 'default_obf_key') {
|
|
46
|
+
if (!Number.isFinite(points)) throw new Error('points must be finite number');
|
|
47
|
+
const y = `${points}:${Date.now()}`;
|
|
48
|
+
const yb = Buffer.from(y, 'utf8');
|
|
49
|
+
const kb = Buffer.from(key, 'utf8');
|
|
50
|
+
const x = q1u(yb, kb);
|
|
51
|
+
const b = x.toString('base64');
|
|
52
|
+
const s = p8t(key);
|
|
53
|
+
const m = l5n(b, k7x, s);
|
|
54
|
+
const t = d2v(m.split('').reverse().join(''), 6, '-');
|
|
55
|
+
return t;
|
|
56
|
+
}
|
|
57
|
+
export function decodePointsObf(token: string, key = 'default_obf_key') {
|
|
58
|
+
try {
|
|
59
|
+
const c = g6h(token, '-');
|
|
60
|
+
const u = c.split('').reverse().join('');
|
|
61
|
+
const s = p8t(key);
|
|
62
|
+
const b = l5n(u, s, k7x);
|
|
63
|
+
const x = Buffer.from(b, 'base64');
|
|
64
|
+
const kb = Buffer.from(key, 'utf8');
|
|
65
|
+
const yb = q1u(x, kb);
|
|
66
|
+
const y = yb.toString('utf8');
|
|
67
|
+
const [v] = y.split(':');
|
|
68
|
+
const n = Number(v);
|
|
69
|
+
if (!Number.isFinite(n)) throw new Error('invalid payload');
|
|
70
|
+
return n;
|
|
71
|
+
} catch (e) {
|
|
72
|
+
throw new Error('Failed to decode obfuscated token');
|
|
73
|
+
}
|
|
74
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
SDKOpts,
|
|
3
|
+
SDKState,
|
|
4
|
+
Token,
|
|
5
|
+
Game,
|
|
6
|
+
Theme,
|
|
7
|
+
Session,
|
|
8
|
+
Context,
|
|
9
|
+
ListUserRewardsResponse,
|
|
10
|
+
ClaimRewardsResponse,
|
|
11
|
+
PromiseResolveFn,
|
|
12
|
+
User,
|
|
13
|
+
} from '@play-fun/types/sdk';
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
WidgetScreen,
|
|
17
|
+
SDKMessages,
|
|
18
|
+
CarouselMessages,
|
|
19
|
+
WidgetMessages,
|
|
20
|
+
SDKEvents,
|
|
21
|
+
SDKActions,
|
|
22
|
+
WidgetActions,
|
|
23
|
+
CarouselActions,
|
|
24
|
+
} from '@play-fun/types/sdk';
|
|
25
|
+
|
|
26
|
+
export interface PaginatedFetchOpts {
|
|
27
|
+
limit?: number;
|
|
28
|
+
cursor?: string;
|
|
29
|
+
sort?: string;
|
|
30
|
+
sortBy?: string;
|
|
31
|
+
query?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type RecursivePartial<T> = {
|
|
35
|
+
[P in keyof T]?: RecursivePartial<T[P]>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Flush protocol types
|
|
39
|
+
export interface FlushState {
|
|
40
|
+
seq: number;
|
|
41
|
+
currentHash: string;
|
|
42
|
+
stepKey: string;
|
|
43
|
+
totalPoints: number;
|
|
44
|
+
initialized: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface FlushResponse {
|
|
48
|
+
seq: number;
|
|
49
|
+
newHash: string;
|
|
50
|
+
nextStepKey: string;
|
|
51
|
+
total: number;
|
|
52
|
+
added: number;
|
|
53
|
+
duplicate?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface CommitResponse {
|
|
57
|
+
saved: number;
|
|
58
|
+
status: 'accepted' | 'pending_review';
|
|
59
|
+
riskScore?: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface SessionStateResponse {
|
|
63
|
+
lastSeq: number;
|
|
64
|
+
lastHash: string;
|
|
65
|
+
stepKey: string;
|
|
66
|
+
totalPoints: number;
|
|
67
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import config, { isDevOrigin } from '@/config';
|
|
2
|
+
import {
|
|
3
|
+
PromiseResolveFn,
|
|
4
|
+
SDKActions,
|
|
5
|
+
SDKMessages,
|
|
6
|
+
Theme,
|
|
7
|
+
WidgetActions,
|
|
8
|
+
WidgetMessages,
|
|
9
|
+
} from '@/types';
|
|
10
|
+
import { UpwardsDashboardActions, UpwardDashboardMessages } from '@play-fun/types/sdk';
|
|
11
|
+
import { DashboardBridge } from '@/dashboard/bridge';
|
|
12
|
+
|
|
13
|
+
const sandbox = `
|
|
14
|
+
allow-same-origin
|
|
15
|
+
allow-scripts
|
|
16
|
+
allow-forms
|
|
17
|
+
allow-popups
|
|
18
|
+
allow-modals
|
|
19
|
+
allow-downloads
|
|
20
|
+
allow-top-navigation
|
|
21
|
+
allow-top-navigation-by-user-activation
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
const initialStyle = {
|
|
25
|
+
display: 'none',
|
|
26
|
+
width: '100%',
|
|
27
|
+
height: '100%',
|
|
28
|
+
position: 'fixed',
|
|
29
|
+
zIndex: '9999',
|
|
30
|
+
background: 'transparent',
|
|
31
|
+
padding: '0',
|
|
32
|
+
margin: '0',
|
|
33
|
+
top: '0',
|
|
34
|
+
left: '0',
|
|
35
|
+
border: 'none',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export class WidgetBridge {
|
|
39
|
+
private style: Partial<CSSStyleDeclaration> = { ...initialStyle };
|
|
40
|
+
|
|
41
|
+
private widgetIFrame: HTMLIFrameElement;
|
|
42
|
+
|
|
43
|
+
private widgetElementResolver?: PromiseResolveFn;
|
|
44
|
+
private widgetElementPromise = new Promise((resolve) => (this.widgetElementResolver = resolve));
|
|
45
|
+
|
|
46
|
+
private widgetReadyResolver?: PromiseResolveFn;
|
|
47
|
+
private widgetReadyPromise = new Promise((resolve) => (this.widgetReadyResolver = resolve));
|
|
48
|
+
|
|
49
|
+
private widgetReady = false;
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
private handleWidgetMessage: (msg: WidgetMessages) => void,
|
|
53
|
+
private url = config.widgetURL,
|
|
54
|
+
) {
|
|
55
|
+
window.addEventListener('message', (e) => {
|
|
56
|
+
const originHostname = new URL(e.origin).hostname;
|
|
57
|
+
const isValidOrigin =
|
|
58
|
+
e.origin === config.widgetURL ||
|
|
59
|
+
(config.dashboardURL && e.origin === config.dashboardURL) ||
|
|
60
|
+
isDevOrigin(originHostname);
|
|
61
|
+
if (isValidOrigin) {
|
|
62
|
+
this._handleWidgetActions(e.data);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
this.widgetIFrame = document.createElement('iframe') as HTMLIFrameElement;
|
|
67
|
+
this.widgetIFrame.sandbox.value = sandbox;
|
|
68
|
+
this._updateStyle(initialStyle);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async init(target: HTMLElement = document.body, url?: string) {
|
|
72
|
+
this.widgetIFrame.src = url ?? this.url;
|
|
73
|
+
this.widgetIFrame.onload = () => {
|
|
74
|
+
this.widgetElementResolver?.({});
|
|
75
|
+
};
|
|
76
|
+
this._waitForWidgetReady();
|
|
77
|
+
target.appendChild(this.widgetIFrame);
|
|
78
|
+
await Promise.all([this.widgetElementPromise, this.widgetReadyPromise]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
sendMessage(msg: SDKMessages) {
|
|
82
|
+
if (this.widgetIFrame.contentWindow) {
|
|
83
|
+
console.log(`Sending message to widget: ${msg.action}`);
|
|
84
|
+
const targetOrigin = new URL(this.url).origin;
|
|
85
|
+
this.widgetIFrame.contentWindow.postMessage(msg, targetOrigin);
|
|
86
|
+
} else {
|
|
87
|
+
console.warn(`No contentWindow found for widget iframe. Message not sent: ${msg.action}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
show(extraStyle?: Partial<CSSStyleDeclaration>) {
|
|
92
|
+
this._updateStyle({
|
|
93
|
+
display: 'block',
|
|
94
|
+
...extraStyle,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
hide() {
|
|
99
|
+
this._updateStyle({ ...initialStyle });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
setTheme(theme: Theme) {
|
|
103
|
+
this.sendMessage({
|
|
104
|
+
action: SDKActions.UI_SetTheme,
|
|
105
|
+
data: theme,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private _updateStyle = (style: Partial<CSSStyleDeclaration>) => {
|
|
110
|
+
this.style = {
|
|
111
|
+
...this.style,
|
|
112
|
+
...style,
|
|
113
|
+
};
|
|
114
|
+
Object.keys(style).forEach((styleKey) => {
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
this.widgetIFrame.style[styleKey] = style[styleKey];
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
private _handleWidgetActions(msg: WidgetMessages | UpwardDashboardMessages) {
|
|
121
|
+
console.log('Handling Widget Action:', msg.action);
|
|
122
|
+
|
|
123
|
+
// Check if this is an UpwardsDashboardAction that should be forwarded to the dashboard
|
|
124
|
+
const isUpwardsDashboardAction = Object.values(UpwardsDashboardActions).includes(
|
|
125
|
+
msg.action as UpwardsDashboardActions,
|
|
126
|
+
);
|
|
127
|
+
if (isUpwardsDashboardAction) {
|
|
128
|
+
console.log('Forwarding UpwardsDashboardAction to dashboard:', msg.action);
|
|
129
|
+
DashboardBridge.sendMessage(msg as UpwardDashboardMessages);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const isValidAction = Object.values(WidgetActions).includes(msg.action as WidgetActions);
|
|
134
|
+
if (isValidAction) {
|
|
135
|
+
if (msg.action === WidgetActions.WidgetReady) {
|
|
136
|
+
console.log('Widget is ready!');
|
|
137
|
+
this.widgetReady = true;
|
|
138
|
+
this.widgetReadyResolver?.({});
|
|
139
|
+
} else {
|
|
140
|
+
this.handleWidgetMessage(msg as WidgetMessages);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private _waitForWidgetReady() {
|
|
146
|
+
if (this.widgetReady) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.sendMessage({
|
|
150
|
+
action: SDKActions.CheckForWidgetReady,
|
|
151
|
+
data: undefined,
|
|
152
|
+
});
|
|
153
|
+
setTimeout(() => {
|
|
154
|
+
this._waitForWidgetReady();
|
|
155
|
+
}, 250);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import OpenGameSDK from '@/sdk';
|
|
2
|
+
import { SDKActions, WidgetActions, WidgetMessages } from '@/types';
|
|
3
|
+
import { DashboardActions, DashboardMessages } from '@play-fun/types/sdk';
|
|
4
|
+
|
|
5
|
+
export const handleWidgetMessage = async (self: OpenGameSDK, msg: WidgetMessages | DashboardMessages) => {
|
|
6
|
+
console.log(`Received widget message: ${msg.action}`, msg.data);
|
|
7
|
+
|
|
8
|
+
switch (msg.action) {
|
|
9
|
+
case WidgetActions.SetPrivyToken:
|
|
10
|
+
console.log('[WidgetBridge] Received Privy token');
|
|
11
|
+
self.handlePrivyTokenResponse(msg.data.privyAccessToken, msg.data.requestId);
|
|
12
|
+
return;
|
|
13
|
+
case WidgetActions.EnableView:
|
|
14
|
+
const heightValue =
|
|
15
|
+
typeof msg.data?.height === 'number'
|
|
16
|
+
? `${msg.data.height}px`
|
|
17
|
+
: (msg.data?.height ?? '100%');
|
|
18
|
+
return self.widget?.show({
|
|
19
|
+
height: heightValue,
|
|
20
|
+
maxHeight: heightValue,
|
|
21
|
+
});
|
|
22
|
+
case WidgetActions.DisableView:
|
|
23
|
+
self.widget?.hide();
|
|
24
|
+
if (self.pointsDisplay?.show) {
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
self.showPoints();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
case WidgetActions.SetIdentityToken:
|
|
31
|
+
return self.setIdentityToken(msg.data);
|
|
32
|
+
|
|
33
|
+
case WidgetActions.SetPlayerId:
|
|
34
|
+
console.log('[WidgetBridge] Setting player ID:', msg.data);
|
|
35
|
+
if (!self.gameId) {
|
|
36
|
+
throw new Error('No game ID found. Cannot set player ID.');
|
|
37
|
+
}
|
|
38
|
+
const { playerId, privyAccessToken } = msg.data;
|
|
39
|
+
// Don't set playerId here - loadGame will set it from server response
|
|
40
|
+
// Setting it before loadGame causes the early-return check to trigger
|
|
41
|
+
return self.loadGame(self.gameId, playerId, privyAccessToken);
|
|
42
|
+
case WidgetActions.ShowClaim:
|
|
43
|
+
return self.showClaim();
|
|
44
|
+
}
|
|
45
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"baseUrl": ".",
|
|
12
|
+
"paths": {
|
|
13
|
+
"@/*": [
|
|
14
|
+
"./src/*"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"lib": ["DOM", "ES2022"],
|
|
18
|
+
"strict": true,
|
|
19
|
+
"esModuleInterop": true,
|
|
20
|
+
"skipLibCheck": false,
|
|
21
|
+
"forceConsistentCasingInFileNames": true,
|
|
22
|
+
},
|
|
23
|
+
"include": ["./src/**/*",],
|
|
24
|
+
"exclude": ["node_modules", "dist", "*.config.ts"]
|
|
25
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
|
+
import { config } from 'dotenv';
|
|
3
|
+
config();
|
|
4
|
+
|
|
5
|
+
export default defineConfig([
|
|
6
|
+
{
|
|
7
|
+
entry: ['src/index.ts'],
|
|
8
|
+
format: ['esm', 'cjs'],
|
|
9
|
+
dts: true,
|
|
10
|
+
splitting: false,
|
|
11
|
+
sourcemap: true,
|
|
12
|
+
clean: true,
|
|
13
|
+
minify: false,
|
|
14
|
+
treeshake: true,
|
|
15
|
+
target: 'es2022',
|
|
16
|
+
outDir: 'dist',
|
|
17
|
+
platform: 'node',
|
|
18
|
+
esbuildOptions(options) {
|
|
19
|
+
options.define = {
|
|
20
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
|
|
21
|
+
'process.env.OGP_API_URL': JSON.stringify(
|
|
22
|
+
process.env.OGP_API_URL || 'https://api.play.fun',
|
|
23
|
+
),
|
|
24
|
+
'process.env.OGP_DASHBOARD_WIDGET_URL': JSON.stringify(
|
|
25
|
+
process.env.OGP_DASHBOARD_WIDGET_URL || '',
|
|
26
|
+
),
|
|
27
|
+
'process.env.OGP_CAROUSEL_URL': JSON.stringify(
|
|
28
|
+
process.env.OGP_CAROUSEL_URL || 'https://carousel.play.fun',
|
|
29
|
+
),
|
|
30
|
+
'process.env.OGP_WIDGET_URL': JSON.stringify(
|
|
31
|
+
process.env.OGP_WIDGET_URL || 'https://widget.play.fun',
|
|
32
|
+
),
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
entry: { sdk: 'src/index.ts' },
|
|
38
|
+
format: ['iife'],
|
|
39
|
+
globalName: 'OpenGameSDK',
|
|
40
|
+
outDir: 'dist',
|
|
41
|
+
outExtension: () => ({ js: '.js' }),
|
|
42
|
+
platform: 'browser',
|
|
43
|
+
target: 'es2020',
|
|
44
|
+
clean: true,
|
|
45
|
+
dts: true,
|
|
46
|
+
sourcemap: true,
|
|
47
|
+
bundle: true,
|
|
48
|
+
minify: false,
|
|
49
|
+
inject: ['src/buffer-shim.ts'],
|
|
50
|
+
noExternal: ['@play-fun/types'],
|
|
51
|
+
esbuildOptions(options) {
|
|
52
|
+
options.alias = {
|
|
53
|
+
'@': './src',
|
|
54
|
+
};
|
|
55
|
+
options.define = {
|
|
56
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
|
|
57
|
+
'process.env.OGP_API_URL': JSON.stringify(
|
|
58
|
+
process.env.OGP_API_URL || 'https://api.play.fun',
|
|
59
|
+
),
|
|
60
|
+
'process.env.OGP_DASHBOARD_URL': JSON.stringify(process.env.OGP_DASHBOARD_URL || ''),
|
|
61
|
+
'process.env.OGP_CAROUSEL_URL': JSON.stringify(
|
|
62
|
+
process.env.OGP_CAROUSEL_URL || 'https://carousel.play.fun',
|
|
63
|
+
),
|
|
64
|
+
'process.env.OGP_WIDGET_URL': JSON.stringify(
|
|
65
|
+
process.env.OGP_WIDGET_URL || 'https://widget.play.fun',
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
options.footer = {
|
|
69
|
+
js: 'OpenGameSDK = OpenGameSDK.default;',
|
|
70
|
+
};
|
|
71
|
+
// options.pure =
|
|
72
|
+
// process.env.NODE_ENV === 'production'
|
|
73
|
+
// ? ['console.log', 'console.debug', 'console.info']
|
|
74
|
+
// : [];
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
]);
|