hotcodepush 0.1.0__py3-none-any.whl
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.
- hotcodepush/__init__.py +183 -0
- hotcodepush/_http.py +314 -0
- hotcodepush/_types.py +15 -0
- hotcodepush/_upload.py +51 -0
- hotcodepush/_version.py +1 -0
- hotcodepush/client.py +81 -0
- hotcodepush/exceptions.py +45 -0
- hotcodepush/models.py +899 -0
- hotcodepush/py.typed +0 -0
- hotcodepush/resources/__init__.py +0 -0
- hotcodepush/resources/_base.py +10 -0
- hotcodepush/resources/apps.py +78 -0
- hotcodepush/resources/audit_logs.py +112 -0
- hotcodepush/resources/binaries.py +84 -0
- hotcodepush/resources/bundle_deltas.py +41 -0
- hotcodepush/resources/bundle_files.py +44 -0
- hotcodepush/resources/bundle_pack.py +54 -0
- hotcodepush/resources/bundle_pack_upload_parts.py +36 -0
- hotcodepush/resources/bundle_pack_uploads.py +65 -0
- hotcodepush/resources/bundles.py +147 -0
- hotcodepush/resources/channel_audience.py +43 -0
- hotcodepush/resources/channel_qr.py +27 -0
- hotcodepush/resources/channel_releases.py +119 -0
- hotcodepush/resources/channels.py +169 -0
- hotcodepush/resources/checkouts.py +26 -0
- hotcodepush/resources/customer_portal_sessions.py +25 -0
- hotcodepush/resources/device_events.py +44 -0
- hotcodepush/resources/devices.py +116 -0
- hotcodepush/resources/file_upload_parts.py +36 -0
- hotcodepush/resources/file_uploads.py +63 -0
- hotcodepush/resources/files.py +53 -0
- hotcodepush/resources/health.py +11 -0
- hotcodepush/resources/invitations.py +50 -0
- hotcodepush/resources/limits.py +20 -0
- hotcodepush/resources/members.py +121 -0
- hotcodepush/resources/notification_preferences.py +51 -0
- hotcodepush/resources/notifications.py +62 -0
- hotcodepush/resources/organization_apps.py +51 -0
- hotcodepush/resources/organization_invitations.py +112 -0
- hotcodepush/resources/organizations.py +110 -0
- hotcodepush/resources/release_audience.py +21 -0
- hotcodepush/resources/releases.py +162 -0
- hotcodepush/resources/rollbacks.py +31 -0
- hotcodepush/resources/signing_keys.py +53 -0
- hotcodepush/resources/sso_provider.py +61 -0
- hotcodepush/resources/sso_provider_verifications.py +27 -0
- hotcodepush/resources/statistics.py +15 -0
- hotcodepush/resources/statistics_fleet.py +17 -0
- hotcodepush/resources/statistics_updates.py +35 -0
- hotcodepush/resources/statistics_usage.py +25 -0
- hotcodepush/resources/subscription.py +53 -0
- hotcodepush/resources/usage.py +66 -0
- hotcodepush/resources/user_password.py +21 -0
- hotcodepush/resources/user_sessions.py +18 -0
- hotcodepush/resources/user_tokens.py +18 -0
- hotcodepush/resources/users.py +46 -0
- hotcodepush/resources/webhook_deliveries.py +91 -0
- hotcodepush/resources/webhooks.py +158 -0
- hotcodepush-0.1.0.dist-info/METADATA +98 -0
- hotcodepush-0.1.0.dist-info/RECORD +62 -0
- hotcodepush-0.1.0.dist-info/WHEEL +4 -0
- hotcodepush-0.1.0.dist-info/licenses/LICENSE +21 -0
hotcodepush/models.py
ADDED
|
@@ -0,0 +1,899 @@
|
|
|
1
|
+
"""The types every resource method takes or returns, derived from the OpenAPI snapshot.
|
|
2
|
+
|
|
3
|
+
Fields are snake_case and read the API's camelCase names; a field the API adds later is kept
|
|
4
|
+
in `model_extra`, so it never breaks a reader. `relations` embeds linked rows as the optional
|
|
5
|
+
fields named after them.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from datetime import date, datetime
|
|
11
|
+
from typing import Annotated, Literal
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
14
|
+
from pydantic.alias_generators import to_camel
|
|
15
|
+
|
|
16
|
+
AppUsageMonthRelation = Literal["app"]
|
|
17
|
+
AuditLogRelation = Literal["app", "user"]
|
|
18
|
+
BundleDeltaRelation = Literal["baseBundle"]
|
|
19
|
+
DeviceRelation = Literal["channel", "currentRelease"]
|
|
20
|
+
FailureAction = Literal["none", "notify", "pause", "revoke"]
|
|
21
|
+
Framework = Literal["capacitor", "cordova", "expo", "react-native"]
|
|
22
|
+
InvitationRelation = Literal["organization"]
|
|
23
|
+
InvitationRole = Literal["admin", "billing", "member"]
|
|
24
|
+
"""A role an invitation grants: any but `owner`, which only a transfer hands over."""
|
|
25
|
+
MemberRelation = Literal["user", "user.accounts"]
|
|
26
|
+
NotificationCategory = Literal[
|
|
27
|
+
"account",
|
|
28
|
+
"billing",
|
|
29
|
+
"lifecycle",
|
|
30
|
+
"newsletter",
|
|
31
|
+
"product_alerts",
|
|
32
|
+
"service_notices",
|
|
33
|
+
"spending_alerts",
|
|
34
|
+
"team_activity",
|
|
35
|
+
]
|
|
36
|
+
NotificationMedium = Literal["email", "in_app"]
|
|
37
|
+
NotificationRelation = Literal["app", "channel", "memberUser", "release"]
|
|
38
|
+
Platform = Literal["android", "ios"]
|
|
39
|
+
ReleaseRelation = Literal["bundle", "channel", "releaseCounters"]
|
|
40
|
+
Role = Literal["admin", "billing", "member", "owner"]
|
|
41
|
+
UserRelation = Literal["accounts", "members", "members.organization"]
|
|
42
|
+
WebhookEvent = Literal[
|
|
43
|
+
"app.created",
|
|
44
|
+
"app.deleted",
|
|
45
|
+
"app.restored",
|
|
46
|
+
"app.transferred",
|
|
47
|
+
"app.updated",
|
|
48
|
+
"binary.created",
|
|
49
|
+
"binary.expired",
|
|
50
|
+
"bundle.deleted",
|
|
51
|
+
"bundle.expired",
|
|
52
|
+
"bundle.uploaded",
|
|
53
|
+
"channel.created",
|
|
54
|
+
"channel.deleted",
|
|
55
|
+
"channel.expired",
|
|
56
|
+
"channel.paused",
|
|
57
|
+
"channel.resumed",
|
|
58
|
+
"channel.updated",
|
|
59
|
+
"device.deleted",
|
|
60
|
+
"invitation.accepted",
|
|
61
|
+
"invitation.created",
|
|
62
|
+
"invitation.revoked",
|
|
63
|
+
"member.joined",
|
|
64
|
+
"member.removed",
|
|
65
|
+
"member.role_changed",
|
|
66
|
+
"organization.deleted",
|
|
67
|
+
"organization.dormancy_noticed",
|
|
68
|
+
"organization.fair_use_warning",
|
|
69
|
+
"organization.restored",
|
|
70
|
+
"organization.spending_cap_changed",
|
|
71
|
+
"organization.spending_cap_reached",
|
|
72
|
+
"organization.spending_cap_warning",
|
|
73
|
+
"organization.storage_limit_reached",
|
|
74
|
+
"organization.storage_limit_warning",
|
|
75
|
+
"organization.updated",
|
|
76
|
+
"release.created",
|
|
77
|
+
"release.failure_rate_exceeded",
|
|
78
|
+
"release.paused",
|
|
79
|
+
"release.resumed",
|
|
80
|
+
"release.revoked",
|
|
81
|
+
"release.rollout_changed",
|
|
82
|
+
"release.updated",
|
|
83
|
+
"signing_key.created",
|
|
84
|
+
"signing_key.deleted",
|
|
85
|
+
"subscription.cancellation_scheduled",
|
|
86
|
+
"subscription.ended",
|
|
87
|
+
"subscription.uncanceled",
|
|
88
|
+
]
|
|
89
|
+
"""An audit type a webhook subscribes to."""
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class HotCodePushModel(BaseModel):
|
|
93
|
+
model_config = ConfigDict(alias_generator=to_camel, extra="allow", populate_by_name=True)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class Account(HotCodePushModel):
|
|
97
|
+
"""A sign-in identity of a user: `credential` for the password, otherwise its provider."""
|
|
98
|
+
|
|
99
|
+
created_at: datetime
|
|
100
|
+
id: str
|
|
101
|
+
provider_id: str
|
|
102
|
+
user_id: str
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class AdoptionPoint(HotCodePushModel):
|
|
106
|
+
"""A moment of a release's adoption curve and the updates confirmed by then."""
|
|
107
|
+
|
|
108
|
+
at: datetime
|
|
109
|
+
confirmed_update_count: int
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class App(HotCodePushModel):
|
|
113
|
+
channel_link_template: str | None
|
|
114
|
+
created_at: datetime
|
|
115
|
+
default_channel_id: str | None
|
|
116
|
+
deleted_at: datetime | None
|
|
117
|
+
framework: Framework
|
|
118
|
+
id: str
|
|
119
|
+
name: str
|
|
120
|
+
next_bundle_number: int
|
|
121
|
+
organization_id: str
|
|
122
|
+
updated_at: datetime
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class AppFile(HotCodePushModel):
|
|
126
|
+
"""A content-addressed file of the app, shared between its bundles."""
|
|
127
|
+
|
|
128
|
+
app_id: str
|
|
129
|
+
created_at: datetime
|
|
130
|
+
sha256: str
|
|
131
|
+
size_bytes: int
|
|
132
|
+
updated_at: datetime
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class AppUsageMonth(HotCodePushModel):
|
|
136
|
+
"""One live app's usage in a month; `app` is set when `relations` names it."""
|
|
137
|
+
|
|
138
|
+
app: NamedEmbed | None = None
|
|
139
|
+
app_id: str
|
|
140
|
+
data_transfer_bytes: int
|
|
141
|
+
month: str
|
|
142
|
+
monthly_active_device_count: int
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class AttributeCondition(HotCodePushModel):
|
|
146
|
+
"""Devices whose attribute `key` holds the value of the SHA-256 `value_sha256`."""
|
|
147
|
+
|
|
148
|
+
key: str
|
|
149
|
+
type: Literal["attribute"] = "attribute"
|
|
150
|
+
value_sha256: str
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Audience(HotCodePushModel):
|
|
154
|
+
"""The channel's active devices, the ones every condition reaches and the estimate at the
|
|
155
|
+
rollout percentage.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
by_binary_version: list[DeviceCount]
|
|
159
|
+
by_platform: list[DeviceCount]
|
|
160
|
+
device_count: int
|
|
161
|
+
estimated_device_count: int
|
|
162
|
+
reached_device_count: int
|
|
163
|
+
warnings: list[AudienceWarning]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class AudienceWarning(HotCodePushModel):
|
|
167
|
+
"""What the release would likely not do, read from the registry and the registered
|
|
168
|
+
binaries.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
code: Literal["FINGERPRINT_UNKNOWN", "UNSUPPORTED_CONDITION_SHARE"]
|
|
172
|
+
details: dict[str, object] | None
|
|
173
|
+
message: str
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class AuditLog(HotCodePushModel):
|
|
177
|
+
"""A row of the audit log: who did what to which object, and when; `app` and `user` are set
|
|
178
|
+
when `relations` names them, while the app or the user is live.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
actor_type: Literal["system", "user"]
|
|
182
|
+
address: str | None
|
|
183
|
+
api_key_id: str | None
|
|
184
|
+
app: NamedEmbed | None = None
|
|
185
|
+
app_id: str | None
|
|
186
|
+
country: str | None
|
|
187
|
+
created_at: datetime
|
|
188
|
+
dispatched_at: datetime | None
|
|
189
|
+
id: str
|
|
190
|
+
object_id: str | None
|
|
191
|
+
organization_id: str | None
|
|
192
|
+
session_id: str | None
|
|
193
|
+
snapshot: dict[str, object]
|
|
194
|
+
type: str
|
|
195
|
+
updated_at: datetime
|
|
196
|
+
user: EmbeddedUser | None = None
|
|
197
|
+
user_agent: str | None
|
|
198
|
+
user_id: str | None
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class Binary(HotCodePushModel):
|
|
202
|
+
"""A store build; the devices running it are the fleet statistics' `binary` buckets."""
|
|
203
|
+
|
|
204
|
+
app_id: str
|
|
205
|
+
build: str
|
|
206
|
+
bundle_id: str
|
|
207
|
+
created_at: datetime
|
|
208
|
+
fingerprint: str | None
|
|
209
|
+
id: str
|
|
210
|
+
platform: Platform
|
|
211
|
+
updated_at: datetime
|
|
212
|
+
version: str
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class BinaryCondition(HotCodePushModel):
|
|
216
|
+
"""Devices whose binary version lies in `range`, `>=2.0.0` say."""
|
|
217
|
+
|
|
218
|
+
range: str
|
|
219
|
+
type: Literal["binary"] = "binary"
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class BinaryCount(HotCodePushModel):
|
|
223
|
+
"""The devices of one binary, `value` its id, named by its platform and version, beside
|
|
224
|
+
their newest report; the value and the names are `None` for the builds no binary records.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
device_count: int
|
|
228
|
+
last_seen_at: datetime
|
|
229
|
+
platform: Platform | None
|
|
230
|
+
value: str | None
|
|
231
|
+
version: str | None
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class Bundle(HotCodePushModel):
|
|
235
|
+
app_id: str
|
|
236
|
+
created_at: datetime
|
|
237
|
+
expires_at: datetime | None
|
|
238
|
+
fingerprint: str | None
|
|
239
|
+
framework: Framework
|
|
240
|
+
git_message: str | None
|
|
241
|
+
git_ref: str | None
|
|
242
|
+
git_remote: str | None
|
|
243
|
+
git_sha: str | None
|
|
244
|
+
id: str
|
|
245
|
+
is_git_dirty: bool | None
|
|
246
|
+
manifest_sha256: str | None
|
|
247
|
+
number: int | None
|
|
248
|
+
platforms: list[Platform]
|
|
249
|
+
signature: str | None
|
|
250
|
+
signature_key_id: str | None
|
|
251
|
+
size_bytes: int
|
|
252
|
+
source: Literal["binary", "upload"]
|
|
253
|
+
status: Literal["ready", "uploading"]
|
|
254
|
+
unused_since: datetime | None
|
|
255
|
+
updated_at: datetime
|
|
256
|
+
version: str
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class BundleDelta(HotCodePushModel):
|
|
260
|
+
"""A delta pack of a bundle against one base, its size and patch count known once built;
|
|
261
|
+
`base_bundle` is set when `relations` names it.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
base_bundle: Bundle | None = None
|
|
265
|
+
base_bundle_id: str
|
|
266
|
+
bundle_id: str
|
|
267
|
+
created_at: datetime
|
|
268
|
+
patch_count: int | None
|
|
269
|
+
requested_at: datetime
|
|
270
|
+
size_bytes: int | None
|
|
271
|
+
status: Literal["built", "failed", "requested"]
|
|
272
|
+
updated_at: datetime
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class BundleFile(HotCodePushModel):
|
|
276
|
+
"""A file a bundle lists; `stored_at` is when the app's store held its hash."""
|
|
277
|
+
|
|
278
|
+
bundle_id: str
|
|
279
|
+
created_at: datetime
|
|
280
|
+
path: str
|
|
281
|
+
sha256: str
|
|
282
|
+
size_bytes: int
|
|
283
|
+
stored_at: datetime | None
|
|
284
|
+
updated_at: datetime
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class BundleSignature(HotCodePushModel):
|
|
288
|
+
"""The signature of a bundle's manifest: the signing key's fingerprint and the value."""
|
|
289
|
+
|
|
290
|
+
key_id: str
|
|
291
|
+
value: str
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class Channel(HotCodePushModel):
|
|
295
|
+
app_id: str
|
|
296
|
+
created_at: datetime
|
|
297
|
+
expires_at: datetime | None
|
|
298
|
+
failure_action: FailureAction | None
|
|
299
|
+
failure_minimum_update_count: int | None
|
|
300
|
+
failure_threshold_percent: int | None
|
|
301
|
+
id: str
|
|
302
|
+
is_discoverable: bool
|
|
303
|
+
is_protected: bool
|
|
304
|
+
name: str
|
|
305
|
+
next_release_number: int
|
|
306
|
+
paused_at: datetime | None
|
|
307
|
+
updated_at: datetime
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class Checkout(HotCodePushModel):
|
|
311
|
+
"""The URL of the Polar checkout to open."""
|
|
312
|
+
|
|
313
|
+
url: str
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class Count(HotCodePushModel):
|
|
317
|
+
"""What every list's `count` answers: the rows the list's filters match."""
|
|
318
|
+
|
|
319
|
+
count: int
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class CustomerPortalSession(HotCodePushModel):
|
|
323
|
+
"""The URL of the Polar customer portal to open."""
|
|
324
|
+
|
|
325
|
+
url: str
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class DailyUpdateCounts(HotCodePushModel):
|
|
329
|
+
"""A day's updates beside the channel's active devices of the day, the adoption rate's
|
|
330
|
+
denominator.
|
|
331
|
+
"""
|
|
332
|
+
|
|
333
|
+
active_device_count: int | None
|
|
334
|
+
confirmed_update_count: int
|
|
335
|
+
day: date
|
|
336
|
+
failure_count: int
|
|
337
|
+
rolled_back_update_count: int
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
class Device(HotCodePushModel):
|
|
341
|
+
"""A device of the registry, the facts of its last report; `channel` and `current_release`
|
|
342
|
+
are set when `relations` names them.
|
|
343
|
+
"""
|
|
344
|
+
|
|
345
|
+
app_id: str
|
|
346
|
+
attributes: dict[str, str]
|
|
347
|
+
binary_build: str
|
|
348
|
+
binary_version: str
|
|
349
|
+
channel: Channel | None = None
|
|
350
|
+
channel_id: str | None
|
|
351
|
+
channel_source: Literal["config", "runtime"]
|
|
352
|
+
country: str | None
|
|
353
|
+
created_at: datetime
|
|
354
|
+
current_release: Release | None = None
|
|
355
|
+
current_release_id: str | None
|
|
356
|
+
device_id: str
|
|
357
|
+
embedded_bundle_id: str | None
|
|
358
|
+
fingerprint: str | None
|
|
359
|
+
last_seen_at: datetime
|
|
360
|
+
os_version: str
|
|
361
|
+
platform: Platform
|
|
362
|
+
sdk_version: str
|
|
363
|
+
updated_at: datetime
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class DeviceCondition(HotCodePushModel):
|
|
367
|
+
"""Devices whose hashed id is one of `hashed_ids`."""
|
|
368
|
+
|
|
369
|
+
hashed_ids: list[str]
|
|
370
|
+
type: Literal["device"] = "device"
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class DeviceCount(HotCodePushModel):
|
|
374
|
+
"""One value of a dimension and the number of devices that report it."""
|
|
375
|
+
|
|
376
|
+
device_count: int
|
|
377
|
+
value: str | None
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class EmbeddedRelease(HotCodePushModel):
|
|
381
|
+
"""The release a notification's `relations` embeds: the id and the number, since a release
|
|
382
|
+
has no name.
|
|
383
|
+
"""
|
|
384
|
+
|
|
385
|
+
id: str
|
|
386
|
+
number: int
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class EmbeddedUser(HotCodePushModel):
|
|
390
|
+
"""A user embedded under another caller's member or audit row: what a colleague is shown;
|
|
391
|
+
`accounts` is set when `relations` names `user.accounts`.
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
accounts: list[Account] | None = None
|
|
395
|
+
created_at: datetime
|
|
396
|
+
email: str
|
|
397
|
+
email_verified: bool
|
|
398
|
+
id: str
|
|
399
|
+
image: str | None
|
|
400
|
+
name: str
|
|
401
|
+
two_factor_enabled: bool
|
|
402
|
+
updated_at: datetime
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
class FingerprintCondition(HotCodePushModel):
|
|
406
|
+
"""Devices whose binary carries the native `fingerprint`."""
|
|
407
|
+
|
|
408
|
+
fingerprint: str
|
|
409
|
+
type: Literal["fingerprint"] = "fingerprint"
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
class FleetStatistics(HotCodePushModel):
|
|
413
|
+
"""The devices seen in the last thirty days: `device_count`, `current_device_count` the ones
|
|
414
|
+
running their channel's newest active release, and their counts per dimension, each the most
|
|
415
|
+
common first.
|
|
416
|
+
"""
|
|
417
|
+
|
|
418
|
+
binary: list[BinaryCount]
|
|
419
|
+
binary_version: list[DeviceCount]
|
|
420
|
+
channel: list[DeviceCount]
|
|
421
|
+
country: list[DeviceCount]
|
|
422
|
+
current_device_count: int
|
|
423
|
+
device_count: int
|
|
424
|
+
os_version: list[OsVersionCount]
|
|
425
|
+
platform: list[DeviceCount]
|
|
426
|
+
release: list[ReleaseCount]
|
|
427
|
+
sdk_version: list[DeviceCount]
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
class Invitation(HotCodePushModel):
|
|
431
|
+
"""An invitation to an organization; `organization` is set on the caller's own invitations
|
|
432
|
+
when `relations` names it.
|
|
433
|
+
"""
|
|
434
|
+
|
|
435
|
+
created_at: datetime
|
|
436
|
+
email: str
|
|
437
|
+
expires_at: datetime
|
|
438
|
+
id: str
|
|
439
|
+
inviter_id: str
|
|
440
|
+
organization: NamedEmbed | None = None
|
|
441
|
+
organization_id: str
|
|
442
|
+
role: InvitationRole
|
|
443
|
+
status: Literal["accepted", "canceled", "pending", "rejected"]
|
|
444
|
+
updated_at: datetime
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
class Limit(HotCodePushModel):
|
|
448
|
+
"""A limit in effect: its value, the plan's default and whether the value overrides it."""
|
|
449
|
+
|
|
450
|
+
default: int
|
|
451
|
+
is_overridden: bool
|
|
452
|
+
value: int
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
class ManifestFile(HotCodePushModel):
|
|
456
|
+
"""A file of a bundle's manifest: its path, the SHA-256 of its content and its size."""
|
|
457
|
+
|
|
458
|
+
path: str
|
|
459
|
+
sha256: str
|
|
460
|
+
size_bytes: int
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class Member(HotCodePushModel):
|
|
464
|
+
"""A member of an organization; `organization` and `user` are set when `relations` names
|
|
465
|
+
them.
|
|
466
|
+
"""
|
|
467
|
+
|
|
468
|
+
created_at: datetime
|
|
469
|
+
id: str
|
|
470
|
+
last_seen_at: datetime | None
|
|
471
|
+
organization: Organization | None = None
|
|
472
|
+
organization_id: str
|
|
473
|
+
role: Role
|
|
474
|
+
updated_at: datetime
|
|
475
|
+
user: EmbeddedUser | None = None
|
|
476
|
+
user_id: str
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
class MultipartUpload(HotCodePushModel):
|
|
480
|
+
upload_id: str
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
class NamedEmbed(HotCodePushModel):
|
|
484
|
+
"""A row another row embeds through `relations`, its id and its name alone: an app, an
|
|
485
|
+
organization, a channel or a member user.
|
|
486
|
+
"""
|
|
487
|
+
|
|
488
|
+
id: str
|
|
489
|
+
name: str
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
class Notification(HotCodePushModel):
|
|
493
|
+
"""An in-app notification of the caller, its `organization_id` `None` for one about the
|
|
494
|
+
account; `app`, `channel`, `member_user` and `release` are set when `relations` names them,
|
|
495
|
+
`None` once the row is deleted.
|
|
496
|
+
"""
|
|
497
|
+
|
|
498
|
+
app: NamedEmbed | None = None
|
|
499
|
+
app_id: str | None
|
|
500
|
+
channel: NamedEmbed | None = None
|
|
501
|
+
channel_id: str | None
|
|
502
|
+
created_at: datetime
|
|
503
|
+
id: str
|
|
504
|
+
member_user: NamedEmbed | None = None
|
|
505
|
+
member_user_id: str | None
|
|
506
|
+
organization_id: str | None
|
|
507
|
+
read_at: datetime | None
|
|
508
|
+
release: EmbeddedRelease | None = None
|
|
509
|
+
release_id: str | None
|
|
510
|
+
type: str
|
|
511
|
+
updated_at: datetime
|
|
512
|
+
user_id: str
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
class NotificationPreference(HotCodePushModel):
|
|
516
|
+
"""Whether the caller receives one category's notifications through one medium, for the
|
|
517
|
+
account or, with `organization_id`, for one membership.
|
|
518
|
+
"""
|
|
519
|
+
|
|
520
|
+
category: NotificationCategory
|
|
521
|
+
is_enabled: bool
|
|
522
|
+
medium: NotificationMedium
|
|
523
|
+
organization_id: str | None
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
class OidcConfig(HotCodePushModel):
|
|
527
|
+
"""The OpenID Connect provider of an organization's SSO; a field left `None` is not sent."""
|
|
528
|
+
|
|
529
|
+
client_id: str
|
|
530
|
+
client_secret: str
|
|
531
|
+
discovery_endpoint: str | None = None
|
|
532
|
+
issuer: str
|
|
533
|
+
scopes: list[str] | None = None
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
class Organization(HotCodePushModel):
|
|
537
|
+
app_count_limit: int | None
|
|
538
|
+
capped_at: datetime | None
|
|
539
|
+
channel_count_per_app_limit: int | None
|
|
540
|
+
country_allowlist: list[str] | None
|
|
541
|
+
created_at: datetime
|
|
542
|
+
current_period_ends_at: datetime | None
|
|
543
|
+
data_transfer_bytes_per_monthly_active_device_limit: int | None
|
|
544
|
+
deleted_at: datetime | None
|
|
545
|
+
enterprise_monthly_active_device_count_limit: int | None
|
|
546
|
+
file_count_per_bundle_limit: int | None
|
|
547
|
+
final_period_ends_at: datetime | None
|
|
548
|
+
id: str
|
|
549
|
+
ip_allowlist: list[str] | None
|
|
550
|
+
is_two_factor_required: bool
|
|
551
|
+
last_spending_cap_reached_sent_at: datetime | None
|
|
552
|
+
last_spending_cap_warning_sent_at: datetime | None
|
|
553
|
+
last_storage_limit_reached_sent_at: datetime | None
|
|
554
|
+
last_storage_warning_sent_at: datetime | None
|
|
555
|
+
member_count_limit: int | None
|
|
556
|
+
name: str
|
|
557
|
+
past_due_at: datetime | None
|
|
558
|
+
plan: Literal["enterprise", "free", "pay_as_you_go"]
|
|
559
|
+
region: str
|
|
560
|
+
release_count_per_app_per_day_limit: int | None
|
|
561
|
+
reported_billable_device_count: int
|
|
562
|
+
reported_billable_device_count_hour: datetime | None
|
|
563
|
+
reported_billable_device_count_month: date | None
|
|
564
|
+
retention_days: int | None
|
|
565
|
+
spending_cap_cents: int
|
|
566
|
+
storage_bytes: int
|
|
567
|
+
storage_bytes_limit: int | None
|
|
568
|
+
subscription_provider: Literal["polar"] | None
|
|
569
|
+
subscription_status: str | None
|
|
570
|
+
unsent_billable_device_count: int
|
|
571
|
+
updated_at: datetime
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
class OsCondition(HotCodePushModel):
|
|
575
|
+
"""Devices whose operating system version lies in `range`, `>=17` say."""
|
|
576
|
+
|
|
577
|
+
range: str
|
|
578
|
+
type: Literal["os"] = "os"
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
class OsVersionCount(HotCodePushModel):
|
|
582
|
+
"""The devices of one version of one platform's operating system."""
|
|
583
|
+
|
|
584
|
+
device_count: int
|
|
585
|
+
platform: Platform
|
|
586
|
+
value: str | None
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
class ReasonCount(HotCodePushModel):
|
|
590
|
+
"""A reason the devices reported and the number of events that gave it."""
|
|
591
|
+
|
|
592
|
+
event_count: int
|
|
593
|
+
reason: str
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
class Release(HotCodePushModel):
|
|
597
|
+
"""A release of a bundle in a channel; `bundle`, `channel` and `release_counters` are set
|
|
598
|
+
when `relations` names them.
|
|
599
|
+
"""
|
|
600
|
+
|
|
601
|
+
auto_paused_at: datetime | None
|
|
602
|
+
bundle: Bundle | None = None
|
|
603
|
+
bundle_id: str
|
|
604
|
+
channel: Channel | None = None
|
|
605
|
+
channel_id: str
|
|
606
|
+
conditions: list[ReleaseCondition]
|
|
607
|
+
created_at: datetime
|
|
608
|
+
created_from_release_id: str | None
|
|
609
|
+
failure_action: FailureAction | None
|
|
610
|
+
failure_minimum_update_count: int | None
|
|
611
|
+
failure_notified_at: datetime | None
|
|
612
|
+
failure_threshold_percent: int | None
|
|
613
|
+
id: str
|
|
614
|
+
is_mandatory: bool
|
|
615
|
+
live_at: datetime | None
|
|
616
|
+
notes: str | None
|
|
617
|
+
number: int
|
|
618
|
+
paused_at: datetime | None
|
|
619
|
+
progression: ReleaseProgression | None
|
|
620
|
+
progression_step_started_at: datetime | None
|
|
621
|
+
purged_at: datetime | None
|
|
622
|
+
release_counters: ReleaseCounters | None = None
|
|
623
|
+
rolled_back_from_release_id: str | None
|
|
624
|
+
rollout_percentage: int
|
|
625
|
+
status: Literal["active", "paused", "revoked"]
|
|
626
|
+
step_start_applied_update_count: int
|
|
627
|
+
updated_at: datetime
|
|
628
|
+
window_start_applied_update_count: int
|
|
629
|
+
window_start_failure_count: int
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
class ReleaseAdoption(HotCodePushModel):
|
|
633
|
+
"""A live release's adoption curve since it went live, with the moments it reached half and
|
|
634
|
+
nine tenths of the channel's active devices.
|
|
635
|
+
"""
|
|
636
|
+
|
|
637
|
+
adoption: list[AdoptionPoint]
|
|
638
|
+
channel_id: str
|
|
639
|
+
live_at: datetime
|
|
640
|
+
number: int
|
|
641
|
+
release_id: str
|
|
642
|
+
time_to_adoption: TimeToAdoption
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
class ReleaseCount(HotCodePushModel):
|
|
646
|
+
"""The devices of one release, `value` its id, named by its number and its channel; all
|
|
647
|
+
three are `None` for the embedded bundles.
|
|
648
|
+
"""
|
|
649
|
+
|
|
650
|
+
channel_id: str | None
|
|
651
|
+
device_count: int
|
|
652
|
+
number: int | None
|
|
653
|
+
value: str | None
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
class ReleaseCounters(HotCodePushModel):
|
|
657
|
+
applied_update_count: int
|
|
658
|
+
confirmed_update_count: int
|
|
659
|
+
crash_failure_count: int
|
|
660
|
+
created_at: datetime
|
|
661
|
+
download_failure_count: int
|
|
662
|
+
readiness_timeout_failure_count: int
|
|
663
|
+
release_id: str
|
|
664
|
+
reported_failure_count: int
|
|
665
|
+
updated_at: datetime
|
|
666
|
+
verification_failure_count: int
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class ReleaseDeviceEvent(HotCodePushModel):
|
|
670
|
+
"""A device's first event of each type on a release, with the reason a failure gave."""
|
|
671
|
+
|
|
672
|
+
created_at: datetime
|
|
673
|
+
device_id: str
|
|
674
|
+
reason: str | None
|
|
675
|
+
release_id: str
|
|
676
|
+
type: Literal["applied", "checked", "confirmed", "failed"]
|
|
677
|
+
updated_at: datetime
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
class ReleaseProgression(HotCodePushModel):
|
|
681
|
+
"""The schedule that raises a release's rollout through `percentages`, a step at a time."""
|
|
682
|
+
|
|
683
|
+
percentages: list[int]
|
|
684
|
+
step_minimum_seconds: int
|
|
685
|
+
step_minimum_update_count: int
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
class SamlConfig(HotCodePushModel):
|
|
689
|
+
"""The SAML provider of an organization's SSO: its `metadata`, or its `cert` with its
|
|
690
|
+
`entity_id`; a field left `None` is not sent.
|
|
691
|
+
"""
|
|
692
|
+
|
|
693
|
+
cert: str | None = None
|
|
694
|
+
entity_id: str | None = None
|
|
695
|
+
entry_point: str
|
|
696
|
+
issuer: str
|
|
697
|
+
metadata: str | None = None
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
class SigningKey(HotCodePushModel):
|
|
701
|
+
"""A public key the app's bundles are verified against; its `fingerprint` is the `key_id` a
|
|
702
|
+
signature names.
|
|
703
|
+
"""
|
|
704
|
+
|
|
705
|
+
app_id: str
|
|
706
|
+
created_at: datetime
|
|
707
|
+
fingerprint: str
|
|
708
|
+
id: str
|
|
709
|
+
public_key: str
|
|
710
|
+
updated_at: datetime
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
class SsoProvider(HotCodePushModel):
|
|
714
|
+
"""An organization's SSO provider: the domain, and the token its TXT record
|
|
715
|
+
`_hotcodepush-sso-{providerId}.{domain}` carries until `domain_verified`; the configs are
|
|
716
|
+
write-only.
|
|
717
|
+
"""
|
|
718
|
+
|
|
719
|
+
created_at: datetime
|
|
720
|
+
domain: str
|
|
721
|
+
domain_verification_token: str | None
|
|
722
|
+
domain_verified: bool
|
|
723
|
+
id: str
|
|
724
|
+
issuer: str
|
|
725
|
+
organization_id: str
|
|
726
|
+
provider_id: str
|
|
727
|
+
type: Literal["oidc", "saml"]
|
|
728
|
+
updated_at: datetime
|
|
729
|
+
user_id: str | None
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
class TimeToAdoption(HotCodePushModel):
|
|
733
|
+
"""When a release reached half and nine tenths of the channel's active devices; `None` until
|
|
734
|
+
it does.
|
|
735
|
+
"""
|
|
736
|
+
|
|
737
|
+
percent50_at: datetime | None
|
|
738
|
+
percent90_at: datetime | None
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
class UpdateStatistics(HotCodePushModel):
|
|
742
|
+
"""The updates per day of the period, the adoption curves of the newest live releases and
|
|
743
|
+
the reasons the devices reported.
|
|
744
|
+
"""
|
|
745
|
+
|
|
746
|
+
days: list[DailyUpdateCounts]
|
|
747
|
+
failure_reasons: list[ReasonCount]
|
|
748
|
+
releases: list[ReleaseAdoption]
|
|
749
|
+
skipped_reasons: list[ReasonCount]
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
class UploadedBundlePack(HotCodePushModel):
|
|
753
|
+
size_bytes: int
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
class UploadedPart(HotCodePushModel):
|
|
757
|
+
"""A part of a multipart upload; its `etag` and `part_number` complete the upload."""
|
|
758
|
+
|
|
759
|
+
etag: str
|
|
760
|
+
part_number: int
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
class Usage(HotCodePushModel):
|
|
764
|
+
"""An organization's monthly active devices and data transfer in `month`, `YYYY-MM`, summed
|
|
765
|
+
over its apps' rows.
|
|
766
|
+
"""
|
|
767
|
+
|
|
768
|
+
data_transfer_bytes: int
|
|
769
|
+
month: str
|
|
770
|
+
monthly_active_device_count: int
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
class UsageDay(HotCodePushModel):
|
|
774
|
+
"""A day's checks and data transfer, beside the bytes the devices reported downloading."""
|
|
775
|
+
|
|
776
|
+
check_count: int
|
|
777
|
+
data_transfer_bytes: int
|
|
778
|
+
day: date
|
|
779
|
+
device_download_bytes: int
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
class UsageMonth(HotCodePushModel):
|
|
783
|
+
"""A month's monthly active devices and data transfer, the numbers the invoice shows."""
|
|
784
|
+
|
|
785
|
+
data_transfer_bytes: int
|
|
786
|
+
month: date
|
|
787
|
+
monthly_active_device_count: int
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
class UsageStatistics(HotCodePushModel):
|
|
791
|
+
"""The monthly active devices and data transfer per month the period touches, and the
|
|
792
|
+
checks, data transfer and device downloads per day.
|
|
793
|
+
"""
|
|
794
|
+
|
|
795
|
+
days: list[UsageDay]
|
|
796
|
+
months: list[UsageMonth]
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
class User(HotCodePushModel):
|
|
800
|
+
"""The caller; `accounts` and `members` are set when `relations` names them."""
|
|
801
|
+
|
|
802
|
+
accounts: list[Account] | None = None
|
|
803
|
+
banned_at: datetime | None
|
|
804
|
+
created_at: datetime
|
|
805
|
+
deleted_at: datetime | None
|
|
806
|
+
discovery_source: (
|
|
807
|
+
Literal[
|
|
808
|
+
"ai_assistant",
|
|
809
|
+
"blog_or_article",
|
|
810
|
+
"friend_or_colleague",
|
|
811
|
+
"github",
|
|
812
|
+
"linkedin",
|
|
813
|
+
"other",
|
|
814
|
+
"reddit",
|
|
815
|
+
"search_engine",
|
|
816
|
+
"x_twitter",
|
|
817
|
+
"youtube",
|
|
818
|
+
]
|
|
819
|
+
| None
|
|
820
|
+
)
|
|
821
|
+
email: str
|
|
822
|
+
email_verified: bool
|
|
823
|
+
id: str
|
|
824
|
+
image: str | None
|
|
825
|
+
intended_framework: Literal["capacitor", "cordova", "expo", "react_native", "unsure"] | None
|
|
826
|
+
job_role: (
|
|
827
|
+
Literal[
|
|
828
|
+
"cto_or_founder",
|
|
829
|
+
"developer",
|
|
830
|
+
"freelancer_or_agency",
|
|
831
|
+
"manager_or_lead",
|
|
832
|
+
"other",
|
|
833
|
+
"student_or_hobbyist",
|
|
834
|
+
]
|
|
835
|
+
| None
|
|
836
|
+
)
|
|
837
|
+
last_seen_at: datetime
|
|
838
|
+
locale: str | None
|
|
839
|
+
members: list[Member] | None = None
|
|
840
|
+
name: str
|
|
841
|
+
time_format: Literal["12h", "24h"] | None
|
|
842
|
+
time_zone: str | None
|
|
843
|
+
two_factor_enabled: bool
|
|
844
|
+
updated_at: datetime
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
class Webhook(HotCodePushModel):
|
|
848
|
+
"""An outbound webhook: the `format`, `raw` for the JSON payload or `slack`, `discord` or
|
|
849
|
+
`teams` for a chat message, the subscribed audit `events`, the app filter, `None` for every
|
|
850
|
+
app's events and the organization's, and `is_enabled`, off after fifty consecutive failed
|
|
851
|
+
deliveries.
|
|
852
|
+
"""
|
|
853
|
+
|
|
854
|
+
app_id: str | None
|
|
855
|
+
consecutive_failure_count: int
|
|
856
|
+
created_at: datetime
|
|
857
|
+
events: list[str]
|
|
858
|
+
format: Literal["discord", "raw", "slack", "teams"]
|
|
859
|
+
id: str
|
|
860
|
+
is_enabled: bool
|
|
861
|
+
name: str
|
|
862
|
+
organization_id: str
|
|
863
|
+
updated_at: datetime
|
|
864
|
+
url: str
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
# Out of the alphabetical order: a subclass follows its base.
|
|
868
|
+
class CreatedWebhook(Webhook):
|
|
869
|
+
"""A created webhook with its signing `secret`, answered this once; `None` for a chat
|
|
870
|
+
format, whose URL carries the token.
|
|
871
|
+
"""
|
|
872
|
+
|
|
873
|
+
secret: str | None
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
class WebhookDelivery(HotCodePushModel):
|
|
877
|
+
"""One event sent to a webhook with its attempts: the `type`, the audit type or
|
|
878
|
+
`webhook.test`, the receiver's last `response_code` and `response_body`, cut at 4,096
|
|
879
|
+
characters, and `next_attempt_at` while the queue retries it.
|
|
880
|
+
"""
|
|
881
|
+
|
|
882
|
+
attempt_count: int
|
|
883
|
+
audit_row_id: str | None
|
|
884
|
+
created_at: datetime
|
|
885
|
+
id: str
|
|
886
|
+
next_attempt_at: datetime | None
|
|
887
|
+
response_body: str | None
|
|
888
|
+
response_code: int | None
|
|
889
|
+
status: Literal["failed", "pending", "succeeded"]
|
|
890
|
+
type: str
|
|
891
|
+
updated_at: datetime
|
|
892
|
+
webhook_id: str
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
ReleaseCondition = Annotated[
|
|
896
|
+
AttributeCondition | BinaryCondition | DeviceCondition | FingerprintCondition | OsCondition,
|
|
897
|
+
Field(discriminator="type"),
|
|
898
|
+
]
|
|
899
|
+
"""A condition a device meets to receive a release."""
|