@mpgd/platform 0.22.0 → 0.23.1
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/capability-conformance.d.ts +6 -5
- package/dist/capability-conformance.js +178 -42
- package/dist/commerce-capabilities.d.ts +0 -6
- package/dist/commerce-capabilities.js +2 -8
- package/dist/commerce-contract.d.ts +12 -2
- package/dist/commerce.d.ts +8 -17
- package/dist/commerce.js +10 -94
- package/dist/index.d.ts +80 -43
- package/dist/index.js +3 -36
- package/dist/notifications-conformance.d.ts +529 -0
- package/dist/notifications-conformance.js +3537 -0
- package/dist/notifications-contract.d.ts +204 -0
- package/dist/notifications-contract.js +1 -0
- package/dist/notifications-policy.d.ts +885 -0
- package/dist/notifications-policy.js +1658 -0
- package/dist/notifications-vectors.d.ts +427 -0
- package/dist/notifications-vectors.js +4949 -0
- package/dist/notifications.d.ts +265 -0
- package/dist/notifications.js +4958 -0
- package/dist/route-vectors.d.ts +23 -0
- package/dist/route-vectors.js +96 -0
- package/dist/routes.d.ts +60 -0
- package/dist/routes.js +209 -0
- package/dist/share-link-conformance.d.ts +47 -0
- package/dist/share-link-conformance.js +100 -0
- package/package.json +28 -4
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import type { IsoTimestamp, NonEmptyString, PositiveQuantity } from './commerce-contract.js';
|
|
2
|
+
import type { PlatformEvidenceEnvelope, PlatformProviderAvailability } from './index.js';
|
|
3
|
+
/** Open topic id declared by the game's topic catalog. */
|
|
4
|
+
export type NotificationTopicId = string & Record<never, never>;
|
|
5
|
+
/** What a topic is for; it decides the consent a send needs (RFC "Topics and purposes"). */
|
|
6
|
+
export type NotificationPurpose = 'service' | 'requested' | 'advertising';
|
|
7
|
+
/** `remote` is a server-sent push, `local` a device-scheduled notification. */
|
|
8
|
+
export type NotificationChannel = 'remote' | 'local';
|
|
9
|
+
/** Open provider id. Reference ids: 'fcm', 'apps-in-toss', 'devvit'. */
|
|
10
|
+
export type NotificationProviderId = NonEmptyString;
|
|
11
|
+
/** The player action a host needs before it can prompt. */
|
|
12
|
+
export type NotificationRequiredAction = 'login' | 'host-settings';
|
|
13
|
+
export type NotificationPermissionState = 'granted' | 'prompt'
|
|
14
|
+
/** Android after one denial: explain, then the dialog may show once more. */
|
|
15
|
+
| 'prompt-with-rationale'
|
|
16
|
+
/** Refused; this host lets the game ask again later. */
|
|
17
|
+
| 'denied'
|
|
18
|
+
/** Only OS or host settings can change it. */
|
|
19
|
+
| 'blocked'
|
|
20
|
+
/** The host gives no read; the server record decides. */
|
|
21
|
+
| 'unknown'
|
|
22
|
+
/** The host needs a player action first: logging in on Devvit. */
|
|
23
|
+
| 'action-required' | 'unsupported';
|
|
24
|
+
export interface NotificationPermissionSnapshot {
|
|
25
|
+
/** Present when `permission.scope` is 'app'. */
|
|
26
|
+
readonly app?: NotificationPermissionState;
|
|
27
|
+
readonly topics: Readonly<Record<NotificationTopicId, NotificationPermissionState>>;
|
|
28
|
+
/** Present with an `action-required` state. */
|
|
29
|
+
readonly requiredAction?: NotificationRequiredAction;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* What one `requestPermission` call produced for a topic: the host's answer
|
|
33
|
+
* when the prompt ran ('granted', 'already-granted', 'denied', and
|
|
34
|
+
* 'dismissed' when it closed without an answer), 'blocked' when the host
|
|
35
|
+
* refused for good or the call did not reach the prompt because the host read
|
|
36
|
+
* was already blocked, 'action-required' when the host needs a player action
|
|
37
|
+
* before it can prompt (`requiredAction` names it), and 'unavailable' when the
|
|
38
|
+
* provider is unsupported or the topic has no mapping for it. The snapshot
|
|
39
|
+
* carries the resulting state, so a second Android denial reports outcome
|
|
40
|
+
* 'denied' with snapshot 'blocked'.
|
|
41
|
+
*/
|
|
42
|
+
export type NotificationPermissionOutcome = 'granted' | 'already-granted' | 'denied' | 'blocked' | 'dismissed' | 'action-required' | 'unavailable';
|
|
43
|
+
export interface NotificationPermissionResult {
|
|
44
|
+
readonly snapshot: NotificationPermissionSnapshot;
|
|
45
|
+
readonly outcomes: Readonly<Record<NotificationTopicId, NotificationPermissionOutcome>>;
|
|
46
|
+
readonly requiredAction?: NotificationRequiredAction;
|
|
47
|
+
/** Host decision for the server record, for example an Apps in Toss agreement event. */
|
|
48
|
+
readonly evidence?: PlatformEvidenceEnvelope;
|
|
49
|
+
}
|
|
50
|
+
export type NotificationPermissionScope = 'app' | 'topic';
|
|
51
|
+
export type NotificationPermissionPrompt = 'os' | 'host' | 'game';
|
|
52
|
+
export type NotificationPermissionAllowance = 'persistent' | 'per-send';
|
|
53
|
+
export type NotificationRemoteAddressing = 'device' | 'platform-user' | 'none';
|
|
54
|
+
export type NotificationRemoteContent = 'free-form' | 'host-template';
|
|
55
|
+
export type NotificationOpenPath = 'payload' | 'landing-url' | 'host-link' | 'none';
|
|
56
|
+
export interface NotificationPermissionCapabilities {
|
|
57
|
+
/** Where delivery permission lives: one for the app, or one per topic. */
|
|
58
|
+
readonly scope: NotificationPermissionScope;
|
|
59
|
+
/** Who renders the consent UI. */
|
|
60
|
+
readonly prompt: NotificationPermissionPrompt;
|
|
61
|
+
/** Whether the client can read the current state without prompting. */
|
|
62
|
+
readonly readable: boolean;
|
|
63
|
+
/** Whether the backend can read the current state at send time (Devvit `isOptedIn`). */
|
|
64
|
+
readonly serverReadable: boolean;
|
|
65
|
+
/** 'per-send': one acceptance allows one delivery (WeChat one-time subscriptions). */
|
|
66
|
+
readonly allowance: NotificationPermissionAllowance;
|
|
67
|
+
readonly userGesture: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* How many denials the host accepts before only settings can change the
|
|
70
|
+
* answer: iOS 1, Android 13+ 2. A dismissed dialog is not a denial. Absent
|
|
71
|
+
* when the host can always ask again (Apps in Toss, Devvit, WeChat).
|
|
72
|
+
*/
|
|
73
|
+
readonly promptLimit?: PositiveQuantity;
|
|
74
|
+
readonly maxTopicsPerPrompt?: PositiveQuantity;
|
|
75
|
+
/** Whether `openSettings` can open the OS or host notification settings. */
|
|
76
|
+
readonly settings: boolean;
|
|
77
|
+
}
|
|
78
|
+
export interface NotificationRemoteCapabilities {
|
|
79
|
+
readonly supported: boolean;
|
|
80
|
+
/** Purposes the host lets the server deliver. */
|
|
81
|
+
readonly purposes: readonly NotificationPurpose[];
|
|
82
|
+
/** `'none'` exactly when `supported` is false. */
|
|
83
|
+
readonly addressing: NotificationRemoteAddressing;
|
|
84
|
+
readonly content: NotificationRemoteContent;
|
|
85
|
+
}
|
|
86
|
+
/** Local reminders are always inexact, so the capability carries no timing. */
|
|
87
|
+
export interface NotificationLocalCapabilities {
|
|
88
|
+
readonly supported: boolean;
|
|
89
|
+
/** Pending-notification ceiling the provider must stay under (iOS: 64). */
|
|
90
|
+
readonly maxPending?: PositiveQuantity;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Notifications v2 capability declaration. A provider returns a fresh object
|
|
94
|
+
* on every read; code branches on these declarations, never on a provider id
|
|
95
|
+
* or target name. Release gates such as Devvit's `approval-required` stay in
|
|
96
|
+
* the target config's `integrations.notifications` state.
|
|
97
|
+
*/
|
|
98
|
+
export interface NotificationCapabilities {
|
|
99
|
+
readonly availability: PlatformProviderAvailability;
|
|
100
|
+
readonly permission: NotificationPermissionCapabilities;
|
|
101
|
+
readonly remote: NotificationRemoteCapabilities;
|
|
102
|
+
readonly local: NotificationLocalCapabilities;
|
|
103
|
+
/** How an open reaches the game. */
|
|
104
|
+
readonly open: NotificationOpenPath;
|
|
105
|
+
}
|
|
106
|
+
export type NotificationEndpointAddress = {
|
|
107
|
+
readonly kind: 'fcm-token' | 'fcm-installation';
|
|
108
|
+
readonly value: NonEmptyString;
|
|
109
|
+
readonly environment?: 'production' | 'sandbox';
|
|
110
|
+
/** The device's app-scope permission when this registration was sent. */
|
|
111
|
+
readonly permission: NotificationPermissionState;
|
|
112
|
+
}
|
|
113
|
+
/** The server resolves the recipient from the authenticated player. */
|
|
114
|
+
| {
|
|
115
|
+
readonly kind: 'platform-user';
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Where the server reaches this installation or player. The installation id
|
|
119
|
+
* is the authenticated session's, never a field of the registration.
|
|
120
|
+
*/
|
|
121
|
+
export interface NotificationEndpointRegistration {
|
|
122
|
+
readonly provider: NotificationProviderId;
|
|
123
|
+
readonly address: NotificationEndpointAddress;
|
|
124
|
+
readonly locale?: NonEmptyString;
|
|
125
|
+
/** IANA zone, used for a topic's quiet hours. */
|
|
126
|
+
readonly timeZone?: NonEmptyString;
|
|
127
|
+
}
|
|
128
|
+
export interface LocalNotificationRequest {
|
|
129
|
+
/** Stable logical key; the provider derives its native id from it. */
|
|
130
|
+
readonly key: NonEmptyString;
|
|
131
|
+
readonly topic: NotificationTopicId;
|
|
132
|
+
/** RFC 3339 with an explicit offset. */
|
|
133
|
+
readonly fireAt: IsoTimestamp;
|
|
134
|
+
readonly title: string;
|
|
135
|
+
readonly body: string;
|
|
136
|
+
/** The topic's root-relative route. Advertising topics never schedule locally. */
|
|
137
|
+
readonly route?: string;
|
|
138
|
+
}
|
|
139
|
+
/** A pending local notification as `listLocal` reports it. */
|
|
140
|
+
export interface LocalNotificationEntry {
|
|
141
|
+
readonly key: NonEmptyString;
|
|
142
|
+
readonly topic: NotificationTopicId;
|
|
143
|
+
readonly fireAt: IsoTimestamp;
|
|
144
|
+
}
|
|
145
|
+
export type LocalScheduleResult = {
|
|
146
|
+
readonly status: 'scheduled' | 'replaced';
|
|
147
|
+
} | {
|
|
148
|
+
readonly status: 'permission-required' | 'capacity-exceeded' | 'unsupported';
|
|
149
|
+
};
|
|
150
|
+
export type NotificationEvent = {
|
|
151
|
+
readonly type: 'opened';
|
|
152
|
+
readonly channel: NotificationChannel;
|
|
153
|
+
readonly source: 'cold' | 'warm';
|
|
154
|
+
readonly topic?: NotificationTopicId;
|
|
155
|
+
/**
|
|
156
|
+
* Untrusted, like `data`: the router opens it only when
|
|
157
|
+
* `isRootRelativeNotificationRoute` accepts it.
|
|
158
|
+
*/
|
|
159
|
+
readonly route?: string;
|
|
160
|
+
/** Untrusted routing data. Never a grant. */
|
|
161
|
+
readonly data?: Readonly<Record<string, string>>;
|
|
162
|
+
/** Host referrer when known, for example Apps in Toss 'push' or 'inbox'. */
|
|
163
|
+
readonly referrer?: string;
|
|
164
|
+
} | {
|
|
165
|
+
readonly type: 'received';
|
|
166
|
+
readonly channel: NotificationChannel;
|
|
167
|
+
readonly topic?: NotificationTopicId;
|
|
168
|
+
} | {
|
|
169
|
+
readonly type: 'endpoint-changed';
|
|
170
|
+
readonly registration: NotificationEndpointRegistration;
|
|
171
|
+
} | {
|
|
172
|
+
readonly type: 'permission-changed';
|
|
173
|
+
readonly snapshot: NotificationPermissionSnapshot;
|
|
174
|
+
};
|
|
175
|
+
export interface NotificationTopicsInput {
|
|
176
|
+
readonly topics: readonly NotificationTopicId[];
|
|
177
|
+
}
|
|
178
|
+
export interface CancelLocalNotificationsInput {
|
|
179
|
+
readonly keys: readonly NonEmptyString[];
|
|
180
|
+
}
|
|
181
|
+
export type NotificationSettingsResult = 'opened' | 'unavailable';
|
|
182
|
+
/**
|
|
183
|
+
* A target's notifications provider. Rules every provider follows (RFC
|
|
184
|
+
* "Client contract"): reads are fresh, events emitted before the first
|
|
185
|
+
* `subscribe` go to that first subscriber exactly once, only
|
|
186
|
+
* `requestPermission` may show a consent UI, an unsupported provider answers
|
|
187
|
+
* instead of throwing, local keys map to stable native ids, and failures use
|
|
188
|
+
* the `NOTIFICATIONS_*` `PlatformOperationError` codes.
|
|
189
|
+
*/
|
|
190
|
+
export interface NotificationProvider {
|
|
191
|
+
readonly provider: NotificationProviderId;
|
|
192
|
+
getCapabilities(): Promise<NotificationCapabilities>;
|
|
193
|
+
getPermission(input: NotificationTopicsInput): Promise<NotificationPermissionSnapshot>;
|
|
194
|
+
requestPermission(input: NotificationTopicsInput): Promise<NotificationPermissionResult>;
|
|
195
|
+
/** Exists exactly when `permission.prompt` is 'game': withdraws the game-rendered consent. */
|
|
196
|
+
revokePermission?(input: NotificationTopicsInput): Promise<NotificationPermissionResult>;
|
|
197
|
+
/** Remote providers: the address the server should send to. */
|
|
198
|
+
register?(): Promise<NotificationEndpointRegistration | null>;
|
|
199
|
+
scheduleLocal?(input: LocalNotificationRequest): Promise<LocalScheduleResult>;
|
|
200
|
+
cancelLocal?(input: CancelLocalNotificationsInput): Promise<void>;
|
|
201
|
+
listLocal?(): Promise<readonly LocalNotificationEntry[]>;
|
|
202
|
+
openSettings?(): Promise<NotificationSettingsResult>;
|
|
203
|
+
subscribe(listener: (event: NotificationEvent) => void): () => void;
|
|
204
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|