@mpgd/target-config 0.1.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/LICENSE +21 -0
- package/dist/effective.d.ts +94 -0
- package/dist/effective.js +137 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +749 -0
- package/dist/runtime.d.ts +106 -0
- package/dist/runtime.js +194 -0
- package/package.json +59 -0
- package/targets.json +133 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { PlatformCapabilities, PlatformGateway } from '@mpgd/platform';
|
|
2
|
+
import type { EffectiveTargetConfig } from './effective';
|
|
3
|
+
export type PlatformFeature = 'iap' | 'rewardedAds' | 'interstitialAds' | 'leaderboard' | 'localization';
|
|
4
|
+
export type AdPlacementType = 'rewarded' | 'interstitial';
|
|
5
|
+
type PlatformConfigTarget = PlatformGateway['target'];
|
|
6
|
+
export type TargetRuntimeKind = 'web-preview' | 'capacitor-android' | 'capacitor-ios' | 'apps-in-toss';
|
|
7
|
+
export type ReleaseProfile = 'web-preview' | 'google-play' | 'app-store' | 'apps-in-toss';
|
|
8
|
+
export type StorageSupport = 'local' | 'native' | 'none';
|
|
9
|
+
export interface TargetFeatureConfig {
|
|
10
|
+
readonly iap: boolean;
|
|
11
|
+
readonly rewardedAds: boolean;
|
|
12
|
+
readonly interstitialAds: boolean;
|
|
13
|
+
readonly leaderboard: boolean;
|
|
14
|
+
readonly localization: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface TargetCapabilityConfig {
|
|
17
|
+
readonly storage: StorageSupport;
|
|
18
|
+
readonly localization: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface TargetMonetizationConfig {
|
|
21
|
+
readonly iap: boolean;
|
|
22
|
+
readonly rewardedAds: boolean;
|
|
23
|
+
readonly interstitialAds: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface TargetLeaderboardConfig {
|
|
26
|
+
readonly native: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface TargetReleaseConfig {
|
|
29
|
+
readonly profile: ReleaseProfile;
|
|
30
|
+
}
|
|
31
|
+
export interface TargetPolicyRestrictions {
|
|
32
|
+
readonly externalPaymentAllowed: boolean;
|
|
33
|
+
readonly remoteExecutableCodeAllowed: boolean;
|
|
34
|
+
readonly installOtherAppCTAAllowed: boolean;
|
|
35
|
+
readonly requiresStoreReview: boolean;
|
|
36
|
+
readonly requiresAitReview: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface TargetConfig {
|
|
39
|
+
readonly runtime: TargetRuntimeKind;
|
|
40
|
+
readonly features: TargetFeatureConfig;
|
|
41
|
+
readonly capabilities: TargetCapabilityConfig;
|
|
42
|
+
readonly monetization: TargetMonetizationConfig;
|
|
43
|
+
readonly leaderboard: TargetLeaderboardConfig;
|
|
44
|
+
readonly release: TargetReleaseConfig;
|
|
45
|
+
readonly policy: TargetPolicyRestrictions;
|
|
46
|
+
}
|
|
47
|
+
export interface TargetConfigMatrix {
|
|
48
|
+
readonly version: string;
|
|
49
|
+
readonly targets: Record<string, TargetConfig>;
|
|
50
|
+
}
|
|
51
|
+
export type FeatureAvailabilityReason = 'available' | 'target-disabled' | 'capability-unsupported';
|
|
52
|
+
export interface FeatureAvailability {
|
|
53
|
+
readonly feature: PlatformFeature;
|
|
54
|
+
readonly enabled: boolean;
|
|
55
|
+
readonly targetEnabled: boolean;
|
|
56
|
+
readonly capabilitySupported: boolean;
|
|
57
|
+
readonly reason: FeatureAvailabilityReason;
|
|
58
|
+
}
|
|
59
|
+
export interface AdPlacementDefinition {
|
|
60
|
+
readonly id: string;
|
|
61
|
+
readonly type: AdPlacementType;
|
|
62
|
+
}
|
|
63
|
+
export interface AdPlacementAvailability {
|
|
64
|
+
readonly id: string;
|
|
65
|
+
readonly type: AdPlacementType;
|
|
66
|
+
readonly enabled: boolean;
|
|
67
|
+
readonly reason: FeatureAvailabilityReason;
|
|
68
|
+
}
|
|
69
|
+
export interface TargetRuntimeSnapshot {
|
|
70
|
+
readonly target: PlatformConfigTarget;
|
|
71
|
+
readonly configTarget: string;
|
|
72
|
+
readonly config: TargetConfig;
|
|
73
|
+
readonly effectiveConfig?: EffectiveTargetConfig;
|
|
74
|
+
readonly capabilities: PlatformCapabilities;
|
|
75
|
+
readonly features: Record<PlatformFeature, FeatureAvailability>;
|
|
76
|
+
readonly adPlacements: readonly AdPlacementAvailability[];
|
|
77
|
+
}
|
|
78
|
+
export interface TargetAvailabilityOptions {
|
|
79
|
+
readonly configTarget?: string;
|
|
80
|
+
readonly effectiveConfig?: EffectiveTargetConfig;
|
|
81
|
+
readonly adPlacements?: readonly AdPlacementDefinition[];
|
|
82
|
+
readonly resolveAdPlacementType?: (placementId: string) => AdPlacementType | undefined;
|
|
83
|
+
}
|
|
84
|
+
export interface TargetConfiguredGateway extends PlatformGateway {
|
|
85
|
+
readonly configTarget: string;
|
|
86
|
+
readonly targetConfig: TargetConfig;
|
|
87
|
+
readonly effectiveConfig?: EffectiveTargetConfig;
|
|
88
|
+
getTargetRuntime(): Promise<TargetRuntimeSnapshot>;
|
|
89
|
+
}
|
|
90
|
+
export declare const platformFeatures: readonly ["iap", "rewardedAds", "interstitialAds", "leaderboard", "localization"];
|
|
91
|
+
export declare function targetConfigKeyForPlatform(target: PlatformConfigTarget): string;
|
|
92
|
+
export declare function getTargetConfig(matrix: TargetConfigMatrix, target: PlatformConfigTarget | string): TargetConfig;
|
|
93
|
+
export declare function isPlatformFeatureEnabled(config: TargetConfig, feature: PlatformFeature): boolean;
|
|
94
|
+
export declare function applyTargetConfigToCapabilities(capabilities: PlatformCapabilities, config: TargetConfig): PlatformCapabilities;
|
|
95
|
+
export declare function getFeatureAvailability(feature: PlatformFeature, config: TargetConfig, capabilities: PlatformCapabilities): FeatureAvailability;
|
|
96
|
+
export declare function createTargetRuntimeSnapshot(input: {
|
|
97
|
+
readonly target: PlatformConfigTarget;
|
|
98
|
+
readonly configTarget?: string;
|
|
99
|
+
readonly config: TargetConfig;
|
|
100
|
+
readonly effectiveConfig?: EffectiveTargetConfig;
|
|
101
|
+
readonly capabilities: PlatformCapabilities;
|
|
102
|
+
readonly adPlacements?: readonly AdPlacementDefinition[];
|
|
103
|
+
}): TargetRuntimeSnapshot;
|
|
104
|
+
export declare function withTargetAvailability(gateway: PlatformGateway, config: TargetConfig, options?: TargetAvailabilityOptions): TargetConfiguredGateway;
|
|
105
|
+
export declare function isTargetConfiguredGateway(gateway: PlatformGateway): gateway is TargetConfiguredGateway;
|
|
106
|
+
export {};
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export const platformFeatures = [
|
|
2
|
+
'iap',
|
|
3
|
+
'rewardedAds',
|
|
4
|
+
'interstitialAds',
|
|
5
|
+
'leaderboard',
|
|
6
|
+
'localization',
|
|
7
|
+
];
|
|
8
|
+
export function targetConfigKeyForPlatform(target) {
|
|
9
|
+
return target === 'browser' ? 'web-preview' : target;
|
|
10
|
+
}
|
|
11
|
+
export function getTargetConfig(matrix, target) {
|
|
12
|
+
const config = matrix.targets[target];
|
|
13
|
+
if (config === undefined) {
|
|
14
|
+
throw new Error(`Missing target config for target: ${target}`);
|
|
15
|
+
}
|
|
16
|
+
return config;
|
|
17
|
+
}
|
|
18
|
+
export function isPlatformFeatureEnabled(config, feature) {
|
|
19
|
+
return config.features[feature];
|
|
20
|
+
}
|
|
21
|
+
export function applyTargetConfigToCapabilities(capabilities, config) {
|
|
22
|
+
return {
|
|
23
|
+
...capabilities,
|
|
24
|
+
nativeIap: capabilities.nativeIap && config.features.iap,
|
|
25
|
+
nativeAds: capabilities.nativeAds &&
|
|
26
|
+
(config.features.rewardedAds || config.features.interstitialAds),
|
|
27
|
+
rewardedAds: capabilities.rewardedAds && config.features.rewardedAds,
|
|
28
|
+
interstitialAds: capabilities.interstitialAds && config.features.interstitialAds,
|
|
29
|
+
nativeLeaderboard: capabilities.nativeLeaderboard && config.features.leaderboard,
|
|
30
|
+
localizedContent: capabilities.localizedContent && config.features.localization,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function getFeatureAvailability(feature, config, capabilities) {
|
|
34
|
+
const targetEnabled = config.features[feature];
|
|
35
|
+
const capabilitySupported = isFeatureCapabilitySupported(feature, capabilities);
|
|
36
|
+
const enabled = targetEnabled && capabilitySupported;
|
|
37
|
+
return {
|
|
38
|
+
feature,
|
|
39
|
+
enabled,
|
|
40
|
+
targetEnabled,
|
|
41
|
+
capabilitySupported,
|
|
42
|
+
reason: enabled
|
|
43
|
+
? 'available'
|
|
44
|
+
: targetEnabled
|
|
45
|
+
? 'capability-unsupported'
|
|
46
|
+
: 'target-disabled',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function createTargetRuntimeSnapshot(input) {
|
|
50
|
+
const configTarget = input.configTarget ?? targetConfigKeyForPlatform(input.target);
|
|
51
|
+
const features = {
|
|
52
|
+
iap: getFeatureAvailability('iap', input.config, input.capabilities),
|
|
53
|
+
rewardedAds: getFeatureAvailability('rewardedAds', input.config, input.capabilities),
|
|
54
|
+
interstitialAds: getFeatureAvailability('interstitialAds', input.config, input.capabilities),
|
|
55
|
+
leaderboard: getFeatureAvailability('leaderboard', input.config, input.capabilities),
|
|
56
|
+
localization: getFeatureAvailability('localization', input.config, input.capabilities),
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
target: input.target,
|
|
60
|
+
configTarget,
|
|
61
|
+
config: input.config,
|
|
62
|
+
...(input.effectiveConfig === undefined ? {} : { effectiveConfig: input.effectiveConfig }),
|
|
63
|
+
capabilities: input.capabilities,
|
|
64
|
+
features,
|
|
65
|
+
adPlacements: (input.adPlacements ?? []).map((placement) => {
|
|
66
|
+
const feature = placement.type === 'rewarded' ? 'rewardedAds' : 'interstitialAds';
|
|
67
|
+
const availability = features[feature];
|
|
68
|
+
return {
|
|
69
|
+
id: placement.id,
|
|
70
|
+
type: placement.type,
|
|
71
|
+
enabled: availability.enabled,
|
|
72
|
+
reason: availability.reason,
|
|
73
|
+
};
|
|
74
|
+
}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function withTargetAvailability(gateway, config, options = {}) {
|
|
78
|
+
const configTarget = options.configTarget ?? targetConfigKeyForPlatform(gateway.target);
|
|
79
|
+
const isAdPlacementAllowed = (placementId, expectedType) => {
|
|
80
|
+
const actualType = options.resolveAdPlacementType?.(placementId);
|
|
81
|
+
if (actualType !== undefined && actualType !== expectedType) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return expectedType === 'rewarded'
|
|
85
|
+
? config.features.rewardedAds
|
|
86
|
+
: config.features.interstitialAds;
|
|
87
|
+
};
|
|
88
|
+
const canPreloadAdPlacement = (placementId) => {
|
|
89
|
+
const actualType = options.resolveAdPlacementType?.(placementId);
|
|
90
|
+
if (actualType === 'rewarded') {
|
|
91
|
+
return config.features.rewardedAds;
|
|
92
|
+
}
|
|
93
|
+
if (actualType === 'interstitial') {
|
|
94
|
+
return config.features.interstitialAds;
|
|
95
|
+
}
|
|
96
|
+
return config.features.rewardedAds || config.features.interstitialAds;
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
...gateway,
|
|
100
|
+
configTarget,
|
|
101
|
+
targetConfig: config,
|
|
102
|
+
...(options.effectiveConfig === undefined
|
|
103
|
+
? {}
|
|
104
|
+
: { effectiveConfig: options.effectiveConfig }),
|
|
105
|
+
async getTargetRuntime() {
|
|
106
|
+
return createTargetRuntimeSnapshot({
|
|
107
|
+
target: gateway.target,
|
|
108
|
+
configTarget,
|
|
109
|
+
config,
|
|
110
|
+
...(options.effectiveConfig === undefined
|
|
111
|
+
? {}
|
|
112
|
+
: { effectiveConfig: options.effectiveConfig }),
|
|
113
|
+
capabilities: applyTargetConfigToCapabilities(await gateway.getCapabilities(), config),
|
|
114
|
+
adPlacements: options.adPlacements ?? [],
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
async getCapabilities() {
|
|
118
|
+
return applyTargetConfigToCapabilities(await gateway.getCapabilities(), config);
|
|
119
|
+
},
|
|
120
|
+
commerce: config.features.iap
|
|
121
|
+
? gateway.commerce
|
|
122
|
+
: {
|
|
123
|
+
async getProducts() {
|
|
124
|
+
return [];
|
|
125
|
+
},
|
|
126
|
+
async purchase() {
|
|
127
|
+
return {
|
|
128
|
+
status: 'cancelled',
|
|
129
|
+
entitlementIds: [],
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
async restore() {
|
|
133
|
+
return {
|
|
134
|
+
restoredEntitlements: [],
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
async getEntitlements() {
|
|
138
|
+
return [];
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
ads: {
|
|
142
|
+
async preload(input) {
|
|
143
|
+
if (canPreloadAdPlacement(input.placementId)) {
|
|
144
|
+
await gateway.ads.preload(input);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
async showRewarded(input) {
|
|
148
|
+
if (!isAdPlacementAllowed(input.placementId, 'rewarded')) {
|
|
149
|
+
return {
|
|
150
|
+
status: 'unavailable',
|
|
151
|
+
rewardGranted: false,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return gateway.ads.showRewarded(input);
|
|
155
|
+
},
|
|
156
|
+
async showInterstitial(input) {
|
|
157
|
+
if (!isAdPlacementAllowed(input.placementId, 'interstitial') ||
|
|
158
|
+
gateway.ads.showInterstitial === undefined) {
|
|
159
|
+
return {
|
|
160
|
+
status: 'unavailable',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return gateway.ads.showInterstitial(input);
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
leaderboard: config.features.leaderboard
|
|
167
|
+
? gateway.leaderboard
|
|
168
|
+
: {
|
|
169
|
+
async submitScore() {
|
|
170
|
+
return {
|
|
171
|
+
submitted: false,
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
async open() { },
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
export function isTargetConfiguredGateway(gateway) {
|
|
179
|
+
return typeof gateway.getTargetRuntime === 'function';
|
|
180
|
+
}
|
|
181
|
+
function isFeatureCapabilitySupported(feature, capabilities) {
|
|
182
|
+
switch (feature) {
|
|
183
|
+
case 'iap':
|
|
184
|
+
return capabilities.nativeIap;
|
|
185
|
+
case 'rewardedAds':
|
|
186
|
+
return capabilities.rewardedAds;
|
|
187
|
+
case 'interstitialAds':
|
|
188
|
+
return capabilities.interstitialAds;
|
|
189
|
+
case 'leaderboard':
|
|
190
|
+
return capabilities.nativeLeaderboard;
|
|
191
|
+
case 'localization':
|
|
192
|
+
return capabilities.localizedContent;
|
|
193
|
+
}
|
|
194
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mpgd/target-config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Target-specific platform feature availability and effective config helpers for mpgd.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/imjlk/mpgd-kit.git",
|
|
9
|
+
"directory": "packages/target-config"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/imjlk/mpgd-kit/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/imjlk/mpgd-kit#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mpgd",
|
|
17
|
+
"phaser",
|
|
18
|
+
"vite",
|
|
19
|
+
"typescript",
|
|
20
|
+
"capacitor",
|
|
21
|
+
"apps-in-toss",
|
|
22
|
+
"game-development",
|
|
23
|
+
"game-distribution"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./targets.json": "./targets.json"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"targets.json"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"typia": "rc",
|
|
40
|
+
"@mpgd/platform": "0.1.0",
|
|
41
|
+
"@mpgd/catalog": "0.1.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"ttsc": "0.16.9",
|
|
45
|
+
"typescript": "7.0.1-rc"
|
|
46
|
+
},
|
|
47
|
+
"main": "./dist/index.js",
|
|
48
|
+
"types": "./dist/index.d.ts",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"check": "ttsc --noEmit",
|
|
54
|
+
"lint": "ttsc --noEmit",
|
|
55
|
+
"format": "ttsc format",
|
|
56
|
+
"fix": "ttsc fix",
|
|
57
|
+
"test": "cd ../.. && node tools/run-ttsx.mjs packages/target-config/test/target-config-smoke.ts"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/targets.json
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2026-07-03",
|
|
3
|
+
"targets": {
|
|
4
|
+
"web-preview": {
|
|
5
|
+
"runtime": "web-preview",
|
|
6
|
+
"features": {
|
|
7
|
+
"iap": false,
|
|
8
|
+
"rewardedAds": false,
|
|
9
|
+
"interstitialAds": false,
|
|
10
|
+
"leaderboard": false,
|
|
11
|
+
"localization": true
|
|
12
|
+
},
|
|
13
|
+
"capabilities": {
|
|
14
|
+
"storage": "local",
|
|
15
|
+
"localization": true
|
|
16
|
+
},
|
|
17
|
+
"monetization": {
|
|
18
|
+
"iap": false,
|
|
19
|
+
"rewardedAds": false,
|
|
20
|
+
"interstitialAds": false
|
|
21
|
+
},
|
|
22
|
+
"leaderboard": {
|
|
23
|
+
"native": false
|
|
24
|
+
},
|
|
25
|
+
"release": {
|
|
26
|
+
"profile": "web-preview"
|
|
27
|
+
},
|
|
28
|
+
"policy": {
|
|
29
|
+
"externalPaymentAllowed": false,
|
|
30
|
+
"remoteExecutableCodeAllowed": false,
|
|
31
|
+
"installOtherAppCTAAllowed": false,
|
|
32
|
+
"requiresStoreReview": false,
|
|
33
|
+
"requiresAitReview": false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"android": {
|
|
37
|
+
"runtime": "capacitor-android",
|
|
38
|
+
"features": {
|
|
39
|
+
"iap": true,
|
|
40
|
+
"rewardedAds": true,
|
|
41
|
+
"interstitialAds": true,
|
|
42
|
+
"leaderboard": true,
|
|
43
|
+
"localization": true
|
|
44
|
+
},
|
|
45
|
+
"capabilities": {
|
|
46
|
+
"storage": "native",
|
|
47
|
+
"localization": true
|
|
48
|
+
},
|
|
49
|
+
"monetization": {
|
|
50
|
+
"iap": true,
|
|
51
|
+
"rewardedAds": true,
|
|
52
|
+
"interstitialAds": true
|
|
53
|
+
},
|
|
54
|
+
"leaderboard": {
|
|
55
|
+
"native": true
|
|
56
|
+
},
|
|
57
|
+
"release": {
|
|
58
|
+
"profile": "google-play"
|
|
59
|
+
},
|
|
60
|
+
"policy": {
|
|
61
|
+
"externalPaymentAllowed": false,
|
|
62
|
+
"remoteExecutableCodeAllowed": false,
|
|
63
|
+
"installOtherAppCTAAllowed": false,
|
|
64
|
+
"requiresStoreReview": true,
|
|
65
|
+
"requiresAitReview": false
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"ios": {
|
|
69
|
+
"runtime": "capacitor-ios",
|
|
70
|
+
"features": {
|
|
71
|
+
"iap": true,
|
|
72
|
+
"rewardedAds": true,
|
|
73
|
+
"interstitialAds": true,
|
|
74
|
+
"leaderboard": true,
|
|
75
|
+
"localization": true
|
|
76
|
+
},
|
|
77
|
+
"capabilities": {
|
|
78
|
+
"storage": "native",
|
|
79
|
+
"localization": true
|
|
80
|
+
},
|
|
81
|
+
"monetization": {
|
|
82
|
+
"iap": true,
|
|
83
|
+
"rewardedAds": true,
|
|
84
|
+
"interstitialAds": true
|
|
85
|
+
},
|
|
86
|
+
"leaderboard": {
|
|
87
|
+
"native": true
|
|
88
|
+
},
|
|
89
|
+
"release": {
|
|
90
|
+
"profile": "app-store"
|
|
91
|
+
},
|
|
92
|
+
"policy": {
|
|
93
|
+
"externalPaymentAllowed": false,
|
|
94
|
+
"remoteExecutableCodeAllowed": false,
|
|
95
|
+
"installOtherAppCTAAllowed": false,
|
|
96
|
+
"requiresStoreReview": true,
|
|
97
|
+
"requiresAitReview": false
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"ait": {
|
|
101
|
+
"runtime": "apps-in-toss",
|
|
102
|
+
"features": {
|
|
103
|
+
"iap": true,
|
|
104
|
+
"rewardedAds": true,
|
|
105
|
+
"interstitialAds": true,
|
|
106
|
+
"leaderboard": true,
|
|
107
|
+
"localization": true
|
|
108
|
+
},
|
|
109
|
+
"capabilities": {
|
|
110
|
+
"storage": "none",
|
|
111
|
+
"localization": true
|
|
112
|
+
},
|
|
113
|
+
"monetization": {
|
|
114
|
+
"iap": true,
|
|
115
|
+
"rewardedAds": true,
|
|
116
|
+
"interstitialAds": true
|
|
117
|
+
},
|
|
118
|
+
"leaderboard": {
|
|
119
|
+
"native": true
|
|
120
|
+
},
|
|
121
|
+
"release": {
|
|
122
|
+
"profile": "apps-in-toss"
|
|
123
|
+
},
|
|
124
|
+
"policy": {
|
|
125
|
+
"externalPaymentAllowed": false,
|
|
126
|
+
"remoteExecutableCodeAllowed": false,
|
|
127
|
+
"installOtherAppCTAAllowed": false,
|
|
128
|
+
"requiresStoreReview": false,
|
|
129
|
+
"requiresAitReview": true
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|