@mpgd/cli 0.11.0 → 0.13.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/dist/index.js +16 -2
- package/package.json +13 -12
- package/templates/phaser-game/README.md +24 -5
- package/templates/phaser-game/agent/acceptance.md +14 -0
- package/templates/phaser-game/agent/brief.md +1 -1
- package/templates/phaser-game/agent/game-manifest.json +1 -1
- package/templates/phaser-game/apps/target-devvit/src/server/index.ts +71 -14
- package/templates/phaser-game/mpgd.targets.json +7 -0
- package/templates/phaser-game/package.json +3 -0
- package/templates/phaser-game/src/platform/buildGateways/verse8.ts +25 -0
- package/templates/phaser-game/src/platform/runtimeDetector.ts +1 -0
- package/templates/phaser-game/vite.shared.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -18,13 +18,18 @@ const packageRoot = resolvePackageRoot(sourceDir);
|
|
|
18
18
|
const detectedKitRoot = resolveDefaultKitRoot();
|
|
19
19
|
const gameTemplateDir = path.resolve(packageRoot, 'templates/phaser-game');
|
|
20
20
|
const cliVersion = readPackageVersion(packageRoot);
|
|
21
|
-
const recommendedMatrixTargets = 'web,microsoft-store,ait,reddit';
|
|
21
|
+
const recommendedMatrixTargets = 'web,microsoft-store,verse8,ait,reddit';
|
|
22
22
|
const defaultDependencyVersion = `^${cliVersion}`;
|
|
23
|
+
const standaloneTemplateDependencyVersionFallbacks = {
|
|
24
|
+
// Initial-published independently from the CLI release line; package metadata wins once concrete.
|
|
25
|
+
'@mpgd/adapter-verse8': '^0.1.0',
|
|
26
|
+
};
|
|
23
27
|
const mpgdTemplateDependencyPackages = [
|
|
24
28
|
{ name: '@mpgd/adapter-ait', packageDir: 'adapters/ait' },
|
|
25
29
|
{ name: '@mpgd/adapter-browser', packageDir: 'adapters/browser' },
|
|
26
30
|
{ name: '@mpgd/adapter-capacitor', packageDir: 'adapters/capacitor' },
|
|
27
31
|
{ name: '@mpgd/adapter-devvit', packageDir: 'adapters/devvit' },
|
|
32
|
+
{ name: '@mpgd/adapter-verse8', packageDir: 'adapters/verse8' },
|
|
28
33
|
{ name: '@mpgd/analytics', packageDir: 'packages/analytics' },
|
|
29
34
|
{ name: '@mpgd/bridge', packageDir: 'packages/bridge' },
|
|
30
35
|
{ name: '@mpgd/catalog', packageDir: 'packages/catalog' },
|
|
@@ -35,10 +40,17 @@ const mpgdTemplateDependencyPackages = [
|
|
|
35
40
|
{ name: '@mpgd/platform', packageDir: 'packages/platform' },
|
|
36
41
|
{ name: '@mpgd/target-config', packageDir: 'packages/target-config' },
|
|
37
42
|
];
|
|
38
|
-
const recommendedMatrixTargetOrder = [
|
|
43
|
+
const recommendedMatrixTargetOrder = [
|
|
44
|
+
'web-preview',
|
|
45
|
+
'microsoft-store',
|
|
46
|
+
'verse8',
|
|
47
|
+
'ait',
|
|
48
|
+
'reddit',
|
|
49
|
+
];
|
|
39
50
|
const allMatrixTargetOrder = [
|
|
40
51
|
'web-preview',
|
|
41
52
|
'microsoft-store',
|
|
53
|
+
'verse8',
|
|
42
54
|
'android',
|
|
43
55
|
'ios',
|
|
44
56
|
'ait',
|
|
@@ -50,6 +62,7 @@ const supportedBuildTargets = [
|
|
|
50
62
|
'web-preview',
|
|
51
63
|
'microsoft-store',
|
|
52
64
|
'msstore',
|
|
65
|
+
'verse8',
|
|
53
66
|
'android',
|
|
54
67
|
'ios',
|
|
55
68
|
'ait',
|
|
@@ -1256,6 +1269,7 @@ function resolveMpgdDependencyVersionReplacements(input) {
|
|
|
1256
1269
|
?? (input.workspace ? 'workspace:*' : undefined)
|
|
1257
1270
|
?? resolvePublishedTemplateDependencyVersion(dependency.name, packageJson)
|
|
1258
1271
|
?? resolveWorkspaceTemplateDependencyVersion(kitRoot, dependency.packageDir)
|
|
1272
|
+
?? standaloneTemplateDependencyVersionFallbacks[dependency.name]
|
|
1259
1273
|
?? defaultDependencyVersion;
|
|
1260
1274
|
return {
|
|
1261
1275
|
placeholder: mpgdDependencyVersionPlaceholder(dependency.name),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpgd/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Gunshi CLI for mpgd-kit starter generation and target workflow orchestration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -49,18 +49,19 @@
|
|
|
49
49
|
"@types/node": "^24.0.0",
|
|
50
50
|
"ttsc": "0.18.4",
|
|
51
51
|
"typescript": "7.0.2",
|
|
52
|
-
"@mpgd/adapter-ait": "0.4.
|
|
53
|
-
"@mpgd/adapter-
|
|
54
|
-
"@mpgd/adapter-
|
|
55
|
-
"@mpgd/adapter-
|
|
56
|
-
"@mpgd/
|
|
57
|
-
"@mpgd/
|
|
58
|
-
"@mpgd/
|
|
59
|
-
"@mpgd/catalog": "0.
|
|
60
|
-
"@mpgd/
|
|
61
|
-
"@mpgd/
|
|
52
|
+
"@mpgd/adapter-ait": "0.4.4",
|
|
53
|
+
"@mpgd/adapter-browser": "0.5.0",
|
|
54
|
+
"@mpgd/adapter-capacitor": "0.4.4",
|
|
55
|
+
"@mpgd/adapter-devvit": "0.8.4",
|
|
56
|
+
"@mpgd/adapter-verse8": "0.2.1",
|
|
57
|
+
"@mpgd/analytics": "0.3.7",
|
|
58
|
+
"@mpgd/bridge": "0.6.1",
|
|
59
|
+
"@mpgd/catalog": "0.5.0",
|
|
60
|
+
"@mpgd/game-services": "0.10.0",
|
|
61
|
+
"@mpgd/i18n": "0.5.3",
|
|
62
|
+
"@mpgd/platform": "0.7.0",
|
|
62
63
|
"@mpgd/phaser-assets": "0.4.1",
|
|
63
|
-
"@mpgd/
|
|
64
|
+
"@mpgd/target-config": "0.8.0"
|
|
64
65
|
},
|
|
65
66
|
"main": "./dist/index.js",
|
|
66
67
|
"types": "./dist/index.d.ts",
|
|
@@ -31,17 +31,17 @@ platform-specific artifacts. Keep an `mpgd-kit` checkout nearby and pass it with
|
|
|
31
31
|
pnpm exec mpgd target build-all \
|
|
32
32
|
--targets-file ./mpgd.targets.json \
|
|
33
33
|
--kit-path ../mpgd-kit \
|
|
34
|
-
--targets web,microsoft-store,ait,reddit \
|
|
34
|
+
--targets web,microsoft-store,verse8,ait,reddit \
|
|
35
35
|
--profile staging \
|
|
36
36
|
--ait-variant wrapper
|
|
37
37
|
pnpm exec mpgd target smoke-all \
|
|
38
38
|
--targets-file ./mpgd.targets.json \
|
|
39
39
|
--kit-path ../mpgd-kit \
|
|
40
|
-
--targets web,microsoft-store,ait,reddit
|
|
40
|
+
--targets web,microsoft-store,verse8,ait,reddit
|
|
41
41
|
pnpm exec mpgd target doctor \
|
|
42
42
|
--targets-file ./mpgd.targets.json \
|
|
43
43
|
--kit-path ../mpgd-kit \
|
|
44
|
-
--targets web,microsoft-store,ait,reddit
|
|
44
|
+
--targets web,microsoft-store,verse8,ait,reddit
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
When developing the kit itself, the same commands work through the repository
|
|
@@ -51,7 +51,7 @@ script:
|
|
|
51
51
|
pnpm --dir ../mpgd-kit mpgd target build-all \
|
|
52
52
|
--targets-file "$PWD/mpgd.targets.json" \
|
|
53
53
|
--kit-path ../mpgd-kit \
|
|
54
|
-
--targets web,microsoft-store,ait,reddit \
|
|
54
|
+
--targets web,microsoft-store,verse8,ait,reddit \
|
|
55
55
|
--profile staging \
|
|
56
56
|
--ait-variant wrapper
|
|
57
57
|
```
|
|
@@ -285,7 +285,26 @@ submission.
|
|
|
285
285
|
app; do not force activation with `skipWaiting()`. Keep the web manifest `id`
|
|
286
286
|
game-specific because the cache namespace uses it to isolate apps sharing an
|
|
287
287
|
origin.
|
|
288
|
-
-
|
|
288
|
+
- Verse8 is a game-owned iframe web target that writes to `artifacts/verse8`.
|
|
289
|
+
The adapter verifies the host-provided auth credential and distinguishes
|
|
290
|
+
Verse8-signed accounts from self-signed guest accounts. Ads are available
|
|
291
|
+
only when placement mappings are present. VXShop stays capability-disabled
|
|
292
|
+
until the gateway receives the literal `purchaseEventAuthority:
|
|
293
|
+
'agent8-server'`, catalog product mappings, and an authenticated Agent8
|
|
294
|
+
entitlement reader. The client purchase result is always `pending`; grants
|
|
295
|
+
belong only in the reserved Agent8 `$onItemPurchased` event. Do not use
|
|
296
|
+
`VXShop.onClose`, client metadata, or a client-created transaction ID as
|
|
297
|
+
purchase evidence. Keep `@agent8/gameserver-node` in the separate Agent8
|
|
298
|
+
server project and use `@mpgd/adapter-verse8/agent8` there for the locked,
|
|
299
|
+
consume-once catalog grant. Authenticated-encrypted Agent8 cloud state is
|
|
300
|
+
available only after the gateway receives a game-owned remote storage client;
|
|
301
|
+
the starter does not install the React browser SDK, configure that client, or
|
|
302
|
+
ship server persistence secrets. Agent8 verified
|
|
303
|
+
leaderboards stay server-only and require a game-specific completion
|
|
304
|
+
verifier, so the generic platform leaderboard capability remains disabled.
|
|
305
|
+
- Reddit Devvit is game-owned in `apps/target-devvit`. Its Redis-backed storage
|
|
306
|
+
bridge fails closed on identity, provider, serialization, and quota errors;
|
|
307
|
+
it never switches progress to browser `localStorage`.
|
|
289
308
|
- Apps in Toss currently uses the kit reference wrapper at
|
|
290
309
|
`${MPGD_KIT_PATH}/apps/target-ait` for smoke packaging. Before a real Toss
|
|
291
310
|
submission, create a game-owned wrapper/config so the app name, CLI state, and
|
|
@@ -36,5 +36,19 @@ For Microsoft Store changes, keep the first pass as a PWA/web target that uses
|
|
|
36
36
|
the browser adapter. Add a dedicated Store commerce adapter only when wiring
|
|
37
37
|
Digital Goods API and Payment Request through backend ledger verification.
|
|
38
38
|
|
|
39
|
+
## Verse8 Agent8 Structured Server
|
|
40
|
+
|
|
41
|
+
Keep the Agent8 server in a separate game-owned project. Its acceptance flow
|
|
42
|
+
must call `createVerse8Agent8LeaderboardBoundary` with an authenticated sender
|
|
43
|
+
account and a game-specific completion verifier, then cover rejected malformed
|
|
44
|
+
submissions, verified recording, and account-scoped snapshot reads.
|
|
45
|
+
|
|
46
|
+
Inject endpoints, persistence secrets, encryption keys, and authentication at
|
|
47
|
+
runtime. Do not commit personal MCP configuration, `.env` files, credentials,
|
|
48
|
+
tokens, or Agent8 authentication state to this generated game. The kit command
|
|
49
|
+
`pnpm smoke:verse8-agent8-acceptance` validates the generic structured-server
|
|
50
|
+
contract and generated Verse8 target surface; it does not validate a deployed
|
|
51
|
+
game server or replace game-owned production evidence.
|
|
52
|
+
|
|
39
53
|
Verify the first screen reports the viewport orientation policy, and treat
|
|
40
54
|
locked orientation modes as soft prompts instead of unsafe WebView hard locks.
|
|
@@ -20,7 +20,7 @@ pnpm check
|
|
|
20
20
|
pnpm build
|
|
21
21
|
pnpm icons:generate
|
|
22
22
|
pnpm icons:verify
|
|
23
|
-
pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets web,microsoft-store,ait,reddit --profile staging --ait-variant wrapper
|
|
23
|
+
pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets web,microsoft-store,verse8,ait,reddit --profile staging --ait-variant wrapper
|
|
24
24
|
pnpm devvit:login
|
|
25
25
|
pnpm devvit:init
|
|
26
26
|
pnpm devvit:playtest
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"title": "__GAME_TITLE__",
|
|
6
6
|
"engine": "phaser-4"
|
|
7
7
|
},
|
|
8
|
-
"targets": ["web-preview", "microsoft-store", "android", "ios", "ait", "reddit"],
|
|
8
|
+
"targets": ["web-preview", "microsoft-store", "verse8", "android", "ios", "ait", "reddit"],
|
|
9
9
|
"futureTargets": ["telegram", "tauri"],
|
|
10
10
|
"platformBoundary": "PlatformGateway",
|
|
11
11
|
"mcpRequirements": {
|
|
@@ -3,9 +3,11 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
|
3
3
|
import { createServer, context, getServerPort, reddit, redis } from '@devvit/web/server';
|
|
4
4
|
import type { UiResponse } from '@devvit/web/shared';
|
|
5
5
|
import {
|
|
6
|
+
bridgeStorageLoadProtocol,
|
|
6
7
|
createBridgeError,
|
|
7
8
|
type BridgeRequest,
|
|
8
9
|
type BridgeResponse,
|
|
10
|
+
type BridgeStorageLoadData,
|
|
9
11
|
} from '@mpgd/bridge';
|
|
10
12
|
import {
|
|
11
13
|
createBridgeRpcRouter,
|
|
@@ -15,6 +17,7 @@ import { createBridgeRpcNodeHandler } from '@mpgd/bridge/orpc/node';
|
|
|
15
17
|
|
|
16
18
|
const maxStorageKeyLength = 128;
|
|
17
19
|
const maxEncodedStorageKeyLength = 384;
|
|
20
|
+
const maxStorageValueBytes = 262_144;
|
|
18
21
|
const maxRequestBodySize = 1_048_576;
|
|
19
22
|
const gameName = '__GAME_NAME__';
|
|
20
23
|
const gameTitle = __GAME_TITLE_TS_LITERAL__;
|
|
@@ -263,7 +266,11 @@ async function loadStorage(input: BridgeRequest): Promise<BridgeResponse> {
|
|
|
263
266
|
const playerId = currentPlayerId();
|
|
264
267
|
|
|
265
268
|
if (playerId === undefined) {
|
|
266
|
-
return
|
|
269
|
+
return createBridgeError(
|
|
270
|
+
input.id,
|
|
271
|
+
'DEVVIT_STORAGE_IDENTITY_REQUIRED',
|
|
272
|
+
'A current Reddit player is required to load storage.',
|
|
273
|
+
);
|
|
267
274
|
}
|
|
268
275
|
|
|
269
276
|
const key = storageKey(input, playerId);
|
|
@@ -272,14 +279,36 @@ async function loadStorage(input: BridgeRequest): Promise<BridgeResponse> {
|
|
|
272
279
|
return key;
|
|
273
280
|
}
|
|
274
281
|
|
|
275
|
-
|
|
282
|
+
let stored: string | null | undefined;
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
stored = await redis.get(key);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
console.warn(`devvit storage load failed: ${errorMessage(error)}`);
|
|
288
|
+
return createBridgeError(
|
|
289
|
+
input.id,
|
|
290
|
+
'DEVVIT_STORAGE_LOAD_FAILED',
|
|
291
|
+
'Devvit storage could not be loaded.',
|
|
292
|
+
true,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
276
295
|
|
|
277
296
|
if (stored === undefined || stored === null) {
|
|
278
|
-
return ok(input,
|
|
297
|
+
return ok(input, {
|
|
298
|
+
__mpgdBridgeProtocol: bridgeStorageLoadProtocol,
|
|
299
|
+
found: false,
|
|
300
|
+
} satisfies BridgeStorageLoadData);
|
|
279
301
|
}
|
|
280
302
|
|
|
281
303
|
try {
|
|
282
|
-
return ok(
|
|
304
|
+
return ok(
|
|
305
|
+
input,
|
|
306
|
+
{
|
|
307
|
+
__mpgdBridgeProtocol: bridgeStorageLoadProtocol,
|
|
308
|
+
found: true,
|
|
309
|
+
value: JSON.parse(stored),
|
|
310
|
+
} satisfies BridgeStorageLoadData,
|
|
311
|
+
);
|
|
283
312
|
} catch {
|
|
284
313
|
return createBridgeError(input.id, 'CORRUPTED_STORAGE_VALUE', 'Stored data is not valid JSON.');
|
|
285
314
|
}
|
|
@@ -289,9 +318,11 @@ async function saveStorage(input: BridgeRequest): Promise<BridgeResponse> {
|
|
|
289
318
|
const playerId = currentPlayerId();
|
|
290
319
|
|
|
291
320
|
if (playerId === undefined) {
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
321
|
+
return createBridgeError(
|
|
322
|
+
input.id,
|
|
323
|
+
'DEVVIT_STORAGE_IDENTITY_REQUIRED',
|
|
324
|
+
'A current Reddit player is required to save storage.',
|
|
325
|
+
);
|
|
295
326
|
}
|
|
296
327
|
|
|
297
328
|
const key = storageKey(input, playerId);
|
|
@@ -301,16 +332,42 @@ async function saveStorage(input: BridgeRequest): Promise<BridgeResponse> {
|
|
|
301
332
|
}
|
|
302
333
|
|
|
303
334
|
const payload = optionalObjectPayload(input.payload) as { readonly value?: unknown };
|
|
335
|
+
let serialized: string;
|
|
304
336
|
|
|
305
337
|
try {
|
|
306
|
-
|
|
307
|
-
} catch (error) {
|
|
308
|
-
console.warn(`devvit storage save was not persisted for key ${key}: ${errorMessage(error)}`);
|
|
338
|
+
const candidate = JSON.stringify(payload.value);
|
|
309
339
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
340
|
+
if (typeof candidate !== 'string') {
|
|
341
|
+
throw new Error('JSON serialization did not produce a string.');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
serialized = candidate;
|
|
345
|
+
} catch {
|
|
346
|
+
return createBridgeError(
|
|
347
|
+
input.id,
|
|
348
|
+
'INVALID_STORAGE_VALUE',
|
|
349
|
+
'Storage values must be JSON serializable.',
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (new TextEncoder().encode(serialized).length > maxStorageValueBytes) {
|
|
354
|
+
return createBridgeError(
|
|
355
|
+
input.id,
|
|
356
|
+
'DEVVIT_STORAGE_QUOTA_EXCEEDED',
|
|
357
|
+
`Storage values must not exceed ${String(maxStorageValueBytes)} UTF-8 bytes.`,
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
await redis.set(key, serialized);
|
|
363
|
+
} catch (error) {
|
|
364
|
+
console.warn(`devvit storage save was not persisted: ${errorMessage(error)}`);
|
|
365
|
+
return createBridgeError(
|
|
366
|
+
input.id,
|
|
367
|
+
'DEVVIT_STORAGE_SAVE_FAILED',
|
|
368
|
+
'Devvit storage could not be saved.',
|
|
369
|
+
true,
|
|
370
|
+
);
|
|
314
371
|
}
|
|
315
372
|
|
|
316
373
|
return ok(input, {
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
"icon": { "profile": "microsoft-pwa" },
|
|
15
15
|
"output": "artifacts/microsoft-store"
|
|
16
16
|
},
|
|
17
|
+
"verse8": {
|
|
18
|
+
"kind": "web",
|
|
19
|
+
"gameApp": ".",
|
|
20
|
+
"adapter": "verse8",
|
|
21
|
+
"icon": { "profile": "web-preview" },
|
|
22
|
+
"output": "artifacts/verse8"
|
|
23
|
+
},
|
|
17
24
|
"android": {
|
|
18
25
|
"kind": "capacitor-android",
|
|
19
26
|
"gameApp": ".",
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
"ait:console:deploy": "aitcc app deploy",
|
|
31
31
|
"build:microsoft-store": "pnpm exec mpgd target build microsoft-store production --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
32
32
|
"smoke:microsoft-store": "pnpm exec mpgd target smoke microsoft-store --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
33
|
+
"build:verse8": "pnpm exec mpgd target build verse8 production --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
34
|
+
"smoke:verse8": "pnpm exec mpgd target smoke verse8 --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
33
35
|
"build:devvit": "pnpm exec mpgd target build reddit production --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
34
36
|
"build:devvit:staging": "pnpm exec mpgd target build reddit staging --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
35
37
|
"smoke:devvit": "pnpm exec mpgd target smoke reddit --targets-file ./mpgd.targets.json --kit-path ${MPGD_KIT_PATH:-__DEFAULT_KIT_PATH__}",
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
"@mpgd/adapter-browser": "__MPGD_DEPENDENCY_VERSION_ADAPTER_BROWSER__",
|
|
60
62
|
"@mpgd/adapter-capacitor": "__MPGD_DEPENDENCY_VERSION_ADAPTER_CAPACITOR__",
|
|
61
63
|
"@mpgd/adapter-devvit": "__MPGD_DEPENDENCY_VERSION_ADAPTER_DEVVIT__",
|
|
64
|
+
"@mpgd/adapter-verse8": "__MPGD_DEPENDENCY_VERSION_ADAPTER_VERSE8__",
|
|
62
65
|
"@mpgd/analytics": "__MPGD_DEPENDENCY_VERSION_ANALYTICS__",
|
|
63
66
|
"@mpgd/bridge": "__MPGD_DEPENDENCY_VERSION_BRIDGE__",
|
|
64
67
|
"@mpgd/catalog": "__MPGD_DEPENDENCY_VERSION_CATALOG__",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createVerse8PlatformGateway } from '@mpgd/adapter-verse8';
|
|
2
|
+
import type { AdPlacements } from '@mpgd/catalog';
|
|
3
|
+
import adPlacementsJson from '@mpgd/catalog/placements.json';
|
|
4
|
+
import type { PlatformGateway } from '@mpgd/platform';
|
|
5
|
+
|
|
6
|
+
import type { RuntimeConfig } from '../runtimeDetector';
|
|
7
|
+
|
|
8
|
+
export async function createBuildGateway(_runtime: RuntimeConfig): Promise<PlatformGateway> {
|
|
9
|
+
const adPlacements = adPlacementsJson as AdPlacements;
|
|
10
|
+
const placementIds = new Map(
|
|
11
|
+
adPlacements.placements.flatMap((placement) => {
|
|
12
|
+
const platformPlacementId = placement.platformPlacementIds.verse8;
|
|
13
|
+
|
|
14
|
+
return platformPlacementId === undefined
|
|
15
|
+
? []
|
|
16
|
+
: [[placement.id, platformPlacementId] as const];
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return createVerse8PlatformGateway({
|
|
21
|
+
resolveAdPlacementId(placementId) {
|
|
22
|
+
return placementIds.get(placementId);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -88,6 +88,8 @@ export function resolveBuildGatewayModule(input: {
|
|
|
88
88
|
return input.debug && input.buildId === devvitSandboxBuildId
|
|
89
89
|
? 'src/platform/buildGateways/redditSandbox.ts'
|
|
90
90
|
: 'src/platform/buildGateways/reddit.ts';
|
|
91
|
+
case 'verse8':
|
|
92
|
+
return 'src/platform/buildGateways/verse8.ts';
|
|
91
93
|
default:
|
|
92
94
|
return 'src/platform/buildGateways/browser.ts';
|
|
93
95
|
}
|