ai-dev-browser 0.5.3__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.
Files changed (155) hide show
  1. ai_dev_browser/__init__.py +110 -0
  2. ai_dev_browser/_cli.py +428 -0
  3. ai_dev_browser/_version.py +13 -0
  4. ai_dev_browser/cdp/__init__.py +6 -0
  5. ai_dev_browser/cdp/accessibility.py +668 -0
  6. ai_dev_browser/cdp/animation.py +494 -0
  7. ai_dev_browser/cdp/audits.py +1990 -0
  8. ai_dev_browser/cdp/autofill.py +292 -0
  9. ai_dev_browser/cdp/background_service.py +215 -0
  10. ai_dev_browser/cdp/bluetooth_emulation.py +626 -0
  11. ai_dev_browser/cdp/browser.py +821 -0
  12. ai_dev_browser/cdp/cache_storage.py +311 -0
  13. ai_dev_browser/cdp/cast.py +172 -0
  14. ai_dev_browser/cdp/console.py +107 -0
  15. ai_dev_browser/cdp/crash_report_context.py +55 -0
  16. ai_dev_browser/cdp/css.py +2710 -0
  17. ai_dev_browser/cdp/debugger.py +1405 -0
  18. ai_dev_browser/cdp/device_access.py +141 -0
  19. ai_dev_browser/cdp/device_orientation.py +45 -0
  20. ai_dev_browser/cdp/dom.py +2257 -0
  21. ai_dev_browser/cdp/dom_debugger.py +321 -0
  22. ai_dev_browser/cdp/dom_snapshot.py +876 -0
  23. ai_dev_browser/cdp/dom_storage.py +222 -0
  24. ai_dev_browser/cdp/emulation.py +1779 -0
  25. ai_dev_browser/cdp/event_breakpoints.py +56 -0
  26. ai_dev_browser/cdp/extensions.py +246 -0
  27. ai_dev_browser/cdp/fed_cm.py +283 -0
  28. ai_dev_browser/cdp/fetch.py +507 -0
  29. ai_dev_browser/cdp/file_system.py +115 -0
  30. ai_dev_browser/cdp/headless_experimental.py +115 -0
  31. ai_dev_browser/cdp/heap_profiler.py +401 -0
  32. ai_dev_browser/cdp/indexed_db.py +528 -0
  33. ai_dev_browser/cdp/input_.py +701 -0
  34. ai_dev_browser/cdp/inspector.py +95 -0
  35. ai_dev_browser/cdp/io.py +101 -0
  36. ai_dev_browser/cdp/layer_tree.py +464 -0
  37. ai_dev_browser/cdp/log.py +190 -0
  38. ai_dev_browser/cdp/media.py +313 -0
  39. ai_dev_browser/cdp/memory.py +305 -0
  40. ai_dev_browser/cdp/network.py +5317 -0
  41. ai_dev_browser/cdp/overlay.py +1468 -0
  42. ai_dev_browser/cdp/page.py +3970 -0
  43. ai_dev_browser/cdp/performance.py +124 -0
  44. ai_dev_browser/cdp/performance_timeline.py +200 -0
  45. ai_dev_browser/cdp/preload.py +575 -0
  46. ai_dev_browser/cdp/profiler.py +420 -0
  47. ai_dev_browser/cdp/pwa.py +278 -0
  48. ai_dev_browser/cdp/py.typed +0 -0
  49. ai_dev_browser/cdp/runtime.py +1589 -0
  50. ai_dev_browser/cdp/schema.py +50 -0
  51. ai_dev_browser/cdp/security.py +518 -0
  52. ai_dev_browser/cdp/service_worker.py +401 -0
  53. ai_dev_browser/cdp/smart_card_emulation.py +891 -0
  54. ai_dev_browser/cdp/storage.py +1573 -0
  55. ai_dev_browser/cdp/system_info.py +327 -0
  56. ai_dev_browser/cdp/target.py +822 -0
  57. ai_dev_browser/cdp/tethering.py +65 -0
  58. ai_dev_browser/cdp/tracing.py +377 -0
  59. ai_dev_browser/cdp/util.py +17 -0
  60. ai_dev_browser/cdp/web_audio.py +606 -0
  61. ai_dev_browser/cdp/web_authn.py +598 -0
  62. ai_dev_browser/cdp/web_mcp.py +219 -0
  63. ai_dev_browser/core/__init__.py +218 -0
  64. ai_dev_browser/core/_case.py +38 -0
  65. ai_dev_browser/core/_cf_template.py +84 -0
  66. ai_dev_browser/core/_element.py +431 -0
  67. ai_dev_browser/core/_tab.py +817 -0
  68. ai_dev_browser/core/_transport.py +362 -0
  69. ai_dev_browser/core/ax.py +605 -0
  70. ai_dev_browser/core/browser.py +323 -0
  71. ai_dev_browser/core/cdp.py +66 -0
  72. ai_dev_browser/core/chrome.py +253 -0
  73. ai_dev_browser/core/cloudflare.py +77 -0
  74. ai_dev_browser/core/config.py +95 -0
  75. ai_dev_browser/core/connection.py +403 -0
  76. ai_dev_browser/core/cookies.py +103 -0
  77. ai_dev_browser/core/dialog.py +165 -0
  78. ai_dev_browser/core/download.py +38 -0
  79. ai_dev_browser/core/elements.py +913 -0
  80. ai_dev_browser/core/human.py +612 -0
  81. ai_dev_browser/core/login.py +122 -0
  82. ai_dev_browser/core/mouse.py +140 -0
  83. ai_dev_browser/core/navigation.py +225 -0
  84. ai_dev_browser/core/overlays.py +148 -0
  85. ai_dev_browser/core/page.py +302 -0
  86. ai_dev_browser/core/port.py +465 -0
  87. ai_dev_browser/core/process.py +114 -0
  88. ai_dev_browser/core/snapshot.py +425 -0
  89. ai_dev_browser/core/storage.py +50 -0
  90. ai_dev_browser/core/tabs.py +125 -0
  91. ai_dev_browser/core/text_match.py +217 -0
  92. ai_dev_browser/core/window.py +84 -0
  93. ai_dev_browser/pool/__init__.py +34 -0
  94. ai_dev_browser/pool/job.py +140 -0
  95. ai_dev_browser/pool/persistence.py +154 -0
  96. ai_dev_browser/pool/pool.py +873 -0
  97. ai_dev_browser/pool/worker.py +171 -0
  98. ai_dev_browser/profile.py +107 -0
  99. ai_dev_browser/py.typed +0 -0
  100. ai_dev_browser/tools/__init__.py +9 -0
  101. ai_dev_browser/tools/_generate.py +209 -0
  102. ai_dev_browser/tools/browser_list.py +14 -0
  103. ai_dev_browser/tools/browser_start.py +14 -0
  104. ai_dev_browser/tools/browser_stop.py +14 -0
  105. ai_dev_browser/tools/cdp_send.py +14 -0
  106. ai_dev_browser/tools/click_by_html_id.py +14 -0
  107. ai_dev_browser/tools/click_by_ref.py +14 -0
  108. ai_dev_browser/tools/click_by_text.py +14 -0
  109. ai_dev_browser/tools/click_by_xpath.py +14 -0
  110. ai_dev_browser/tools/cloudflare_verify.py +14 -0
  111. ai_dev_browser/tools/cookies_list.py +14 -0
  112. ai_dev_browser/tools/cookies_load.py +14 -0
  113. ai_dev_browser/tools/cookies_save.py +14 -0
  114. ai_dev_browser/tools/dialog_respond.py +14 -0
  115. ai_dev_browser/tools/download.py +14 -0
  116. ai_dev_browser/tools/drag_by_ref.py +14 -0
  117. ai_dev_browser/tools/find_by_html_id.py +14 -0
  118. ai_dev_browser/tools/find_by_xpath.py +14 -0
  119. ai_dev_browser/tools/focus_by_ref.py +14 -0
  120. ai_dev_browser/tools/highlight_by_ref.py +14 -0
  121. ai_dev_browser/tools/hover_by_ref.py +14 -0
  122. ai_dev_browser/tools/html_by_ref.py +14 -0
  123. ai_dev_browser/tools/js_evaluate.py +14 -0
  124. ai_dev_browser/tools/login_interactive.py +14 -0
  125. ai_dev_browser/tools/mouse_click.py +14 -0
  126. ai_dev_browser/tools/mouse_drag.py +14 -0
  127. ai_dev_browser/tools/mouse_move.py +14 -0
  128. ai_dev_browser/tools/page_discover.py +14 -0
  129. ai_dev_browser/tools/page_emulate_focus.py +14 -0
  130. ai_dev_browser/tools/page_goto.py +14 -0
  131. ai_dev_browser/tools/page_html.py +14 -0
  132. ai_dev_browser/tools/page_info.py +14 -0
  133. ai_dev_browser/tools/page_reload.py +14 -0
  134. ai_dev_browser/tools/page_screenshot.py +14 -0
  135. ai_dev_browser/tools/page_scroll.py +14 -0
  136. ai_dev_browser/tools/page_wait_element.py +14 -0
  137. ai_dev_browser/tools/page_wait_ready.py +14 -0
  138. ai_dev_browser/tools/page_wait_url.py +14 -0
  139. ai_dev_browser/tools/screenshot_by_ref.py +14 -0
  140. ai_dev_browser/tools/select_by_ref.py +14 -0
  141. ai_dev_browser/tools/storage_get.py +14 -0
  142. ai_dev_browser/tools/storage_set.py +14 -0
  143. ai_dev_browser/tools/tab_close.py +14 -0
  144. ai_dev_browser/tools/tab_list.py +14 -0
  145. ai_dev_browser/tools/tab_new.py +14 -0
  146. ai_dev_browser/tools/tab_switch.py +14 -0
  147. ai_dev_browser/tools/type_by_ref.py +14 -0
  148. ai_dev_browser/tools/type_by_text.py +14 -0
  149. ai_dev_browser/tools/upload_by_ref.py +14 -0
  150. ai_dev_browser/tools/window_set.py +14 -0
  151. ai_dev_browser-0.5.3.dist-info/METADATA +177 -0
  152. ai_dev_browser-0.5.3.dist-info/RECORD +155 -0
  153. ai_dev_browser-0.5.3.dist-info/WHEEL +5 -0
  154. ai_dev_browser-0.5.3.dist-info/licenses/LICENSE +25 -0
  155. ai_dev_browser-0.5.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,401 @@
1
+ # DO NOT EDIT THIS FILE!
2
+ #
3
+ # This file is generated from the CDP specification. If you need to make
4
+ # changes, edit the generator and regenerate all of the modules.
5
+ #
6
+ # CDP domain: ServiceWorker (experimental)
7
+
8
+ from __future__ import annotations
9
+ import enum
10
+ import typing
11
+ from dataclasses import dataclass
12
+ from .util import event_class, T_JSON_DICT
13
+
14
+ from . import target
15
+
16
+
17
+ class RegistrationID(str):
18
+ def to_json(self) -> str:
19
+ return self
20
+
21
+ @classmethod
22
+ def from_json(cls, json: str) -> RegistrationID:
23
+ return cls(json)
24
+
25
+ def __repr__(self):
26
+ return 'RegistrationID({})'.format(super().__repr__())
27
+
28
+
29
+ @dataclass
30
+ class ServiceWorkerRegistration:
31
+ '''
32
+ ServiceWorker registration.
33
+ '''
34
+ registration_id: RegistrationID
35
+
36
+ scope_url: str
37
+
38
+ is_deleted: bool
39
+
40
+ def to_json(self) -> T_JSON_DICT:
41
+ json: T_JSON_DICT = dict()
42
+ json['registrationId'] = self.registration_id.to_json()
43
+ json['scopeURL'] = self.scope_url
44
+ json['isDeleted'] = self.is_deleted
45
+ return json
46
+
47
+ @classmethod
48
+ def from_json(cls, json: T_JSON_DICT) -> ServiceWorkerRegistration:
49
+ return cls(
50
+ registration_id=RegistrationID.from_json(json['registrationId']),
51
+ scope_url=str(json['scopeURL']),
52
+ is_deleted=bool(json['isDeleted']),
53
+ )
54
+
55
+
56
+ class ServiceWorkerVersionRunningStatus(enum.Enum):
57
+ STOPPED = "stopped"
58
+ STARTING = "starting"
59
+ RUNNING = "running"
60
+ STOPPING = "stopping"
61
+
62
+ def to_json(self) -> str:
63
+ return self.value
64
+
65
+ @classmethod
66
+ def from_json(cls, json: str) -> ServiceWorkerVersionRunningStatus:
67
+ return cls(json)
68
+
69
+
70
+ class ServiceWorkerVersionStatus(enum.Enum):
71
+ NEW = "new"
72
+ INSTALLING = "installing"
73
+ INSTALLED = "installed"
74
+ ACTIVATING = "activating"
75
+ ACTIVATED = "activated"
76
+ REDUNDANT = "redundant"
77
+
78
+ def to_json(self) -> str:
79
+ return self.value
80
+
81
+ @classmethod
82
+ def from_json(cls, json: str) -> ServiceWorkerVersionStatus:
83
+ return cls(json)
84
+
85
+
86
+ @dataclass
87
+ class ServiceWorkerVersion:
88
+ '''
89
+ ServiceWorker version.
90
+ '''
91
+ version_id: str
92
+
93
+ registration_id: RegistrationID
94
+
95
+ script_url: str
96
+
97
+ running_status: ServiceWorkerVersionRunningStatus
98
+
99
+ status: ServiceWorkerVersionStatus
100
+
101
+ #: The Last-Modified header value of the main script.
102
+ script_last_modified: typing.Optional[float] = None
103
+
104
+ #: The time at which the response headers of the main script were received from the server.
105
+ #: For cached script it is the last time the cache entry was validated.
106
+ script_response_time: typing.Optional[float] = None
107
+
108
+ controlled_clients: typing.Optional[typing.List[target.TargetID]] = None
109
+
110
+ target_id: typing.Optional[target.TargetID] = None
111
+
112
+ router_rules: typing.Optional[str] = None
113
+
114
+ def to_json(self) -> T_JSON_DICT:
115
+ json: T_JSON_DICT = dict()
116
+ json['versionId'] = self.version_id
117
+ json['registrationId'] = self.registration_id.to_json()
118
+ json['scriptURL'] = self.script_url
119
+ json['runningStatus'] = self.running_status.to_json()
120
+ json['status'] = self.status.to_json()
121
+ if self.script_last_modified is not None:
122
+ json['scriptLastModified'] = self.script_last_modified
123
+ if self.script_response_time is not None:
124
+ json['scriptResponseTime'] = self.script_response_time
125
+ if self.controlled_clients is not None:
126
+ json['controlledClients'] = [i.to_json() for i in self.controlled_clients]
127
+ if self.target_id is not None:
128
+ json['targetId'] = self.target_id.to_json()
129
+ if self.router_rules is not None:
130
+ json['routerRules'] = self.router_rules
131
+ return json
132
+
133
+ @classmethod
134
+ def from_json(cls, json: T_JSON_DICT) -> ServiceWorkerVersion:
135
+ return cls(
136
+ version_id=str(json['versionId']),
137
+ registration_id=RegistrationID.from_json(json['registrationId']),
138
+ script_url=str(json['scriptURL']),
139
+ running_status=ServiceWorkerVersionRunningStatus.from_json(json['runningStatus']),
140
+ status=ServiceWorkerVersionStatus.from_json(json['status']),
141
+ script_last_modified=float(json['scriptLastModified']) if json.get('scriptLastModified', None) is not None else None,
142
+ script_response_time=float(json['scriptResponseTime']) if json.get('scriptResponseTime', None) is not None else None,
143
+ controlled_clients=[target.TargetID.from_json(i) for i in json['controlledClients']] if json.get('controlledClients', None) is not None else None,
144
+ target_id=target.TargetID.from_json(json['targetId']) if json.get('targetId', None) is not None else None,
145
+ router_rules=str(json['routerRules']) if json.get('routerRules', None) is not None else None,
146
+ )
147
+
148
+
149
+ @dataclass
150
+ class ServiceWorkerErrorMessage:
151
+ '''
152
+ ServiceWorker error message.
153
+ '''
154
+ error_message: str
155
+
156
+ registration_id: RegistrationID
157
+
158
+ version_id: str
159
+
160
+ source_url: str
161
+
162
+ line_number: int
163
+
164
+ column_number: int
165
+
166
+ def to_json(self) -> T_JSON_DICT:
167
+ json: T_JSON_DICT = dict()
168
+ json['errorMessage'] = self.error_message
169
+ json['registrationId'] = self.registration_id.to_json()
170
+ json['versionId'] = self.version_id
171
+ json['sourceURL'] = self.source_url
172
+ json['lineNumber'] = self.line_number
173
+ json['columnNumber'] = self.column_number
174
+ return json
175
+
176
+ @classmethod
177
+ def from_json(cls, json: T_JSON_DICT) -> ServiceWorkerErrorMessage:
178
+ return cls(
179
+ error_message=str(json['errorMessage']),
180
+ registration_id=RegistrationID.from_json(json['registrationId']),
181
+ version_id=str(json['versionId']),
182
+ source_url=str(json['sourceURL']),
183
+ line_number=int(json['lineNumber']),
184
+ column_number=int(json['columnNumber']),
185
+ )
186
+
187
+
188
+ def deliver_push_message(
189
+ origin: str,
190
+ registration_id: RegistrationID,
191
+ data: str
192
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
193
+ '''
194
+ :param origin:
195
+ :param registration_id:
196
+ :param data:
197
+ '''
198
+ params: T_JSON_DICT = dict()
199
+ params['origin'] = origin
200
+ params['registrationId'] = registration_id.to_json()
201
+ params['data'] = data
202
+ cmd_dict: T_JSON_DICT = {
203
+ 'method': 'ServiceWorker.deliverPushMessage',
204
+ 'params': params,
205
+ }
206
+ json = yield cmd_dict
207
+
208
+
209
+ def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
210
+
211
+ cmd_dict: T_JSON_DICT = {
212
+ 'method': 'ServiceWorker.disable',
213
+ }
214
+ json = yield cmd_dict
215
+
216
+
217
+ def dispatch_sync_event(
218
+ origin: str,
219
+ registration_id: RegistrationID,
220
+ tag: str,
221
+ last_chance: bool
222
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
223
+ '''
224
+ :param origin:
225
+ :param registration_id:
226
+ :param tag:
227
+ :param last_chance:
228
+ '''
229
+ params: T_JSON_DICT = dict()
230
+ params['origin'] = origin
231
+ params['registrationId'] = registration_id.to_json()
232
+ params['tag'] = tag
233
+ params['lastChance'] = last_chance
234
+ cmd_dict: T_JSON_DICT = {
235
+ 'method': 'ServiceWorker.dispatchSyncEvent',
236
+ 'params': params,
237
+ }
238
+ json = yield cmd_dict
239
+
240
+
241
+ def dispatch_periodic_sync_event(
242
+ origin: str,
243
+ registration_id: RegistrationID,
244
+ tag: str
245
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
246
+ '''
247
+ :param origin:
248
+ :param registration_id:
249
+ :param tag:
250
+ '''
251
+ params: T_JSON_DICT = dict()
252
+ params['origin'] = origin
253
+ params['registrationId'] = registration_id.to_json()
254
+ params['tag'] = tag
255
+ cmd_dict: T_JSON_DICT = {
256
+ 'method': 'ServiceWorker.dispatchPeriodicSyncEvent',
257
+ 'params': params,
258
+ }
259
+ json = yield cmd_dict
260
+
261
+
262
+ def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
263
+
264
+ cmd_dict: T_JSON_DICT = {
265
+ 'method': 'ServiceWorker.enable',
266
+ }
267
+ json = yield cmd_dict
268
+
269
+
270
+ def set_force_update_on_page_load(
271
+ force_update_on_page_load: bool
272
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
273
+ '''
274
+ :param force_update_on_page_load:
275
+ '''
276
+ params: T_JSON_DICT = dict()
277
+ params['forceUpdateOnPageLoad'] = force_update_on_page_load
278
+ cmd_dict: T_JSON_DICT = {
279
+ 'method': 'ServiceWorker.setForceUpdateOnPageLoad',
280
+ 'params': params,
281
+ }
282
+ json = yield cmd_dict
283
+
284
+
285
+ def skip_waiting(
286
+ scope_url: str
287
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
288
+ '''
289
+ :param scope_url:
290
+ '''
291
+ params: T_JSON_DICT = dict()
292
+ params['scopeURL'] = scope_url
293
+ cmd_dict: T_JSON_DICT = {
294
+ 'method': 'ServiceWorker.skipWaiting',
295
+ 'params': params,
296
+ }
297
+ json = yield cmd_dict
298
+
299
+
300
+ def start_worker(
301
+ scope_url: str
302
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
303
+ '''
304
+ :param scope_url:
305
+ '''
306
+ params: T_JSON_DICT = dict()
307
+ params['scopeURL'] = scope_url
308
+ cmd_dict: T_JSON_DICT = {
309
+ 'method': 'ServiceWorker.startWorker',
310
+ 'params': params,
311
+ }
312
+ json = yield cmd_dict
313
+
314
+
315
+ def stop_all_workers() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
316
+
317
+ cmd_dict: T_JSON_DICT = {
318
+ 'method': 'ServiceWorker.stopAllWorkers',
319
+ }
320
+ json = yield cmd_dict
321
+
322
+
323
+ def stop_worker(
324
+ version_id: str
325
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
326
+ '''
327
+ :param version_id:
328
+ '''
329
+ params: T_JSON_DICT = dict()
330
+ params['versionId'] = version_id
331
+ cmd_dict: T_JSON_DICT = {
332
+ 'method': 'ServiceWorker.stopWorker',
333
+ 'params': params,
334
+ }
335
+ json = yield cmd_dict
336
+
337
+
338
+ def unregister(
339
+ scope_url: str
340
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
341
+ '''
342
+ :param scope_url:
343
+ '''
344
+ params: T_JSON_DICT = dict()
345
+ params['scopeURL'] = scope_url
346
+ cmd_dict: T_JSON_DICT = {
347
+ 'method': 'ServiceWorker.unregister',
348
+ 'params': params,
349
+ }
350
+ json = yield cmd_dict
351
+
352
+
353
+ def update_registration(
354
+ scope_url: str
355
+ ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
356
+ '''
357
+ :param scope_url:
358
+ '''
359
+ params: T_JSON_DICT = dict()
360
+ params['scopeURL'] = scope_url
361
+ cmd_dict: T_JSON_DICT = {
362
+ 'method': 'ServiceWorker.updateRegistration',
363
+ 'params': params,
364
+ }
365
+ json = yield cmd_dict
366
+
367
+
368
+ @event_class('ServiceWorker.workerErrorReported')
369
+ @dataclass
370
+ class WorkerErrorReported:
371
+ error_message: ServiceWorkerErrorMessage
372
+
373
+ @classmethod
374
+ def from_json(cls, json: T_JSON_DICT) -> WorkerErrorReported:
375
+ return cls(
376
+ error_message=ServiceWorkerErrorMessage.from_json(json['errorMessage'])
377
+ )
378
+
379
+
380
+ @event_class('ServiceWorker.workerRegistrationUpdated')
381
+ @dataclass
382
+ class WorkerRegistrationUpdated:
383
+ registrations: typing.List[ServiceWorkerRegistration]
384
+
385
+ @classmethod
386
+ def from_json(cls, json: T_JSON_DICT) -> WorkerRegistrationUpdated:
387
+ return cls(
388
+ registrations=[ServiceWorkerRegistration.from_json(i) for i in json['registrations']]
389
+ )
390
+
391
+
392
+ @event_class('ServiceWorker.workerVersionUpdated')
393
+ @dataclass
394
+ class WorkerVersionUpdated:
395
+ versions: typing.List[ServiceWorkerVersion]
396
+
397
+ @classmethod
398
+ def from_json(cls, json: T_JSON_DICT) -> WorkerVersionUpdated:
399
+ return cls(
400
+ versions=[ServiceWorkerVersion.from_json(i) for i in json['versions']]
401
+ )