@mpgd/platform 0.22.0 → 0.23.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.
@@ -0,0 +1,265 @@
1
+ import { type tags } from 'typia';
2
+ import { PlatformOperationError, type NotificationSubscriptionAdapter, type NotificationSubscriptionResult, type NotificationSubscriptionStatus } from './index.js';
3
+ import type { CancelLocalNotificationsInput, LocalNotificationEntry, LocalNotificationRequest, LocalScheduleResult, NotificationCapabilities, NotificationEndpointRegistration, NotificationEvent, NotificationPermissionOutcome, NotificationPermissionResult, NotificationPermissionSnapshot, NotificationPermissionState, NotificationProviderId, NotificationSettingsResult, NotificationTopicId, NotificationTopicsInput } from './notifications-contract.js';
4
+ import { type NotificationConsentRecord, type NotificationDeliveryProviderEntry, type NotificationDeployment, type NotificationNotice, type NotificationNoticeIdentity, type NotificationTemplateData, type NotificationTopicDefinition, type ReminderResult } from './notifications-policy.js';
5
+ /**
6
+ * Notifications v2 contract module (docs/specs/notifications/notifications-v2-rfc.md).
7
+ * Pure types, validators, and helpers only: no provider lives here, and
8
+ * nothing in this module sends a notification or grants anything. The
9
+ * contract is a draft until the protocol version is released as 2.0.0.
10
+ */
11
+ export declare const notificationsProtocolVersion: '2.0.0-draft.1';
12
+ export declare const notificationsProtocol: 'mpgd.notifications.v2';
13
+ export type { CancelLocalNotificationsInput, LocalNotificationEntry, LocalNotificationRequest, LocalScheduleResult, NotificationCapabilities, NotificationChannel, NotificationEndpointAddress, NotificationEndpointRegistration, NotificationEvent, NotificationLocalCapabilities, NotificationOpenPath, NotificationPermissionAllowance, NotificationPermissionCapabilities, NotificationPermissionOutcome, NotificationPermissionPrompt, NotificationPermissionResult, NotificationPermissionScope, NotificationPermissionSnapshot, NotificationPermissionState, NotificationProvider, NotificationProviderId, NotificationPurpose, NotificationRemoteAddressing, NotificationRemoteCapabilities, NotificationRemoteContent, NotificationRequiredAction, NotificationSettingsResult, NotificationTopicId, NotificationTopicsInput, } from './notifications-contract.js';
14
+ export { applyNotificationAdvertisingLabel, checkNotificationNightWindow, checkNotificationQuietHours, createNotificationNoticeIdempotencyKey, createNotificationReminderIdempotencyKey, evaluateLocalNotificationReminder, evaluateNotificationDelivery, evaluateNotificationReminderConsent, fillNotificationTemplate, findNotificationCopy, isNotificationCalendarDate, isNotificationTimestamp, isRecordableNotificationPermissionState, isRootRelativeNotificationRoute, isSameNotificationNotice, isValidNotificationTimeZone, latestNotificationConsent, listNotificationNotices, normalizeNotificationTimestamp, notificationAdvertisingOptOutActionId, notificationAdvertisingPrefix, notificationConsentResultDueBy, notificationDefaultDeploymentTimeZone, notificationDefaultOptOutLine, notificationInputBounds, notificationKeyIssue, notificationNightWindow, notificationNoticeCopyIssues, notificationNoticeLeadDays, notificationNoticeSendFrom, notificationNoticeTopic, notificationNoticeVariantCopy, notificationNoticeVariantFallbacks, notificationNoticeVariants, notificationPermissionConsentKind, notificationPermissionStateOf, notificationProviderCarriesNotices, notificationReconfirmationDueBy, notificationReconfirmationListDays, notificationRegistryMismatch, notificationReservedKeyPrefix, notificationReservedKeyPrefixes, notificationSendFingerprint, notificationSuppressionReasons, notificationTemplateDataIssue, notificationTopicDefinitionIssues, notificationTopicNeedsNoAgreement, readNotificationTemplate, recordableNotificationPermissionStates, referenceNotificationProviders, referenceNotificationTargetProviders, renderNotificationAdvertisement, resolveNotificationAdvertisingSettings, resolveNotificationContent, routeNotificationReminder, toSeoulCalendarDate, type EvaluateLocalNotificationReminderInput, type EvaluateNotificationDeliveryInput, type EvaluateNotificationReminderConsentInput, type LocalNotificationReminderDecision, type NotificationAction, type NotificationAdvertisingRules, type NotificationAdvertisingSender, type NotificationAdvertisingSettings, type NotificationClockTime, type NotificationConsentKind, type NotificationConsentRecord, type NotificationConsentSource, type NotificationConsentState, type NotificationDeferralReason, type NotificationDeliveryContent, type NotificationDeliveryDecision, type NotificationDeliveryHistoryEntry, type NotificationDeliveryOutcome, type NotificationDeliveryProviderEntry, type NotificationDeliveryRefusal, type NotificationDeliveryStatus, type NotificationDeployment, type NotificationMappingField, type NotificationNotice, type NotificationNoticeCopy, type NotificationNoticeIdentity, type NotificationNoticeKind, type NotificationNoticeLocaleCopy, type NotificationNoticeSettings, type NotificationNoticeVariant, type NotificationProviderLimit, type NotificationProviderRegistryEntry, type NotificationQuietHours, type NotificationRecordablePermissionState, type NotificationReminderRoute, type NotificationReminderStatus, type NotificationSendRequest, type NotificationSuppressionReason, type NotificationTemplateData, type NotificationTopicCopy, type NotificationTopicDeclaration, type NotificationTopicDefinition, type NotificationTopicFrequency, type NotificationTopicIssue, type NotificationTopicMapping, type NotificationUnavailableReason, type NotificationWindowCheck, type ReminderResult, type ResolveNotificationContentInput, } from './notifications-policy.js';
15
+ type NonEmptyString = string & tags.MinLength<1>;
16
+ type NonNegativeInteger = number & tags.Type<'uint32'>;
17
+ export type NotificationErrorCode =
18
+ /** A method the provider does not implement. */
19
+ 'NOTIFICATIONS_UNSUPPORTED'
20
+ /** The host's own code is kept as `hostCode`. */
21
+ | 'NOTIFICATIONS_CONFIGURATION_REQUIRED' | 'NOTIFICATIONS_USER_GESTURE_REQUIRED' | 'NOTIFICATIONS_HOST_VERSION_UNSUPPORTED'
22
+ /** Input outside the bounds, a reserved key prefix, or a timestamp without an offset. */
23
+ | 'NOTIFICATIONS_INVALID_INPUT'
24
+ /** A key stored for another request. */
25
+ | 'NOTIFICATIONS_IDEMPOTENCY_CONFLICT' | 'NOTIFICATIONS_TEMPORARILY_UNAVAILABLE'
26
+ /** A bridge without the v2 methods; not retryable. */
27
+ | 'NOTIFICATIONS_V2_UNAVAILABLE';
28
+ export declare const notificationErrorCodes: readonly ["NOTIFICATIONS_UNSUPPORTED", "NOTIFICATIONS_CONFIGURATION_REQUIRED", "NOTIFICATIONS_USER_GESTURE_REQUIRED", "NOTIFICATIONS_HOST_VERSION_UNSUPPORTED", "NOTIFICATIONS_INVALID_INPUT", "NOTIFICATIONS_IDEMPOTENCY_CONFLICT", "NOTIFICATIONS_TEMPORARILY_UNAVAILABLE", "NOTIFICATIONS_V2_UNAVAILABLE"];
29
+ export declare function isNotificationErrorCode(value: unknown): value is NotificationErrorCode;
30
+ export interface NotificationErrorOptions {
31
+ readonly message?: string;
32
+ /** Only `NOTIFICATIONS_TEMPORARILY_UNAVAILABLE` is retryable unless a caller says otherwise. */
33
+ readonly retryable?: boolean;
34
+ /** The host's own code, kept verbatim with `NOTIFICATIONS_CONFIGURATION_REQUIRED`. */
35
+ readonly hostCode?: string;
36
+ readonly cause?: unknown;
37
+ }
38
+ /** Normalized notifications failure; only `NOTIFICATIONS_TEMPORARILY_UNAVAILABLE` is retryable by default. */
39
+ export declare class NotificationError extends PlatformOperationError {
40
+ readonly code: NotificationErrorCode;
41
+ readonly hostCode: string | undefined;
42
+ constructor(code: NotificationErrorCode, options?: NotificationErrorOptions);
43
+ }
44
+ export interface NotificationRuntimePermissionSnapshot extends NotificationPermissionSnapshot {
45
+ /** Whether the host answered each topic, or the latest backend record did. */
46
+ readonly sources: Readonly<Record<NotificationTopicId, 'host' | 'record'>>;
47
+ }
48
+ export interface NotificationRuntimeRequestPermissionInput extends NotificationTopicsInput {
49
+ /** Whether the call runs inside a player gesture. */
50
+ readonly gesture: boolean;
51
+ }
52
+ export interface NotificationTopicPreferenceInput {
53
+ readonly topic: NotificationTopicId;
54
+ readonly enabled: boolean;
55
+ }
56
+ export interface NotificationAdvertisingConsentInput {
57
+ readonly advertising?: 'granted' | 'withdrawn';
58
+ readonly night?: 'granted' | 'withdrawn';
59
+ readonly textVersion: string;
60
+ }
61
+ export interface SetNotificationReminderInput {
62
+ readonly key: string;
63
+ readonly topic: NotificationTopicId;
64
+ /** RFC 3339 with an explicit offset. */
65
+ readonly fireAt: string;
66
+ readonly templateData?: NotificationTemplateData;
67
+ /** A post or comment id for providers whose sends need a link (Devvit). */
68
+ readonly link?: string;
69
+ }
70
+ export interface CancelNotificationReminderInput {
71
+ readonly key: string;
72
+ }
73
+ /**
74
+ * The notice `notices.recordShown` records: a notice as `notices.list()` gave
75
+ * it, or exactly its name (its kind, the kind and time of the record it
76
+ * reports on, and its `dueBy`).
77
+ */
78
+ export type RecordNotificationNoticeInput = NotificationNoticeIdentity | NotificationNotice;
79
+ /**
80
+ * The game-facing notifications surface: the provider composed with the
81
+ * backend. Games call this, never the provider. Consent records are written
82
+ * here (RFC "Runtime" rules); remote sends happen only on the server.
83
+ */
84
+ export interface NotificationRuntime {
85
+ getPermission(input: NotificationTopicsInput): Promise<NotificationRuntimePermissionSnapshot>;
86
+ requestPermission(input: NotificationRuntimeRequestPermissionInput): Promise<NotificationPermissionResult>;
87
+ /** Game-rendered consent only (`permission.prompt` is 'game'). */
88
+ revokePermission(input: NotificationTopicsInput): Promise<NotificationPermissionResult>;
89
+ register(): Promise<void>;
90
+ /** Unbinds this installation's address from the player, for example at logout. */
91
+ unregister(): Promise<void>;
92
+ setTopicPreference(input: NotificationTopicPreferenceInput): Promise<void>;
93
+ setAdvertisingConsent(input: NotificationAdvertisingConsentInput): Promise<void>;
94
+ readonly reminders: {
95
+ set(input: SetNotificationReminderInput): Promise<ReminderResult>;
96
+ cancel(input: CancelNotificationReminderInput): Promise<ReminderResult>;
97
+ };
98
+ readonly notices: {
99
+ list(): Promise<readonly NotificationNotice[]>;
100
+ recordShown(input: RecordNotificationNoticeInput): Promise<void>;
101
+ };
102
+ openSettings(): Promise<NotificationSettingsResult>;
103
+ subscribe(listener: (event: NotificationEvent) => void): () => void;
104
+ }
105
+ /** Bridge event envelope; `sequence` is per session and starts at 0. */
106
+ export interface NotificationEventEnvelope {
107
+ readonly protocol: typeof notificationsProtocol;
108
+ readonly sequence: NonNegativeInteger;
109
+ readonly event: NotificationEvent;
110
+ }
111
+ export interface NotificationBridgeProtocolPayload {
112
+ readonly protocol: typeof notificationsProtocol;
113
+ }
114
+ export type NotificationBridgeGetCapabilitiesPayload = NotificationBridgeProtocolPayload;
115
+ export interface NotificationBridgeGetCapabilitiesResult {
116
+ readonly protocolVersion: NonEmptyString;
117
+ readonly provider: NotificationProviderId;
118
+ readonly capabilities: NotificationCapabilities;
119
+ }
120
+ export type NotificationBridgeGetPermissionPayload = NotificationTopicsInput;
121
+ export type NotificationBridgeGetPermissionResult = NotificationPermissionSnapshot;
122
+ export interface NotificationBridgeRequestPermissionPayload {
123
+ readonly topics: readonly NotificationTopicId[] & tags.MinItems<1>;
124
+ }
125
+ export type NotificationBridgeRequestPermissionResult = NotificationPermissionResult;
126
+ export type NotificationBridgeRevokePermissionPayload = NotificationBridgeRequestPermissionPayload;
127
+ export type NotificationBridgeRevokePermissionResult = NotificationPermissionResult;
128
+ export type NotificationBridgeRegisterPayload = NotificationBridgeProtocolPayload;
129
+ export interface NotificationBridgeRegisterResult {
130
+ /** `null` when the provider has no address yet, or none to register. */
131
+ readonly registration: NotificationEndpointRegistration | null;
132
+ }
133
+ export type NotificationBridgeScheduleLocalPayload = LocalNotificationRequest;
134
+ export type NotificationBridgeScheduleLocalResult = LocalScheduleResult;
135
+ export type NotificationBridgeCancelLocalPayload = CancelLocalNotificationsInput;
136
+ export interface NotificationBridgeCancelLocalResult {
137
+ readonly cancelled: boolean;
138
+ }
139
+ export type NotificationBridgeListLocalPayload = NotificationBridgeProtocolPayload;
140
+ export interface NotificationBridgeListLocalResult {
141
+ readonly pending: readonly LocalNotificationEntry[];
142
+ }
143
+ export type NotificationBridgeOpenSettingsPayload = NotificationBridgeProtocolPayload;
144
+ export interface NotificationBridgeOpenSettingsResult {
145
+ readonly status: NotificationSettingsResult;
146
+ }
147
+ export interface NotificationBridgeMethods {
148
+ readonly 'notifications.v2.getCapabilities': {
149
+ readonly payload: NotificationBridgeGetCapabilitiesPayload;
150
+ readonly result: NotificationBridgeGetCapabilitiesResult;
151
+ };
152
+ readonly 'notifications.v2.getPermission': {
153
+ readonly payload: NotificationBridgeGetPermissionPayload;
154
+ readonly result: NotificationBridgeGetPermissionResult;
155
+ };
156
+ readonly 'notifications.v2.requestPermission': {
157
+ readonly payload: NotificationBridgeRequestPermissionPayload;
158
+ readonly result: NotificationBridgeRequestPermissionResult;
159
+ };
160
+ readonly 'notifications.v2.revokePermission': {
161
+ readonly payload: NotificationBridgeRevokePermissionPayload;
162
+ readonly result: NotificationBridgeRevokePermissionResult;
163
+ };
164
+ readonly 'notifications.v2.register': {
165
+ readonly payload: NotificationBridgeRegisterPayload;
166
+ readonly result: NotificationBridgeRegisterResult;
167
+ };
168
+ readonly 'notifications.v2.scheduleLocal': {
169
+ readonly payload: NotificationBridgeScheduleLocalPayload;
170
+ readonly result: NotificationBridgeScheduleLocalResult;
171
+ };
172
+ readonly 'notifications.v2.cancelLocal': {
173
+ readonly payload: NotificationBridgeCancelLocalPayload;
174
+ readonly result: NotificationBridgeCancelLocalResult;
175
+ };
176
+ readonly 'notifications.v2.listLocal': {
177
+ readonly payload: NotificationBridgeListLocalPayload;
178
+ readonly result: NotificationBridgeListLocalResult;
179
+ };
180
+ readonly 'notifications.v2.openSettings': {
181
+ readonly payload: NotificationBridgeOpenSettingsPayload;
182
+ readonly result: NotificationBridgeOpenSettingsResult;
183
+ };
184
+ }
185
+ export type NotificationBridgeMethod = keyof NotificationBridgeMethods;
186
+ export declare const notificationBridgeMethods: readonly ["notifications.v2.getCapabilities", "notifications.v2.getPermission", "notifications.v2.requestPermission", "notifications.v2.revokePermission", "notifications.v2.register", "notifications.v2.scheduleLocal", "notifications.v2.cancelLocal", "notifications.v2.listLocal", "notifications.v2.openSettings"];
187
+ /** A fresh capability block for a provider that has no notification path; callers must not share it. */
188
+ export declare function createUnsupportedNotificationCapabilities(): NotificationCapabilities;
189
+ /** Validates a capability block, including `remote.addressing: 'none'` exactly when `remote.supported` is false. */
190
+ export declare function assertNotificationCapabilities(input: unknown): NotificationCapabilities;
191
+ export declare function isNotificationCapabilities(input: unknown): input is NotificationCapabilities;
192
+ export declare const assertNotificationPermissionSnapshot: (input: unknown) => NotificationPermissionSnapshot;
193
+ export declare const assertNotificationPermissionResult: (input: unknown) => NotificationPermissionResult;
194
+ export declare const isNotificationPermissionResult: (input: unknown) => input is NotificationPermissionResult;
195
+ /** Validates a registration's shape and that `Intl` knows its `timeZone`, which quiet hours read. */
196
+ export declare function assertNotificationEndpointRegistration(input: unknown): NotificationEndpointRegistration;
197
+ /** Validates a local reminder request, including a root-relative `route`. */
198
+ export declare function assertLocalNotificationRequest(input: unknown): LocalNotificationRequest;
199
+ export declare const assertLocalScheduleResult: (input: unknown) => LocalScheduleResult;
200
+ export declare const assertLocalNotificationEntry: (input: unknown) => LocalNotificationEntry;
201
+ /** Validates an event; an `endpoint-changed` registration follows `assertNotificationEndpointRegistration`. */
202
+ export declare function assertNotificationEvent(input: unknown): NotificationEvent;
203
+ export declare function isNotificationEvent(input: unknown): input is NotificationEvent;
204
+ /** Validates an envelope; its event follows `assertNotificationEvent`. */
205
+ export declare function assertNotificationEventEnvelope(input: unknown): NotificationEventEnvelope;
206
+ export declare function isNotificationEventEnvelope(input: unknown): input is NotificationEventEnvelope;
207
+ export declare const assertNotificationConsentRecord: (input: unknown) => NotificationConsentRecord;
208
+ export declare const assertNotificationNotice: (input: unknown) => NotificationNotice;
209
+ /**
210
+ * Validates a `notices.recordShown` input: a listed notice as is, or exactly
211
+ * its name (kind, record kind and time, `dueBy`), with no other key in either
212
+ * form. The time parses strictly with an offset, and `dueBy` is a date that
213
+ * exists.
214
+ */
215
+ export declare const assertRecordNotificationNoticeInput: (input: unknown) => RecordNotificationNoticeInput;
216
+ export declare const assertNotificationDeliveryProviderEntry: (input: unknown) => NotificationDeliveryProviderEntry;
217
+ /** Validates deployment settings, including a `timeZone` that `Intl` knows, which quiet hours read. */
218
+ export declare function assertNotificationDeployment(input: unknown): NotificationDeployment;
219
+ /** Validates a topic definition's shape and the rules of `notificationTopicDefinitionIssues`. */
220
+ export declare function assertNotificationTopicDefinition(input: unknown): NotificationTopicDefinition;
221
+ export declare const assertNotificationBridgeGetCapabilitiesPayload: (input: unknown) => NotificationBridgeProtocolPayload;
222
+ /** Validates a `getCapabilities` answer, whose block follows `assertNotificationCapabilities`. */
223
+ export declare function assertNotificationBridgeGetCapabilitiesResult(input: unknown): NotificationBridgeGetCapabilitiesResult;
224
+ export declare const assertNotificationBridgeGetPermissionPayload: (input: unknown) => NotificationTopicsInput;
225
+ export declare const assertNotificationBridgeGetPermissionResult: (input: unknown) => NotificationPermissionSnapshot;
226
+ export declare const assertNotificationBridgeRequestPermissionPayload: (input: unknown) => NotificationBridgeRequestPermissionPayload;
227
+ export declare const assertNotificationBridgeRequestPermissionResult: (input: unknown) => NotificationPermissionResult;
228
+ export declare const assertNotificationBridgeRevokePermissionPayload: (input: unknown) => NotificationBridgeRequestPermissionPayload;
229
+ export declare const assertNotificationBridgeRevokePermissionResult: (input: unknown) => NotificationPermissionResult;
230
+ export declare const assertNotificationBridgeRegisterPayload: (input: unknown) => NotificationBridgeProtocolPayload;
231
+ /** Validates a `register` answer, whose registration follows `assertNotificationEndpointRegistration`. */
232
+ export declare function assertNotificationBridgeRegisterResult(input: unknown): NotificationBridgeRegisterResult;
233
+ export declare const assertNotificationBridgeScheduleLocalPayload: typeof assertLocalNotificationRequest;
234
+ export declare const assertNotificationBridgeScheduleLocalResult: (input: unknown) => LocalScheduleResult;
235
+ export declare const assertNotificationBridgeCancelLocalPayload: (input: unknown) => CancelLocalNotificationsInput;
236
+ export declare const assertNotificationBridgeCancelLocalResult: (input: unknown) => NotificationBridgeCancelLocalResult;
237
+ export declare const assertNotificationBridgeListLocalPayload: (input: unknown) => NotificationBridgeProtocolPayload;
238
+ export declare const assertNotificationBridgeListLocalResult: (input: unknown) => NotificationBridgeListLocalResult;
239
+ export declare const assertNotificationBridgeOpenSettingsPayload: (input: unknown) => NotificationBridgeProtocolPayload;
240
+ export declare const assertNotificationBridgeOpenSettingsResult: (input: unknown) => NotificationBridgeOpenSettingsResult;
241
+ /**
242
+ * v1 status for a topic's v2 permission state. `unknown` reaches this only when
243
+ * no granted record answered for it, so it is not subscribed.
244
+ */
245
+ export declare function toNotificationSubscriptionStatus(state: NotificationPermissionState): NotificationSubscriptionStatus;
246
+ /** v1 result for a v2 permission outcome; a missing outcome is `unavailable`. */
247
+ export declare function toNotificationSubscriptionResult(outcome: NotificationPermissionOutcome | undefined): NotificationSubscriptionResult;
248
+ /**
249
+ * Serves v1 `NotificationSubscriptionAdapter` callers from the v2 runtime, so
250
+ * reads see backend records (RFC "Migration and PR plan" table).
251
+ *
252
+ * - `catalog` holds the topics resolved for the runtime's target, as the
253
+ * runtime reads them (`resolveNotificationTopicsForTarget` in
254
+ * `@mpgd/catalog`). A v1 topic that is not among them, because the catalog
255
+ * does not declare it or the target does not map it, reads
256
+ * `configuration-required` and requests `unavailable`. So does an entry
257
+ * that still carries a catalog's `targets`, which names no single target.
258
+ * - Reads map a failure whose code is `NOTIFICATIONS_CONFIGURATION_REQUIRED`
259
+ * to `configuration-required`, whether it is a `NotificationError`, another
260
+ * `PlatformOperationError`, or a bridge error with that `code`, and rethrow
261
+ * other failures.
262
+ * - Requests run with `gesture: true`, as v1 callers ask from a player
263
+ * action, and any thrown error answers `unavailable`.
264
+ */
265
+ export declare function toNotificationSubscriptionAdapter(runtime: Pick<NotificationRuntime, 'getPermission' | 'requestPermission'>, catalog: readonly Pick<NotificationTopicDefinition, 'id'>[]): NotificationSubscriptionAdapter;