supython 0.5.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 (188) hide show
  1. supython/__init__.py +8 -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 +149 -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/body_size.py +184 -0
  100. supython/cli.py +1653 -0
  101. supython/client/__init__.py +67 -0
  102. supython/client/_auth.py +249 -0
  103. supython/client/_client.py +145 -0
  104. supython/client/_config.py +92 -0
  105. supython/client/_functions.py +69 -0
  106. supython/client/_storage.py +255 -0
  107. supython/client/py.typed +0 -0
  108. supython/db.py +151 -0
  109. supython/db_admin.py +8 -0
  110. supython/functions/__init__.py +19 -0
  111. supython/functions/context.py +262 -0
  112. supython/functions/loader.py +307 -0
  113. supython/functions/router.py +228 -0
  114. supython/functions/schemas.py +50 -0
  115. supython/gen/__init__.py +5 -0
  116. supython/gen/_introspect.py +137 -0
  117. supython/gen/types_py.py +270 -0
  118. supython/gen/types_ts.py +365 -0
  119. supython/health.py +229 -0
  120. supython/hooks.py +117 -0
  121. supython/jobs/__init__.py +31 -0
  122. supython/jobs/backends.py +97 -0
  123. supython/jobs/context.py +58 -0
  124. supython/jobs/cron.py +152 -0
  125. supython/jobs/cron_inproc.py +118 -0
  126. supython/jobs/decorators.py +76 -0
  127. supython/jobs/registry.py +79 -0
  128. supython/jobs/router.py +136 -0
  129. supython/jobs/schemas.py +92 -0
  130. supython/jobs/service.py +311 -0
  131. supython/jobs/worker.py +219 -0
  132. supython/jwks.py +257 -0
  133. supython/keyset.py +279 -0
  134. supython/logging_config.py +291 -0
  135. supython/mail.py +33 -0
  136. supython/mailer.py +65 -0
  137. supython/migrate.py +81 -0
  138. supython/migrations/0001_extensions_and_roles.sql +46 -0
  139. supython/migrations/0002_auth_schema.sql +66 -0
  140. supython/migrations/0003_demo_todos.sql +42 -0
  141. supython/migrations/0004_auth_v0_2.sql +47 -0
  142. supython/migrations/0005_storage_schema.sql +117 -0
  143. supython/migrations/0006_realtime_schema.sql +206 -0
  144. supython/migrations/0007_jobs_schema.sql +254 -0
  145. supython/migrations/0008_jobs_last_error.sql +56 -0
  146. supython/migrations/0009_auth_rate_limits.sql +33 -0
  147. supython/migrations/0010_worker_heartbeat.sql +14 -0
  148. supython/migrations/0011_admin_schema.sql +45 -0
  149. supython/migrations/0012_auth_banned_until.sql +10 -0
  150. supython/migrations/0013_email_templates.sql +19 -0
  151. supython/migrations/0014_realtime_payload_warning.sql +96 -0
  152. supython/migrations/0015_backups_schema.sql +14 -0
  153. supython/passwords.py +15 -0
  154. supython/realtime/__init__.py +6 -0
  155. supython/realtime/broker.py +814 -0
  156. supython/realtime/protocol.py +234 -0
  157. supython/realtime/router.py +184 -0
  158. supython/realtime/schemas.py +207 -0
  159. supython/realtime/service.py +261 -0
  160. supython/realtime/topics.py +175 -0
  161. supython/realtime/websocket.py +586 -0
  162. supython/scaffold/__init__.py +5 -0
  163. supython/scaffold/init_project.py +133 -0
  164. supython/scaffold/templates/Caddyfile.tmpl +4 -0
  165. supython/scaffold/templates/README.md.tmpl +22 -0
  166. supython/scaffold/templates/docker-compose.prod.yml.tmpl +84 -0
  167. supython/scaffold/templates/docker-compose.yml.tmpl +41 -0
  168. supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +9 -0
  169. supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +3 -0
  170. supython/scaffold/templates/env.example.tmpl +149 -0
  171. supython/scaffold/templates/functions_README.md.tmpl +21 -0
  172. supython/scaffold/templates/gitignore.tmpl +14 -0
  173. supython/scaffold/templates/migrations/.gitkeep +0 -0
  174. supython/secretset.py +347 -0
  175. supython/security_headers.py +78 -0
  176. supython/settings.py +198 -0
  177. supython/storage/__init__.py +5 -0
  178. supython/storage/backends.py +392 -0
  179. supython/storage/router.py +341 -0
  180. supython/storage/schemas.py +50 -0
  181. supython/storage/service.py +445 -0
  182. supython/storage/signing.py +119 -0
  183. supython/tokens.py +85 -0
  184. supython-0.5.0.dist-info/METADATA +714 -0
  185. supython-0.5.0.dist-info/RECORD +188 -0
  186. supython-0.5.0.dist-info/WHEEL +4 -0
  187. supython-0.5.0.dist-info/entry_points.txt +2 -0
  188. supython-0.5.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