supython 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.
Files changed (200) hide show
  1. supython/__init__.py +24 -0
  2. supython/admin/__init__.py +3 -0
  3. supython/admin/api/__init__.py +24 -0
  4. supython/admin/api/auth.py +118 -0
  5. supython/admin/api/auth_templates.py +67 -0
  6. supython/admin/api/auth_users.py +225 -0
  7. supython/admin/api/db.py +174 -0
  8. supython/admin/api/functions.py +92 -0
  9. supython/admin/api/jobs.py +192 -0
  10. supython/admin/api/ops.py +224 -0
  11. supython/admin/api/realtime.py +281 -0
  12. supython/admin/api/service_auth.py +49 -0
  13. supython/admin/api/service_auth_templates.py +83 -0
  14. supython/admin/api/service_auth_users.py +346 -0
  15. supython/admin/api/service_db.py +214 -0
  16. supython/admin/api/service_functions.py +287 -0
  17. supython/admin/api/service_jobs.py +282 -0
  18. supython/admin/api/service_ops.py +213 -0
  19. supython/admin/api/service_realtime.py +30 -0
  20. supython/admin/api/service_storage.py +220 -0
  21. supython/admin/api/storage.py +117 -0
  22. supython/admin/api/system.py +37 -0
  23. supython/admin/audit.py +29 -0
  24. supython/admin/deps.py +22 -0
  25. supython/admin/errors.py +16 -0
  26. supython/admin/schemas.py +310 -0
  27. supython/admin/session.py +52 -0
  28. supython/admin/spa.py +38 -0
  29. supython/admin/static/assets/Alert-dluGVkos.js +49 -0
  30. supython/admin/static/assets/Audit-Njung3HI.js +2 -0
  31. supython/admin/static/assets/Backups-DzPlFgrm.js +2 -0
  32. supython/admin/static/assets/Buckets-ByacGkU1.js +2 -0
  33. supython/admin/static/assets/Channels-BoIuTtam.js +353 -0
  34. supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +2 -0
  35. supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +2 -0
  36. supython/admin/static/assets/Crons-B67vc39F.js +2 -0
  37. supython/admin/static/assets/DashboardView-CUTFVL6k.js +2 -0
  38. supython/admin/static/assets/DataTable-COAAWEft.js +747 -0
  39. supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +75 -0
  40. supython/admin/static/assets/DrawerContent-TpYTFgF1.js +139 -0
  41. supython/admin/static/assets/Empty-cr2r7e2u.js +25 -0
  42. supython/admin/static/assets/EmptyState-DeDck-OL.js +2 -0
  43. supython/admin/static/assets/Grid-hFkp9F4P.js +2 -0
  44. supython/admin/static/assets/Input-DppYTq9C.js +259 -0
  45. supython/admin/static/assets/Invoke-DW3Nveeh.js +2 -0
  46. supython/admin/static/assets/JsonField-DibyJgun.js +2 -0
  47. supython/admin/static/assets/LoginView-BjLyE3Ds.css +1 -0
  48. supython/admin/static/assets/LoginView-CoOjECT_.js +111 -0
  49. supython/admin/static/assets/Logs-D9WYrnIT.js +2 -0
  50. supython/admin/static/assets/Logs-DS1XPa0h.css +1 -0
  51. supython/admin/static/assets/Migrations-DOSC2ddQ.js +2 -0
  52. supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +2 -0
  53. supython/admin/static/assets/Queue-CywZs6vI.js +2 -0
  54. supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +2 -0
  55. supython/admin/static/assets/RlsEditor-BSlH9vSc.js +2 -0
  56. supython/admin/static/assets/Routes-BiLXE49D.js +2 -0
  57. supython/admin/static/assets/Routes-C-ianIGD.css +1 -0
  58. supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +1 -0
  59. supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +2 -0
  60. supython/admin/static/assets/Select-DIzZyRZb.js +434 -0
  61. supython/admin/static/assets/Space-n5-XcguU.js +400 -0
  62. supython/admin/static/assets/SqlEditor-b8pTsILY.js +3 -0
  63. supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +104 -0
  64. supython/admin/static/assets/TableData-CQIagLKn.js +2 -0
  65. supython/admin/static/assets/Tag-D1fOKpTH.js +72 -0
  66. supython/admin/static/assets/Templates-BS-ugkdq.js +2 -0
  67. supython/admin/static/assets/Thing-CEAniuMg.js +107 -0
  68. supython/admin/static/assets/Users-wzwajhlh.js +2 -0
  69. supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +1 -0
  70. supython/admin/static/assets/dist-VXIJLCYq.js +13 -0
  71. supython/admin/static/assets/format-length-CGCY1rMh.js +2 -0
  72. supython/admin/static/assets/get-Ca6unauB.js +2 -0
  73. supython/admin/static/assets/index-CeE6v959.js +951 -0
  74. supython/admin/static/assets/pinia-COXwfrOX.js +2 -0
  75. supython/admin/static/assets/resources-Bt6thQCD.js +44 -0
  76. supython/admin/static/assets/use-locale-mtgM0a3a.js +2 -0
  77. supython/admin/static/assets/use-merged-state-BvhkaHNX.js +2 -0
  78. supython/admin/static/assets/useConfirm-tMjvBFXR.js +2 -0
  79. supython/admin/static/assets/useResource-C_rJCY8C.js +2 -0
  80. supython/admin/static/assets/useTable-CnZc5zhi.js +363 -0
  81. supython/admin/static/assets/useTable-Dg0XlRlq.css +1 -0
  82. supython/admin/static/assets/useToast-DsZKx0IX.js +2 -0
  83. supython/admin/static/assets/utils-sbXoq7Ir.js +2 -0
  84. supython/admin/static/favicon.svg +1 -0
  85. supython/admin/static/icons.svg +24 -0
  86. supython/admin/static/index.html +24 -0
  87. supython/app.py +162 -0
  88. supython/auth/__init__.py +3 -0
  89. supython/auth/_email_job.py +11 -0
  90. supython/auth/providers/__init__.py +34 -0
  91. supython/auth/providers/github.py +22 -0
  92. supython/auth/providers/google.py +19 -0
  93. supython/auth/providers/oauth.py +56 -0
  94. supython/auth/providers/registry.py +16 -0
  95. supython/auth/ratelimit.py +39 -0
  96. supython/auth/router.py +282 -0
  97. supython/auth/schemas.py +79 -0
  98. supython/auth/service.py +587 -0
  99. supython/backups/__init__.py +24 -0
  100. supython/backups/_backup_job.py +170 -0
  101. supython/backups/schemas.py +18 -0
  102. supython/backups/service.py +217 -0
  103. supython/body_size.py +184 -0
  104. supython/cli.py +1663 -0
  105. supython/client/__init__.py +67 -0
  106. supython/client/_auth.py +249 -0
  107. supython/client/_client.py +145 -0
  108. supython/client/_config.py +92 -0
  109. supython/client/_functions.py +69 -0
  110. supython/client/_storage.py +255 -0
  111. supython/client/py.typed +0 -0
  112. supython/db.py +151 -0
  113. supython/db_admin.py +8 -0
  114. supython/extensions.py +36 -0
  115. supython/functions/__init__.py +19 -0
  116. supython/functions/context.py +262 -0
  117. supython/functions/loader.py +307 -0
  118. supython/functions/router.py +228 -0
  119. supython/functions/schemas.py +50 -0
  120. supython/gen/__init__.py +5 -0
  121. supython/gen/_introspect.py +137 -0
  122. supython/gen/types_py.py +270 -0
  123. supython/gen/types_ts.py +365 -0
  124. supython/health.py +229 -0
  125. supython/hooks.py +117 -0
  126. supython/jobs/__init__.py +31 -0
  127. supython/jobs/backends.py +97 -0
  128. supython/jobs/context.py +58 -0
  129. supython/jobs/cron.py +152 -0
  130. supython/jobs/cron_inproc.py +119 -0
  131. supython/jobs/decorators.py +76 -0
  132. supython/jobs/registry.py +79 -0
  133. supython/jobs/router.py +136 -0
  134. supython/jobs/schemas.py +92 -0
  135. supython/jobs/service.py +311 -0
  136. supython/jobs/worker.py +219 -0
  137. supython/jwks.py +257 -0
  138. supython/keyset.py +279 -0
  139. supython/logging_config.py +291 -0
  140. supython/mail.py +33 -0
  141. supython/mailer.py +65 -0
  142. supython/migrate.py +81 -0
  143. supython/migrations/0001_extensions_and_roles.sql +46 -0
  144. supython/migrations/0002_auth_schema.sql +66 -0
  145. supython/migrations/0003_demo_todos.sql +42 -0
  146. supython/migrations/0004_auth_v0_2.sql +47 -0
  147. supython/migrations/0005_storage_schema.sql +117 -0
  148. supython/migrations/0006_realtime_schema.sql +206 -0
  149. supython/migrations/0007_jobs_schema.sql +254 -0
  150. supython/migrations/0008_jobs_last_error.sql +56 -0
  151. supython/migrations/0009_auth_rate_limits.sql +33 -0
  152. supython/migrations/0010_worker_heartbeat.sql +14 -0
  153. supython/migrations/0011_admin_schema.sql +45 -0
  154. supython/migrations/0012_auth_banned_until.sql +10 -0
  155. supython/migrations/0013_email_templates.sql +19 -0
  156. supython/migrations/0014_realtime_payload_warning.sql +96 -0
  157. supython/migrations/0015_backups_schema.sql +14 -0
  158. supython/passwords.py +15 -0
  159. supython/realtime/__init__.py +6 -0
  160. supython/realtime/broker.py +814 -0
  161. supython/realtime/protocol.py +234 -0
  162. supython/realtime/router.py +184 -0
  163. supython/realtime/schemas.py +207 -0
  164. supython/realtime/service.py +261 -0
  165. supython/realtime/topics.py +175 -0
  166. supython/realtime/websocket.py +586 -0
  167. supython/scaffold/__init__.py +5 -0
  168. supython/scaffold/init_project.py +144 -0
  169. supython/scaffold/templates/Caddyfile.tmpl +4 -0
  170. supython/scaffold/templates/README.md.tmpl +22 -0
  171. supython/scaffold/templates/apps_hooks.py.tmpl +11 -0
  172. supython/scaffold/templates/apps_jobs.py.tmpl +8 -0
  173. supython/scaffold/templates/asgi.py.tmpl +14 -0
  174. supython/scaffold/templates/docker-compose.prod.yml.tmpl +84 -0
  175. supython/scaffold/templates/docker-compose.yml.tmpl +45 -0
  176. supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +9 -0
  177. supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +3 -0
  178. supython/scaffold/templates/env.example.tmpl +168 -0
  179. supython/scaffold/templates/functions_README.md.tmpl +21 -0
  180. supython/scaffold/templates/gitignore.tmpl +14 -0
  181. supython/scaffold/templates/manage.py.tmpl +11 -0
  182. supython/scaffold/templates/migrations/.gitkeep +0 -0
  183. supython/scaffold/templates/package_init.py.tmpl +1 -0
  184. supython/scaffold/templates/settings.py.tmpl +31 -0
  185. supython/secretset.py +347 -0
  186. supython/security_headers.py +78 -0
  187. supython/settings.py +244 -0
  188. supython/settings_module.py +117 -0
  189. supython/storage/__init__.py +5 -0
  190. supython/storage/backends.py +392 -0
  191. supython/storage/router.py +341 -0
  192. supython/storage/schemas.py +50 -0
  193. supython/storage/service.py +445 -0
  194. supython/storage/signing.py +119 -0
  195. supython/tokens.py +85 -0
  196. supython-0.1.0.dist-info/METADATA +756 -0
  197. supython-0.1.0.dist-info/RECORD +200 -0
  198. supython-0.1.0.dist-info/WHEEL +4 -0
  199. supython-0.1.0.dist-info/entry_points.txt +2 -0
  200. supython-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,310 @@
1
+ from datetime import datetime
2
+ from typing import Any, Literal
3
+ from uuid import UUID
4
+
5
+ from pydantic import BaseModel, EmailStr, Field
6
+
7
+
8
+ class LoginRequest(BaseModel):
9
+ email: EmailStr
10
+ password: str
11
+
12
+
13
+ class SessionResponse(BaseModel):
14
+ admin_id: UUID
15
+ email: str
16
+ expires_at: datetime
17
+
18
+
19
+ class SchemaInfo(BaseModel):
20
+ name: str
21
+ owner: str
22
+ is_user: bool
23
+
24
+
25
+ class TableInfo(BaseModel):
26
+ name: str
27
+ rls_enabled: bool
28
+
29
+
30
+ class RowsPage(BaseModel):
31
+ columns: list[str]
32
+ rows: list[list[Any]]
33
+ total: int
34
+
35
+
36
+ class SqlExecRequest(BaseModel):
37
+ statement: str
38
+ read_only: bool = True
39
+
40
+
41
+ class SqlExecResponse(BaseModel):
42
+ columns: list[str]
43
+ rows: list[list[Any]]
44
+ row_count: int
45
+
46
+
47
+ class DryRunRequest(BaseModel):
48
+ ddl: str
49
+ sample_query: str
50
+
51
+
52
+ class DryRunResponse(BaseModel):
53
+ columns: list[str]
54
+ rows: list[list[Any]]
55
+
56
+
57
+ class RlsPolicy(BaseModel):
58
+ schemaname: str
59
+ tablename: str
60
+ policyname: str
61
+ permissive: str | None = None
62
+ roles: list[str] | None = None
63
+ cmd: str | None = None
64
+ qual: str | None = None
65
+ with_check: str | None = None
66
+
67
+
68
+ class MigrationRecord(BaseModel):
69
+ version: str
70
+ applied_at: datetime | None = None
71
+ source: str
72
+
73
+
74
+ class SystemStatus(BaseModel):
75
+ pool_size: int
76
+ jwks_kid: str
77
+ broker: bool
78
+ jobs: bool
79
+
80
+
81
+ class SystemVersion(BaseModel):
82
+ version: str
83
+
84
+
85
+ class AdminUser(BaseModel):
86
+ id: UUID
87
+ email: str
88
+ created_at: datetime
89
+ last_sign_in_at: datetime | None = None
90
+ banned_until: datetime | None = None
91
+ email_confirmed_at: datetime | None = None
92
+
93
+
94
+ class AdminUsersPage(BaseModel):
95
+ rows: list[AdminUser]
96
+ total: int
97
+
98
+
99
+ class Identity(BaseModel):
100
+ id: UUID
101
+ user_id: UUID
102
+ provider: str
103
+ provider_user_id: str
104
+ identity_data: dict[str, Any]
105
+ created_at: datetime
106
+
107
+
108
+ class AuditEvent(BaseModel):
109
+ id: UUID
110
+ user_id: UUID | None = None
111
+ event: str
112
+ ip: str | None = None
113
+ ua: str | None = None
114
+ payload: dict[str, Any]
115
+ created_at: datetime
116
+
117
+
118
+ class AdminUserDetail(BaseModel):
119
+ user: AdminUser
120
+ identities: list[Identity]
121
+ recent_audit: list[AuditEvent]
122
+
123
+
124
+ class BanRequest(BaseModel):
125
+ duration_seconds: int | None = None
126
+
127
+
128
+ class RefreshToken(BaseModel):
129
+ id: int
130
+ user_id: UUID
131
+ token: str
132
+ parent: str | None = None
133
+ revoked: bool
134
+ created_at: datetime
135
+
136
+
137
+ class RefreshTokensPage(BaseModel):
138
+ rows: list[RefreshToken]
139
+ total: int
140
+
141
+
142
+ class AdminAuditPage(BaseModel):
143
+ rows: list[AuditEvent]
144
+ total: int
145
+
146
+
147
+ class EmailTemplate(BaseModel):
148
+ name: str
149
+ subject: str
150
+ text_body: str
151
+ updated_at: datetime
152
+
153
+
154
+ class EmailTemplateUpdate(BaseModel):
155
+ subject: str | None = None
156
+ text_body: str | None = None
157
+
158
+
159
+ class AdminBucket(BaseModel):
160
+ id: UUID
161
+ name: str
162
+ owner: UUID | None = None
163
+ public: bool
164
+ object_count: int
165
+ total_size: int
166
+ file_size_limit: int | None = None
167
+ allowed_mime_types: list[str] | None = None
168
+ created_at: datetime
169
+ updated_at: datetime
170
+
171
+
172
+ class AdminObject(BaseModel):
173
+ id: UUID
174
+ bucket: str
175
+ name: str
176
+ owner: UUID
177
+ size: int
178
+ mime_type: str | None = None
179
+ etag: str | None = None
180
+ created_at: datetime
181
+ updated_at: datetime
182
+
183
+
184
+ class AdminObjectsPage(BaseModel):
185
+ rows: list[AdminObject]
186
+ total: int
187
+ prefix: str | None = None
188
+
189
+
190
+ class AdminSignObjectRequest(BaseModel):
191
+ expires_in: int | None = Field(default=None, ge=1)
192
+ role: Literal["service_role", "authenticated", "anon"] = "service_role"
193
+ impersonate_sub: UUID | None = None
194
+
195
+
196
+ class AdminSignedUrlResponse(BaseModel):
197
+ signed_url: str
198
+ token: str
199
+ expires_at: datetime
200
+ expires_in: int
201
+ signed_under_role: str
202
+
203
+
204
+ class FunctionRoute(BaseModel):
205
+ name: str
206
+ path: str
207
+ methods: list[str]
208
+ auth: Literal["authenticated", "anon"]
209
+
210
+
211
+ class FunctionSourceResponse(BaseModel):
212
+ name: str
213
+ path: str
214
+ source: str
215
+ size: int
216
+
217
+
218
+ class FunctionInvokeRequest(BaseModel):
219
+ method: str = "POST"
220
+ headers: dict[str, str] = Field(default_factory=dict)
221
+ body: Any | None = None
222
+ query: str | None = None
223
+
224
+
225
+ class FunctionInvokeResponse(BaseModel):
226
+ status: int
227
+ headers: dict[str, str]
228
+ body: Any | None = None
229
+ body_text: str
230
+ elapsed_ms: float
231
+
232
+
233
+ class AdminBroadcastRequest(BaseModel):
234
+ """Body for POST /admin/api/v1/realtime/broadcast."""
235
+
236
+ topic: str = Field(min_length=1)
237
+ event: str = Field(min_length=1, max_length=255)
238
+ payload: dict[str, Any] = Field(default_factory=dict)
239
+
240
+
241
+ class AdminJobRow(BaseModel):
242
+ id: UUID
243
+ name: str
244
+ version: int = 1
245
+ status: str
246
+ payload: dict[str, Any] | None = None
247
+ queue: str = "default"
248
+ user_id: UUID | None = None
249
+ attempts: int = 0
250
+ max_attempts: int = 3
251
+ run_at: datetime | None = None
252
+ locked_at: datetime | None = None
253
+ locked_by: str | None = None
254
+ role: str = "service_role"
255
+ finished_at: datetime | None = None
256
+ created_at: datetime | None = None
257
+ last_error: str | None = None
258
+
259
+
260
+ class AdminJobsPage(BaseModel):
261
+ rows: list[AdminJobRow]
262
+ total: int
263
+ counts: dict[str, int] = {}
264
+
265
+
266
+ class AdminCronRow(BaseModel):
267
+ id: UUID
268
+ name: str
269
+ cron_expr: str
270
+ job_name: str
271
+ job_version: int = 1
272
+ payload: dict[str, Any] | None = None
273
+ queue: str = "default"
274
+ enabled: bool = True
275
+ last_fire_at: datetime | None = None
276
+ created_at: datetime | None = None
277
+ pg_cron_active: bool | None = None
278
+
279
+
280
+ class PgCronHealth(BaseModel):
281
+ installed: bool
282
+ active_jobs: int = 0
283
+ extension_version: str | None = None
284
+
285
+
286
+ class AdminBackupRow(BaseModel):
287
+ id: UUID
288
+ kind: str
289
+ status: str
290
+ size: int | None = None
291
+ file_path: str | None = None
292
+ error_message: str | None = None
293
+ started_at: datetime
294
+ finished_at: datetime | None = None
295
+ created_at: datetime
296
+
297
+
298
+ class AdminBackupsPage(BaseModel):
299
+ rows: list[AdminBackupRow]
300
+ total: int
301
+
302
+
303
+ class StartBackupRequest(BaseModel):
304
+ kind: Literal["full", "schema-only"] = "full"
305
+
306
+
307
+ class BackupDownloadResponse(BaseModel):
308
+ download_url: str
309
+ expires_in: int
310
+ backup_id: UUID
@@ -0,0 +1,52 @@
1
+ import hashlib
2
+ import secrets
3
+ from datetime import datetime, timedelta, timezone
4
+ from uuid import UUID
5
+
6
+ import asyncpg
7
+
8
+ SESSION_COOKIE = "supython_admin"
9
+ SESSION_PATH = "/admin"
10
+ SESSION_TTL = timedelta(hours=8)
11
+
12
+
13
+ def _hash(token: str) -> bytes:
14
+ return hashlib.sha256(token.encode("utf-8")).digest()
15
+
16
+
17
+ async def issue(
18
+ conn: asyncpg.Connection, *, admin_id: UUID, ip: str | None, ua: str | None
19
+ ) -> tuple[str, datetime]:
20
+ raw = secrets.token_urlsafe(32)
21
+ expires = datetime.now(timezone.utc) + SESSION_TTL
22
+ await conn.execute(
23
+ """
24
+ insert into admin.admin_sessions (admin_id, token_hash, expires_at, ip, user_agent)
25
+ values ($1, $2, $3, $4, $5)
26
+ """,
27
+ admin_id, _hash(raw), expires, ip, ua,
28
+ )
29
+ return raw, expires
30
+
31
+
32
+ async def resolve(
33
+ conn: asyncpg.Connection, raw: str
34
+ ) -> tuple[UUID, datetime] | None:
35
+ row = await conn.fetchrow(
36
+ """
37
+ select admin_id, expires_at
38
+ from admin.admin_sessions
39
+ where token_hash = $1
40
+ and revoked_at is null
41
+ and expires_at > now()
42
+ """,
43
+ _hash(raw),
44
+ )
45
+ return (row["admin_id"], row["expires_at"]) if row else None
46
+
47
+
48
+ async def revoke(conn: asyncpg.Connection, raw: str) -> None:
49
+ await conn.execute(
50
+ "update admin.admin_sessions set revoked_at = now() where token_hash = $1",
51
+ _hash(raw),
52
+ )
supython/admin/spa.py ADDED
@@ -0,0 +1,38 @@
1
+ import logging
2
+ from importlib.resources import files
3
+ from pathlib import Path
4
+
5
+ from fastapi import FastAPI, HTTPException, status
6
+ from fastapi.responses import FileResponse
7
+ from fastapi.staticfiles import StaticFiles
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def mount(app: FastAPI) -> None:
13
+ static_dir = Path(str(files("supython.admin").joinpath("static")))
14
+ assets_path = static_dir / "assets"
15
+ index = static_dir / "index.html"
16
+
17
+ if assets_path.exists():
18
+ app.mount(
19
+ "/admin/assets",
20
+ StaticFiles(directory=assets_path),
21
+ name="admin-assets",
22
+ )
23
+
24
+ @app.get("/admin", include_in_schema=False)
25
+ @app.get("/admin/{full_path:path}", include_in_schema=False)
26
+ async def spa_fallback(full_path: str = "") -> FileResponse:
27
+ if not index.exists():
28
+ raise HTTPException(
29
+ status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
30
+ detail="Admin SPA bundle not built. Run `npm run build` in admin-ui/.",
31
+ )
32
+ return FileResponse(index)
33
+
34
+ if not index.exists():
35
+ logger.warning(
36
+ "Admin SPA index.html not found at %s — /admin will return 503 until the bundle is built.",
37
+ index,
38
+ )
@@ -0,0 +1,49 @@
1
+ import{Bt as e,E as t,Ft as n,Gt as r,It as i,Jt as a,Kt as o,O as s,On as c,S as l,Sn as u,Yt as d,Zt as f,_ as p,_t as m,ht as h,j as g,lt as _,mn as v,tr as y,ut as b,wn as x,x as S}from"./Space-n5-XcguU.js";import{F as C,I as w,L as T,M as E,N as D,P as O}from"./index-CeE6v959.js";function k(e){let{lineHeight:t,borderRadius:r,fontWeightStrong:a,baseColor:o,dividerColor:s,actionColor:c,textColor1:l,textColor2:u,closeColorHover:d,closeColorPressed:f,closeIconColor:p,closeIconColorHover:m,closeIconColorPressed:h,infoColor:g,successColor:_,warningColor:v,errorColor:y,fontSize:b}=e;return Object.assign(Object.assign({},D),{fontSize:b,lineHeight:t,titleFontWeight:a,borderRadius:r,border:`1px solid ${s}`,color:c,titleTextColor:l,iconColor:u,contentTextColor:u,closeBorderRadius:r,closeColorHover:d,closeColorPressed:f,closeIconColor:p,closeIconColorHover:m,closeIconColorPressed:h,borderInfo:`1px solid ${i(o,n(g,{alpha:.25}))}`,colorInfo:i(o,n(g,{alpha:.08})),titleTextColorInfo:l,iconColorInfo:g,contentTextColorInfo:u,closeColorHoverInfo:d,closeColorPressedInfo:f,closeIconColorInfo:p,closeIconColorHoverInfo:m,closeIconColorPressedInfo:h,borderSuccess:`1px solid ${i(o,n(_,{alpha:.25}))}`,colorSuccess:i(o,n(_,{alpha:.08})),titleTextColorSuccess:l,iconColorSuccess:_,contentTextColorSuccess:u,closeColorHoverSuccess:d,closeColorPressedSuccess:f,closeIconColorSuccess:p,closeIconColorHoverSuccess:m,closeIconColorPressedSuccess:h,borderWarning:`1px solid ${i(o,n(v,{alpha:.33}))}`,colorWarning:i(o,n(v,{alpha:.08})),titleTextColorWarning:l,iconColorWarning:v,contentTextColorWarning:u,closeColorHoverWarning:d,closeColorPressedWarning:f,closeIconColorWarning:p,closeIconColorHoverWarning:m,closeIconColorPressedWarning:h,borderError:`1px solid ${i(o,n(y,{alpha:.25}))}`,colorError:i(o,n(y,{alpha:.08})),titleTextColorError:l,iconColorError:y,contentTextColorError:u,closeColorHoverError:d,closeColorPressedError:f,closeIconColorError:p,closeIconColorHoverError:m,closeIconColorPressedError:h})}var A={name:`Alert`,common:p,self:k},j=o(`alert`,`
2
+ line-height: var(--n-line-height);
3
+ border-radius: var(--n-border-radius);
4
+ position: relative;
5
+ transition: background-color .3s var(--n-bezier);
6
+ background-color: var(--n-color);
7
+ text-align: start;
8
+ word-break: break-word;
9
+ `,[a(`border`,`
10
+ border-radius: inherit;
11
+ position: absolute;
12
+ left: 0;
13
+ right: 0;
14
+ top: 0;
15
+ bottom: 0;
16
+ transition: border-color .3s var(--n-bezier);
17
+ border: var(--n-border);
18
+ pointer-events: none;
19
+ `),d(`closable`,[o(`alert-body`,[a(`title`,`
20
+ padding-right: 24px;
21
+ `)])]),a(`icon`,{color:`var(--n-icon-color)`}),o(`alert-body`,{padding:`var(--n-padding)`},[a(`title`,{color:`var(--n-title-text-color)`}),a(`content`,{color:`var(--n-content-text-color)`})]),E({originalTransition:`transform .3s var(--n-bezier)`,enterToProps:{transform:`scale(1)`},leaveToProps:{transform:`scale(0.9)`}}),a(`icon`,`
22
+ position: absolute;
23
+ left: 0;
24
+ top: 0;
25
+ align-items: center;
26
+ justify-content: center;
27
+ display: flex;
28
+ width: var(--n-icon-size);
29
+ height: var(--n-icon-size);
30
+ font-size: var(--n-icon-size);
31
+ margin: var(--n-icon-margin);
32
+ `),a(`close`,`
33
+ transition:
34
+ color .3s var(--n-bezier),
35
+ background-color .3s var(--n-bezier);
36
+ position: absolute;
37
+ right: 0;
38
+ top: 0;
39
+ margin: var(--n-close-margin);
40
+ `),d(`show-icon`,[o(`alert-body`,{paddingLeft:`calc(var(--n-icon-margin-left) + var(--n-icon-size) + var(--n-icon-margin-right))`})]),d(`right-adjust`,[o(`alert-body`,{paddingRight:`calc(var(--n-close-size) + var(--n-padding) + 2px)`})]),o(`alert-body`,`
41
+ border-radius: var(--n-border-radius);
42
+ transition: border-color .3s var(--n-bezier);
43
+ `,[a(`title`,`
44
+ transition: color .3s var(--n-bezier);
45
+ font-size: 16px;
46
+ line-height: 19px;
47
+ font-weight: var(--n-title-font-weight);
48
+ `,[r(`& +`,[a(`content`,{marginTop:`9px`})])]),a(`content`,{transition:`color .3s var(--n-bezier)`,fontSize:`var(--n-font-size)`})]),a(`icon`,{transition:`color .3s var(--n-bezier)`})]),M=u({name:`Alert`,inheritAttrs:!1,props:Object.assign(Object.assign({},s.props),{title:String,showIcon:{type:Boolean,default:!0},type:{type:String,default:`default`},bordered:{type:Boolean,default:!0},closable:Boolean,onClose:Function,onAfterLeave:Function,onAfterHide:Function}),slots:Object,setup(t){let{mergedClsPrefixRef:n,mergedBorderedRef:r,inlineThemeDisabled:i,mergedRtlRef:a}=b(t),o=s(`Alert`,`-alert`,j,A,t,n),c=g(`Alert`,a,n),l=v(()=>{let{common:{cubicBezierEaseInOut:n},self:r}=o.value,{fontSize:i,borderRadius:a,titleFontWeight:s,lineHeight:c,iconSize:l,iconMargin:u,iconMarginRtl:d,closeIconSize:p,closeBorderRadius:m,closeSize:h,closeMargin:g,closeMarginRtl:_,padding:v}=r,{type:y}=t,{left:b,right:x}=e(u);return{"--n-bezier":n,"--n-color":r[f(`color`,y)],"--n-close-icon-size":p,"--n-close-border-radius":m,"--n-close-color-hover":r[f(`closeColorHover`,y)],"--n-close-color-pressed":r[f(`closeColorPressed`,y)],"--n-close-icon-color":r[f(`closeIconColor`,y)],"--n-close-icon-color-hover":r[f(`closeIconColorHover`,y)],"--n-close-icon-color-pressed":r[f(`closeIconColorPressed`,y)],"--n-icon-color":r[f(`iconColor`,y)],"--n-border":r[f(`border`,y)],"--n-title-text-color":r[f(`titleTextColor`,y)],"--n-content-text-color":r[f(`contentTextColor`,y)],"--n-line-height":c,"--n-border-radius":a,"--n-font-size":i,"--n-title-font-weight":s,"--n-icon-size":l,"--n-icon-margin":u,"--n-icon-margin-rtl":d,"--n-close-size":h,"--n-close-margin":g,"--n-close-margin-rtl":_,"--n-padding":v,"--n-icon-margin-left":b,"--n-icon-margin-right":x}}),u=i?_(`alert`,v(()=>t.type[0]),l,t):void 0,d=y(!0),p=()=>{let{onAfterLeave:e,onAfterHide:n}=t;e&&e(),n&&n()};return{rtlEnabled:c,mergedClsPrefix:n,mergedBordered:r,visible:d,handleCloseClick:()=>{Promise.resolve(t.onClose?.call(t)).then(e=>{e!==!1&&(d.value=!1)})},handleAfterLeave:()=>{p()},mergedTheme:o,cssVars:i?void 0:l,themeClass:u?.themeClass,onRender:u?.onRender}},render(){var e;return(e=this.onRender)==null||e.call(this),x(S,{onAfterLeave:this.handleAfterLeave},{default:()=>{let{mergedClsPrefix:e,$slots:n}=this,r={class:[`${e}-alert`,this.themeClass,this.closable&&`${e}-alert--closable`,this.showIcon&&`${e}-alert--show-icon`,!this.title&&this.closable&&`${e}-alert--right-adjust`,this.rtlEnabled&&`${e}-alert--rtl`],style:this.cssVars,role:`alert`};return this.visible?x(`div`,Object.assign({},c(this.$attrs,r)),this.closable&&x(l,{clsPrefix:e,class:`${e}-alert__close`,onClick:this.handleCloseClick}),this.bordered&&x(`div`,{class:`${e}-alert__border`}),this.showIcon&&x(`div`,{class:`${e}-alert__icon`,"aria-hidden":`true`},h(n.icon,()=>[x(t,{clsPrefix:e},{default:()=>{switch(this.type){case`success`:return x(C,null);case`info`:return x(w,null);case`warning`:return x(O,null);case`error`:return x(T,null);default:return null}}})])),x(`div`,{class:[`${e}-alert-body`,this.mergedBordered&&`${e}-alert-body--bordered`]},m(n.header,t=>{let n=t||this.title;return n?x(`div`,{class:`${e}-alert-body__title`},n):null}),n.default&&x(`div`,{class:`${e}-alert-body__content`},n))):null}})}});export{M as t};
49
+ //# sourceMappingURL=Alert-dluGVkos.js.map
@@ -0,0 +1,2 @@
1
+ import{Gn as e,In as t,Sn as n,bn as r,gn as i,mn as a,r as o,sr as s,t as c,tr as l,un as u,ur as d,vn as f,wn as p,xn as m}from"./Space-n5-XcguU.js";import{t as h}from"./Tag-D1fOKpTH.js";import{n as g,t as _}from"./DataTable-COAAWEft.js";import{n as v,t as y}from"./DescriptionsItem-P8JUDaBs.js";import{n as b,t as x}from"./useTable-CnZc5zhi.js";import{n as S,t as C}from"./DrawerContent-TpYTFgF1.js";import{t as w}from"./resources-Bt6thQCD.js";import{c as T}from"./index-CeE6v959.js";import{t as E}from"./JsonField-DibyJgun.js";var D=n({__name:`Audit`,setup(n){let D=[{type:`text`,key:`event`,label:`Event`,placeholder:`e.g. login, signup`,debounceMs:300,width:200},{type:`text`,key:`ip`,label:`IP`,placeholder:`e.g. 192.168`,debounceMs:300,width:160},{type:`date`,key:`from`,label:`From`,width:160},{type:`date`,key:`to`,label:`To`,width:160}],{q:O,data:k,loading:A,error:j,refresh:M}=x(e=>w.audit({event:e.filters.event||void 0,ip:e.filters.ip||void 0,from_date:e.filters.from||void 0,to_date:e.filters.to||void 0,limit:e.limit,offset:e.offset}),{event:null,ip:null,from:null,to:null}),N=a(()=>k.value?.rows??[]),P=a(()=>k.value?.total??0),F=[{title:`Time`,key:`created_at`,width:170,render:e=>new Date(e.created_at).toLocaleString()},{title:`Actor`,key:`user_id`,width:320,render:e=>e.user_id?e.user_id:`—`,ellipsis:{tooltip:!0}},{title:`Event`,key:`event`,width:160,render:e=>p(h,{type:`info`,size:`small`},{default:()=>e.event})},{title:`IP`,key:`ip`,width:130,render:e=>e.ip??`—`},{title:`UA`,key:`ua`,width:200,ellipsis:{tooltip:!0},render:e=>e.ua?e.ua.slice(0,40)+(e.ua.length>40?`…`:``):`—`}],I=l(!1),L=l(null);function R(e){L.value=e,I.value=!0}function z(){I.value=!1,L.value=null}return(n,a)=>(t(),i(s(o),{title:`Audit Log`,size:`small`},{default:e(()=>[m(s(c),{vertical:``,size:16},{default:e(()=>[m(b,{q:s(O),rows:N.value,total:P.value,loading:s(A),error:s(j),columns:F,filters:D,"search-placeholder":`Filter rows…`,onRefresh:s(M)},{default:e(()=>[m(s(_),{columns:F,data:N.value,bordered:!1,"row-props":e=>({style:`cursor: pointer`,onClick:()=>R(e)})},null,8,[`data`,`row-props`]),m(s(g),{page:Math.floor(s(O).offset/s(O).limit)+1,"page-count":Math.max(1,Math.ceil(P.value/s(O).limit)),style:{"margin-top":`12px`},"onUpdate:page":a[0]||=e=>s(O).offset=(e-1)*s(O).limit},null,8,[`page`,`page-count`])]),_:1},8,[`q`,`rows`,`total`,`loading`,`error`,`onRefresh`])]),_:1}),m(s(S),{show:I.value,width:520,placement:`right`,"mask-closable":!0,"onUpdate:show":a[1]||=e=>{e||z()}},{default:e(()=>[m(s(C),{title:L.value?`Event: ${L.value.event}`:`Event detail`,closable:``,onClose:z},{default:e(()=>[L.value?(t(),f(u,{key:0},[m(s(v),{bordered:``,"label-placement":`top`,column:1,size:`small`,style:{"margin-bottom":`16px`}},{default:e(()=>[m(s(y),{label:`ID`},{default:e(()=>[m(s(T),{code:``},{default:e(()=>[r(d(L.value.id),1)]),_:1})]),_:1}),m(s(y),{label:`Event`},{default:e(()=>[r(d(L.value.event),1)]),_:1}),m(s(y),{label:`Actor (user_id)`},{default:e(()=>[r(d(L.value.user_id??`—`),1)]),_:1}),m(s(y),{label:`Time`},{default:e(()=>[r(d(new Date(L.value.created_at).toLocaleString()),1)]),_:1}),m(s(y),{label:`IP`},{default:e(()=>[r(d(L.value.ip??`—`),1)]),_:1}),m(s(y),{label:`User-Agent`},{default:e(()=>[r(d(L.value.ua??`—`),1)]),_:1})]),_:1}),m(s(T),{strong:``,style:{display:`block`,"margin-bottom":`8px`}},{default:e(()=>[...a[2]||=[r(` Payload `,-1)]]),_:1}),m(E,{value:L.value.payload},null,8,[`value`])],64)):(t(),i(s(T),{key:1,depth:`3`},{default:e(()=>[...a[3]||=[r(`Click a row to see full event details.`,-1)]]),_:1}))]),_:1},8,[`title`])]),_:1},8,[`show`])]),_:1}))}});export{D as default};
2
+ //# sourceMappingURL=Audit-Njung3HI.js.map
@@ -0,0 +1,2 @@
1
+ import{Fn as e,Gn as t,In as n,Sn as r,Un as i,_n as a,bn as o,c as s,gn as c,mn as l,r as u,sr as d,t as f,tr as p,un as m,ur as h,vn as g,wn as _,xn as v}from"./Space-n5-XcguU.js";import{t as y}from"./Tag-D1fOKpTH.js";import{n as b,t as x}from"./DataTable-COAAWEft.js";import{n as S,t as C}from"./DescriptionsItem-P8JUDaBs.js";import{n as w,t as T}from"./useTable-CnZc5zhi.js";import{n as E,t as D}from"./DrawerContent-TpYTFgF1.js";import{a as O}from"./resources-Bt6thQCD.js";import{c as k,y as A}from"./index-CeE6v959.js";import{t as j}from"./useToast-DsZKx0IX.js";import{t as M}from"./useConfirm-tMjvBFXR.js";var N=3e3,P=r({__name:`Backups`,setup(r){let P=j(),F=M(),I={running:`info`,completed:`success`,failed:`error`,pending:`warning`};function L(e){return e?new Date(e).toLocaleString():`—`}function R(e){if(e==null)return`—`;if(e===0)return`0 B`;let t=[`B`,`KB`,`MB`,`GB`],n=Math.floor(Math.log10(e)/3),r=t[Math.min(n,t.length-1)];return`${(e/1e3**Math.min(n,t.length-1)).toFixed(2)} ${r}`}let{q:z,data:B,loading:V,error:H,refresh:U}=T(e=>O.backups({limit:e.limit,offset:e.offset}),{}),W=l(()=>B.value?.rows??[]),G=l(()=>B.value?.total??0),K=[{title:`Kind`,key:`kind`,width:120,render:e=>_(y,{type:e.kind===`full`?`primary`:`default`,size:`small`},{default:()=>e.kind})},{title:`Status`,key:`status`,width:120,render:e=>_(y,{type:I[e.status]??`default`,size:`small`},{default:()=>e.status})},{title:`Size`,key:`size`,width:110,render:e=>R(e.size)},{title:`Started`,key:`started_at`,width:160,render:e=>L(e.started_at)},{title:`Finished`,key:`finished_at`,width:160,render:e=>L(e.finished_at)},{title:``,key:`actions`,width:110,render:e=>e.status!==`completed`||!e.file_path?null:_(s,{size:`tiny`,type:`primary`,secondary:!0,onClick:t=>{t.stopPropagation(),Q(e)}},{default:()=>`Download`})}],q=p(!1),J=p(null);function Y(e){J.value=e,q.value=!0}function X(){q.value=!1,J.value=null}async function Z(e){let t=e===`full`?`Full backup`:`Schema-only backup`;if(await F(`Start ${t.toLowerCase()}?`,`The backup will run in the background. You can monitor its status in the list.`))try{await O.startBackup(e),P.success(`${t} started.`),await U()}catch(e){P.error(e.message??`Start backup failed`)}}async function Q(e){try{let t=await O.downloadUrl(e.id);window.open(t.download_url,`_blank`)}catch(e){P.error(e.message??`Download failed`)}}let ee=l(()=>W.value.some(e=>e.status===`running`)),$=null;async function te(){try{B.value=await O.backups({limit:z.limit,offset:z.offset})}catch{}}return i(ee,e=>{e&&$===null?$=setInterval(()=>{te()},N):!e&&$!==null&&(clearInterval($),$=null)},{immediate:!0}),i(W,e=>{if(!J.value)return;let t=e.find(e=>e.id===J.value.id);t&&(J.value=t)}),e(()=>{$!==null&&(clearInterval($),$=null)}),(e,r)=>(n(),c(d(u),{title:`Backups`,size:`small`},{default:t(()=>[v(d(f),{style:{"margin-bottom":`16px`}},{default:t(()=>[v(d(s),{type:`primary`,size:`small`,onClick:r[0]||=e=>Z(`full`)},{default:t(()=>[...r[5]||=[o(` Start Full Backup `,-1)]]),_:1}),v(d(s),{size:`small`,onClick:r[1]||=e=>Z(`schema-only`)},{default:t(()=>[...r[6]||=[o(` Start Schema-only Backup `,-1)]]),_:1})]),_:1}),v(w,{q:d(z),rows:W.value,total:G.value,loading:d(V),error:d(H),columns:K,onRefresh:d(U)},{default:t(()=>[v(d(x),{columns:K,data:W.value,bordered:!1,"row-props":e=>({style:`cursor: pointer`,onClick:()=>Y(e)})},null,8,[`data`,`row-props`]),v(d(b),{page:Math.floor(d(z).offset/d(z).limit)+1,"page-count":Math.max(1,Math.ceil(G.value/d(z).limit)),style:{"margin-top":`12px`},"onUpdate:page":r[2]||=e=>d(z).offset=(e-1)*d(z).limit},null,8,[`page`,`page-count`])]),_:1},8,[`q`,`rows`,`total`,`loading`,`error`,`onRefresh`]),v(d(E),{show:q.value,width:520,placement:`right`,"mask-closable":!0,"onUpdate:show":r[4]||=e=>{e||X()}},{default:t(()=>[v(d(D),{title:`Backup detail`,closable:``,onClose:X},{default:t(()=>[J.value?(n(),g(m,{key:0},[v(d(f),{style:{"margin-bottom":`20px`}},{default:t(()=>[J.value.status===`completed`&&J.value.file_path?(n(),c(d(s),{key:0,type:`primary`,size:`small`,onClick:r[3]||=e=>Q(J.value)},{default:t(()=>[...r[7]||=[o(` Download `,-1)]]),_:1})):a(``,!0)]),_:1}),v(d(S),{bordered:``,"label-placement":`top`,column:1,size:`small`},{default:t(()=>[v(d(C),{label:`id`},{default:t(()=>[v(d(k),{code:``},{default:t(()=>[o(h(J.value.id),1)]),_:1})]),_:1}),v(d(C),{label:`kind`},{default:t(()=>[v(d(y),{type:J.value.kind===`full`?`primary`:`default`,size:`small`},{default:t(()=>[o(h(J.value.kind),1)]),_:1},8,[`type`])]),_:1}),v(d(C),{label:`status`},{default:t(()=>[v(d(y),{type:I[J.value.status]??`default`,size:`small`},{default:t(()=>[o(h(J.value.status),1)]),_:1},8,[`type`])]),_:1}),v(d(C),{label:`size`},{default:t(()=>[o(h(R(J.value.size)),1)]),_:1}),v(d(C),{label:`started_at`},{default:t(()=>[o(h(L(J.value.started_at)),1)]),_:1}),v(d(C),{label:`finished_at`},{default:t(()=>[o(h(L(J.value.finished_at)),1)]),_:1}),v(d(C),{label:`created_at`},{default:t(()=>[o(h(L(J.value.created_at)),1)]),_:1}),v(d(C),{label:`file_path`},{default:t(()=>[o(h(J.value.file_path??`—`),1)]),_:1})]),_:1}),J.value.error_message?(n(),g(m,{key:0},[v(d(A)),v(d(k),{strong:``,style:{display:`block`,"margin-bottom":`8px`}},{default:t(()=>[...r[8]||=[o(` Error `,-1)]]),_:1}),v(d(k),{type:`error`,style:{"white-space":`pre-wrap`,"font-size":`13px`}},{default:t(()=>[o(h(J.value.error_message),1)]),_:1})],64)):a(``,!0)],64)):(n(),c(d(k),{key:1,depth:`3`},{default:t(()=>[...r[9]||=[o(`Select a backup row to see details.`,-1)]]),_:1}))]),_:1})]),_:1},8,[`show`])]),_:1}))}});export{P as default};
2
+ //# sourceMappingURL=Backups-DzPlFgrm.js.map
@@ -0,0 +1,2 @@
1
+ import{Gn as e,In as t,Rn as n,Sn as r,_n as i,bn as a,gn as o,hn as s,r as c,sr as l,un as u,ur as d,vn as f,xn as p}from"./Space-n5-XcguU.js";import{t as m}from"./Tag-D1fOKpTH.js";import{n as h,t as g}from"./Grid-hFkp9F4P.js";import{l as _,s as v}from"./resources-Bt6thQCD.js";import{c as y,s as b}from"./index-CeE6v959.js";import{t as x}from"./useResource-C_rJCY8C.js";import{n as S,t as C}from"./EmptyState-DeDck-OL.js";var w={style:{display:`flex`,"align-items":`center`,gap:`8px`}},T={style:{display:`grid`,"grid-template-columns":`1fr 1fr`,gap:`12px`}},E={style:{"margin-top":`12px`}},D={style:{"margin-top":`8px`}},O=r({__name:`Buckets`,setup(r){let O=b(),{data:k,loading:A,error:j,refresh:M}=x(()=>v.buckets());function N(e){if(e===0)return`0 B`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=Math.min(Math.floor(Math.log(e)/Math.log(1024)),t.length-1);return`${(e/1024**n).toFixed(n===0?0:1)} ${t[n]}`}function P(e){O.push(`/storage/${encodeURIComponent(e.name)}`)}function F(e,t){return e?`success`:t.object_count>0?`warning`:`default`}return(r,v)=>(t(),f(`div`,null,[v[3]||=s(`div`,{style:{display:`flex`,"align-items":`center`,"justify-content":`space-between`,"margin-bottom":`16px`}},[s(`h1`,{style:{margin:`0`,"font-size":`20px`,"font-weight":`600`}},` Storage Buckets `)],-1),p(S,{error:l(j),retry:l(M)},null,8,[`error`,`retry`]),p(l(_),{show:l(A)},{default:e(()=>[l(k)&&l(k).length?(t(),o(l(g),{key:0,cols:`1 s:2 m:3 l:4`,responsive:`screen`,"x-gap":16,"y-gap":16},{default:e(()=>[(t(!0),f(u,null,n(l(k),n=>(t(),o(l(h),{key:n.id},{default:e(()=>[p(l(c),{size:`small`,hoverable:``,segmented:{content:!0},onClick:e=>P(n)},{header:e(()=>[s(`div`,w,[p(l(m),{type:F(n.public,n),size:`small`,bordered:!1},{default:e(()=>[a(d(n.public?`Public`:`Private`),1)]),_:2},1032,[`type`]),p(l(y),{strong:``,style:{"font-size":`14px`,flex:`1`,"min-width":`0`,overflow:`hidden`,"text-overflow":`ellipsis`,"white-space":`nowrap`}},{default:e(()=>[a(d(n.name),1)]),_:2},1024)])]),default:e(()=>[s(`div`,T,[s(`div`,null,[p(l(y),{depth:`3`,style:{"font-size":`11px`,display:`block`,"margin-bottom":`2px`}},{default:e(()=>[...v[0]||=[a(` Objects `,-1)]]),_:1}),p(l(y),{strong:``,style:{"font-size":`20px`}},{default:e(()=>[a(d(n.object_count.toLocaleString()),1)]),_:2},1024)]),s(`div`,null,[p(l(y),{depth:`3`,style:{"font-size":`11px`,display:`block`,"margin-bottom":`2px`}},{default:e(()=>[...v[1]||=[a(` Total Size `,-1)]]),_:1}),p(l(y),{strong:``,style:{"font-size":`16px`}},{default:e(()=>[a(d(N(n.total_size)),1)]),_:2},1024)])]),s(`div`,E,[p(l(y),{depth:`3`,style:{"font-size":`11px`,display:`block`,"margin-bottom":`2px`}},{default:e(()=>[...v[2]||=[a(` Owner `,-1)]]),_:1}),p(l(y),{code:``,style:{"font-size":`12px`}},{default:e(()=>[a(d(n.owner?n.owner.slice(0,8)+`…`:`(none)`),1)]),_:2},1024)]),s(`div`,D,[p(l(y),{depth:`3`,style:{"font-size":`11px`}},{default:e(()=>[a(` Created `+d(new Date(n.created_at).toLocaleDateString()),1)]),_:2},1024)])]),_:2},1032,[`onClick`])]),_:2},1024))),128))]),_:1})):l(k)&&!l(k).length?(t(),o(C,{key:1,description:`No storage buckets found.`})):i(``,!0)]),_:1},8,[`show`])]))}});export{O as default};
2
+ //# sourceMappingURL=Buckets-ByacGkU1.js.map