fix: address code review findings for DNS management
- CRITICAL: Change DNS zones endpoint from GET to POST to avoid leaking API token in URL query parameters - HIGH: Add sync.RWMutex to protect dnsProvider field in Server, Deployer, and proxy Manager against concurrent read/write races - HIGH: Capture old DNS provider reference synchronously before launching background cleanup goroutine - HIGH: Use getDNS()/getDNSProviderLocked() accessors instead of direct field reads in all DNS operations
This commit is contained in:
@@ -0,0 +1,581 @@
|
||||
{
|
||||
".svelte-kit/generated/server/internal.js": {
|
||||
"file": "internal.js",
|
||||
"name": "internal",
|
||||
"src": ".svelte-kit/generated/server/internal.js",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_root.js",
|
||||
"_environment.js",
|
||||
"_internal.js"
|
||||
]
|
||||
},
|
||||
"_EntityPicker.RxInhUBX.css": {
|
||||
"file": "_app/immutable/assets/EntityPicker.RxInhUBX.css",
|
||||
"src": "_EntityPicker.RxInhUBX.css"
|
||||
},
|
||||
"_EntityPicker.js": {
|
||||
"file": "chunks/EntityPicker.js",
|
||||
"name": "EntityPicker",
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_IconX.js",
|
||||
"_index2.js"
|
||||
],
|
||||
"css": [
|
||||
"_app/immutable/assets/EntityPicker.RxInhUBX.css"
|
||||
]
|
||||
},
|
||||
"_FormField.js": {
|
||||
"file": "chunks/FormField.js",
|
||||
"name": "FormField",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconAlert.js": {
|
||||
"file": "chunks/IconAlert.js",
|
||||
"name": "IconAlert",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconCheck.js": {
|
||||
"file": "chunks/IconCheck.js",
|
||||
"name": "IconCheck",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconChevronRight.js": {
|
||||
"file": "chunks/IconChevronRight.js",
|
||||
"name": "IconChevronRight",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconDeploy.js": {
|
||||
"file": "chunks/IconDeploy.js",
|
||||
"name": "IconDeploy",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconGlobe.js": {
|
||||
"file": "chunks/IconGlobe.js",
|
||||
"name": "IconGlobe",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconLoader.js": {
|
||||
"file": "chunks/IconLoader.js",
|
||||
"name": "IconLoader",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconPlus.js": {
|
||||
"file": "chunks/IconPlus.js",
|
||||
"name": "IconPlus",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconSettings.js": {
|
||||
"file": "chunks/IconSettings.js",
|
||||
"name": "IconSettings",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconTrash.js": {
|
||||
"file": "chunks/IconTrash.js",
|
||||
"name": "IconTrash",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_IconX.js": {
|
||||
"file": "chunks/IconX.js",
|
||||
"name": "IconX",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_Skeleton.js": {
|
||||
"file": "chunks/Skeleton.js",
|
||||
"name": "Skeleton",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_SkeletonCard.js": {
|
||||
"file": "chunks/SkeletonCard.js",
|
||||
"name": "SkeletonCard",
|
||||
"imports": [
|
||||
"_Skeleton.js"
|
||||
]
|
||||
},
|
||||
"_api.js": {
|
||||
"file": "chunks/api.js",
|
||||
"name": "api"
|
||||
},
|
||||
"_environment.js": {
|
||||
"file": "chunks/environment.js",
|
||||
"name": "environment"
|
||||
},
|
||||
"_exports.js": {
|
||||
"file": "chunks/exports.js",
|
||||
"name": "exports"
|
||||
},
|
||||
"_false.js": {
|
||||
"file": "chunks/false.js",
|
||||
"name": "false"
|
||||
},
|
||||
"_index-server.js": {
|
||||
"file": "chunks/index-server.js",
|
||||
"name": "index-server",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_index.js": {
|
||||
"file": "chunks/index.js",
|
||||
"name": "index",
|
||||
"imports": [
|
||||
"_false.js"
|
||||
]
|
||||
},
|
||||
"_index2.js": {
|
||||
"file": "chunks/index2.js",
|
||||
"name": "index",
|
||||
"imports": [
|
||||
"_index3.js"
|
||||
]
|
||||
},
|
||||
"_index3.js": {
|
||||
"file": "chunks/index3.js",
|
||||
"name": "index",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_internal.js": {
|
||||
"file": "chunks/internal.js",
|
||||
"name": "internal",
|
||||
"imports": [
|
||||
"_root.js",
|
||||
"_environment.js"
|
||||
]
|
||||
},
|
||||
"_root.js": {
|
||||
"file": "chunks/root.js",
|
||||
"name": "root",
|
||||
"imports": [
|
||||
"_index.js"
|
||||
]
|
||||
},
|
||||
"_shared.js": {
|
||||
"file": "chunks/shared.js",
|
||||
"name": "shared",
|
||||
"imports": [
|
||||
"_utils.js"
|
||||
]
|
||||
},
|
||||
"_state.svelte.js": {
|
||||
"file": "chunks/state.svelte.js",
|
||||
"name": "state.svelte",
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_root.js"
|
||||
]
|
||||
},
|
||||
"_stores.js": {
|
||||
"file": "chunks/stores.js",
|
||||
"name": "stores",
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_root.js",
|
||||
"_state.svelte.js"
|
||||
]
|
||||
},
|
||||
"_theme.js": {
|
||||
"file": "chunks/theme.js",
|
||||
"name": "theme",
|
||||
"imports": [
|
||||
"_index3.js"
|
||||
]
|
||||
},
|
||||
"_toast.js": {
|
||||
"file": "chunks/toast.js",
|
||||
"name": "toast",
|
||||
"imports": [
|
||||
"_index3.js"
|
||||
]
|
||||
},
|
||||
"_utils.js": {
|
||||
"file": "chunks/utils.js",
|
||||
"name": "utils"
|
||||
},
|
||||
"node_modules/@sveltejs/kit/src/runtime/app/server/remote/index.js": {
|
||||
"file": "remote-entry.js",
|
||||
"name": "remote-entry",
|
||||
"src": "node_modules/@sveltejs/kit/src/runtime/app/server/remote/index.js",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_shared.js",
|
||||
"_false.js",
|
||||
"_environment.js"
|
||||
]
|
||||
},
|
||||
"node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte": {
|
||||
"file": "entries/fallbacks/error.svelte.js",
|
||||
"name": "entries/fallbacks/error.svelte",
|
||||
"src": "node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_state.svelte.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_index3.js",
|
||||
"_root.js"
|
||||
]
|
||||
},
|
||||
"node_modules/@sveltejs/kit/src/runtime/server/index.js": {
|
||||
"file": "index.js",
|
||||
"name": "index",
|
||||
"src": "node_modules/@sveltejs/kit/src/runtime/server/index.js",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_false.js",
|
||||
"_environment.js",
|
||||
"_shared.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_index3.js",
|
||||
"_internal.js"
|
||||
]
|
||||
},
|
||||
"src/routes/+layout.svelte": {
|
||||
"file": "entries/pages/_layout.svelte.js",
|
||||
"name": "entries/pages/_layout.svelte",
|
||||
"src": "src/routes/+layout.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index-server.js",
|
||||
"_stores.js",
|
||||
"_toast.js",
|
||||
"_IconCheck.js",
|
||||
"_IconX.js",
|
||||
"_IconAlert.js",
|
||||
"_theme.js",
|
||||
"_index2.js",
|
||||
"_IconGlobe.js",
|
||||
"_IconDeploy.js",
|
||||
"_IconSettings.js",
|
||||
"_index3.js"
|
||||
],
|
||||
"css": [
|
||||
"_app/immutable/assets/_layout.ZH2qq8sR.css"
|
||||
]
|
||||
},
|
||||
"src/routes/+layout.ts": {
|
||||
"file": "entries/pages/_layout.ts.js",
|
||||
"name": "entries/pages/_layout.ts",
|
||||
"src": "src/routes/+layout.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/+page.svelte": {
|
||||
"file": "entries/pages/_page.svelte.js",
|
||||
"name": "entries/pages/_page.svelte",
|
||||
"src": "src/routes/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index2.js",
|
||||
"_IconDeploy.js",
|
||||
"_IconAlert.js",
|
||||
"_SkeletonCard.js"
|
||||
]
|
||||
},
|
||||
"src/routes/containers/stale/+page.svelte": {
|
||||
"file": "entries/pages/containers/stale/_page.svelte.js",
|
||||
"name": "entries/pages/containers/stale/_page.svelte",
|
||||
"src": "src/routes/containers/stale/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_api.js",
|
||||
"_IconTrash.js",
|
||||
"_IconLoader.js",
|
||||
"_index2.js",
|
||||
"_IconAlert.js",
|
||||
"_SkeletonCard.js",
|
||||
"_toast.js"
|
||||
]
|
||||
},
|
||||
"src/routes/containers/stale/+page.ts": {
|
||||
"file": "entries/pages/containers/stale/_page.ts.js",
|
||||
"name": "entries/pages/containers/stale/_page.ts",
|
||||
"src": "src/routes/containers/stale/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/deploy/+page.svelte": {
|
||||
"file": "entries/pages/deploy/_page.svelte.js",
|
||||
"name": "entries/pages/deploy/_page.svelte",
|
||||
"src": "src/routes/deploy/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_FormField.js",
|
||||
"_EntityPicker.js",
|
||||
"_toast.js",
|
||||
"_index2.js"
|
||||
]
|
||||
},
|
||||
"src/routes/events/+page.svelte": {
|
||||
"file": "entries/pages/events/_page.svelte.js",
|
||||
"name": "entries/pages/events/_page.svelte",
|
||||
"src": "src/routes/events/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index-server.js",
|
||||
"_index2.js"
|
||||
]
|
||||
},
|
||||
"src/routes/events/+page.ts": {
|
||||
"file": "entries/pages/events/_page.ts.js",
|
||||
"name": "entries/pages/events/_page.ts",
|
||||
"src": "src/routes/events/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/login/+page.svelte": {
|
||||
"file": "entries/pages/login/_page.svelte.js",
|
||||
"name": "entries/pages/login/_page.svelte",
|
||||
"src": "src/routes/login/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_root.js",
|
||||
"_state.svelte.js",
|
||||
"_index2.js",
|
||||
"_theme.js"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/+page.svelte": {
|
||||
"file": "entries/pages/projects/_page.svelte.js",
|
||||
"name": "entries/pages/projects/_page.svelte",
|
||||
"src": "src/routes/projects/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index2.js",
|
||||
"_IconPlus.js",
|
||||
"_Skeleton.js"
|
||||
],
|
||||
"css": [
|
||||
"_app/immutable/assets/EntityPicker.RxInhUBX.css"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/[id]/+page.svelte": {
|
||||
"file": "entries/pages/projects/_id_/_page.svelte.js",
|
||||
"name": "entries/pages/projects/_id_/_page.svelte",
|
||||
"src": "src/routes/projects/[id]/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_root.js",
|
||||
"_state.svelte.js",
|
||||
"_index2.js",
|
||||
"_Skeleton.js",
|
||||
"_toast.js"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/[id]/env/+page.svelte": {
|
||||
"file": "entries/pages/projects/_id_/env/_page.svelte.js",
|
||||
"name": "entries/pages/projects/_id_/env/_page.svelte",
|
||||
"src": "src/routes/projects/[id]/env/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_stores.js",
|
||||
"_toast.js",
|
||||
"_index2.js",
|
||||
"_IconChevronRight.js",
|
||||
"_Skeleton.js"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/[id]/volumes/+page.svelte": {
|
||||
"file": "entries/pages/projects/_id_/volumes/_page.svelte.js",
|
||||
"name": "entries/pages/projects/_id_/volumes/_page.svelte",
|
||||
"src": "src/routes/projects/[id]/volumes/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_stores.js",
|
||||
"_toast.js",
|
||||
"_index2.js",
|
||||
"_IconChevronRight.js",
|
||||
"_Skeleton.js"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/[id]/volumes/[volId]/browse/+page.svelte": {
|
||||
"file": "entries/pages/projects/_id_/volumes/_volId_/browse/_page.svelte.js",
|
||||
"name": "entries/pages/projects/_id_/volumes/_volId_/browse/_page.svelte",
|
||||
"src": "src/routes/projects/[id]/volumes/[volId]/browse/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_stores.js",
|
||||
"_toast.js",
|
||||
"_index2.js",
|
||||
"_IconChevronRight.js",
|
||||
"_Skeleton.js"
|
||||
]
|
||||
},
|
||||
"src/routes/projects/[id]/volumes/[volId]/browse/+page.ts": {
|
||||
"file": "entries/pages/projects/_id_/volumes/_volId_/browse/_page.ts.js",
|
||||
"name": "entries/pages/projects/_id_/volumes/_volId_/browse/_page.ts",
|
||||
"src": "src/routes/projects/[id]/volumes/[volId]/browse/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/proxies/+page.svelte": {
|
||||
"file": "entries/pages/proxies/_page.svelte.js",
|
||||
"name": "entries/pages/proxies/_page.svelte",
|
||||
"src": "src/routes/proxies/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index2.js",
|
||||
"_IconGlobe.js",
|
||||
"_IconLoader.js"
|
||||
]
|
||||
},
|
||||
"src/routes/proxies/+page.ts": {
|
||||
"file": "entries/pages/proxies/_page.ts.js",
|
||||
"name": "entries/pages/proxies/_page.ts",
|
||||
"src": "src/routes/proxies/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/proxies/[id]/edit/+page.svelte": {
|
||||
"file": "entries/pages/proxies/_id_/edit/_page.svelte.js",
|
||||
"name": "entries/pages/proxies/_id_/edit/_page.svelte",
|
||||
"src": "src/routes/proxies/[id]/edit/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_root.js",
|
||||
"_state.svelte.js",
|
||||
"_index2.js",
|
||||
"_IconGlobe.js",
|
||||
"_IconLoader.js"
|
||||
]
|
||||
},
|
||||
"src/routes/proxies/[id]/edit/+page.ts": {
|
||||
"file": "entries/pages/proxies/_id_/edit/_page.ts.js",
|
||||
"name": "entries/pages/proxies/_id_/edit/_page.ts",
|
||||
"src": "src/routes/proxies/[id]/edit/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/proxies/create/+page.svelte": {
|
||||
"file": "entries/pages/proxies/create/_page.svelte.js",
|
||||
"name": "entries/pages/proxies/create/_page.svelte",
|
||||
"src": "src/routes/proxies/create/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_exports.js",
|
||||
"_utils.js",
|
||||
"_root.js",
|
||||
"_state.svelte.js",
|
||||
"_index2.js",
|
||||
"_api.js",
|
||||
"_FormField.js",
|
||||
"_IconCheck.js",
|
||||
"_IconX.js",
|
||||
"_IconLoader.js",
|
||||
"_IconGlobe.js"
|
||||
]
|
||||
},
|
||||
"src/routes/proxies/create/+page.ts": {
|
||||
"file": "entries/pages/proxies/create/_page.ts.js",
|
||||
"name": "entries/pages/proxies/create/_page.ts",
|
||||
"src": "src/routes/proxies/create/+page.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"src/routes/settings/+layout.svelte": {
|
||||
"file": "entries/pages/settings/_layout.svelte.js",
|
||||
"name": "entries/pages/settings/_layout.svelte",
|
||||
"src": "src/routes/settings/+layout.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_stores.js",
|
||||
"_index2.js",
|
||||
"_IconSettings.js"
|
||||
]
|
||||
},
|
||||
"src/routes/settings/+page.svelte": {
|
||||
"file": "entries/pages/settings/_page.svelte.js",
|
||||
"name": "entries/pages/settings/_page.svelte",
|
||||
"src": "src/routes/settings/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_EntityPicker.js",
|
||||
"_toast.js",
|
||||
"_index2.js",
|
||||
"_Skeleton.js"
|
||||
]
|
||||
},
|
||||
"src/routes/settings/auth/+page.svelte": {
|
||||
"file": "entries/pages/settings/auth/_page.svelte.js",
|
||||
"name": "entries/pages/settings/auth/_page.svelte",
|
||||
"src": "src/routes/settings/auth/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_index2.js",
|
||||
"_IconTrash.js",
|
||||
"_IconPlus.js"
|
||||
]
|
||||
},
|
||||
"src/routes/settings/credentials/+page.svelte": {
|
||||
"file": "entries/pages/settings/credentials/_page.svelte.js",
|
||||
"name": "entries/pages/settings/credentials/_page.svelte",
|
||||
"src": "src/routes/settings/credentials/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_Skeleton.js",
|
||||
"_toast.js",
|
||||
"_index2.js"
|
||||
]
|
||||
},
|
||||
"src/routes/settings/registries/+page.svelte": {
|
||||
"file": "entries/pages/settings/registries/_page.svelte.js",
|
||||
"name": "entries/pages/settings/registries/_page.svelte",
|
||||
"src": "src/routes/settings/registries/+page.svelte",
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"_index.js",
|
||||
"_Skeleton.js",
|
||||
"_toast.js",
|
||||
"_index2.js",
|
||||
"_IconPlus.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.entity-picker-backdrop.svelte-1bxz98v{position:fixed;inset:0;z-index:60;background:var(--surface-overlay);backdrop-filter:blur(4px);animation:fade-in var(--transition-normal) forwards}.entity-picker-container.svelte-1bxz98v{position:fixed;inset:0;z-index:61;display:flex;align-items:flex-start;justify-content:center;padding-top:12vh;pointer-events:none}.entity-picker-modal.svelte-1bxz98v{pointer-events:auto;width:90vw;max-width:500px;background:var(--surface-card);border:1px solid var(--border-primary);border-radius:var(--radius-xl);box-shadow:var(--shadow-xl);overflow:hidden;animation:scale-in var(--transition-normal) forwards;display:flex;flex-direction:column}.entity-picker-header.svelte-1bxz98v{display:flex;align-items:center;justify-content:space-between;padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--border-secondary)}.entity-picker-title.svelte-1bxz98v{font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--text-primary);margin:0}.entity-picker-close.svelte-1bxz98v{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:var(--radius-md);background:transparent;color:var(--text-tertiary);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.entity-picker-close.svelte-1bxz98v:hover{background:var(--surface-card-hover);color:var(--text-primary)}.entity-picker-search.svelte-1bxz98v{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--border-secondary)}.entity-picker-search-icon{flex-shrink:0;color:var(--text-tertiary)}.entity-picker-search-input.svelte-1bxz98v{flex:1;border:none;outline:none;background:transparent;font-size:var(--text-sm);color:var(--text-primary);font-family:var(--font-family-sans)}.entity-picker-search-input.svelte-1bxz98v::placeholder{color:var(--text-tertiary)}.entity-picker-close-inline.svelte-1bxz98v{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--text-tertiary);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.entity-picker-close-inline.svelte-1bxz98v:hover{background:var(--surface-card-hover);color:var(--text-primary)}.entity-picker-list.svelte-1bxz98v{overflow-y:auto;max-height:60vh;padding:var(--space-1) 0}.entity-picker-empty.svelte-1bxz98v{padding:var(--space-8) var(--space-4);text-align:center;font-size:var(--text-sm);color:var(--text-tertiary)}.entity-picker-group-header.svelte-1bxz98v{padding:var(--space-2) var(--space-4) var(--space-1);font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.05em}.entity-picker-item.svelte-1bxz98v{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-4);border:none;background:transparent;cursor:pointer;text-align:left;font-family:var(--font-family-sans);transition:background var(--transition-fast);border-left:3px solid transparent}.entity-picker-item--highlighted.svelte-1bxz98v{background:var(--surface-card-hover)}.entity-picker-item--current.svelte-1bxz98v{border-left-color:var(--color-brand-500)}.entity-picker-item-icon.svelte-1bxz98v{flex-shrink:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:var(--text-tertiary)}.entity-picker-item-content.svelte-1bxz98v{display:flex;flex-direction:column;gap:1px;min-width:0}.entity-picker-item-label.svelte-1bxz98v{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.entity-picker-item-description.svelte-1bxz98v{font-size:var(--text-xs);color:var(--text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.entity-picker-item--disabled.svelte-1bxz98v{opacity:.45;cursor:default;pointer-events:none}.entity-picker-item-hint.svelte-1bxz98v{font-size:var(--text-xs);color:var(--text-tertiary);font-style:italic;white-space:nowrap}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,140 @@
|
||||
import { a as attr, b as attr_class, c as clsx, e as escape_html, s as store_get, f as ensure_array_like, u as unsubscribe_stores, k as bind_props, i as derived } from "./index.js";
|
||||
import { I as IconX } from "./IconX.js";
|
||||
import { t } from "./index2.js";
|
||||
/* empty css */
|
||||
function html(value) {
|
||||
var html2 = String(value ?? "");
|
||||
var open = "<!---->";
|
||||
return open + html2 + "<!---->";
|
||||
}
|
||||
function IconSearch($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg>`);
|
||||
}
|
||||
function EntityPicker($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const {
|
||||
open = void 0,
|
||||
items,
|
||||
current = "",
|
||||
placeholder,
|
||||
title = "",
|
||||
onselect,
|
||||
onclose
|
||||
} = $$props;
|
||||
let query = "";
|
||||
let highlightIndex = 0;
|
||||
const filtered = derived(() => {
|
||||
const q = query.toLowerCase().trim();
|
||||
if (!q) return items;
|
||||
return items.filter((item) => item.label.toLowerCase().includes(q) || (item.description?.toLowerCase().includes(q) ?? false));
|
||||
});
|
||||
const grouped = derived(() => {
|
||||
const groups = [];
|
||||
const seen = /* @__PURE__ */ new Map();
|
||||
for (const item of filtered()) {
|
||||
const groupName = item.group ?? "";
|
||||
const idx = seen.get(groupName);
|
||||
if (idx !== void 0) {
|
||||
groups[idx].items.push(item);
|
||||
} else {
|
||||
seen.set(groupName, groups.length);
|
||||
groups.push({ name: groupName, items: [item] });
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
});
|
||||
const flatFiltered = derived(filtered);
|
||||
function flatIndexOf(groupIdx, itemIdx) {
|
||||
let index = 0;
|
||||
for (let g = 0; g < groupIdx; g++) {
|
||||
index += grouped()[g].items.length;
|
||||
}
|
||||
return index + itemIdx;
|
||||
}
|
||||
if (open) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="entity-picker-backdrop svelte-1bxz98v"></div> <div class="entity-picker-container svelte-1bxz98v"><div class="entity-picker-modal svelte-1bxz98v" role="dialog" aria-modal="true"${attr("aria-label", title)}>`);
|
||||
if (title) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="entity-picker-header svelte-1bxz98v"><h2 class="entity-picker-title svelte-1bxz98v">${escape_html(title)}</h2> <button type="button" class="entity-picker-close svelte-1bxz98v" aria-label="Close">`);
|
||||
IconX($$renderer2, { size: 18 });
|
||||
$$renderer2.push(`<!----></button></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="entity-picker-search svelte-1bxz98v">`);
|
||||
IconSearch($$renderer2, { size: 16, class: "entity-picker-search-icon" });
|
||||
$$renderer2.push(`<!----> <input${attr("value", query)} type="text" class="entity-picker-search-input svelte-1bxz98v"${attr("placeholder", placeholder ?? store_get($$store_subs ??= {}, "$t", t)("entityPicker.search"))} autocomplete="off" spellcheck="false"/> `);
|
||||
if (!title) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<button type="button" class="entity-picker-close-inline svelte-1bxz98v" aria-label="Close">`);
|
||||
IconX($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----></button>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> <div class="entity-picker-list svelte-1bxz98v">`);
|
||||
if (flatFiltered().length === 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="entity-picker-empty svelte-1bxz98v">${escape_html(store_get($$store_subs ??= {}, "$t", t)("entityPicker.noResults"))}</div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`<!--[-->`);
|
||||
const each_array = ensure_array_like(grouped());
|
||||
for (let gIdx = 0, $$length = each_array.length; gIdx < $$length; gIdx++) {
|
||||
let group = each_array[gIdx];
|
||||
if (group.name) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="entity-picker-group-header svelte-1bxz98v">${escape_html(group.name)}</div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <!--[-->`);
|
||||
const each_array_1 = ensure_array_like(group.items);
|
||||
for (let iIdx = 0, $$length2 = each_array_1.length; iIdx < $$length2; iIdx++) {
|
||||
let item = each_array_1[iIdx];
|
||||
const flatIdx = flatIndexOf(gIdx, iIdx);
|
||||
const isHighlighted = flatIdx === highlightIndex;
|
||||
const isCurrent = item.value === current;
|
||||
$$renderer2.push(`<button type="button"${attr_class("entity-picker-item svelte-1bxz98v", void 0, {
|
||||
"entity-picker-item--highlighted": isHighlighted && !item.disabled,
|
||||
"entity-picker-item--current": isCurrent,
|
||||
"entity-picker-item--disabled": item.disabled
|
||||
})}${attr("data-highlighted", isHighlighted)}${attr("disabled", item.disabled, true)}>`);
|
||||
if (item.icon) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="entity-picker-item-icon svelte-1bxz98v">${html(item.icon)}</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <span class="entity-picker-item-content svelte-1bxz98v"><span class="entity-picker-item-label svelte-1bxz98v">${escape_html(item.label)}</span> `);
|
||||
if (item.disabledHint) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="entity-picker-item-hint svelte-1bxz98v">${escape_html(item.disabledHint)}</span>`);
|
||||
} else if (item.description) {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
$$renderer2.push(`<span class="entity-picker-item-description svelte-1bxz98v">${escape_html(item.description)}</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></span></button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div></div></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
bind_props($$props, { open });
|
||||
});
|
||||
}
|
||||
export {
|
||||
EntityPicker as E,
|
||||
IconSearch as I
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
import { a as attr, e as escape_html, b as attr_class, k as bind_props, g as stringify } from "./index.js";
|
||||
function FormField($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
let {
|
||||
label,
|
||||
name,
|
||||
type = "text",
|
||||
value = "",
|
||||
placeholder = "",
|
||||
required = false,
|
||||
disabled = false,
|
||||
error = "",
|
||||
helpText = "",
|
||||
oninput
|
||||
} = $$props;
|
||||
const inputBase = "w-full rounded-lg border px-3 py-2 text-sm transition-all duration-150 focus:outline-none focus:ring-2 bg-[var(--surface-input)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]";
|
||||
const inputNormal = "border-[var(--border-input)] focus:ring-[var(--color-brand-500)] focus:border-[var(--color-brand-500)]";
|
||||
const inputError = "border-[var(--color-danger)] focus:ring-[var(--color-danger)]";
|
||||
const inputDisabled = "opacity-60 cursor-not-allowed bg-[var(--surface-card-hover)]";
|
||||
$$renderer2.push(`<div class="flex flex-col gap-1.5"><label${attr("for", name)} class="text-sm font-medium text-[var(--text-primary)]">${escape_html(label)} `);
|
||||
if (required) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="text-[var(--color-danger)]">*</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></label> `);
|
||||
if (type === "textarea") {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<textarea${attr("id", name)}${attr("name", name)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr_class(`${stringify(inputBase)} ${stringify(error ? inputError : inputNormal)} ${stringify(disabled ? inputDisabled : "")}`)} rows="3">`);
|
||||
const $$body = escape_html(value);
|
||||
if ($$body) {
|
||||
$$renderer2.push(`${$$body}`);
|
||||
}
|
||||
$$renderer2.push(`</textarea>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`<input${attr("id", name)}${attr("name", name)}${attr("type", type)}${attr("value", value)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr_class(`${stringify(inputBase)} ${stringify(error ? inputError : inputNormal)} ${stringify(disabled ? inputDisabled : "")}`)}/>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
if (error) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<p class="text-xs text-[var(--color-danger)]">${escape_html(error)}</p>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
if (helpText && !error) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<p class="text-xs text-[var(--text-tertiary)]">${escape_html(helpText)}</p>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
bind_props($$props, { value });
|
||||
});
|
||||
}
|
||||
export {
|
||||
FormField as F
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconAlert($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path><path d="M12 9v4"></path><path d="M12 17h.01"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconAlert as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconCheck($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconCheck as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconChevronRight($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="m9 18 6-6-6-6"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconChevronRight as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconDeploy($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconDeploy as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconGlobe($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"></path><path d="M2 12h20"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconGlobe as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, g as stringify } from "./index.js";
|
||||
function IconLoader($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(`animate-spin ${stringify(c)}`)} aria-hidden="true"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconLoader as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconPlus($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconPlus as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconSettings($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"></path><circle cx="12" cy="12" r="3"></circle></svg>`);
|
||||
}
|
||||
export {
|
||||
IconSettings as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconTrash($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path><line x1="10" x2="10" y1="11" y2="17"></line><line x1="14" x2="14" y1="11" y2="17"></line></svg>`);
|
||||
}
|
||||
export {
|
||||
IconTrash as I
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { a as attr, b as attr_class, c as clsx } from "./index.js";
|
||||
function IconX($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M18 6 6 18"></path><path d="m6 6 12 12"></path></svg>`);
|
||||
}
|
||||
export {
|
||||
IconX as I
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { b as attr_class, l as attr_style, g as stringify } from "./index.js";
|
||||
function Skeleton($$renderer, $$props) {
|
||||
const {
|
||||
class: className = "",
|
||||
width = "100%",
|
||||
height = "1rem",
|
||||
rounded = false
|
||||
} = $$props;
|
||||
$$renderer.push(`<div${attr_class(`skeleton ${stringify(className)}`)}${attr_style(`width: ${stringify(width)}; height: ${stringify(height)}; ${stringify(rounded ? "border-radius: 9999px;" : "")}`)} aria-hidden="true"></div>`);
|
||||
}
|
||||
export {
|
||||
Skeleton as S
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import "clsx";
|
||||
import { S as Skeleton } from "./Skeleton.js";
|
||||
function SkeletonCard($$renderer) {
|
||||
$$renderer.push(`<div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div class="flex items-start justify-between"><div class="flex-1 space-y-2">`);
|
||||
Skeleton($$renderer, { width: "60%", height: "1.25rem" });
|
||||
$$renderer.push(`<!----> `);
|
||||
Skeleton($$renderer, { width: "80%", height: "0.875rem" });
|
||||
$$renderer.push(`<!----></div> `);
|
||||
Skeleton($$renderer, { width: "4rem", height: "1.5rem", rounded: true });
|
||||
$$renderer.push(`<!----></div> <div class="mt-4 flex gap-4">`);
|
||||
Skeleton($$renderer, { width: "5rem", height: "0.875rem" });
|
||||
$$renderer.push(`<!----> `);
|
||||
Skeleton($$renderer, { width: "4rem", height: "0.875rem" });
|
||||
$$renderer.push(`<!----></div> <div class="mt-3 flex gap-3">`);
|
||||
Skeleton($$renderer, { width: "3.5rem", height: "0.75rem" });
|
||||
$$renderer.push(`<!----> `);
|
||||
Skeleton($$renderer, { width: "4.5rem", height: "0.75rem" });
|
||||
$$renderer.push(`<!----></div></div>`);
|
||||
}
|
||||
export {
|
||||
SkeletonCard as S
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
const TOKEN_KEY = "auth_token";
|
||||
function getAuthToken() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
return localStorage.getItem(TOKEN_KEY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function clearAuth() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
}
|
||||
}
|
||||
class ApiError extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.name = "ApiError";
|
||||
}
|
||||
}
|
||||
async function request(path, init) {
|
||||
const token = getAuthToken();
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
...init?.headers
|
||||
};
|
||||
if (token) {
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
const res = await fetch(path, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
if (res.status === 401 && typeof window !== "undefined" && !path.includes("/auth/")) {
|
||||
clearAuth();
|
||||
window.location.href = "/login";
|
||||
throw new ApiError("Authentication required", 401);
|
||||
}
|
||||
let envelope;
|
||||
try {
|
||||
envelope = await res.json();
|
||||
} catch {
|
||||
throw new ApiError(
|
||||
`Server returned non-JSON response (HTTP ${res.status})`,
|
||||
res.status
|
||||
);
|
||||
}
|
||||
if (!envelope.success) {
|
||||
throw new ApiError(envelope.error ?? "Unknown API error", res.status);
|
||||
}
|
||||
return envelope.data;
|
||||
}
|
||||
function post(path, body) {
|
||||
return request(path, {
|
||||
method: "POST",
|
||||
body: body !== void 0 ? JSON.stringify(body) : void 0
|
||||
});
|
||||
}
|
||||
function validateProxy(host, port) {
|
||||
return post("/api/proxies/validate", { host, port });
|
||||
}
|
||||
function cleanupStaleContainer(id) {
|
||||
return post(`/api/containers/stale/${id}/cleanup`);
|
||||
}
|
||||
function bulkCleanupStaleContainers() {
|
||||
return post("/api/containers/stale/cleanup");
|
||||
}
|
||||
export {
|
||||
bulkCleanupStaleContainers as b,
|
||||
cleanupStaleContainer as c,
|
||||
validateProxy as v
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
let base = "";
|
||||
let assets = base;
|
||||
const app_dir = "_app";
|
||||
const relative = true;
|
||||
const initial = { base, assets };
|
||||
function override(paths) {
|
||||
base = paths.base;
|
||||
assets = paths.assets;
|
||||
}
|
||||
function reset() {
|
||||
base = initial.base;
|
||||
assets = initial.assets;
|
||||
}
|
||||
function set_assets(path) {
|
||||
assets = initial.assets = path;
|
||||
}
|
||||
let prerendering = false;
|
||||
function set_building() {
|
||||
}
|
||||
function set_prerendering() {
|
||||
prerendering = true;
|
||||
}
|
||||
export {
|
||||
set_building as a,
|
||||
set_prerendering as b,
|
||||
base as c,
|
||||
app_dir as d,
|
||||
assets as e,
|
||||
reset as f,
|
||||
override as o,
|
||||
prerendering as p,
|
||||
relative as r,
|
||||
set_assets as s
|
||||
};
|
||||
@@ -0,0 +1,174 @@
|
||||
const SCHEME = /^[a-z][a-z\d+\-.]+:/i;
|
||||
const internal = new URL("sveltekit-internal://");
|
||||
function resolve(base, path) {
|
||||
if (path[0] === "/" && path[1] === "/") return path;
|
||||
let url = new URL(base, internal);
|
||||
url = new URL(path, url);
|
||||
return url.protocol === internal.protocol ? url.pathname + url.search + url.hash : url.href;
|
||||
}
|
||||
function normalize_path(path, trailing_slash) {
|
||||
if (path === "/" || trailing_slash === "ignore") return path;
|
||||
if (trailing_slash === "never") {
|
||||
return path.endsWith("/") ? path.slice(0, -1) : path;
|
||||
} else if (trailing_slash === "always" && !path.endsWith("/")) {
|
||||
return path + "/";
|
||||
}
|
||||
return path;
|
||||
}
|
||||
function decode_pathname(pathname) {
|
||||
return pathname.split("%25").map(decodeURI).join("%25");
|
||||
}
|
||||
function decode_params(params) {
|
||||
for (const key in params) {
|
||||
params[key] = decodeURIComponent(params[key]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
function make_trackable(url, callback, search_params_callback, allow_hash = false) {
|
||||
const tracked = new URL(url);
|
||||
Object.defineProperty(tracked, "searchParams", {
|
||||
value: new Proxy(tracked.searchParams, {
|
||||
get(obj, key) {
|
||||
if (key === "get" || key === "getAll" || key === "has") {
|
||||
return (param, ...rest) => {
|
||||
search_params_callback(param);
|
||||
return obj[key](param, ...rest);
|
||||
};
|
||||
}
|
||||
callback();
|
||||
const value = Reflect.get(obj, key);
|
||||
return typeof value === "function" ? value.bind(obj) : value;
|
||||
}
|
||||
}),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
const tracked_url_properties = ["href", "pathname", "search", "toString", "toJSON"];
|
||||
if (allow_hash) tracked_url_properties.push("hash");
|
||||
for (const property of tracked_url_properties) {
|
||||
Object.defineProperty(tracked, property, {
|
||||
get() {
|
||||
callback();
|
||||
return url[property];
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
{
|
||||
tracked[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
|
||||
return inspect(url, opts);
|
||||
};
|
||||
tracked.searchParams[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
|
||||
return inspect(url.searchParams, opts);
|
||||
};
|
||||
}
|
||||
if (!allow_hash) {
|
||||
disable_hash(tracked);
|
||||
}
|
||||
return tracked;
|
||||
}
|
||||
function disable_hash(url) {
|
||||
allow_nodejs_console_log(url);
|
||||
Object.defineProperty(url, "hash", {
|
||||
get() {
|
||||
throw new Error(
|
||||
"Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead"
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
function disable_search(url) {
|
||||
allow_nodejs_console_log(url);
|
||||
for (const property of ["search", "searchParams"]) {
|
||||
Object.defineProperty(url, property, {
|
||||
get() {
|
||||
throw new Error(`Cannot access url.${property} on a page with prerendering enabled`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function allow_nodejs_console_log(url) {
|
||||
{
|
||||
url[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
|
||||
return inspect(new URL(url), opts);
|
||||
};
|
||||
}
|
||||
}
|
||||
function validator(expected) {
|
||||
function validate(module, file) {
|
||||
if (!module) return;
|
||||
for (const key in module) {
|
||||
if (key[0] === "_" || expected.has(key)) continue;
|
||||
const values = [...expected.values()];
|
||||
const hint = hint_for_supported_files(key, file?.slice(file.lastIndexOf("."))) ?? `valid exports are ${values.join(", ")}, or anything with a '_' prefix`;
|
||||
throw new Error(`Invalid export '${key}'${file ? ` in ${file}` : ""} (${hint})`);
|
||||
}
|
||||
}
|
||||
return validate;
|
||||
}
|
||||
function hint_for_supported_files(key, ext = ".js") {
|
||||
const supported_files = [];
|
||||
if (valid_layout_exports.has(key)) {
|
||||
supported_files.push(`+layout${ext}`);
|
||||
}
|
||||
if (valid_page_exports.has(key)) {
|
||||
supported_files.push(`+page${ext}`);
|
||||
}
|
||||
if (valid_layout_server_exports.has(key)) {
|
||||
supported_files.push(`+layout.server${ext}`);
|
||||
}
|
||||
if (valid_page_server_exports.has(key)) {
|
||||
supported_files.push(`+page.server${ext}`);
|
||||
}
|
||||
if (valid_server_exports.has(key)) {
|
||||
supported_files.push(`+server${ext}`);
|
||||
}
|
||||
if (supported_files.length > 0) {
|
||||
return `'${key}' is a valid export in ${supported_files.slice(0, -1).join(", ")}${supported_files.length > 1 ? " or " : ""}${supported_files.at(-1)}`;
|
||||
}
|
||||
}
|
||||
const valid_layout_exports = /* @__PURE__ */ new Set([
|
||||
"load",
|
||||
"prerender",
|
||||
"csr",
|
||||
"ssr",
|
||||
"trailingSlash",
|
||||
"config"
|
||||
]);
|
||||
const valid_page_exports = /* @__PURE__ */ new Set([...valid_layout_exports, "entries"]);
|
||||
const valid_layout_server_exports = /* @__PURE__ */ new Set([...valid_layout_exports]);
|
||||
const valid_page_server_exports = /* @__PURE__ */ new Set([...valid_layout_server_exports, "actions", "entries"]);
|
||||
const valid_server_exports = /* @__PURE__ */ new Set([
|
||||
"GET",
|
||||
"POST",
|
||||
"PATCH",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"OPTIONS",
|
||||
"HEAD",
|
||||
"fallback",
|
||||
"prerender",
|
||||
"trailingSlash",
|
||||
"config",
|
||||
"entries"
|
||||
]);
|
||||
const validate_layout_exports = validator(valid_layout_exports);
|
||||
const validate_page_exports = validator(valid_page_exports);
|
||||
const validate_layout_server_exports = validator(valid_layout_server_exports);
|
||||
const validate_page_server_exports = validator(valid_page_server_exports);
|
||||
const validate_server_exports = validator(valid_server_exports);
|
||||
export {
|
||||
SCHEME as S,
|
||||
decode_params as a,
|
||||
validate_layout_exports as b,
|
||||
validate_page_server_exports as c,
|
||||
disable_search as d,
|
||||
validate_page_exports as e,
|
||||
decode_pathname as f,
|
||||
validate_server_exports as g,
|
||||
make_trackable as m,
|
||||
normalize_path as n,
|
||||
resolve as r,
|
||||
validate_layout_server_exports as v
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
const BROWSER = false;
|
||||
export {
|
||||
BROWSER as B
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import { d as ssr_context } from "./index.js";
|
||||
import "clsx";
|
||||
function onDestroy(fn) {
|
||||
/** @type {SSRContext} */
|
||||
ssr_context.r.on_destroy(fn);
|
||||
}
|
||||
export {
|
||||
onDestroy as o
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
import { w as writable, d as derived } from "./index3.js";
|
||||
const app$1 = { "name": "Docker Watcher", "version": "v0.1" };
|
||||
const health$1 = { "connected": "connected", "disconnected": "disconnected", "rawError": "Technical details", "retryNow": "Retry now" };
|
||||
const nav$1 = { "dashboard": "Dashboard", "projects": "Projects", "deploy": "Deploy", "proxies": "Proxies", "events": "Events", "settings": "Settings", "logout": "Log out" };
|
||||
const dashboard$1 = { "title": "Dashboard", "quickDeploy": "Quick Deploy", "totalProjects": "Total Projects", "runningInstances": "Running Instances", "failedInstances": "Failed Instances", "projects": "Projects", "retry": "Retry", "noProjects": "No projects yet.", "addFirst": "Add your first project", "loadFailed": "Failed to load dashboard", "staleContainers": "Stale Containers" };
|
||||
const projects$1 = { "title": "Projects", "addProject": "Add Project", "cancel": "Cancel", "newProject": "New Project", "name": "Name", "image": "Image", "port": "Port", "registry": "Registry", "created": "Created", "view": "View", "noProjects": "No projects configured yet.", "getStarted": 'Click "Add Project" to get started.', "createProject": "Create Project", "creating": "Creating...", "healthcheck": "Healthcheck Path", "nameRequired": "Name and image are required.", "loadFailed": "Failed to load projects", "createFailed": "Failed to create project", "browseImages": "Browse Images", "selectImage": "Select an image", "noImages": "No images found", "loadingImages": "Loading images...", "imageLoadFailed": "Failed to load images" };
|
||||
const projectDetail$1 = { "deleteProject": "Delete Project", "envVars": "Environment Variables", "volumes": "Volume Mounts", "stages": "Stages", "noStages": "No stages configured for this project.", "pattern": "Pattern", "autoDeploy": "auto-deploy", "requiresConfirm": "requires confirm", "instances": "instances", "deployNewVersion": "Deploy new version", "selectTag": "Select tag to deploy", "loadingTags": "Loading tags...", "chooseTag": "Choose a tag...", "enterTag": "Enter image tag (e.g., dev-abc123)", "deploy": "Deploy", "deploying": "Deploying...", "recentDeploys": "Recent Deploys", "noDeployHistory": "No deploy history for this project.", "tag": "Tag", "status": "Status", "started": "Started", "finished": "Finished", "error": "Error", "noInstancesRunning": "No instances running", "deleteConfirmTitle": "Delete Project", "deleteConfirmMessage": "This will permanently delete the project '{name}' and all its stages, instances, and deploy history. This cannot be undone.", "loadFailed": "Failed to load project", "deleteFailed": "Failed to delete project", "deployFailed": "Deploy failed" };
|
||||
const envEditor$1 = { "title": "Environment Variables", "description": "Manage per-stage environment variable overrides. Stage-level values override project-level defaults.", "stage": "Stage", "projectDefaults": "Project-Level Defaults", "stageOverrides": "Stage Overrides", "key": "Key", "value": "Value", "secret": "Secret", "source": "Source", "actions": "Actions", "overridden": "overridden", "inherited": "inherited", "overridesProject": "overrides project", "stageOnly": "stage only", "edit": "Edit", "change": "Change", "delete": "Delete", "save": "Save", "add": "Add", "adding": "Adding...", "noStages": "No stages configured. Add stages to the project first.", "loadFailed": "Failed to load project", "envAdded": "Environment variable added", "envUpdated": "Environment variable updated", "envDeleted": "Environment variable deleted", "addFailed": "Failed to add env var", "updateFailed": "Failed to update env var", "deleteFailed": "Failed to delete env var", "loadEnvFailed": "Failed to load env vars" };
|
||||
const volumeEditor$1 = { "title": "Volume Mounts", "description": "Configure volume mounts for containers. Choose a scope to control how volumes are shared between deploys.", "sourceHost": "Source (Host)", "targetContainer": "Target (Container)", "scope": "Scope", "nameColumn": "Name", "namePlaceholder": "e.g. shared-db", "requiresName": "requires name", "noHostPath": "no host path", "tmpfs": "tmpfs (in-memory)", "actions": "Actions", "edit": "Edit", "delete": "Delete", "save": "Save", "add": "Add", "adding": "Adding...", "noVolumes": "No volumes configured yet. Add one above.", "volumeAdded": "Volume added", "volumeUpdated": "Volume updated", "volumeDeleted": "Volume deleted", "loadFailed": "Failed to load volumes", "addFailed": "Failed to add volume", "updateFailed": "Failed to update volume", "deleteFailed": "Failed to delete volume" };
|
||||
const volumeBrowser$1 = { "title": "Volume Browser", "loadFailed": "Failed to load directory", "empty": "This directory is empty.", "name": "Name", "size": "Size", "modified": "Modified", "downloadAll": "Download volume as ZIP", "downloadFolder": "Download folder as ZIP", "upload": "Upload files", "uploaded": "Uploaded", "files": "file(s)", "uploadFailed": "Failed to upload files", "browse": "Browse", "download": "Download" };
|
||||
const quickDeploy$1 = { "title": "Quick Deploy", "description": "Deploy a container image with zero configuration. Paste an image URL, review the defaults, and deploy.", "step1": "1. Enter Image URL", "imageUrl": "Image URL", "imageUrlHelp": "Full image URL including tag (e.g., git.example.com/user/app:dev-abc123)", "inspect": "Inspect", "inspecting": "Inspecting...", "step2": "2. Review Configuration", "reviewDesc": "These defaults were detected from the image. Adjust as needed before deploying.", "projectName": "Project Name", "port": "Port", "portHelp": "Container port to expose (1-65535)", "healthCheckPath": "Health Check Path", "healthCheckHelp": "Optional HTTP path for health verification", "stage": "Stage", "development": "Development", "release": "Release", "production": "Production", "stageHelp": "Deployment stage for this image", "subdomainOverride": "Subdomain Override", "subdomainHelp": "Leave empty to use the default subdomain pattern", "envVars": "Environment Variables", "envVarsHelp": "One per line, KEY=VALUE format", "step3": "3. Deploy", "deployDesc": "A new project will be created and the container will be deployed immediately.", "deployBtn": "Deploy", "inspectedSuccess": "Image inspected successfully", "deployedSuccess": "Deployed {name} successfully!", "inspectFailed": "Failed to inspect image", "deployFailed": "Deployment failed", "browseImages": "Browse", "selectImage": "Select an image from a registry", "noImages": "No images found", "loadingImages": "Loading...", "imageLoadFailed": "Failed to load images" };
|
||||
const settings$1 = { "title": "Settings", "general": "General", "registries": "Registries", "credentials": "Credentials", "authentication": "Authentication", "appearance": "Appearance", "staleThreshold": "Stale threshold (days)", "staleThresholdHelp": "Containers inactive for longer than this will be flagged as stale." };
|
||||
const settingsGeneral$1 = { "title": "General Settings", "globalConfig": "Global Configuration", "domain": "Domain", "domainHelp": "Base domain for subdomain routing", "serverIp": "Server IP", "serverIpHelp": "Public IP address of the server", "dockerNetwork": "Docker Network", "dockerNetworkHelp": "Docker network for deployed containers", "subdomainPattern": "Subdomain Pattern", "subdomainPatternHelp": "Pattern for auto-generated subdomains", "pollingInterval": "Polling Interval (seconds)", "pollingIntervalHelp": "How often to check registries for new tags (10-86400)", "notificationUrl": "Notification URL", "notificationUrlHelp": "Webhook URL for deploy notifications", "saveSettings": "Save Settings", "saving": "Saving...", "saved": "Settings saved successfully", "saveFailed": "Failed to save settings", "loadFailed": "Failed to load settings", "webhookUrl": "Webhook URL", "webhookDesc": "This secret URL receives image push notifications from your CI pipeline.", "noWebhookUrl": "No webhook URL configured", "copy": "Copy", "copied": "Webhook URL copied to clipboard", "regenerateUrl": "Regenerate URL", "regenerating": "Regenerating...", "regenerated": "Webhook URL regenerated", "regenerateFailed": "Failed to regenerate webhook URL", "regenerateWarning": "Warning: regenerating will invalidate the current URL. Update your CI pipelines.", "sslCertificate": "SSL Certificate", "sslCertificateHelp": "Wildcard certificate from NPM for auto-SSL on proxy hosts", "selectCertificate": "Select Certificate", "noCertificate": "None (no SSL)", "clearCertificate": "Clear", "loadingCertificates": "Loading certificates...", "noCertificatesFound": "No wildcard certificates found in NPM" };
|
||||
const settingsRegistries$1 = { "title": "Container Registries", "description": "Manage your container registries for image detection.", "addRegistry": "Add Registry", "editRegistry": "Edit Registry", "addNewRegistry": "Add New Registry", "name": "Name", "nameHelp": "A friendly name for this registry", "url": "URL", "urlHelp": "Registry base URL", "type": "Type", "typeHelp": "Registry type for API compatibility", "token": "Token", "tokenHelpNew": "API token for authentication", "tokenHelpEdit": "Leave empty to keep the existing token", "owner": "Owner", "ownerHelp": "Package owners, comma-separated (e.g., alexei,my-org)", "save": "Save", "saving": "Saving...", "update": "Update", "test": "Test", "testing": "Testing...", "edit": "Edit", "delete": "Delete", "noRegistries": "No registries configured yet.", "addFirst": "Add your first registry", "registryUpdated": "Registry updated", "registryAdded": "Registry added", "registryDeleted": 'Registry "{name}" deleted', "testSuccess": 'Connection to "{name}" successful', "saveFailed": "Failed to save registry", "deleteFailed": "Failed to delete registry", "testFailed": "Connection test failed", "loadFailed": "Failed to load registries", "deleteConfirm": 'Delete registry "{name}"? This cannot be undone.' };
|
||||
const settingsCredentials$1 = { "title": "Credentials", "description": "Manage credentials for Nginx Proxy Manager and registry tokens. All values are encrypted at rest.", "npm": "Nginx Proxy Manager", "npmDesc": "Credentials for managing proxy hosts via NPM API", "configured": "Configured", "npmUrl": "NPM URL", "npmUrlHelp": "Nginx Proxy Manager API URL", "email": "Email", "emailHelp": "NPM admin email", "password": "Password", "passwordHelpNew": "NPM admin password (will be encrypted)", "passwordHelpEdit": "Enter the new password to replace the existing one", "changeCredentials": "Change Credentials", "save": "Save", "saving": "Saving...", "saved": "NPM credentials saved", "saveFailed": "Failed to save NPM credentials", "loadFailed": "Failed to load credentials", "registryTokens": "Registry Tokens", "registryTokensDesc": "Registry authentication tokens are managed per-registry in the", "registriesLink": "Registries", "registryTokensSuffix": "section. Each registry stores its token encrypted in the database." };
|
||||
const settingsAuth$1 = { "title": "Authentication Settings", "description": "Configure authentication mode and manage users.", "authMode": "Authentication Mode", "local": "Local (username/password)", "oidc": "OIDC (SSO)", "oidcConfig": "OIDC Provider Configuration", "issuerUrl": "Issuer URL", "clientId": "Client ID", "clientSecret": "Client Secret", "redirectUrl": "Redirect URL", "saveSettings": "Save Settings", "saving": "Saving...", "saved": "Settings saved", "saveFailed": "Failed to save", "loadFailed": "Failed to load settings", "localUsers": "Local Users", "username": "Username", "email": "Email", "role": "Role", "created": "Created", "noUsers": "No users found.", "addUser": "Add User", "viewer": "Viewer", "admin": "Admin", "userCreated": "User created", "userDeleted": "User deleted", "createFailed": "Failed to create user", "deleteFailed": "Failed to delete user", "deleteConfirm": "Are you sure you want to delete this user?", "usernameRequired": "Username and password are required", "password": "Password" };
|
||||
const login$1 = { "title": "Docker Watcher", "subtitle": "Sign in to your account", "username": "Username", "password": "Password", "signIn": "Sign in", "signingIn": "Signing in...", "or": "or", "ssoButton": "Sign in with SSO (OIDC)", "loginFailed": "Login failed", "networkError": "Network error" };
|
||||
const proxies$1 = { "title": "Proxies", "create": "Create Proxy", "noProxies": "No proxies configured yet.", "noProxiesDesc": "Create a standalone proxy or deploy a project to see proxies here.", "standalone": "Standalone Proxies", "managed": "Managed", "lastChecked": "Last checked", "health": { "healthy": "Healthy", "unhealthy": "Unhealthy", "unknown": "Unknown" }, "filter": { "search": "Search proxies...", "health": "Health", "type": "Type", "all": "All", "clear": "Clear filters" }, "form": { "title": "Create Proxy", "editTitle": "Edit Proxy", "destination": "Destination URL / IP", "port": "Port", "domain": "Domain", "domainHelp": "The public domain for this proxy.", "validate": "Validate", "validating": "Validating...", "create": "Create Proxy", "save": "Save Changes", "cancel": "Cancel", "delete": "Delete", "deleteConfirm": "Delete this proxy? This cannot be undone." }, "validation": { "title": "Destination Validation", "syntax": "URL syntax", "dns": "DNS resolution", "tcp": "TCP connection", "http": "HTTP response", "checking": "Checking...", "skipped": "Skipped" } };
|
||||
const common$1 = { "cancel": "Cancel", "confirm": "Confirm", "delete": "Delete", "edit": "Edit", "save": "Save", "retry": "Retry", "loading": "Loading...", "noData": "No data", "project": "Project", "back": "Back", "actions": "Actions", "stop": "Stop", "start": "Start", "restart": "Restart", "remove": "Remove", "instance": "instance", "instances": "instances" };
|
||||
const instance$1 = { "stopConfirm": "This will stop the running container. The instance can be started again later.", "restartConfirm": "This will restart the container, causing brief downtime.", "removeConfirm": "This will permanently remove the container and its proxy configuration. This cannot be undone.", "actionFailed": "Action failed" };
|
||||
const empty$1 = { "noProjects": "No projects yet", "noProjectsDesc": "Get started by creating your first project or use Quick Deploy.", "createProject": "Create Project", "noInstances": "No instances", "noInstancesDesc": "Deploy a new version to see instances here.", "noDeploys": "No deploy history", "noDeploysDesc": "Deploy history will appear here after your first deployment.", "noRegistries": "No registries", "noRegistriesDesc": "Add a container registry to enable image detection.", "noVolumes": "No volumes", "noVolumesDesc": "Configure volume mounts for persistent data.", "noUsers": "No users", "noUsersDesc": "Add local users to manage access." };
|
||||
const validation$1 = { "required": "{field} is required", "invalidUrl": "Invalid URL format", "invalidDomain": "Invalid domain format", "invalidIp": "Invalid IP format", "invalidEmail": "Invalid email format", "invalidPort": "Port must be between 1 and 65535", "invalidPollingInterval": "Polling interval must be between 10 and 86400 seconds", "invalidProjectName": "Only lowercase letters, numbers, and hyphens allowed", "requiredWhenUpdating": "{field} is required when updating credentials", "requiredForNew": "{field} is required for new registries" };
|
||||
const confirm$1 = { "stopInstance": "Stop Instance", "startInstance": "Start Instance", "restartInstance": "Restart Instance", "removeInstance": "Remove Instance" };
|
||||
const theme$1 = { "light": "Light", "dark": "Dark", "system": "System" };
|
||||
const entityPicker$1 = { "search": "Search...", "noResults": "No results found" };
|
||||
const stale$1 = { "title": "Stale Containers", "noStale": "No stale containers", "noStaleDesc": "All containers are healthy and running.", "cleanup": "Clean up", "cleanupAll": "Clean up all", "confirmCleanup": "This will stop and remove the container. Continue?", "confirmBulkCleanup": "This will stop and remove all stale containers. Continue?", "daysStale": "days stale", "lastAlive": "Last alive", "count": "Stale", "cleanedUp": "Container cleaned up", "bulkCleanedUp": "{count} containers cleaned up", "cleanupFailed": "Cleanup failed", "loadFailed": "Failed to load stale containers" };
|
||||
const events$1 = { "title": "Event Log", "noEvents": "No events found", "noEventsDesc": "Events will appear here as they occur.", "loadMore": "Load more", "newEvents": "new events", "filter": { "severity": "Severity", "source": "Source", "dateRange": "Date range", "search": "Search events...", "lastHour": "Last hour", "last24h": "Last 24 hours", "last7d": "Last 7 days", "allTime": "All time", "clear": "Clear filters" }, "severity": { "info": "Info", "warn": "Warning", "error": "Error" }, "source": { "deploy": "Deploy", "container": "Container", "proxy": "Proxy", "system": "System" }, "metadata": "Details" };
|
||||
const stats$1 = { "cpu": "CPU", "mem": "MEM", "unavailable": "Stats unavailable" };
|
||||
const systemHealth$1 = { "title": "System Health", "containers": "Containers", "proxies": "Proxies", "recentErrors": "Recent Errors" };
|
||||
const language$1 = { "en": "English", "ru": "Russian" };
|
||||
const en = {
|
||||
app: app$1,
|
||||
health: health$1,
|
||||
nav: nav$1,
|
||||
dashboard: dashboard$1,
|
||||
projects: projects$1,
|
||||
projectDetail: projectDetail$1,
|
||||
envEditor: envEditor$1,
|
||||
volumeEditor: volumeEditor$1,
|
||||
volumeBrowser: volumeBrowser$1,
|
||||
quickDeploy: quickDeploy$1,
|
||||
settings: settings$1,
|
||||
settingsGeneral: settingsGeneral$1,
|
||||
settingsRegistries: settingsRegistries$1,
|
||||
settingsCredentials: settingsCredentials$1,
|
||||
settingsAuth: settingsAuth$1,
|
||||
login: login$1,
|
||||
proxies: proxies$1,
|
||||
common: common$1,
|
||||
instance: instance$1,
|
||||
empty: empty$1,
|
||||
validation: validation$1,
|
||||
confirm: confirm$1,
|
||||
theme: theme$1,
|
||||
entityPicker: entityPicker$1,
|
||||
stale: stale$1,
|
||||
events: events$1,
|
||||
stats: stats$1,
|
||||
systemHealth: systemHealth$1,
|
||||
language: language$1
|
||||
};
|
||||
const app = { "name": "Docker Watcher", "version": "v0.1" };
|
||||
const health = { "connected": "подключён", "disconnected": "отключён", "rawError": "Технические детали", "retryNow": "Проверить сейчас" };
|
||||
const nav = { "dashboard": "Панель", "projects": "Проекты", "deploy": "Деплой", "proxies": "Прокси", "events": "События", "settings": "Настройки", "logout": "Выйти" };
|
||||
const dashboard = { "title": "Панель управления", "quickDeploy": "Быстрый деплой", "totalProjects": "Всего проектов", "runningInstances": "Запущенных экземпляров", "failedInstances": "Сбойных экземпляров", "projects": "Проекты", "retry": "Повторить", "noProjects": "Проектов пока нет.", "addFirst": "Добавьте первый проект", "loadFailed": "Не удалось загрузить панель", "staleContainers": "Устаревшие контейнеры" };
|
||||
const projects = { "title": "Проекты", "addProject": "Добавить проект", "cancel": "Отмена", "newProject": "Новый проект", "name": "Название", "image": "Образ", "port": "Порт", "registry": "Реестр", "created": "Создан", "view": "Открыть", "noProjects": "Проекты ещё не настроены.", "getStarted": "Нажмите «Добавить проект» для начала.", "createProject": "Создать проект", "creating": "Создание...", "healthcheck": "Путь проверки здоровья", "nameRequired": "Название и образ обязательны.", "loadFailed": "Не удалось загрузить проекты", "createFailed": "Не удалось создать проект", "browseImages": "Обзор образов", "selectImage": "Выберите образ", "noImages": "Образы не найдены", "loadingImages": "Загрузка образов...", "imageLoadFailed": "Не удалось загрузить образы" };
|
||||
const projectDetail = { "deleteProject": "Удалить проект", "envVars": "Переменные окружения", "volumes": "Тома", "stages": "Стадии", "noStages": "Для этого проекта не настроены стадии.", "pattern": "Шаблон", "autoDeploy": "авто-деплой", "requiresConfirm": "нужно подтверждение", "instances": "экземпляров", "deployNewVersion": "Развернуть новую версию", "selectTag": "Выберите тег для деплоя", "loadingTags": "Загрузка тегов...", "chooseTag": "Выберите тег...", "enterTag": "Введите тег образа (напр., dev-abc123)", "deploy": "Развернуть", "deploying": "Развёртывание...", "recentDeploys": "Последние деплои", "noDeployHistory": "Нет истории деплоев для этого проекта.", "tag": "Тег", "status": "Статус", "started": "Начат", "finished": "Завершён", "error": "Ошибка", "noInstancesRunning": "Нет запущенных экземпляров", "deleteConfirmTitle": "Удалить проект", "deleteConfirmMessage": "Это безвозвратно удалит проект '{name}' и все его стадии, экземпляры и историю деплоев.", "loadFailed": "Не удалось загрузить проект", "deleteFailed": "Не удалось удалить проект", "deployFailed": "Деплой не удался" };
|
||||
const envEditor = { "title": "Переменные окружения", "description": "Управление переопределениями переменных окружения на уровне стадий. Значения стадий переопределяют значения проекта.", "stage": "Стадия", "projectDefaults": "Значения проекта по умолчанию", "stageOverrides": "Переопределения стадии", "key": "Ключ", "value": "Значение", "secret": "Секрет", "source": "Источник", "actions": "Действия", "overridden": "переопределено", "inherited": "наследуется", "overridesProject": "переопределяет проект", "stageOnly": "только стадия", "edit": "Изменить", "change": "Изменить", "delete": "Удалить", "save": "Сохранить", "add": "Добавить", "adding": "Добавление...", "noStages": "Стадии не настроены. Сначала добавьте стадии к проекту.", "loadFailed": "Не удалось загрузить проект", "envAdded": "Переменная окружения добавлена", "envUpdated": "Переменная окружения обновлена", "envDeleted": "Переменная окружения удалена", "addFailed": "Не удалось добавить переменную", "updateFailed": "Не удалось обновить переменную", "deleteFailed": "Не удалось удалить переменную", "loadEnvFailed": "Не удалось загрузить переменные" };
|
||||
const volumeEditor = { "title": "Тома", "description": "Настройка монтирования томов для контейнеров. Выберите область видимости для управления общим доступом между развёртываниями.", "sourceHost": "Источник (хост)", "targetContainer": "Цель (контейнер)", "scope": "Область", "nameColumn": "Имя", "namePlaceholder": "напр. shared-db", "requiresName": "требуется имя", "noHostPath": "нет пути на хосте", "tmpfs": "tmpfs (в памяти)", "actions": "Действия", "edit": "Изменить", "delete": "Удалить", "save": "Сохранить", "add": "Добавить", "adding": "Добавление...", "noVolumes": "Тома ещё не настроены. Добавьте один выше.", "volumeAdded": "Том добавлен", "volumeUpdated": "Том обновлён", "volumeDeleted": "Том удалён", "loadFailed": "Не удалось загрузить тома", "addFailed": "Не удалось добавить том", "updateFailed": "Не удалось обновить том", "deleteFailed": "Не удалось удалить том" };
|
||||
const volumeBrowser = { "title": "Обзор тома", "loadFailed": "Не удалось загрузить каталог", "empty": "Этот каталог пуст.", "name": "Имя", "size": "Размер", "modified": "Изменён", "downloadAll": "Скачать том как ZIP", "downloadFolder": "Скачать папку как ZIP", "upload": "Загрузить файлы", "uploaded": "Загружено", "files": "файл(ов)", "uploadFailed": "Не удалось загрузить файлы", "browse": "Обзор", "download": "Скачать" };
|
||||
const quickDeploy = { "title": "Быстрый деплой", "description": "Разверните образ контейнера без настройки. Вставьте URL образа, проверьте параметры и разверните.", "step1": "1. Введите URL образа", "imageUrl": "URL образа", "imageUrlHelp": "Полный URL образа с тегом (напр., git.example.com/user/app:dev-abc123)", "inspect": "Проверить", "inspecting": "Проверка...", "step2": "2. Проверка конфигурации", "reviewDesc": "Эти параметры были обнаружены из образа. Измените при необходимости перед деплоем.", "projectName": "Имя проекта", "port": "Порт", "portHelp": "Порт контейнера (1-65535)", "healthCheckPath": "Путь проверки здоровья", "healthCheckHelp": "Необязательный HTTP-путь для проверки работоспособности", "stage": "Стадия", "development": "Разработка", "release": "Релиз", "production": "Продакшн", "stageHelp": "Стадия развёртывания для этого образа", "subdomainOverride": "Переопределение поддомена", "subdomainHelp": "Оставьте пустым для использования шаблона по умолчанию", "envVars": "Переменные окружения", "envVarsHelp": "По одной на строку, формат KEY=VALUE", "step3": "3. Развёртывание", "deployDesc": "Будет создан новый проект и контейнер будет развёрнут немедленно.", "deployBtn": "Развернуть", "inspectedSuccess": "Образ успешно проверен", "deployedSuccess": "{name} успешно развёрнут!", "inspectFailed": "Не удалось проверить образ", "deployFailed": "Развёртывание не удалось", "browseImages": "Обзор", "selectImage": "Выберите образ из реестра", "noImages": "Образы не найдены", "loadingImages": "Загрузка...", "imageLoadFailed": "Не удалось загрузить образы" };
|
||||
const settings = { "title": "Настройки", "general": "Общие", "registries": "Реестры", "credentials": "Учётные данные", "authentication": "Аутентификация", "appearance": "Внешний вид", "staleThreshold": "Порог устаревания (дни)", "staleThresholdHelp": "Контейнеры, неактивные дольше этого срока, будут помечены как устаревшие." };
|
||||
const settingsGeneral = { "title": "Общие настройки", "globalConfig": "Глобальная конфигурация", "domain": "Домен", "domainHelp": "Базовый домен для маршрутизации поддоменов", "serverIp": "IP сервера", "serverIpHelp": "Публичный IP-адрес сервера", "dockerNetwork": "Docker-сеть", "dockerNetworkHelp": "Docker-сеть для развёрнутых контейнеров", "subdomainPattern": "Шаблон поддомена", "subdomainPatternHelp": "Шаблон для автоматически генерируемых поддоменов", "pollingInterval": "Интервал опроса (секунды)", "pollingIntervalHelp": "Как часто проверять реестры на новые теги (10-86400)", "notificationUrl": "URL уведомлений", "notificationUrlHelp": "URL вебхука для уведомлений о деплоях", "saveSettings": "Сохранить настройки", "saving": "Сохранение...", "saved": "Настройки успешно сохранены", "saveFailed": "Не удалось сохранить настройки", "loadFailed": "Не удалось загрузить настройки", "webhookUrl": "URL вебхука", "webhookDesc": "Этот секретный URL получает уведомления о push-событиях из вашего CI-пайплайна.", "noWebhookUrl": "URL вебхука не настроен", "copy": "Копировать", "copied": "URL вебхука скопирован в буфер обмена", "regenerateUrl": "Перегенерировать URL", "regenerating": "Перегенерация...", "regenerated": "URL вебхука перегенерирован", "regenerateFailed": "Не удалось перегенерировать URL вебхука", "regenerateWarning": "Внимание: перегенерация сделает текущий URL недействительным. Обновите ваши CI-пайплайны.", "sslCertificate": "SSL-сертификат", "sslCertificateHelp": "Wildcard-сертификат из NPM для автоматического SSL на прокси-хостах", "selectCertificate": "Выбрать сертификат", "noCertificate": "Нет (без SSL)", "clearCertificate": "Очистить", "loadingCertificates": "Загрузка сертификатов...", "noCertificatesFound": "Wildcard-сертификаты в NPM не найдены" };
|
||||
const settingsRegistries = { "title": "Реестры контейнеров", "description": "Управление реестрами контейнеров для обнаружения образов.", "addRegistry": "Добавить реестр", "editRegistry": "Редактировать реестр", "addNewRegistry": "Добавить новый реестр", "name": "Название", "nameHelp": "Понятное название для этого реестра", "url": "URL", "urlHelp": "Базовый URL реестра", "type": "Тип", "typeHelp": "Тип реестра для совместимости API", "token": "Токен", "tokenHelpNew": "API-токен для аутентификации", "tokenHelpEdit": "Оставьте пустым, чтобы сохранить текущий токен", "owner": "Владелец", "ownerHelp": "Владельцы пакетов через запятую (напр., alexei,my-org)", "save": "Сохранить", "saving": "Сохранение...", "update": "Обновить", "test": "Тест", "testing": "Тестирование...", "edit": "Изменить", "delete": "Удалить", "noRegistries": "Реестры ещё не настроены.", "addFirst": "Добавьте первый реестр", "registryUpdated": "Реестр обновлён", "registryAdded": "Реестр добавлен", "registryDeleted": "Реестр «{name}» удалён", "testSuccess": "Подключение к «{name}» успешно", "saveFailed": "Не удалось сохранить реестр", "deleteFailed": "Не удалось удалить реестр", "testFailed": "Тест подключения не удался", "loadFailed": "Не удалось загрузить реестры", "deleteConfirm": "Удалить реестр «{name}»? Это действие необратимо." };
|
||||
const settingsCredentials = { "title": "Учётные данные", "description": "Управление учётными данными для Nginx Proxy Manager и токенами реестров. Все значения зашифрованы.", "npm": "Nginx Proxy Manager", "npmDesc": "Учётные данные для управления прокси-хостами через NPM API", "configured": "Настроено", "npmUrl": "URL NPM", "npmUrlHelp": "URL API Nginx Proxy Manager", "email": "Email", "emailHelp": "Email администратора NPM", "password": "Пароль", "passwordHelpNew": "Пароль администратора NPM (будет зашифрован)", "passwordHelpEdit": "Введите новый пароль для замены текущего", "changeCredentials": "Изменить учётные данные", "save": "Сохранить", "saving": "Сохранение...", "saved": "Учётные данные NPM сохранены", "saveFailed": "Не удалось сохранить учётные данные NPM", "loadFailed": "Не удалось загрузить учётные данные", "registryTokens": "Токены реестров", "registryTokensDesc": "Токены аутентификации реестров управляются для каждого реестра в разделе", "registriesLink": "Реестры", "registryTokensSuffix": ". Каждый реестр хранит свой токен в зашифрованном виде." };
|
||||
const settingsAuth = { "title": "Настройки аутентификации", "description": "Настройка режима аутентификации и управление пользователями.", "authMode": "Режим аутентификации", "local": "Локальный (логин/пароль)", "oidc": "OIDC (SSO)", "oidcConfig": "Конфигурация OIDC-провайдера", "issuerUrl": "URL издателя", "clientId": "ID клиента", "clientSecret": "Секрет клиента", "redirectUrl": "URL перенаправления", "saveSettings": "Сохранить настройки", "saving": "Сохранение...", "saved": "Настройки сохранены", "saveFailed": "Не удалось сохранить", "loadFailed": "Не удалось загрузить настройки", "localUsers": "Локальные пользователи", "username": "Имя пользователя", "email": "Email", "role": "Роль", "created": "Создан", "noUsers": "Пользователи не найдены.", "addUser": "Добавить пользователя", "viewer": "Наблюдатель", "admin": "Администратор", "userCreated": "Пользователь создан", "userDeleted": "Пользователь удалён", "createFailed": "Не удалось создать пользователя", "deleteFailed": "Не удалось удалить пользователя", "deleteConfirm": "Вы уверены, что хотите удалить этого пользователя?", "usernameRequired": "Имя пользователя и пароль обязательны", "password": "Пароль" };
|
||||
const login = { "title": "Docker Watcher", "subtitle": "Войдите в свой аккаунт", "username": "Имя пользователя", "password": "Пароль", "signIn": "Войти", "signingIn": "Вход...", "or": "или", "ssoButton": "Войти через SSO (OIDC)", "loginFailed": "Ошибка входа", "networkError": "Ошибка сети" };
|
||||
const proxies = { "title": "Прокси", "create": "Создать прокси", "noProxies": "Прокси ещё не настроены.", "noProxiesDesc": "Создайте автономный прокси или разверните проект, чтобы увидеть прокси здесь.", "standalone": "Автономные прокси", "managed": "Управляемые", "lastChecked": "Последняя проверка", "health": { "healthy": "Работает", "unhealthy": "Недоступен", "unknown": "Неизвестно" }, "filter": { "search": "Поиск прокси...", "health": "Здоровье", "type": "Тип", "all": "Все", "clear": "Сбросить фильтры" }, "form": { "title": "Создать прокси", "editTitle": "Редактировать прокси", "destination": "URL / IP назначения", "port": "Порт", "domain": "Домен", "domainHelp": "Публичный домен для этого прокси.", "validate": "Проверить", "validating": "Проверка...", "create": "Создать прокси", "save": "Сохранить изменения", "cancel": "Отмена", "delete": "Удалить", "deleteConfirm": "Удалить этот прокси? Это действие необратимо." }, "validation": { "title": "Проверка назначения", "syntax": "Синтаксис URL", "dns": "DNS разрешение", "tcp": "TCP подключение", "http": "HTTP ответ", "checking": "Проверка...", "skipped": "Пропущено" } };
|
||||
const common = { "cancel": "Отмена", "confirm": "Подтвердить", "delete": "Удалить", "edit": "Изменить", "save": "Сохранить", "retry": "Повторить", "loading": "Загрузка...", "noData": "Нет данных", "project": "Проект", "back": "Назад", "actions": "Действия", "stop": "Остановить", "start": "Запустить", "restart": "Перезапустить", "remove": "Удалить", "instance": "экземпляр", "instances": "экземпляров" };
|
||||
const instance = { "stopConfirm": "Контейнер будет остановлен. Экземпляр можно будет запустить снова позже.", "restartConfirm": "Контейнер будет перезапущен с кратковременным простоем.", "removeConfirm": "Контейнер и его прокси-конфигурация будут безвозвратно удалены.", "actionFailed": "Действие не удалось" };
|
||||
const empty = { "noProjects": "Проектов пока нет", "noProjectsDesc": "Начните с создания первого проекта или используйте быстрый деплой.", "createProject": "Создать проект", "noInstances": "Нет экземпляров", "noInstancesDesc": "Разверните новую версию, чтобы увидеть экземпляры здесь.", "noDeploys": "Нет истории деплоев", "noDeploysDesc": "История деплоев появится здесь после первого развёртывания.", "noRegistries": "Нет реестров", "noRegistriesDesc": "Добавьте реестр контейнеров для обнаружения образов.", "noVolumes": "Нет томов", "noVolumesDesc": "Настройте монтирование томов для постоянных данных.", "noUsers": "Нет пользователей", "noUsersDesc": "Добавьте локальных пользователей для управления доступом." };
|
||||
const validation = { "required": "Поле {field} обязательно", "invalidUrl": "Неверный формат URL", "invalidDomain": "Неверный формат домена", "invalidIp": "Неверный формат IP", "invalidEmail": "Неверный формат email", "invalidPort": "Порт должен быть от 1 до 65535", "invalidPollingInterval": "Интервал опроса должен быть от 10 до 86400 секунд", "invalidProjectName": "Допускаются только строчные буквы, цифры и дефисы", "requiredWhenUpdating": "Поле {field} обязательно при обновлении учётных данных", "requiredForNew": "Поле {field} обязательно для новых реестров" };
|
||||
const confirm = { "stopInstance": "Остановить экземпляр", "startInstance": "Запустить экземпляр", "restartInstance": "Перезапустить экземпляр", "removeInstance": "Удалить экземпляр" };
|
||||
const theme = { "light": "Светлая", "dark": "Тёмная", "system": "Системная" };
|
||||
const entityPicker = { "search": "Поиск...", "noResults": "Ничего не найдено" };
|
||||
const stale = { "title": "Устаревшие контейнеры", "noStale": "Нет устаревших контейнеров", "noStaleDesc": "Все контейнеры исправны и работают.", "cleanup": "Очистить", "cleanupAll": "Очистить все", "confirmCleanup": "Это остановит и удалит контейнер. Продолжить?", "confirmBulkCleanup": "Это остановит и удалит все устаревшие контейнеры. Продолжить?", "daysStale": "дней устарел", "lastAlive": "Последний раз жив", "count": "Устаревшие", "cleanedUp": "Контейнер очищен", "bulkCleanedUp": "{count} контейнеров очищено", "cleanupFailed": "Не удалось очистить", "loadFailed": "Не удалось загрузить устаревшие контейнеры" };
|
||||
const events = { "title": "Журнал событий", "noEvents": "Событий не найдено", "noEventsDesc": "События будут отображаться здесь по мере их возникновения.", "loadMore": "Загрузить ещё", "newEvents": "новых событий", "filter": { "severity": "Уровень", "source": "Источник", "dateRange": "Период", "search": "Поиск событий...", "lastHour": "Последний час", "last24h": "Последние 24 часа", "last7d": "Последние 7 дней", "allTime": "За всё время", "clear": "Сбросить фильтры" }, "severity": { "info": "Инфо", "warn": "Предупреждение", "error": "Ошибка" }, "source": { "deploy": "Развёртывание", "container": "Контейнер", "proxy": "Прокси", "system": "Система" }, "metadata": "Подробности" };
|
||||
const stats = { "cpu": "ЦП", "mem": "ОЗУ", "unavailable": "Статистика недоступна" };
|
||||
const systemHealth = { "title": "Состояние системы", "containers": "Контейнеры", "proxies": "Прокси", "recentErrors": "Недавние ошибки" };
|
||||
const language = { "en": "Английский", "ru": "Русский" };
|
||||
const ru = {
|
||||
app,
|
||||
health,
|
||||
nav,
|
||||
dashboard,
|
||||
projects,
|
||||
projectDetail,
|
||||
envEditor,
|
||||
volumeEditor,
|
||||
volumeBrowser,
|
||||
quickDeploy,
|
||||
settings,
|
||||
settingsGeneral,
|
||||
settingsRegistries,
|
||||
settingsCredentials,
|
||||
settingsAuth,
|
||||
login,
|
||||
proxies,
|
||||
common,
|
||||
instance,
|
||||
empty,
|
||||
validation,
|
||||
confirm,
|
||||
theme,
|
||||
entityPicker,
|
||||
stale,
|
||||
events,
|
||||
stats,
|
||||
systemHealth,
|
||||
language
|
||||
};
|
||||
const LOCALE_KEY = "dw_locale";
|
||||
const translations = { en, ru };
|
||||
function getInitialLocale() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
const stored = localStorage.getItem(LOCALE_KEY);
|
||||
if (stored === "en" || stored === "ru") return stored;
|
||||
}
|
||||
if (typeof navigator !== "undefined") {
|
||||
const lang = navigator.language.toLowerCase();
|
||||
if (lang.startsWith("ru")) return "ru";
|
||||
}
|
||||
return "en";
|
||||
}
|
||||
const locale = writable(getInitialLocale());
|
||||
locale.subscribe((value) => {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.setItem(LOCALE_KEY, value);
|
||||
}
|
||||
});
|
||||
function getNestedValue(obj, path) {
|
||||
const parts = path.split(".");
|
||||
let current = obj;
|
||||
for (const part of parts) {
|
||||
if (current === null || current === void 0 || typeof current !== "object") {
|
||||
return path;
|
||||
}
|
||||
current = current[part];
|
||||
}
|
||||
return typeof current === "string" ? current : path;
|
||||
}
|
||||
const t = derived(locale, ($locale) => {
|
||||
const dict = translations[$locale] ?? translations.en;
|
||||
return (key, params) => {
|
||||
let result = getNestedValue(dict, key);
|
||||
if (result === key) {
|
||||
result = getNestedValue(translations.en, key);
|
||||
}
|
||||
if (params) {
|
||||
for (const [paramKey, paramValue] of Object.entries(params)) {
|
||||
result = result.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
});
|
||||
const availableLocales = ["en", "ru"];
|
||||
export {
|
||||
availableLocales as a,
|
||||
locale as l,
|
||||
t
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
import { n as noop, m as safe_not_equal, o as subscribe_to_store, r as run_all } from "./index.js";
|
||||
const subscriber_queue = [];
|
||||
function readable(value, start) {
|
||||
return {
|
||||
subscribe: writable(value, start).subscribe
|
||||
};
|
||||
}
|
||||
function writable(value, start = noop) {
|
||||
let stop = null;
|
||||
const subscribers = /* @__PURE__ */ new Set();
|
||||
function set(new_value) {
|
||||
if (safe_not_equal(value, new_value)) {
|
||||
value = new_value;
|
||||
if (stop) {
|
||||
const run_queue = !subscriber_queue.length;
|
||||
for (const subscriber of subscribers) {
|
||||
subscriber[1]();
|
||||
subscriber_queue.push(subscriber, value);
|
||||
}
|
||||
if (run_queue) {
|
||||
for (let i = 0; i < subscriber_queue.length; i += 2) {
|
||||
subscriber_queue[i][0](subscriber_queue[i + 1]);
|
||||
}
|
||||
subscriber_queue.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function update(fn) {
|
||||
set(fn(
|
||||
/** @type {T} */
|
||||
value
|
||||
));
|
||||
}
|
||||
function subscribe(run, invalidate = noop) {
|
||||
const subscriber = [run, invalidate];
|
||||
subscribers.add(subscriber);
|
||||
if (subscribers.size === 1) {
|
||||
stop = start(set, update) || noop;
|
||||
}
|
||||
run(
|
||||
/** @type {T} */
|
||||
value
|
||||
);
|
||||
return () => {
|
||||
subscribers.delete(subscriber);
|
||||
if (subscribers.size === 0 && stop) {
|
||||
stop();
|
||||
stop = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return { set, update, subscribe };
|
||||
}
|
||||
function derived(stores, fn, initial_value) {
|
||||
const single = !Array.isArray(stores);
|
||||
const stores_array = single ? [stores] : stores;
|
||||
if (!stores_array.every(Boolean)) {
|
||||
throw new Error("derived() expects stores as input, got a falsy value");
|
||||
}
|
||||
const auto = fn.length < 2;
|
||||
return readable(initial_value, (set, update) => {
|
||||
let started = false;
|
||||
const values = [];
|
||||
let pending = 0;
|
||||
let cleanup = noop;
|
||||
const sync = () => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
cleanup();
|
||||
const result = fn(single ? values[0] : values, set, update);
|
||||
if (auto) {
|
||||
set(result);
|
||||
} else {
|
||||
cleanup = typeof result === "function" ? result : noop;
|
||||
}
|
||||
};
|
||||
const unsubscribers = stores_array.map(
|
||||
(store, i) => subscribe_to_store(
|
||||
store,
|
||||
(value) => {
|
||||
values[i] = value;
|
||||
pending &= ~(1 << i);
|
||||
if (started) {
|
||||
sync();
|
||||
}
|
||||
},
|
||||
() => {
|
||||
pending |= 1 << i;
|
||||
}
|
||||
)
|
||||
);
|
||||
started = true;
|
||||
sync();
|
||||
return function stop() {
|
||||
run_all(unsubscribers);
|
||||
cleanup();
|
||||
started = false;
|
||||
};
|
||||
});
|
||||
}
|
||||
function get(store) {
|
||||
let value;
|
||||
subscribe_to_store(store, (_) => value = _)();
|
||||
return value;
|
||||
}
|
||||
export {
|
||||
derived as d,
|
||||
get as g,
|
||||
readable as r,
|
||||
writable as w
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
import { r as root } from "./root.js";
|
||||
import "./environment.js";
|
||||
let public_env = {};
|
||||
function set_private_env(environment) {
|
||||
}
|
||||
function set_public_env(environment) {
|
||||
public_env = environment;
|
||||
}
|
||||
let read_implementation = null;
|
||||
function set_read_implementation(fn) {
|
||||
read_implementation = fn;
|
||||
}
|
||||
function set_manifest(_) {
|
||||
}
|
||||
const options = {
|
||||
app_template_contains_nonce: false,
|
||||
async: false,
|
||||
csp: { "mode": "auto", "directives": { "upgrade-insecure-requests": false, "block-all-mixed-content": false }, "reportOnly": { "upgrade-insecure-requests": false, "block-all-mixed-content": false } },
|
||||
csrf_check_origin: true,
|
||||
csrf_trusted_origins: [],
|
||||
embedded: false,
|
||||
env_public_prefix: "PUBLIC_",
|
||||
env_private_prefix: "",
|
||||
hash_routing: false,
|
||||
hooks: null,
|
||||
// added lazily, via `get_hooks`
|
||||
preload_strategy: "modulepreload",
|
||||
root,
|
||||
service_worker: false,
|
||||
service_worker_options: void 0,
|
||||
server_error_boundaries: false,
|
||||
templates: {
|
||||
app: ({ head, body, assets, nonce, env }) => '<!doctype html>\r\n<html lang="en">\r\n <head>\r\n <meta charset="utf-8" />\r\n <link rel="icon" href="' + assets + '/favicon.png" />\r\n <meta name="viewport" content="width=device-width, initial-scale=1" />\r\n ' + head + '\r\n </head>\r\n <body data-sveltekit-preload-data="hover">\r\n <div style="display: contents">' + body + "</div>\r\n </body>\r\n</html>\r\n",
|
||||
error: ({ status, message }) => '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>' + message + `</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
--bg: white;
|
||||
--fg: #222;
|
||||
--divider: #ccc;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
'Open Sans',
|
||||
'Helvetica Neue',
|
||||
sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 32rem;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-weight: 200;
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
top: -0.05rem;
|
||||
}
|
||||
|
||||
.message {
|
||||
border-left: 1px solid var(--divider);
|
||||
padding: 0 0 0 1rem;
|
||||
margin: 0 0 0 1rem;
|
||||
min-height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message h1 {
|
||||
font-weight: 400;
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
--bg: #222;
|
||||
--fg: #ddd;
|
||||
--divider: #666;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error">
|
||||
<span class="status">` + status + '</span>\n <div class="message">\n <h1>' + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n"
|
||||
},
|
||||
version_hash: "m287x4"
|
||||
};
|
||||
async function get_hooks() {
|
||||
let handle;
|
||||
let handleFetch;
|
||||
let handleError;
|
||||
let handleValidationError;
|
||||
let init;
|
||||
let reroute;
|
||||
let transport;
|
||||
return {
|
||||
handle,
|
||||
handleFetch,
|
||||
handleError,
|
||||
handleValidationError,
|
||||
init,
|
||||
reroute,
|
||||
transport
|
||||
};
|
||||
}
|
||||
export {
|
||||
set_public_env as a,
|
||||
set_read_implementation as b,
|
||||
set_manifest as c,
|
||||
get_hooks as g,
|
||||
options as o,
|
||||
public_env as p,
|
||||
read_implementation as r,
|
||||
set_private_env as s
|
||||
};
|
||||
@@ -0,0 +1,966 @@
|
||||
import { H as HYDRATION_ERROR, C as COMMENT_NODE, p as HYDRATION_END, q as HYDRATION_START, t as HYDRATION_START_ELSE, v as get_next_sibling, w as effect_tracking, x as get, y as render_effect, z as source, A as untrack, B as increment, D as queue_micro_task, E as active_effect, F as BOUNDARY_EFFECT, G as block, I as branch, J as create_text, K as pause_effect, L as current_batch, M as move_effect, N as defer_effect, O as set_active_effect, P as set_active_reaction, Q as set_component_context, R as Batch, S as handle_error, T as active_reaction, U as component_context, V as internal_set, W as destroy_effect, X as invoke_error_boundary, Y as svelte_boundary_reset_onerror, Z as HYDRATION_START_FAILED, _ as EFFECT_TRANSPARENT, $ as EFFECT_PRESERVED, a0 as define_property, a1 as init_operations, a2 as get_first_child, a3 as hydration_failed, a4 as clear_text_content, a5 as component_root, a6 as array_from, a7 as is_passive_event, a8 as push, a9 as pop, aa as set, ab as LEGACY_PROPS, ac as flushSync, ad as mutable_source, ae as render, af as setContext, i as derived } from "./index.js";
|
||||
function hydration_mismatch(location) {
|
||||
{
|
||||
console.warn(`https://svelte.dev/e/hydration_mismatch`);
|
||||
}
|
||||
}
|
||||
function svelte_boundary_reset_noop() {
|
||||
{
|
||||
console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
|
||||
}
|
||||
}
|
||||
let hydrating = false;
|
||||
function set_hydrating(value) {
|
||||
hydrating = value;
|
||||
}
|
||||
let hydrate_node;
|
||||
function set_hydrate_node(node) {
|
||||
if (node === null) {
|
||||
hydration_mismatch();
|
||||
throw HYDRATION_ERROR;
|
||||
}
|
||||
return hydrate_node = node;
|
||||
}
|
||||
function hydrate_next() {
|
||||
return set_hydrate_node(get_next_sibling(hydrate_node));
|
||||
}
|
||||
function next(count = 1) {
|
||||
if (hydrating) {
|
||||
var i = count;
|
||||
var node = hydrate_node;
|
||||
while (i--) {
|
||||
node = /** @type {TemplateNode} */
|
||||
get_next_sibling(node);
|
||||
}
|
||||
hydrate_node = node;
|
||||
}
|
||||
}
|
||||
function skip_nodes(remove = true) {
|
||||
var depth = 0;
|
||||
var node = hydrate_node;
|
||||
while (true) {
|
||||
if (node.nodeType === COMMENT_NODE) {
|
||||
var data = (
|
||||
/** @type {Comment} */
|
||||
node.data
|
||||
);
|
||||
if (data === HYDRATION_END) {
|
||||
if (depth === 0) return node;
|
||||
depth -= 1;
|
||||
} else if (data === HYDRATION_START || data === HYDRATION_START_ELSE || // "[1", "[2", etc. for if blocks
|
||||
data[0] === "[" && !isNaN(Number(data.slice(1)))) {
|
||||
depth += 1;
|
||||
}
|
||||
}
|
||||
var next2 = (
|
||||
/** @type {TemplateNode} */
|
||||
get_next_sibling(node)
|
||||
);
|
||||
if (remove) node.remove();
|
||||
node = next2;
|
||||
}
|
||||
}
|
||||
function createSubscriber(start) {
|
||||
let subscribers = 0;
|
||||
let version = source(0);
|
||||
let stop;
|
||||
return () => {
|
||||
if (effect_tracking()) {
|
||||
get(version);
|
||||
render_effect(() => {
|
||||
if (subscribers === 0) {
|
||||
stop = untrack(() => start(() => increment(version)));
|
||||
}
|
||||
subscribers += 1;
|
||||
return () => {
|
||||
queue_micro_task(() => {
|
||||
subscribers -= 1;
|
||||
if (subscribers === 0) {
|
||||
stop?.();
|
||||
stop = void 0;
|
||||
increment(version);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
|
||||
function boundary(node, props, children, transform_error) {
|
||||
new Boundary(node, props, children, transform_error);
|
||||
}
|
||||
class Boundary {
|
||||
/** @type {Boundary | null} */
|
||||
parent;
|
||||
is_pending = false;
|
||||
/**
|
||||
* API-level transformError transform function. Transforms errors before they reach the `failed` snippet.
|
||||
* Inherited from parent boundary, or defaults to identity.
|
||||
* @type {(error: unknown) => unknown}
|
||||
*/
|
||||
transform_error;
|
||||
/** @type {TemplateNode} */
|
||||
#anchor;
|
||||
/** @type {TemplateNode | null} */
|
||||
#hydrate_open = hydrating ? hydrate_node : null;
|
||||
/** @type {BoundaryProps} */
|
||||
#props;
|
||||
/** @type {((anchor: Node) => void)} */
|
||||
#children;
|
||||
/** @type {Effect} */
|
||||
#effect;
|
||||
/** @type {Effect | null} */
|
||||
#main_effect = null;
|
||||
/** @type {Effect | null} */
|
||||
#pending_effect = null;
|
||||
/** @type {Effect | null} */
|
||||
#failed_effect = null;
|
||||
/** @type {DocumentFragment | null} */
|
||||
#offscreen_fragment = null;
|
||||
#local_pending_count = 0;
|
||||
#pending_count = 0;
|
||||
#pending_count_update_queued = false;
|
||||
/** @type {Set<Effect>} */
|
||||
#dirty_effects = /* @__PURE__ */ new Set();
|
||||
/** @type {Set<Effect>} */
|
||||
#maybe_dirty_effects = /* @__PURE__ */ new Set();
|
||||
/**
|
||||
* A source containing the number of pending async deriveds/expressions.
|
||||
* Only created if `$effect.pending()` is used inside the boundary,
|
||||
* otherwise updating the source results in needless `Batch.ensure()`
|
||||
* calls followed by no-op flushes
|
||||
* @type {Source<number> | null}
|
||||
*/
|
||||
#effect_pending = null;
|
||||
#effect_pending_subscriber = createSubscriber(() => {
|
||||
this.#effect_pending = source(this.#local_pending_count);
|
||||
return () => {
|
||||
this.#effect_pending = null;
|
||||
};
|
||||
});
|
||||
/**
|
||||
* @param {TemplateNode} node
|
||||
* @param {BoundaryProps} props
|
||||
* @param {((anchor: Node) => void)} children
|
||||
* @param {((error: unknown) => unknown) | undefined} [transform_error]
|
||||
*/
|
||||
constructor(node, props, children, transform_error) {
|
||||
this.#anchor = node;
|
||||
this.#props = props;
|
||||
this.#children = (anchor) => {
|
||||
var effect = (
|
||||
/** @type {Effect} */
|
||||
active_effect
|
||||
);
|
||||
effect.b = this;
|
||||
effect.f |= BOUNDARY_EFFECT;
|
||||
children(anchor);
|
||||
};
|
||||
this.parent = /** @type {Effect} */
|
||||
active_effect.b;
|
||||
this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
|
||||
this.#effect = block(() => {
|
||||
if (hydrating) {
|
||||
const comment = (
|
||||
/** @type {Comment} */
|
||||
this.#hydrate_open
|
||||
);
|
||||
hydrate_next();
|
||||
const server_rendered_pending = comment.data === HYDRATION_START_ELSE;
|
||||
const server_rendered_failed = comment.data.startsWith(HYDRATION_START_FAILED);
|
||||
if (server_rendered_failed) {
|
||||
const serialized_error = JSON.parse(comment.data.slice(HYDRATION_START_FAILED.length));
|
||||
this.#hydrate_failed_content(serialized_error);
|
||||
} else if (server_rendered_pending) {
|
||||
this.#hydrate_pending_content();
|
||||
} else {
|
||||
this.#hydrate_resolved_content();
|
||||
}
|
||||
} else {
|
||||
this.#render();
|
||||
}
|
||||
}, flags);
|
||||
if (hydrating) {
|
||||
this.#anchor = hydrate_node;
|
||||
}
|
||||
}
|
||||
#hydrate_resolved_content() {
|
||||
try {
|
||||
this.#main_effect = branch(() => this.#children(this.#anchor));
|
||||
} catch (error) {
|
||||
this.error(error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {unknown} error The deserialized error from the server's hydration comment
|
||||
*/
|
||||
#hydrate_failed_content(error) {
|
||||
const failed = this.#props.failed;
|
||||
if (!failed) return;
|
||||
this.#failed_effect = branch(() => {
|
||||
failed(
|
||||
this.#anchor,
|
||||
() => error,
|
||||
() => () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
#hydrate_pending_content() {
|
||||
const pending = this.#props.pending;
|
||||
if (!pending) return;
|
||||
this.is_pending = true;
|
||||
this.#pending_effect = branch(() => pending(this.#anchor));
|
||||
queue_micro_task(() => {
|
||||
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
|
||||
var anchor = create_text();
|
||||
fragment.append(anchor);
|
||||
this.#main_effect = this.#run(() => {
|
||||
return branch(() => this.#children(anchor));
|
||||
});
|
||||
if (this.#pending_count === 0) {
|
||||
this.#anchor.before(fragment);
|
||||
this.#offscreen_fragment = null;
|
||||
pause_effect(
|
||||
/** @type {Effect} */
|
||||
this.#pending_effect,
|
||||
() => {
|
||||
this.#pending_effect = null;
|
||||
}
|
||||
);
|
||||
this.#resolve(
|
||||
/** @type {Batch} */
|
||||
current_batch
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
#render() {
|
||||
try {
|
||||
this.is_pending = this.has_pending_snippet();
|
||||
this.#pending_count = 0;
|
||||
this.#local_pending_count = 0;
|
||||
this.#main_effect = branch(() => {
|
||||
this.#children(this.#anchor);
|
||||
});
|
||||
if (this.#pending_count > 0) {
|
||||
var fragment = this.#offscreen_fragment = document.createDocumentFragment();
|
||||
move_effect(this.#main_effect, fragment);
|
||||
const pending = (
|
||||
/** @type {(anchor: Node) => void} */
|
||||
this.#props.pending
|
||||
);
|
||||
this.#pending_effect = branch(() => pending(this.#anchor));
|
||||
} else {
|
||||
this.#resolve(
|
||||
/** @type {Batch} */
|
||||
current_batch
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.error(error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
#resolve(batch) {
|
||||
this.is_pending = false;
|
||||
batch.transfer_effects(this.#dirty_effects, this.#maybe_dirty_effects);
|
||||
}
|
||||
/**
|
||||
* Defer an effect inside a pending boundary until the boundary resolves
|
||||
* @param {Effect} effect
|
||||
*/
|
||||
defer_effect(effect) {
|
||||
defer_effect(effect, this.#dirty_effects, this.#maybe_dirty_effects);
|
||||
}
|
||||
/**
|
||||
* Returns `false` if the effect exists inside a boundary whose pending snippet is shown
|
||||
* @returns {boolean}
|
||||
*/
|
||||
is_rendered() {
|
||||
return !this.is_pending && (!this.parent || this.parent.is_rendered());
|
||||
}
|
||||
has_pending_snippet() {
|
||||
return !!this.#props.pending;
|
||||
}
|
||||
/**
|
||||
* @template T
|
||||
* @param {() => T} fn
|
||||
*/
|
||||
#run(fn) {
|
||||
var previous_effect = active_effect;
|
||||
var previous_reaction = active_reaction;
|
||||
var previous_ctx = component_context;
|
||||
set_active_effect(this.#effect);
|
||||
set_active_reaction(this.#effect);
|
||||
set_component_context(this.#effect.ctx);
|
||||
try {
|
||||
Batch.ensure();
|
||||
return fn();
|
||||
} catch (e) {
|
||||
handle_error(e);
|
||||
return null;
|
||||
} finally {
|
||||
set_active_effect(previous_effect);
|
||||
set_active_reaction(previous_reaction);
|
||||
set_component_context(previous_ctx);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Updates the pending count associated with the currently visible pending snippet,
|
||||
* if any, such that we can replace the snippet with content once work is done
|
||||
* @param {1 | -1} d
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
#update_pending_count(d, batch) {
|
||||
if (!this.has_pending_snippet()) {
|
||||
if (this.parent) {
|
||||
this.parent.#update_pending_count(d, batch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.#pending_count += d;
|
||||
if (this.#pending_count === 0) {
|
||||
this.#resolve(batch);
|
||||
if (this.#pending_effect) {
|
||||
pause_effect(this.#pending_effect, () => {
|
||||
this.#pending_effect = null;
|
||||
});
|
||||
}
|
||||
if (this.#offscreen_fragment) {
|
||||
this.#anchor.before(this.#offscreen_fragment);
|
||||
this.#offscreen_fragment = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update the source that powers `$effect.pending()` inside this boundary,
|
||||
* and controls when the current `pending` snippet (if any) is removed.
|
||||
* Do not call from inside the class
|
||||
* @param {1 | -1} d
|
||||
* @param {Batch} batch
|
||||
*/
|
||||
update_pending_count(d, batch) {
|
||||
this.#update_pending_count(d, batch);
|
||||
this.#local_pending_count += d;
|
||||
if (!this.#effect_pending || this.#pending_count_update_queued) return;
|
||||
this.#pending_count_update_queued = true;
|
||||
queue_micro_task(() => {
|
||||
this.#pending_count_update_queued = false;
|
||||
if (this.#effect_pending) {
|
||||
internal_set(this.#effect_pending, this.#local_pending_count);
|
||||
}
|
||||
});
|
||||
}
|
||||
get_effect_pending() {
|
||||
this.#effect_pending_subscriber();
|
||||
return get(
|
||||
/** @type {Source<number>} */
|
||||
this.#effect_pending
|
||||
);
|
||||
}
|
||||
/** @param {unknown} error */
|
||||
error(error) {
|
||||
var onerror = this.#props.onerror;
|
||||
let failed = this.#props.failed;
|
||||
if (!onerror && !failed) {
|
||||
throw error;
|
||||
}
|
||||
if (this.#main_effect) {
|
||||
destroy_effect(this.#main_effect);
|
||||
this.#main_effect = null;
|
||||
}
|
||||
if (this.#pending_effect) {
|
||||
destroy_effect(this.#pending_effect);
|
||||
this.#pending_effect = null;
|
||||
}
|
||||
if (this.#failed_effect) {
|
||||
destroy_effect(this.#failed_effect);
|
||||
this.#failed_effect = null;
|
||||
}
|
||||
if (hydrating) {
|
||||
set_hydrate_node(
|
||||
/** @type {TemplateNode} */
|
||||
this.#hydrate_open
|
||||
);
|
||||
next();
|
||||
set_hydrate_node(skip_nodes());
|
||||
}
|
||||
var did_reset = false;
|
||||
var calling_on_error = false;
|
||||
const reset = () => {
|
||||
if (did_reset) {
|
||||
svelte_boundary_reset_noop();
|
||||
return;
|
||||
}
|
||||
did_reset = true;
|
||||
if (calling_on_error) {
|
||||
svelte_boundary_reset_onerror();
|
||||
}
|
||||
if (this.#failed_effect !== null) {
|
||||
pause_effect(this.#failed_effect, () => {
|
||||
this.#failed_effect = null;
|
||||
});
|
||||
}
|
||||
this.#run(() => {
|
||||
this.#render();
|
||||
});
|
||||
};
|
||||
const handle_error_result = (transformed_error) => {
|
||||
try {
|
||||
calling_on_error = true;
|
||||
onerror?.(transformed_error, reset);
|
||||
calling_on_error = false;
|
||||
} catch (error2) {
|
||||
invoke_error_boundary(error2, this.#effect && this.#effect.parent);
|
||||
}
|
||||
if (failed) {
|
||||
this.#failed_effect = this.#run(() => {
|
||||
try {
|
||||
return branch(() => {
|
||||
var effect = (
|
||||
/** @type {Effect} */
|
||||
active_effect
|
||||
);
|
||||
effect.b = this;
|
||||
effect.f |= BOUNDARY_EFFECT;
|
||||
failed(
|
||||
this.#anchor,
|
||||
() => transformed_error,
|
||||
() => reset
|
||||
);
|
||||
});
|
||||
} catch (error2) {
|
||||
invoke_error_boundary(
|
||||
error2,
|
||||
/** @type {Effect} */
|
||||
this.#effect.parent
|
||||
);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
queue_micro_task(() => {
|
||||
var result;
|
||||
try {
|
||||
result = this.transform_error(error);
|
||||
} catch (e) {
|
||||
invoke_error_boundary(e, this.#effect && this.#effect.parent);
|
||||
return;
|
||||
}
|
||||
if (result !== null && typeof result === "object" && typeof /** @type {any} */
|
||||
result.then === "function") {
|
||||
result.then(
|
||||
handle_error_result,
|
||||
/** @param {unknown} e */
|
||||
(e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)
|
||||
);
|
||||
} else {
|
||||
handle_error_result(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const event_symbol = Symbol("events");
|
||||
const all_registered_events = /* @__PURE__ */ new Set();
|
||||
const root_event_handles = /* @__PURE__ */ new Set();
|
||||
let last_propagated_event = null;
|
||||
function handle_event_propagation(event) {
|
||||
var handler_element = this;
|
||||
var owner_document = (
|
||||
/** @type {Node} */
|
||||
handler_element.ownerDocument
|
||||
);
|
||||
var event_name = event.type;
|
||||
var path = event.composedPath?.() || [];
|
||||
var current_target = (
|
||||
/** @type {null | Element} */
|
||||
path[0] || event.target
|
||||
);
|
||||
last_propagated_event = event;
|
||||
var path_idx = 0;
|
||||
var handled_at = last_propagated_event === event && event[event_symbol];
|
||||
if (handled_at) {
|
||||
var at_idx = path.indexOf(handled_at);
|
||||
if (at_idx !== -1 && (handler_element === document || handler_element === /** @type {any} */
|
||||
window)) {
|
||||
event[event_symbol] = handler_element;
|
||||
return;
|
||||
}
|
||||
var handler_idx = path.indexOf(handler_element);
|
||||
if (handler_idx === -1) {
|
||||
return;
|
||||
}
|
||||
if (at_idx <= handler_idx) {
|
||||
path_idx = at_idx;
|
||||
}
|
||||
}
|
||||
current_target = /** @type {Element} */
|
||||
path[path_idx] || event.target;
|
||||
if (current_target === handler_element) return;
|
||||
define_property(event, "currentTarget", {
|
||||
configurable: true,
|
||||
get() {
|
||||
return current_target || owner_document;
|
||||
}
|
||||
});
|
||||
var previous_reaction = active_reaction;
|
||||
var previous_effect = active_effect;
|
||||
set_active_reaction(null);
|
||||
set_active_effect(null);
|
||||
try {
|
||||
var throw_error;
|
||||
var other_errors = [];
|
||||
while (current_target !== null) {
|
||||
var parent_element = current_target.assignedSlot || current_target.parentNode || /** @type {any} */
|
||||
current_target.host || null;
|
||||
try {
|
||||
var delegated = current_target[event_symbol]?.[event_name];
|
||||
if (delegated != null && (!/** @type {any} */
|
||||
current_target.disabled || // DOM could've been updated already by the time this is reached, so we check this as well
|
||||
// -> the target could not have been disabled because it emits the event in the first place
|
||||
event.target === current_target)) {
|
||||
delegated.call(current_target, event);
|
||||
}
|
||||
} catch (error) {
|
||||
if (throw_error) {
|
||||
other_errors.push(error);
|
||||
} else {
|
||||
throw_error = error;
|
||||
}
|
||||
}
|
||||
if (event.cancelBubble || parent_element === handler_element || parent_element === null) {
|
||||
break;
|
||||
}
|
||||
current_target = parent_element;
|
||||
}
|
||||
if (throw_error) {
|
||||
for (let error of other_errors) {
|
||||
queueMicrotask(() => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
throw throw_error;
|
||||
}
|
||||
} finally {
|
||||
event[event_symbol] = handler_element;
|
||||
delete event.currentTarget;
|
||||
set_active_reaction(previous_reaction);
|
||||
set_active_effect(previous_effect);
|
||||
}
|
||||
}
|
||||
function assign_nodes(start, end) {
|
||||
var effect = (
|
||||
/** @type {Effect} */
|
||||
active_effect
|
||||
);
|
||||
if (effect.nodes === null) {
|
||||
effect.nodes = { start, end, a: null, t: null };
|
||||
}
|
||||
}
|
||||
function mount(component, options) {
|
||||
return _mount(component, options);
|
||||
}
|
||||
function hydrate(component, options) {
|
||||
init_operations();
|
||||
options.intro = options.intro ?? false;
|
||||
const target = options.target;
|
||||
const was_hydrating = hydrating;
|
||||
const previous_hydrate_node = hydrate_node;
|
||||
try {
|
||||
var anchor = get_first_child(target);
|
||||
while (anchor && (anchor.nodeType !== COMMENT_NODE || /** @type {Comment} */
|
||||
anchor.data !== HYDRATION_START)) {
|
||||
anchor = get_next_sibling(anchor);
|
||||
}
|
||||
if (!anchor) {
|
||||
throw HYDRATION_ERROR;
|
||||
}
|
||||
set_hydrating(true);
|
||||
set_hydrate_node(
|
||||
/** @type {Comment} */
|
||||
anchor
|
||||
);
|
||||
const instance = _mount(component, { ...options, anchor });
|
||||
set_hydrating(false);
|
||||
return (
|
||||
/** @type {Exports} */
|
||||
instance
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.split("\n").some((line) => line.startsWith("https://svelte.dev/e/"))) {
|
||||
throw error;
|
||||
}
|
||||
if (error !== HYDRATION_ERROR) {
|
||||
console.warn("Failed to hydrate: ", error);
|
||||
}
|
||||
if (options.recover === false) {
|
||||
hydration_failed();
|
||||
}
|
||||
init_operations();
|
||||
clear_text_content(target);
|
||||
set_hydrating(false);
|
||||
return mount(component, options);
|
||||
} finally {
|
||||
set_hydrating(was_hydrating);
|
||||
set_hydrate_node(previous_hydrate_node);
|
||||
}
|
||||
}
|
||||
const listeners = /* @__PURE__ */ new Map();
|
||||
function _mount(Component, { target, anchor, props = {}, events, context, intro = true, transformError }) {
|
||||
init_operations();
|
||||
var component = void 0;
|
||||
var unmount2 = component_root(() => {
|
||||
var anchor_node = anchor ?? target.appendChild(create_text());
|
||||
boundary(
|
||||
/** @type {TemplateNode} */
|
||||
anchor_node,
|
||||
{
|
||||
pending: () => {
|
||||
}
|
||||
},
|
||||
(anchor_node2) => {
|
||||
push({});
|
||||
var ctx = (
|
||||
/** @type {ComponentContext} */
|
||||
component_context
|
||||
);
|
||||
if (context) ctx.c = context;
|
||||
if (events) {
|
||||
props.$$events = events;
|
||||
}
|
||||
if (hydrating) {
|
||||
assign_nodes(
|
||||
/** @type {TemplateNode} */
|
||||
anchor_node2,
|
||||
null
|
||||
);
|
||||
}
|
||||
component = Component(anchor_node2, props) || {};
|
||||
if (hydrating) {
|
||||
active_effect.nodes.end = hydrate_node;
|
||||
if (hydrate_node === null || hydrate_node.nodeType !== COMMENT_NODE || /** @type {Comment} */
|
||||
hydrate_node.data !== HYDRATION_END) {
|
||||
hydration_mismatch();
|
||||
throw HYDRATION_ERROR;
|
||||
}
|
||||
}
|
||||
pop();
|
||||
},
|
||||
transformError
|
||||
);
|
||||
var registered_events = /* @__PURE__ */ new Set();
|
||||
var event_handle = (events2) => {
|
||||
for (var i = 0; i < events2.length; i++) {
|
||||
var event_name = events2[i];
|
||||
if (registered_events.has(event_name)) continue;
|
||||
registered_events.add(event_name);
|
||||
var passive = is_passive_event(event_name);
|
||||
for (const node of [target, document]) {
|
||||
var counts = listeners.get(node);
|
||||
if (counts === void 0) {
|
||||
counts = /* @__PURE__ */ new Map();
|
||||
listeners.set(node, counts);
|
||||
}
|
||||
var count = counts.get(event_name);
|
||||
if (count === void 0) {
|
||||
node.addEventListener(event_name, handle_event_propagation, { passive });
|
||||
counts.set(event_name, 1);
|
||||
} else {
|
||||
counts.set(event_name, count + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
event_handle(array_from(all_registered_events));
|
||||
root_event_handles.add(event_handle);
|
||||
return () => {
|
||||
for (var event_name of registered_events) {
|
||||
for (const node of [target, document]) {
|
||||
var counts = (
|
||||
/** @type {Map<string, number>} */
|
||||
listeners.get(node)
|
||||
);
|
||||
var count = (
|
||||
/** @type {number} */
|
||||
counts.get(event_name)
|
||||
);
|
||||
if (--count == 0) {
|
||||
node.removeEventListener(event_name, handle_event_propagation);
|
||||
counts.delete(event_name);
|
||||
if (counts.size === 0) {
|
||||
listeners.delete(node);
|
||||
}
|
||||
} else {
|
||||
counts.set(event_name, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
root_event_handles.delete(event_handle);
|
||||
if (anchor_node !== anchor) {
|
||||
anchor_node.parentNode?.removeChild(anchor_node);
|
||||
}
|
||||
};
|
||||
});
|
||||
mounted_components.set(component, unmount2);
|
||||
return component;
|
||||
}
|
||||
let mounted_components = /* @__PURE__ */ new WeakMap();
|
||||
function unmount(component, options) {
|
||||
const fn = mounted_components.get(component);
|
||||
if (fn) {
|
||||
mounted_components.delete(component);
|
||||
return fn(options);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
function asClassComponent$1(component) {
|
||||
return class extends Svelte4Component {
|
||||
/** @param {any} options */
|
||||
constructor(options) {
|
||||
super({
|
||||
component,
|
||||
...options
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
class Svelte4Component {
|
||||
/** @type {any} */
|
||||
#events;
|
||||
/** @type {Record<string, any>} */
|
||||
#instance;
|
||||
/**
|
||||
* @param {ComponentConstructorOptions & {
|
||||
* component: any;
|
||||
* }} options
|
||||
*/
|
||||
constructor(options) {
|
||||
var sources = /* @__PURE__ */ new Map();
|
||||
var add_source = (key, value) => {
|
||||
var s = mutable_source(value, false, false);
|
||||
sources.set(key, s);
|
||||
return s;
|
||||
};
|
||||
const props = new Proxy(
|
||||
{ ...options.props || {}, $$events: {} },
|
||||
{
|
||||
get(target, prop) {
|
||||
return get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
|
||||
},
|
||||
has(target, prop) {
|
||||
if (prop === LEGACY_PROPS) return true;
|
||||
get(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
|
||||
return Reflect.has(target, prop);
|
||||
},
|
||||
set(target, prop, value) {
|
||||
set(sources.get(prop) ?? add_source(prop, value), value);
|
||||
return Reflect.set(target, prop, value);
|
||||
}
|
||||
}
|
||||
);
|
||||
this.#instance = (options.hydrate ? hydrate : mount)(options.component, {
|
||||
target: options.target,
|
||||
anchor: options.anchor,
|
||||
props,
|
||||
context: options.context,
|
||||
intro: options.intro ?? false,
|
||||
recover: options.recover,
|
||||
transformError: options.transformError
|
||||
});
|
||||
if (!options?.props?.$$host || options.sync === false) {
|
||||
flushSync();
|
||||
}
|
||||
this.#events = props.$$events;
|
||||
for (const key of Object.keys(this.#instance)) {
|
||||
if (key === "$set" || key === "$destroy" || key === "$on") continue;
|
||||
define_property(this, key, {
|
||||
get() {
|
||||
return this.#instance[key];
|
||||
},
|
||||
/** @param {any} value */
|
||||
set(value) {
|
||||
this.#instance[key] = value;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
}
|
||||
this.#instance.$set = /** @param {Record<string, any>} next */
|
||||
(next2) => {
|
||||
Object.assign(props, next2);
|
||||
};
|
||||
this.#instance.$destroy = () => {
|
||||
unmount(this.#instance);
|
||||
};
|
||||
}
|
||||
/** @param {Record<string, any>} props */
|
||||
$set(props) {
|
||||
this.#instance.$set(props);
|
||||
}
|
||||
/**
|
||||
* @param {string} event
|
||||
* @param {(...args: any[]) => any} callback
|
||||
* @returns {any}
|
||||
*/
|
||||
$on(event, callback) {
|
||||
this.#events[event] = this.#events[event] || [];
|
||||
const cb = (...args) => callback.call(this, ...args);
|
||||
this.#events[event].push(cb);
|
||||
return () => {
|
||||
this.#events[event] = this.#events[event].filter(
|
||||
/** @param {any} fn */
|
||||
(fn) => fn !== cb
|
||||
);
|
||||
};
|
||||
}
|
||||
$destroy() {
|
||||
this.#instance.$destroy();
|
||||
}
|
||||
}
|
||||
function asClassComponent(component) {
|
||||
const component_constructor = asClassComponent$1(component);
|
||||
const _render = (props, { context, csp, transformError } = {}) => {
|
||||
const result = render(component, { props, context, csp, transformError });
|
||||
const munged = Object.defineProperties(
|
||||
/** @type {LegacyRenderResult & PromiseLike<LegacyRenderResult>} */
|
||||
{},
|
||||
{
|
||||
css: {
|
||||
value: { code: "", map: null }
|
||||
},
|
||||
head: {
|
||||
get: () => result.head
|
||||
},
|
||||
html: {
|
||||
get: () => result.body
|
||||
},
|
||||
then: {
|
||||
/**
|
||||
* this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
|
||||
*
|
||||
* @template TResult1
|
||||
* @template [TResult2=never]
|
||||
* @param { (value: LegacyRenderResult) => TResult1 } onfulfilled
|
||||
* @param { (reason: unknown) => TResult2 } onrejected
|
||||
*/
|
||||
value: (onfulfilled, onrejected) => {
|
||||
{
|
||||
const user_result = onfulfilled({
|
||||
css: munged.css,
|
||||
head: munged.head,
|
||||
html: munged.html
|
||||
});
|
||||
return Promise.resolve(user_result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
return munged;
|
||||
};
|
||||
component_constructor.render = _render;
|
||||
return component_constructor;
|
||||
}
|
||||
function Root($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
let {
|
||||
stores,
|
||||
page,
|
||||
constructors,
|
||||
components = [],
|
||||
form,
|
||||
data_0 = null,
|
||||
data_1 = null,
|
||||
data_2 = null
|
||||
} = $$props;
|
||||
{
|
||||
setContext("__svelte__", stores);
|
||||
}
|
||||
{
|
||||
stores.page.set(page);
|
||||
}
|
||||
const Pyramid_2 = derived(() => constructors[2]);
|
||||
if (constructors[1]) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
const Pyramid_0 = constructors[0];
|
||||
if (Pyramid_0) {
|
||||
$$renderer2.push("<!--[-->");
|
||||
Pyramid_0($$renderer2, {
|
||||
data: data_0,
|
||||
form,
|
||||
params: page.params,
|
||||
children: ($$renderer3) => {
|
||||
if (constructors[2]) {
|
||||
$$renderer3.push("<!--[0-->");
|
||||
const Pyramid_1 = constructors[1];
|
||||
if (Pyramid_1) {
|
||||
$$renderer3.push("<!--[-->");
|
||||
Pyramid_1($$renderer3, {
|
||||
data: data_1,
|
||||
form,
|
||||
params: page.params,
|
||||
children: ($$renderer4) => {
|
||||
if (Pyramid_2()) {
|
||||
$$renderer4.push("<!--[-->");
|
||||
Pyramid_2()($$renderer4, { data: data_2, form, params: page.params });
|
||||
$$renderer4.push("<!--]-->");
|
||||
} else {
|
||||
$$renderer4.push("<!--[!-->");
|
||||
$$renderer4.push("<!--]-->");
|
||||
}
|
||||
},
|
||||
$$slots: { default: true }
|
||||
});
|
||||
$$renderer3.push("<!--]-->");
|
||||
} else {
|
||||
$$renderer3.push("<!--[!-->");
|
||||
$$renderer3.push("<!--]-->");
|
||||
}
|
||||
} else {
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
const Pyramid_1 = constructors[1];
|
||||
if (Pyramid_1) {
|
||||
$$renderer3.push("<!--[-->");
|
||||
Pyramid_1($$renderer3, { data: data_1, form, params: page.params });
|
||||
$$renderer3.push("<!--]-->");
|
||||
} else {
|
||||
$$renderer3.push("<!--[!-->");
|
||||
$$renderer3.push("<!--]-->");
|
||||
}
|
||||
}
|
||||
$$renderer3.push(`<!--]-->`);
|
||||
},
|
||||
$$slots: { default: true }
|
||||
});
|
||||
$$renderer2.push("<!--]-->");
|
||||
} else {
|
||||
$$renderer2.push("<!--[!-->");
|
||||
$$renderer2.push("<!--]-->");
|
||||
}
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
const Pyramid_0 = constructors[0];
|
||||
if (Pyramid_0) {
|
||||
$$renderer2.push("<!--[-->");
|
||||
Pyramid_0($$renderer2, { data: data_0, form, params: page.params });
|
||||
$$renderer2.push("<!--]-->");
|
||||
} else {
|
||||
$$renderer2.push("<!--[!-->");
|
||||
$$renderer2.push("<!--]-->");
|
||||
}
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
});
|
||||
}
|
||||
const root = asClassComponent(Root);
|
||||
export {
|
||||
root as r
|
||||
};
|
||||
@@ -0,0 +1,789 @@
|
||||
import { json, text } from "@sveltejs/kit";
|
||||
import { SvelteKitError, HttpError } from "@sveltejs/kit/internal";
|
||||
import { with_request_store } from "@sveltejs/kit/internal/server";
|
||||
import * as devalue from "devalue";
|
||||
import { t as text_decoder, b as base64_encode, a as base64_decode } from "./utils.js";
|
||||
const SVELTE_KIT_ASSETS = "/_svelte_kit_assets";
|
||||
const ENDPOINT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
|
||||
const MUTATIVE_METHODS = ["POST", "PUT", "PATCH", "DELETE"];
|
||||
const PAGE_METHODS = ["GET", "POST", "HEAD"];
|
||||
function set_nested_value(object, path_string, value) {
|
||||
if (path_string.startsWith("n:")) {
|
||||
path_string = path_string.slice(2);
|
||||
value = value === "" ? void 0 : parseFloat(value);
|
||||
} else if (path_string.startsWith("b:")) {
|
||||
path_string = path_string.slice(2);
|
||||
value = value === "on";
|
||||
}
|
||||
deep_set(object, split_path(path_string), value);
|
||||
}
|
||||
function convert_formdata(data) {
|
||||
const result = {};
|
||||
for (let key of data.keys()) {
|
||||
const is_array = key.endsWith("[]");
|
||||
let values = data.getAll(key);
|
||||
if (is_array) key = key.slice(0, -2);
|
||||
if (values.length > 1 && !is_array) {
|
||||
throw new Error(`Form cannot contain duplicated keys — "${key}" has ${values.length} values`);
|
||||
}
|
||||
values = values.filter(
|
||||
(entry) => typeof entry === "string" || entry.name !== "" || entry.size > 0
|
||||
);
|
||||
if (key.startsWith("n:")) {
|
||||
key = key.slice(2);
|
||||
values = values.map((v) => v === "" ? void 0 : parseFloat(
|
||||
/** @type {string} */
|
||||
v
|
||||
));
|
||||
} else if (key.startsWith("b:")) {
|
||||
key = key.slice(2);
|
||||
values = values.map((v) => v === "on");
|
||||
}
|
||||
set_nested_value(result, key, is_array ? values : values[0]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const BINARY_FORM_CONTENT_TYPE = "application/x-sveltekit-formdata";
|
||||
const BINARY_FORM_VERSION = 0;
|
||||
const HEADER_BYTES = 1 + 4 + 2;
|
||||
async function deserialize_binary_form(request) {
|
||||
if (request.headers.get("content-type") !== BINARY_FORM_CONTENT_TYPE) {
|
||||
const form_data = await request.formData();
|
||||
return { data: convert_formdata(form_data), meta: {}, form_data };
|
||||
}
|
||||
if (!request.body) {
|
||||
throw deserialize_error("no body");
|
||||
}
|
||||
const content_length = parseInt(request.headers.get("content-length") ?? "");
|
||||
if (Number.isNaN(content_length)) {
|
||||
throw deserialize_error("invalid Content-Length header");
|
||||
}
|
||||
const reader = request.body.getReader();
|
||||
const chunks = [];
|
||||
function get_chunk(index) {
|
||||
if (index in chunks) return chunks[index];
|
||||
let i = chunks.length;
|
||||
while (i <= index) {
|
||||
chunks[i] = reader.read().then((chunk) => chunk.value);
|
||||
i++;
|
||||
}
|
||||
return chunks[index];
|
||||
}
|
||||
async function get_buffer(offset, length) {
|
||||
let start_chunk;
|
||||
let chunk_start = 0;
|
||||
let chunk_index;
|
||||
for (chunk_index = 0; ; chunk_index++) {
|
||||
const chunk = await get_chunk(chunk_index);
|
||||
if (!chunk) return null;
|
||||
const chunk_end = chunk_start + chunk.byteLength;
|
||||
if (offset >= chunk_start && offset < chunk_end) {
|
||||
start_chunk = chunk;
|
||||
break;
|
||||
}
|
||||
chunk_start = chunk_end;
|
||||
}
|
||||
if (offset + length <= chunk_start + start_chunk.byteLength) {
|
||||
return start_chunk.subarray(offset - chunk_start, offset + length - chunk_start);
|
||||
}
|
||||
const chunks2 = [start_chunk.subarray(offset - chunk_start)];
|
||||
let cursor = start_chunk.byteLength - offset + chunk_start;
|
||||
while (cursor < length) {
|
||||
chunk_index++;
|
||||
let chunk = await get_chunk(chunk_index);
|
||||
if (!chunk) return null;
|
||||
if (chunk.byteLength > length - cursor) {
|
||||
chunk = chunk.subarray(0, length - cursor);
|
||||
}
|
||||
chunks2.push(chunk);
|
||||
cursor += chunk.byteLength;
|
||||
}
|
||||
const buffer = new Uint8Array(length);
|
||||
cursor = 0;
|
||||
for (const chunk of chunks2) {
|
||||
buffer.set(chunk, cursor);
|
||||
cursor += chunk.byteLength;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
const header = await get_buffer(0, HEADER_BYTES);
|
||||
if (!header) throw deserialize_error("too short");
|
||||
if (header[0] !== BINARY_FORM_VERSION) {
|
||||
throw deserialize_error(`got version ${header[0]}, expected version ${BINARY_FORM_VERSION}`);
|
||||
}
|
||||
const header_view = new DataView(header.buffer, header.byteOffset, header.byteLength);
|
||||
const data_length = header_view.getUint32(1, true);
|
||||
if (HEADER_BYTES + data_length > content_length) {
|
||||
throw deserialize_error("data overflow");
|
||||
}
|
||||
const file_offsets_length = header_view.getUint16(5, true);
|
||||
if (HEADER_BYTES + data_length + file_offsets_length > content_length) {
|
||||
throw deserialize_error("file offset table overflow");
|
||||
}
|
||||
const data_buffer = await get_buffer(HEADER_BYTES, data_length);
|
||||
if (!data_buffer) throw deserialize_error("data too short");
|
||||
let file_offsets;
|
||||
let files_start_offset;
|
||||
if (file_offsets_length > 0) {
|
||||
const file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);
|
||||
if (!file_offsets_buffer) throw deserialize_error("file offset table too short");
|
||||
const parsed_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));
|
||||
if (!Array.isArray(parsed_offsets) || parsed_offsets.some((n) => typeof n !== "number" || !Number.isInteger(n) || n < 0)) {
|
||||
throw deserialize_error("invalid file offset table");
|
||||
}
|
||||
file_offsets = /** @type {Array<number>} */
|
||||
parsed_offsets;
|
||||
files_start_offset = HEADER_BYTES + data_length + file_offsets_length;
|
||||
}
|
||||
const file_spans = [];
|
||||
const [data, meta] = devalue.parse(text_decoder.decode(data_buffer), {
|
||||
File: ([name, type, size, last_modified, index]) => {
|
||||
if (typeof name !== "string" || typeof type !== "string" || typeof size !== "number" || typeof last_modified !== "number" || typeof index !== "number") {
|
||||
throw deserialize_error("invalid file metadata");
|
||||
}
|
||||
let offset = file_offsets[index];
|
||||
if (offset === void 0) {
|
||||
throw deserialize_error("duplicate file offset table index");
|
||||
}
|
||||
file_offsets[index] = void 0;
|
||||
offset += files_start_offset;
|
||||
if (offset + size > content_length) {
|
||||
throw deserialize_error("file data overflow");
|
||||
}
|
||||
file_spans.push({ offset, size });
|
||||
return new Proxy(new LazyFile(name, type, size, last_modified, get_chunk, offset), {
|
||||
getPrototypeOf() {
|
||||
return File.prototype;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
file_spans.sort((a, b) => a.offset - b.offset || a.size - b.size);
|
||||
for (let i = 1; i < file_spans.length; i++) {
|
||||
const previous = file_spans[i - 1];
|
||||
const current = file_spans[i];
|
||||
const previous_end = previous.offset + previous.size;
|
||||
if (previous_end < current.offset) {
|
||||
throw deserialize_error("gaps in file data");
|
||||
}
|
||||
if (previous_end > current.offset) {
|
||||
throw deserialize_error("overlapping file data");
|
||||
}
|
||||
}
|
||||
void (async () => {
|
||||
let has_more = true;
|
||||
while (has_more) {
|
||||
const chunk = await get_chunk(chunks.length);
|
||||
has_more = !!chunk;
|
||||
}
|
||||
})();
|
||||
return { data, meta, form_data: null };
|
||||
}
|
||||
function deserialize_error(message) {
|
||||
return new SvelteKitError(400, "Bad Request", `Could not deserialize binary form: ${message}`);
|
||||
}
|
||||
class LazyFile {
|
||||
/** @type {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} */
|
||||
#get_chunk;
|
||||
/** @type {number} */
|
||||
#offset;
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} type
|
||||
* @param {number} size
|
||||
* @param {number} last_modified
|
||||
* @param {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} get_chunk
|
||||
* @param {number} offset
|
||||
*/
|
||||
constructor(name, type, size, last_modified, get_chunk, offset) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.lastModified = last_modified;
|
||||
this.webkitRelativePath = "";
|
||||
this.#get_chunk = get_chunk;
|
||||
this.#offset = offset;
|
||||
this.arrayBuffer = this.arrayBuffer.bind(this);
|
||||
this.bytes = this.bytes.bind(this);
|
||||
this.slice = this.slice.bind(this);
|
||||
this.stream = this.stream.bind(this);
|
||||
this.text = this.text.bind(this);
|
||||
}
|
||||
/** @type {ArrayBuffer | undefined} */
|
||||
#buffer;
|
||||
async arrayBuffer() {
|
||||
this.#buffer ??= await new Response(this.stream()).arrayBuffer();
|
||||
return this.#buffer;
|
||||
}
|
||||
async bytes() {
|
||||
return new Uint8Array(await this.arrayBuffer());
|
||||
}
|
||||
/**
|
||||
* @param {number=} start
|
||||
* @param {number=} end
|
||||
* @param {string=} contentType
|
||||
*/
|
||||
slice(start = 0, end = this.size, contentType = this.type) {
|
||||
if (start < 0) {
|
||||
start = Math.max(this.size + start, 0);
|
||||
} else {
|
||||
start = Math.min(start, this.size);
|
||||
}
|
||||
if (end < 0) {
|
||||
end = Math.max(this.size + end, 0);
|
||||
} else {
|
||||
end = Math.min(end, this.size);
|
||||
}
|
||||
const size = Math.max(end - start, 0);
|
||||
const file = new LazyFile(
|
||||
this.name,
|
||||
contentType,
|
||||
size,
|
||||
this.lastModified,
|
||||
this.#get_chunk,
|
||||
this.#offset + start
|
||||
);
|
||||
return file;
|
||||
}
|
||||
stream() {
|
||||
let cursor = 0;
|
||||
let chunk_index = 0;
|
||||
return new ReadableStream({
|
||||
start: async (controller) => {
|
||||
let chunk_start = 0;
|
||||
let start_chunk;
|
||||
for (chunk_index = 0; ; chunk_index++) {
|
||||
const chunk = await this.#get_chunk(chunk_index);
|
||||
if (!chunk) return null;
|
||||
const chunk_end = chunk_start + chunk.byteLength;
|
||||
if (this.#offset >= chunk_start && this.#offset < chunk_end) {
|
||||
start_chunk = chunk;
|
||||
break;
|
||||
}
|
||||
chunk_start = chunk_end;
|
||||
}
|
||||
if (this.#offset + this.size <= chunk_start + start_chunk.byteLength) {
|
||||
controller.enqueue(
|
||||
start_chunk.subarray(this.#offset - chunk_start, this.#offset + this.size - chunk_start)
|
||||
);
|
||||
controller.close();
|
||||
} else {
|
||||
controller.enqueue(start_chunk.subarray(this.#offset - chunk_start));
|
||||
cursor = start_chunk.byteLength - this.#offset + chunk_start;
|
||||
}
|
||||
},
|
||||
pull: async (controller) => {
|
||||
chunk_index++;
|
||||
let chunk = await this.#get_chunk(chunk_index);
|
||||
if (!chunk) {
|
||||
controller.error("incomplete file data");
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
if (chunk.byteLength > this.size - cursor) {
|
||||
chunk = chunk.subarray(0, this.size - cursor);
|
||||
}
|
||||
controller.enqueue(chunk);
|
||||
cursor += chunk.byteLength;
|
||||
if (cursor >= this.size) {
|
||||
controller.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
async text() {
|
||||
return text_decoder.decode(await this.arrayBuffer());
|
||||
}
|
||||
}
|
||||
const path_regex = /^[a-zA-Z_$]\w*(\.[a-zA-Z_$]\w*|\[\d+\])*$/;
|
||||
function split_path(path) {
|
||||
if (!path_regex.test(path)) {
|
||||
throw new Error(`Invalid path ${path}`);
|
||||
}
|
||||
return path.split(/\.|\[|\]/).filter(Boolean);
|
||||
}
|
||||
function check_prototype_pollution(key) {
|
||||
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
||||
throw new Error(
|
||||
`Invalid key "${key}"`
|
||||
);
|
||||
}
|
||||
}
|
||||
function deep_set(object, keys, value) {
|
||||
let current = object;
|
||||
for (let i = 0; i < keys.length - 1; i += 1) {
|
||||
const key = keys[i];
|
||||
check_prototype_pollution(key);
|
||||
const is_array = /^\d+$/.test(keys[i + 1]);
|
||||
const exists = Object.hasOwn(current, key);
|
||||
const inner = current[key];
|
||||
if (exists && is_array !== Array.isArray(inner)) {
|
||||
throw new Error(`Invalid array key ${keys[i + 1]}`);
|
||||
}
|
||||
if (!exists) {
|
||||
current[key] = is_array ? [] : {};
|
||||
}
|
||||
current = current[key];
|
||||
}
|
||||
const final_key = keys[keys.length - 1];
|
||||
check_prototype_pollution(final_key);
|
||||
current[final_key] = value;
|
||||
}
|
||||
function normalize_issue(issue, server = false) {
|
||||
const normalized = { name: "", path: [], message: issue.message, server };
|
||||
if (issue.path !== void 0) {
|
||||
let name = "";
|
||||
for (const segment of issue.path) {
|
||||
const key = (
|
||||
/** @type {string | number} */
|
||||
typeof segment === "object" ? segment.key : segment
|
||||
);
|
||||
normalized.path.push(key);
|
||||
if (typeof key === "number") {
|
||||
name += `[${key}]`;
|
||||
} else if (typeof key === "string") {
|
||||
name += name === "" ? key : "." + key;
|
||||
}
|
||||
}
|
||||
normalized.name = name;
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
function flatten_issues(issues) {
|
||||
const result = {};
|
||||
for (const issue of issues) {
|
||||
(result.$ ??= []).push(issue);
|
||||
let name = "";
|
||||
if (issue.path !== void 0) {
|
||||
for (const key of issue.path) {
|
||||
if (typeof key === "number") {
|
||||
name += `[${key}]`;
|
||||
} else if (typeof key === "string") {
|
||||
name += name === "" ? key : "." + key;
|
||||
}
|
||||
(result[name] ??= []).push(issue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function deep_get(object, path) {
|
||||
let current = object;
|
||||
for (const key of path) {
|
||||
if (current == null || typeof current !== "object") {
|
||||
return current;
|
||||
}
|
||||
current = current[key];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
function create_field_proxy(target, get_input, set_input, get_issues, path = []) {
|
||||
const get_value = () => {
|
||||
return deep_get(get_input(), path);
|
||||
};
|
||||
return new Proxy(target, {
|
||||
get(target2, prop) {
|
||||
if (typeof prop === "symbol") return target2[prop];
|
||||
if (/^\d+$/.test(prop)) {
|
||||
return create_field_proxy({}, get_input, set_input, get_issues, [
|
||||
...path,
|
||||
parseInt(prop, 10)
|
||||
]);
|
||||
}
|
||||
const key = build_path_string(path);
|
||||
if (prop === "set") {
|
||||
const set_func = function(newValue) {
|
||||
set_input(path, newValue);
|
||||
return newValue;
|
||||
};
|
||||
return create_field_proxy(set_func, get_input, set_input, get_issues, [...path, prop]);
|
||||
}
|
||||
if (prop === "value") {
|
||||
return create_field_proxy(get_value, get_input, set_input, get_issues, [...path, prop]);
|
||||
}
|
||||
if (prop === "issues" || prop === "allIssues") {
|
||||
const issues_func = () => {
|
||||
const all_issues = get_issues()[key === "" ? "$" : key];
|
||||
if (prop === "allIssues") {
|
||||
return all_issues?.map((issue) => ({
|
||||
path: issue.path,
|
||||
message: issue.message
|
||||
}));
|
||||
}
|
||||
return all_issues?.filter((issue) => issue.name === key)?.map((issue) => ({
|
||||
path: issue.path,
|
||||
message: issue.message
|
||||
}));
|
||||
};
|
||||
return create_field_proxy(issues_func, get_input, set_input, get_issues, [...path, prop]);
|
||||
}
|
||||
if (prop === "as") {
|
||||
const as_func = (type, input_value) => {
|
||||
const is_array = type === "file multiple" || type === "select multiple" || type === "checkbox" && typeof input_value === "string";
|
||||
const prefix = type === "number" || type === "range" ? "n:" : type === "checkbox" && !is_array ? "b:" : "";
|
||||
const base_props = {
|
||||
name: prefix + key + (is_array ? "[]" : ""),
|
||||
get "aria-invalid"() {
|
||||
const issues = get_issues();
|
||||
return key in issues ? "true" : void 0;
|
||||
}
|
||||
};
|
||||
if (type !== "text" && type !== "select" && type !== "select multiple") {
|
||||
base_props.type = type === "file multiple" ? "file" : type;
|
||||
}
|
||||
if (type === "submit" || type === "hidden") {
|
||||
return Object.defineProperties(base_props, {
|
||||
value: { value: input_value, enumerable: true }
|
||||
});
|
||||
}
|
||||
if (type === "select" || type === "select multiple") {
|
||||
return Object.defineProperties(base_props, {
|
||||
multiple: { value: is_array, enumerable: true },
|
||||
value: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return get_value();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (type === "checkbox" || type === "radio") {
|
||||
return Object.defineProperties(base_props, {
|
||||
value: { value: input_value ?? "on", enumerable: true },
|
||||
checked: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
const value = get_value();
|
||||
if (type === "radio") {
|
||||
return value === input_value;
|
||||
}
|
||||
if (is_array) {
|
||||
return (value ?? []).includes(input_value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (type === "file" || type === "file multiple") {
|
||||
return Object.defineProperties(base_props, {
|
||||
multiple: { value: is_array, enumerable: true },
|
||||
files: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
const value = get_value();
|
||||
if (value instanceof File) {
|
||||
if (typeof DataTransfer !== "undefined") {
|
||||
const fileList = new DataTransfer();
|
||||
fileList.items.add(value);
|
||||
return fileList.files;
|
||||
}
|
||||
return { 0: value, length: 1 };
|
||||
}
|
||||
if (Array.isArray(value) && value.every((f) => f instanceof File)) {
|
||||
if (typeof DataTransfer !== "undefined") {
|
||||
const fileList = new DataTransfer();
|
||||
value.forEach((file) => fileList.items.add(file));
|
||||
return fileList.files;
|
||||
}
|
||||
const fileListLike = { length: value.length };
|
||||
value.forEach((file, index) => {
|
||||
fileListLike[index] = file;
|
||||
});
|
||||
return fileListLike;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return Object.defineProperties(base_props, {
|
||||
value: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
const value = get_value();
|
||||
return value != null ? String(value) : "";
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
return create_field_proxy(as_func, get_input, set_input, get_issues, [...path, "as"]);
|
||||
}
|
||||
return create_field_proxy({}, get_input, set_input, get_issues, [...path, prop]);
|
||||
}
|
||||
});
|
||||
}
|
||||
function build_path_string(path) {
|
||||
let result = "";
|
||||
for (const segment of path) {
|
||||
if (typeof segment === "number") {
|
||||
result += `[${segment}]`;
|
||||
} else {
|
||||
result += result === "" ? segment : "." + segment;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function negotiate(accept, types) {
|
||||
const parts = [];
|
||||
accept.split(",").forEach((str, i) => {
|
||||
const match = /([^/ \t]+)\/([^; \t]+)[ \t]*(?:;[ \t]*q=([0-9.]+))?/.exec(str);
|
||||
if (match) {
|
||||
const [, type, subtype, q = "1"] = match;
|
||||
parts.push({ type, subtype, q: +q, i });
|
||||
}
|
||||
});
|
||||
parts.sort((a, b) => {
|
||||
if (a.q !== b.q) {
|
||||
return b.q - a.q;
|
||||
}
|
||||
if (a.subtype === "*" !== (b.subtype === "*")) {
|
||||
return a.subtype === "*" ? 1 : -1;
|
||||
}
|
||||
if (a.type === "*" !== (b.type === "*")) {
|
||||
return a.type === "*" ? 1 : -1;
|
||||
}
|
||||
return a.i - b.i;
|
||||
});
|
||||
let accepted;
|
||||
let min_priority = Infinity;
|
||||
for (const mimetype of types) {
|
||||
const [type, subtype] = mimetype.split("/");
|
||||
const priority = parts.findIndex(
|
||||
(part) => (part.type === type || part.type === "*") && (part.subtype === subtype || part.subtype === "*")
|
||||
);
|
||||
if (priority !== -1 && priority < min_priority) {
|
||||
accepted = mimetype;
|
||||
min_priority = priority;
|
||||
}
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
function is_content_type(request, ...types) {
|
||||
const type = request.headers.get("content-type")?.split(";", 1)[0].trim() ?? "";
|
||||
return types.includes(type.toLowerCase());
|
||||
}
|
||||
function is_form_content_type(request) {
|
||||
return is_content_type(
|
||||
request,
|
||||
"application/x-www-form-urlencoded",
|
||||
"multipart/form-data",
|
||||
"text/plain",
|
||||
BINARY_FORM_CONTENT_TYPE
|
||||
);
|
||||
}
|
||||
function coalesce_to_error(err) {
|
||||
return err instanceof Error || err && /** @type {any} */
|
||||
err.name && /** @type {any} */
|
||||
err.message ? (
|
||||
/** @type {Error} */
|
||||
err
|
||||
) : new Error(JSON.stringify(err));
|
||||
}
|
||||
function normalize_error(error) {
|
||||
return (
|
||||
/** @type {import('../exports/internal/index.js').Redirect | HttpError | SvelteKitError | Error} */
|
||||
error
|
||||
);
|
||||
}
|
||||
function get_status(error) {
|
||||
return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500;
|
||||
}
|
||||
function get_message(error) {
|
||||
return error instanceof SvelteKitError ? error.text : "Internal Error";
|
||||
}
|
||||
const escape_html_attr_dict = {
|
||||
"&": "&",
|
||||
'"': """
|
||||
// Svelte also escapes < because the escape function could be called inside a `noscript` there
|
||||
// https://github.com/sveltejs/svelte/security/advisories/GHSA-8266-84wp-wv5c
|
||||
// However, that doesn't apply in SvelteKit
|
||||
};
|
||||
const escape_html_dict = {
|
||||
"&": "&",
|
||||
"<": "<"
|
||||
};
|
||||
const surrogates = (
|
||||
// high surrogate without paired low surrogate
|
||||
"[\\ud800-\\udbff](?![\\udc00-\\udfff])|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\udc00-\\udfff]"
|
||||
);
|
||||
const escape_html_attr_regex = new RegExp(
|
||||
`[${Object.keys(escape_html_attr_dict).join("")}]|` + surrogates,
|
||||
"g"
|
||||
);
|
||||
const escape_html_regex = new RegExp(
|
||||
`[${Object.keys(escape_html_dict).join("")}]|` + surrogates,
|
||||
"g"
|
||||
);
|
||||
function escape_html(str, is_attr) {
|
||||
const dict = is_attr ? escape_html_attr_dict : escape_html_dict;
|
||||
const escaped_str = str.replace(is_attr ? escape_html_attr_regex : escape_html_regex, (match) => {
|
||||
if (match.length === 2) {
|
||||
return match;
|
||||
}
|
||||
return dict[match] ?? `&#${match.charCodeAt(0)};`;
|
||||
});
|
||||
return escaped_str;
|
||||
}
|
||||
function method_not_allowed(mod, method) {
|
||||
return text(`${method} method not allowed`, {
|
||||
status: 405,
|
||||
headers: {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
|
||||
// "The server must generate an Allow header field in a 405 status code response"
|
||||
allow: allowed_methods(mod).join(", ")
|
||||
}
|
||||
});
|
||||
}
|
||||
function allowed_methods(mod) {
|
||||
const allowed = ENDPOINT_METHODS.filter((method) => method in mod);
|
||||
if ("GET" in mod && !("HEAD" in mod)) {
|
||||
allowed.push("HEAD");
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
function get_global_name(options) {
|
||||
return `__sveltekit_${options.version_hash}`;
|
||||
}
|
||||
function static_error_page(options, status, message) {
|
||||
let page = options.templates.error({ status, message: escape_html(message) });
|
||||
return text(page, {
|
||||
headers: { "content-type": "text/html; charset=utf-8" },
|
||||
status
|
||||
});
|
||||
}
|
||||
async function handle_fatal_error(event, state, options, error) {
|
||||
error = error instanceof HttpError ? error : coalesce_to_error(error);
|
||||
const status = get_status(error);
|
||||
const body = await handle_error_and_jsonify(event, state, options, error);
|
||||
const type = negotiate(event.request.headers.get("accept") || "text/html", [
|
||||
"application/json",
|
||||
"text/html"
|
||||
]);
|
||||
if (event.isDataRequest || type === "application/json") {
|
||||
return json(body, {
|
||||
status
|
||||
});
|
||||
}
|
||||
return static_error_page(options, status, body.message);
|
||||
}
|
||||
async function handle_error_and_jsonify(event, state, options, error) {
|
||||
if (error instanceof HttpError) {
|
||||
return { message: "Unknown Error", ...error.body };
|
||||
}
|
||||
const status = get_status(error);
|
||||
const message = get_message(error);
|
||||
return await with_request_store(
|
||||
{ event, state },
|
||||
() => options.hooks.handleError({ error, event, status, message })
|
||||
) ?? { message };
|
||||
}
|
||||
function redirect_response(status, location) {
|
||||
const response = new Response(void 0, {
|
||||
status,
|
||||
headers: { location }
|
||||
});
|
||||
return response;
|
||||
}
|
||||
function clarify_devalue_error(event, error) {
|
||||
if (error.path) {
|
||||
return `Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error.message} (${error.path}). If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#Universal-hooks-transport.`;
|
||||
}
|
||||
if (error.path === "") {
|
||||
return `Data returned from \`load\` while rendering ${event.route.id} is not a plain object`;
|
||||
}
|
||||
return error.message;
|
||||
}
|
||||
function serialize_uses(node) {
|
||||
const uses = {};
|
||||
if (node.uses && node.uses.dependencies.size > 0) {
|
||||
uses.dependencies = Array.from(node.uses.dependencies);
|
||||
}
|
||||
if (node.uses && node.uses.search_params.size > 0) {
|
||||
uses.search_params = Array.from(node.uses.search_params);
|
||||
}
|
||||
if (node.uses && node.uses.params.size > 0) {
|
||||
uses.params = Array.from(node.uses.params);
|
||||
}
|
||||
if (node.uses?.parent) uses.parent = 1;
|
||||
if (node.uses?.route) uses.route = 1;
|
||||
if (node.uses?.url) uses.url = 1;
|
||||
return uses;
|
||||
}
|
||||
function has_prerendered_path(manifest, pathname) {
|
||||
return manifest._.prerendered_routes.has(pathname) || pathname.at(-1) === "/" && manifest._.prerendered_routes.has(pathname.slice(0, -1));
|
||||
}
|
||||
function format_server_error(status, error, event) {
|
||||
const formatted_text = `
|
||||
\x1B[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1B[0m`;
|
||||
if (status === 404) {
|
||||
return formatted_text;
|
||||
}
|
||||
return `${formatted_text}
|
||||
${error.stack}`;
|
||||
}
|
||||
function get_node_type(node_id) {
|
||||
const parts = node_id?.split("/");
|
||||
const filename = parts?.at(-1);
|
||||
if (!filename) return "unknown";
|
||||
const dot_parts = filename.split(".");
|
||||
return dot_parts.slice(0, -1).join(".");
|
||||
}
|
||||
const INVALIDATED_PARAM = "x-sveltekit-invalidated";
|
||||
const TRAILING_SLASH_PARAM = "x-sveltekit-trailing-slash";
|
||||
function stringify(data, transport) {
|
||||
const encoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.encode]));
|
||||
return devalue.stringify(data, encoders);
|
||||
}
|
||||
function stringify_remote_arg(value, transport) {
|
||||
if (value === void 0) return "";
|
||||
const json_string = stringify(value, transport);
|
||||
const bytes = new TextEncoder().encode(json_string);
|
||||
return base64_encode(bytes).replaceAll("=", "").replaceAll("+", "-").replaceAll("/", "_");
|
||||
}
|
||||
function parse_remote_arg(string, transport) {
|
||||
if (!string) return void 0;
|
||||
const json_string = text_decoder.decode(
|
||||
// no need to add back `=` characters, atob can handle it
|
||||
base64_decode(string.replaceAll("-", "+").replaceAll("_", "/"))
|
||||
);
|
||||
const decoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.decode]));
|
||||
return devalue.parse(json_string, decoders);
|
||||
}
|
||||
function create_remote_key(id, payload) {
|
||||
return id + "/" + payload;
|
||||
}
|
||||
export {
|
||||
ENDPOINT_METHODS as E,
|
||||
INVALIDATED_PARAM as I,
|
||||
MUTATIVE_METHODS as M,
|
||||
PAGE_METHODS as P,
|
||||
SVELTE_KIT_ASSETS as S,
|
||||
TRAILING_SLASH_PARAM as T,
|
||||
set_nested_value as a,
|
||||
stringify as b,
|
||||
create_field_proxy as c,
|
||||
deep_set as d,
|
||||
create_remote_key as e,
|
||||
flatten_issues as f,
|
||||
negotiate as g,
|
||||
handle_error_and_jsonify as h,
|
||||
get_status as i,
|
||||
is_form_content_type as j,
|
||||
normalize_error as k,
|
||||
get_global_name as l,
|
||||
method_not_allowed as m,
|
||||
normalize_issue as n,
|
||||
serialize_uses as o,
|
||||
clarify_devalue_error as p,
|
||||
get_node_type as q,
|
||||
escape_html as r,
|
||||
stringify_remote_arg as s,
|
||||
static_error_page as t,
|
||||
redirect_response as u,
|
||||
parse_remote_arg as v,
|
||||
deserialize_binary_form as w,
|
||||
has_prerendered_path as x,
|
||||
handle_fatal_error as y,
|
||||
format_server_error as z
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
import "clsx";
|
||||
import { n as noop } from "./index.js";
|
||||
import "./exports.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "./root.js";
|
||||
const is_legacy = noop.toString().includes("$$") || /function \w+\(\) \{\}/.test(noop.toString());
|
||||
const placeholder_url = "a:";
|
||||
if (is_legacy) {
|
||||
({
|
||||
data: {},
|
||||
form: null,
|
||||
error: null,
|
||||
params: {},
|
||||
route: { id: null },
|
||||
state: {},
|
||||
status: -1,
|
||||
url: new URL(placeholder_url)
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { j as getContext } from "./index.js";
|
||||
import "clsx";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "./exports.js";
|
||||
import "./utils.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "./root.js";
|
||||
import "./state.svelte.js";
|
||||
const getStores = () => {
|
||||
const stores$1 = getContext("__svelte__");
|
||||
return {
|
||||
/** @type {typeof page} */
|
||||
page: {
|
||||
subscribe: stores$1.page.subscribe
|
||||
},
|
||||
/** @type {typeof navigating} */
|
||||
navigating: {
|
||||
subscribe: stores$1.navigating.subscribe
|
||||
},
|
||||
/** @type {typeof updated} */
|
||||
updated: stores$1.updated
|
||||
};
|
||||
};
|
||||
const page = {
|
||||
subscribe(fn) {
|
||||
const store = getStores().page;
|
||||
return store.subscribe(fn);
|
||||
}
|
||||
};
|
||||
export {
|
||||
page as p
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { w as writable, d as derived } from "./index3.js";
|
||||
const THEME_KEY = "dw_theme";
|
||||
function getInitialMode() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
const stored = localStorage.getItem(THEME_KEY);
|
||||
if (stored === "light" || stored === "dark" || stored === "system") return stored;
|
||||
}
|
||||
return "system";
|
||||
}
|
||||
const themeMode = writable(getInitialMode());
|
||||
themeMode.subscribe((value) => {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.setItem(THEME_KEY, value);
|
||||
}
|
||||
});
|
||||
derived(themeMode, ($mode) => {
|
||||
if ($mode === "system") {
|
||||
if (typeof window !== "undefined") {
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
}
|
||||
return "light";
|
||||
}
|
||||
return $mode;
|
||||
});
|
||||
export {
|
||||
themeMode as t
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
import { w as writable } from "./index3.js";
|
||||
function createToastStore() {
|
||||
const { subscribe, update } = writable([]);
|
||||
let counter = 0;
|
||||
function add(message, type = "info", duration = 5e3) {
|
||||
const id = `toast-${++counter}-${Date.now()}`;
|
||||
const toast = { id, message, type, duration };
|
||||
update((toasts2) => [...toasts2, toast]);
|
||||
if (duration > 0) {
|
||||
setTimeout(() => remove(id), duration);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
function remove(id) {
|
||||
update((toasts2) => toasts2.filter((t) => t.id !== id));
|
||||
}
|
||||
function success(message, duration = 5e3) {
|
||||
return add(message, "success", duration);
|
||||
}
|
||||
function error(message, duration = 7e3) {
|
||||
return add(message, "error", duration);
|
||||
}
|
||||
function warning(message, duration = 5e3) {
|
||||
return add(message, "warning", duration);
|
||||
}
|
||||
function info(message, duration = 5e3) {
|
||||
return add(message, "info", duration);
|
||||
}
|
||||
return {
|
||||
subscribe,
|
||||
add,
|
||||
remove,
|
||||
success,
|
||||
error,
|
||||
warning,
|
||||
info
|
||||
};
|
||||
}
|
||||
const toasts = createToastStore();
|
||||
export {
|
||||
toasts as t
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
const text_encoder = new TextEncoder();
|
||||
const text_decoder = new TextDecoder();
|
||||
function get_relative_path(from, to) {
|
||||
const from_parts = from.split(/[/\\]/);
|
||||
const to_parts = to.split(/[/\\]/);
|
||||
from_parts.pop();
|
||||
while (from_parts[0] === to_parts[0]) {
|
||||
from_parts.shift();
|
||||
to_parts.shift();
|
||||
}
|
||||
let i = from_parts.length;
|
||||
while (i--) from_parts[i] = "..";
|
||||
return from_parts.concat(to_parts).join("/");
|
||||
}
|
||||
function base64_encode(bytes) {
|
||||
if (globalThis.Buffer) {
|
||||
return globalThis.Buffer.from(bytes).toString("base64");
|
||||
}
|
||||
let binary = "";
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return btoa(binary);
|
||||
}
|
||||
function base64_decode(encoded) {
|
||||
if (globalThis.Buffer) {
|
||||
const buffer = globalThis.Buffer.from(encoded, "base64");
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
const binary = atob(encoded);
|
||||
const bytes = new Uint8Array(binary.length);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
export {
|
||||
base64_decode as a,
|
||||
base64_encode as b,
|
||||
text_encoder as c,
|
||||
get_relative_path as g,
|
||||
text_decoder as t
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import { j as getContext, e as escape_html } from "../../chunks/index.js";
|
||||
import "clsx";
|
||||
import "../../chunks/state.svelte.js";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "../../chunks/exports.js";
|
||||
import "../../chunks/utils.js";
|
||||
import { w as writable } from "../../chunks/index3.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "../../chunks/root.js";
|
||||
function create_updated_store() {
|
||||
const { set, subscribe } = writable(false);
|
||||
{
|
||||
return {
|
||||
subscribe,
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
check: async () => false
|
||||
};
|
||||
}
|
||||
}
|
||||
const stores = {
|
||||
updated: /* @__PURE__ */ create_updated_store()
|
||||
};
|
||||
({
|
||||
check: stores.updated.check
|
||||
});
|
||||
function context() {
|
||||
return getContext("__request__");
|
||||
}
|
||||
const page$1 = {
|
||||
get error() {
|
||||
return context().page.error;
|
||||
},
|
||||
get status() {
|
||||
return context().page.status;
|
||||
}
|
||||
};
|
||||
const page = page$1;
|
||||
function Error$1($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
$$renderer2.push(`<h1>${escape_html(page.status)}</h1> <p>${escape_html(page.error?.message)}</p>`);
|
||||
});
|
||||
}
|
||||
export {
|
||||
Error$1 as default
|
||||
};
|
||||
@@ -0,0 +1,294 @@
|
||||
import { a as attr, b as attr_class, c as clsx, f as ensure_array_like, s as store_get, g as stringify, e as escape_html, u as unsubscribe_stores, i as derived } from "../../chunks/index.js";
|
||||
import { o as onDestroy } from "../../chunks/index-server.js";
|
||||
import { p as page } from "../../chunks/stores.js";
|
||||
import { t as toasts } from "../../chunks/toast.js";
|
||||
import { I as IconCheck } from "../../chunks/IconCheck.js";
|
||||
import { I as IconX } from "../../chunks/IconX.js";
|
||||
import { I as IconAlert } from "../../chunks/IconAlert.js";
|
||||
import { t as themeMode } from "../../chunks/theme.js";
|
||||
import { t, a as availableLocales, l as locale } from "../../chunks/index2.js";
|
||||
import { I as IconGlobe } from "../../chunks/IconGlobe.js";
|
||||
import { I as IconDeploy } from "../../chunks/IconDeploy.js";
|
||||
import { I as IconSettings } from "../../chunks/IconSettings.js";
|
||||
import { w as writable, g as get } from "../../chunks/index3.js";
|
||||
function IconDashboard($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><rect width="7" height="9" x="3" y="3" rx="1"></rect><rect width="7" height="5" x="14" y="3" rx="1"></rect><rect width="7" height="9" x="14" y="12" rx="1"></rect><rect width="7" height="5" x="3" y="16" rx="1"></rect></svg>`);
|
||||
}
|
||||
function IconProjects($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path></svg>`);
|
||||
}
|
||||
function IconInfo($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M12 16v-4"></path><path d="M12 8h.01"></path></svg>`);
|
||||
}
|
||||
function IconSun($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2"></path><path d="M12 20v2"></path><path d="m4.93 4.93 1.41 1.41"></path><path d="m17.66 17.66 1.41 1.41"></path><path d="M2 12h2"></path><path d="M20 12h2"></path><path d="m6.34 17.66-1.41 1.41"></path><path d="m19.07 4.93-1.41 1.41"></path></svg>`);
|
||||
}
|
||||
function IconMoon($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path></svg>`);
|
||||
}
|
||||
function IconMonitor($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg>`);
|
||||
}
|
||||
function IconMenu($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><line x1="4" x2="20" y1="12" y2="12"></line><line x1="4" x2="20" y1="6" y2="6"></line><line x1="4" x2="20" y1="18" y2="18"></line></svg>`);
|
||||
}
|
||||
function IconProxies($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"></path><path d="M2 12h20"></path></svg>`);
|
||||
}
|
||||
function IconEvents($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z"></path><path d="M15 3v4a2 2 0 0 0 2 2h4"></path><path d="M8 13h.01"></path><path d="M8 17h.01"></path><path d="M12 13h4"></path><path d="M12 17h4"></path></svg>`);
|
||||
}
|
||||
function IconLogout($$renderer, $$props) {
|
||||
const { size = 24, class: className = "" } = $$props;
|
||||
$$renderer.push(`<svg${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(className))}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>`);
|
||||
}
|
||||
function Toast($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const bgMap = {
|
||||
success: "bg-[var(--color-success)]",
|
||||
error: "bg-[var(--color-danger)]",
|
||||
warning: "bg-[var(--color-warning)]",
|
||||
info: "bg-[var(--color-info)]"
|
||||
};
|
||||
$$renderer2.push(`<div class="fixed top-4 right-4 z-[100] flex flex-col gap-2 pointer-events-none"><!--[-->`);
|
||||
const each_array = ensure_array_like(store_get($$store_subs ??= {}, "$toasts", toasts));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let toast = each_array[$$index];
|
||||
$$renderer2.push(`<div${attr_class(`pointer-events-auto flex items-center gap-3 rounded-xl px-4 py-3 text-white shadow-lg animate-slide-in ${stringify(bgMap[toast.type])}`)} role="alert"><div class="flex h-5 w-5 flex-shrink-0 items-center justify-center">`);
|
||||
if (toast.type === "success") {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
IconCheck($$renderer2, { size: 18 });
|
||||
} else if (toast.type === "error") {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
IconX($$renderer2, { size: 18 });
|
||||
} else if (toast.type === "warning") {
|
||||
$$renderer2.push("<!--[2-->");
|
||||
IconAlert($$renderer2, { size: 18 });
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
IconInfo($$renderer2, { size: 18 });
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> <span class="flex-1 text-sm font-medium">${escape_html(toast.message)}</span> <button class="ml-2 rounded-md p-0.5 text-white/70 hover:text-white transition-colors" aria-label="Dismiss notification">`);
|
||||
IconX($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----></button></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function ThemeToggle($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const modes = ["light", "dark", "system"];
|
||||
$$renderer2.push(`<div class="flex items-center gap-0.5 rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] p-0.5"><!--[-->`);
|
||||
const each_array = ensure_array_like(modes);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let mode = each_array[$$index];
|
||||
$$renderer2.push(`<button type="button"${attr_class(`flex items-center justify-center rounded-md p-1.5 transition-all duration-150 ${stringify(store_get($$store_subs ??= {}, "$themeMode", themeMode) === mode ? "bg-[var(--color-brand-100)] text-[var(--color-brand-700)] shadow-sm" : "text-[var(--text-tertiary)] hover:text-[var(--text-secondary)]")}`)}${attr("title", store_get($$store_subs ??= {}, "$t", t)(`theme.${mode}`))}>`);
|
||||
if (mode === "light") {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
IconSun($$renderer2, { size: 14 });
|
||||
} else if (mode === "dark") {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
IconMoon($$renderer2, { size: 14 });
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
IconMonitor($$renderer2, { size: 14 });
|
||||
}
|
||||
$$renderer2.push(`<!--]--></button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function LocaleSwitcher($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
$$renderer2.push(`<div class="flex items-center gap-1.5">`);
|
||||
IconGlobe($$renderer2, { size: 14, class: "text-[var(--text-tertiary)]" });
|
||||
$$renderer2.push(`<!----> <div class="flex items-center gap-0.5 rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] p-0.5"><!--[-->`);
|
||||
const each_array = ensure_array_like(availableLocales);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let loc = each_array[$$index];
|
||||
$$renderer2.push(`<button type="button"${attr_class(`rounded-md px-2 py-0.5 text-xs font-medium transition-all duration-150 ${stringify(store_get($$store_subs ??= {}, "$locale", locale) === loc ? "bg-[var(--color-brand-100)] text-[var(--color-brand-700)] shadow-sm" : "text-[var(--text-tertiary)] hover:text-[var(--text-secondary)]")}`)}>${escape_html(loc.toUpperCase())}</button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function createInstanceStatusStore() {
|
||||
const { subscribe, set, update: storeUpdate } = writable({
|
||||
statuses: {},
|
||||
lastUpdate: 0,
|
||||
deployStatuses: {}
|
||||
});
|
||||
return {
|
||||
subscribe,
|
||||
/** Update an instance's status from an SSE event. */
|
||||
update(payload) {
|
||||
storeUpdate((state) => ({
|
||||
...state,
|
||||
statuses: {
|
||||
...state.statuses,
|
||||
[payload.instance_id]: payload.status
|
||||
},
|
||||
lastUpdate: Date.now()
|
||||
}));
|
||||
},
|
||||
/** Record a deploy status change from an SSE event. */
|
||||
notifyDeploy(payload) {
|
||||
storeUpdate((state) => ({
|
||||
...state,
|
||||
deployStatuses: {
|
||||
...state.deployStatuses,
|
||||
[payload.deploy_id]: payload
|
||||
},
|
||||
lastUpdate: Date.now()
|
||||
}));
|
||||
},
|
||||
/** Get the current status of an instance, or undefined if not tracked. */
|
||||
getStatus(instanceId) {
|
||||
return get({ subscribe }).statuses[instanceId];
|
||||
},
|
||||
/** Reset the store (e.g., on disconnect). */
|
||||
reset() {
|
||||
set({
|
||||
statuses: {},
|
||||
lastUpdate: 0,
|
||||
deployStatuses: {}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
createInstanceStatusStore();
|
||||
function _layout($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const { children } = $$props;
|
||||
const navItems = [
|
||||
{ href: "/", labelKey: "nav.dashboard", icon: "dashboard" },
|
||||
{
|
||||
href: "/projects",
|
||||
labelKey: "nav.projects",
|
||||
icon: "projects"
|
||||
},
|
||||
{ href: "/deploy", labelKey: "nav.deploy", icon: "deploy" },
|
||||
{ href: "/proxies", labelKey: "nav.proxies", icon: "proxies" },
|
||||
{ href: "/events", labelKey: "nav.events", icon: "events" },
|
||||
{
|
||||
href: "/settings",
|
||||
labelKey: "nav.settings",
|
||||
icon: "settings"
|
||||
}
|
||||
];
|
||||
function isActive(href, pathname) {
|
||||
if (href === "/") return pathname === "/";
|
||||
return pathname.startsWith(href);
|
||||
}
|
||||
let sseConnection = null;
|
||||
const isLoginPage = derived(() => store_get($$store_subs ??= {}, "$page", page).url.pathname === "/login");
|
||||
onDestroy(() => {
|
||||
sseConnection?.close();
|
||||
sseConnection = null;
|
||||
});
|
||||
if (isLoginPage()) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
children($$renderer2);
|
||||
$$renderer2.push(`<!---->`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`<div class="flex h-screen overflow-hidden bg-[var(--surface-page)]">`);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <aside${attr_class(`fixed inset-y-0 left-0 z-50 flex w-64 flex-col border-r border-[var(--border-primary)] bg-[var(--surface-sidebar)] transition-transform duration-300 lg:static lg:translate-x-0 ${stringify("-translate-x-full")}`)}><div class="flex h-16 items-center gap-2.5 border-b border-[var(--border-primary)] px-5"><div class="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--color-brand-600)]"><svg class="h-4.5 w-4.5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25"></path></svg></div> <span class="text-base font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</span> <button class="ml-auto rounded-md p-1 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] lg:hidden" aria-label="Close sidebar">`);
|
||||
IconX($$renderer2, { size: 20 });
|
||||
$$renderer2.push(`<!----></button></div> <nav class="flex-1 space-y-0.5 px-3 py-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(navItems);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let item = each_array[$$index];
|
||||
const active = isActive(item.href, store_get($$store_subs ??= {}, "$page", page).url.pathname);
|
||||
$$renderer2.push(`<a${attr("href", item.href)}${attr_class(`group flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-150 ${stringify(active ? "bg-[var(--color-brand-50)] text-[var(--color-brand-700)] shadow-sm" : "text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)]")}`)}>`);
|
||||
if (item.icon === "dashboard") {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
IconDashboard($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else if (item.icon === "projects") {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
IconProjects($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else if (item.icon === "deploy") {
|
||||
$$renderer2.push("<!--[2-->");
|
||||
IconDeploy($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else if (item.icon === "proxies") {
|
||||
$$renderer2.push("<!--[3-->");
|
||||
IconProxies($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else if (item.icon === "events") {
|
||||
$$renderer2.push("<!--[4-->");
|
||||
IconEvents($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else if (item.icon === "settings") {
|
||||
$$renderer2.push("<!--[5-->");
|
||||
IconSettings($$renderer2, {
|
||||
size: 18,
|
||||
class: `${stringify(active ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)] group-hover:text-[var(--text-secondary)]")} transition-colors duration-150`
|
||||
});
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> ${escape_html(store_get($$store_subs ??= {}, "$t", t)(item.labelKey))} `);
|
||||
if (active) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="ml-auto h-1.5 w-1.5 rounded-full bg-[var(--color-brand-600)]"></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></a>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></nav> <div class="space-y-3 border-t border-[var(--border-primary)] px-4 py-3">`);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="flex items-center justify-between">`);
|
||||
ThemeToggle($$renderer2);
|
||||
$$renderer2.push(`<!----> `);
|
||||
LocaleSwitcher($$renderer2);
|
||||
$$renderer2.push(`<!----></div> <div class="flex items-center justify-between"><p class="text-xs text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))} ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.version"))}</p> <button class="inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium text-[var(--text-secondary)] transition-colors hover:bg-[var(--surface-card-hover)] hover:text-[var(--color-danger)]"${attr("title", store_get($$store_subs ??= {}, "$t", t)("nav.logout"))}>`);
|
||||
IconLogout($$renderer2, { size: 14 });
|
||||
$$renderer2.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("nav.logout"))}</button></div></div></aside> <div class="flex flex-1 flex-col overflow-hidden"><header class="flex h-14 items-center gap-3 border-b border-[var(--border-primary)] bg-[var(--surface-sidebar)] px-4 lg:hidden"><button class="rounded-md p-1.5 text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)] transition-colors" aria-label="Open sidebar">`);
|
||||
IconMenu($$renderer2, { size: 22 });
|
||||
$$renderer2.push(`<!----></button> <div class="flex h-7 w-7 items-center justify-center rounded-lg bg-[var(--color-brand-600)]"><svg class="h-3.5 w-3.5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25"></path></svg></div> <span class="text-sm font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</span></header> <main class="flex-1 overflow-y-auto"><div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 sm:py-8">`);
|
||||
children($$renderer2);
|
||||
$$renderer2.push(`<!----></div></main></div></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
Toast($$renderer2);
|
||||
$$renderer2.push(`<!---->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_layout as default
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
const ssr = false;
|
||||
const prerender = false;
|
||||
export {
|
||||
prerender,
|
||||
ssr
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
import { a as attr, b as attr_class, c as clsx, h as head, e as escape_html, s as store_get, g as stringify, f as ensure_array_like, u as unsubscribe_stores, i as derived } from "../../chunks/index.js";
|
||||
import { t } from "../../chunks/index2.js";
|
||||
import { I as IconDeploy } from "../../chunks/IconDeploy.js";
|
||||
import { I as IconAlert } from "../../chunks/IconAlert.js";
|
||||
import { S as SkeletonCard } from "../../chunks/SkeletonCard.js";
|
||||
import "clsx";
|
||||
function IconServer($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg>`);
|
||||
}
|
||||
function IconBox($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"></path><path d="m3.3 7 8.7 5 8.7-5"></path><path d="M12 22V12"></path></svg>`);
|
||||
}
|
||||
function IconClock($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`);
|
||||
}
|
||||
function SystemHealthCard($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
});
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let projects = [];
|
||||
let instancesByProject = {};
|
||||
let staleContainers = [];
|
||||
const totalProjects = derived(() => projects.length);
|
||||
const totalRunning = derived(() => Object.values(instancesByProject).flat().filter((i) => i.status === "running").length);
|
||||
const totalFailed = derived(() => Object.values(instancesByProject).flat().filter((i) => i.status === "failed").length);
|
||||
const totalStale = derived(() => staleContainers.length);
|
||||
head("1uha8ag", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-6"><div class="flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.title"))}</h1> <a href="/deploy" class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] active:animate-press">`);
|
||||
IconDeploy($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.quickDeploy"))}</a></div> <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"><div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div class="flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]">`);
|
||||
IconBox($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.totalProjects"))}</p> <p class="mt-0.5 text-2xl font-bold text-[var(--text-primary)]">${escape_html(totalProjects())}</p></div></div> <div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div class="flex h-12 w-12 items-center justify-center rounded-xl bg-emerald-50 text-emerald-600">`);
|
||||
IconServer($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.runningInstances"))}</p> <p class="mt-0.5 text-2xl font-bold text-emerald-600">${escape_html(totalRunning())}</p></div></div> <div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div${attr_class(`flex h-12 w-12 items-center justify-center rounded-xl ${stringify(totalFailed() > 0 ? "bg-red-50 text-red-600" : "bg-gray-50 text-gray-400")}`)}>`);
|
||||
IconAlert($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.failedInstances"))}</p> <p${attr_class(`mt-0.5 text-2xl font-bold ${stringify(totalFailed() > 0 ? "text-red-600" : "text-[var(--text-primary)]")}`)}>${escape_html(totalFailed())}</p></div></div> <a href="/containers/stale" class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)] transition-colors hover:bg-[var(--surface-card-hover)]"><div${attr_class(`flex h-12 w-12 items-center justify-center rounded-xl ${stringify(totalStale() > 0 ? "bg-amber-50 text-amber-600" : "bg-gray-50 text-gray-400")}`)}>`);
|
||||
IconClock($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.staleContainers"))}</p> <p${attr_class(`mt-0.5 text-2xl font-bold ${stringify(totalStale() > 0 ? "text-amber-600" : "text-[var(--text-primary)]")}`)}>${escape_html(totalStale())}</p></div></a></div> `);
|
||||
SystemHealthCard($$renderer2);
|
||||
$$renderer2.push(`<!----> <div><h2 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.projects"))}</h2> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(3));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
SkeletonCard($$renderer2);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
import { b as attr_class, g as stringify, e as escape_html, s as store_get, u as unsubscribe_stores, i as derived, h as head, a as attr, f as ensure_array_like } from "../../../../chunks/index.js";
|
||||
import { c as cleanupStaleContainer, b as bulkCleanupStaleContainers } from "../../../../chunks/api.js";
|
||||
import { I as IconTrash } from "../../../../chunks/IconTrash.js";
|
||||
import { I as IconLoader } from "../../../../chunks/IconLoader.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
import { I as IconAlert } from "../../../../chunks/IconAlert.js";
|
||||
import { S as SkeletonCard } from "../../../../chunks/SkeletonCard.js";
|
||||
import { t as toasts } from "../../../../chunks/toast.js";
|
||||
function ConfirmDialog($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const {
|
||||
open,
|
||||
title,
|
||||
message,
|
||||
confirmLabel = "Confirm",
|
||||
confirmVariant = "primary",
|
||||
onconfirm,
|
||||
oncancel
|
||||
} = $$props;
|
||||
const confirmClass = derived(() => confirmVariant === "danger" ? "bg-[var(--color-danger)] hover:bg-[var(--color-danger-dark)] focus-visible:outline-[var(--color-danger)]" : "bg-[var(--color-brand-600)] hover:bg-[var(--color-brand-700)] focus-visible:outline-[var(--color-brand-600)]");
|
||||
const iconBgClass = derived(() => confirmVariant === "danger" ? "bg-[var(--color-danger-light)]" : "bg-[var(--color-brand-50)]");
|
||||
const iconColorClass = derived(() => confirmVariant === "danger" ? "text-[var(--color-danger)]" : "text-[var(--color-brand-600)]");
|
||||
if (open) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="fixed inset-0 z-40 bg-[var(--surface-overlay)] animate-fade-in" role="presentation"></div> <div class="fixed inset-0 z-50 flex items-center justify-center p-4"><div class="w-full max-w-md rounded-2xl bg-[var(--surface-card)] p-6 shadow-xl animate-scale-in"><div class="flex items-start gap-4"><div${attr_class(`flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full ${stringify(iconBgClass())}`)}>`);
|
||||
IconAlert($$renderer2, { size: 20, class: iconColorClass() });
|
||||
$$renderer2.push(`<!----></div> <div class="flex-1"><h3 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(title)}</h3> <p class="mt-2 text-sm text-[var(--text-secondary)] leading-relaxed">${escape_html(message)}</p></div></div> <div class="mt-6 flex justify-end gap-3"><button type="button" class="rounded-lg px-4 py-2 text-sm font-medium text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] transition-colors active:animate-press">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.cancel"))}</button> <button type="button"${attr_class(`rounded-lg px-4 py-2 text-sm font-medium text-white ${stringify(confirmClass())} shadow-sm transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 active:animate-press`)}>${escape_html(confirmLabel)}</button></div></div></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let containers = [];
|
||||
let confirmSingleId = "";
|
||||
let confirmBulk = false;
|
||||
let cleaningIds = /* @__PURE__ */ new Set();
|
||||
let bulkCleaning = false;
|
||||
async function handleConfirmCleanup() {
|
||||
const id = confirmSingleId;
|
||||
confirmSingleId = "";
|
||||
cleaningIds = /* @__PURE__ */ new Set([...cleaningIds, id]);
|
||||
try {
|
||||
await cleanupStaleContainer(id);
|
||||
containers = containers.filter((c) => c.id !== id);
|
||||
toasts.success(store_get($$store_subs ??= {}, "$t", t)("stale.cleanedUp"));
|
||||
} catch (e) {
|
||||
toasts.error(e instanceof Error ? e.message : store_get($$store_subs ??= {}, "$t", t)("stale.cleanupFailed"));
|
||||
} finally {
|
||||
const next = new Set(cleaningIds);
|
||||
next.delete(id);
|
||||
cleaningIds = next;
|
||||
}
|
||||
}
|
||||
async function handleConfirmBulkCleanup() {
|
||||
confirmBulk = false;
|
||||
bulkCleaning = true;
|
||||
try {
|
||||
const result = await bulkCleanupStaleContainers();
|
||||
containers = [];
|
||||
toasts.success(store_get($$store_subs ??= {}, "$t", t)("stale.bulkCleanedUp", { count: String(result.deleted) }));
|
||||
} catch (e) {
|
||||
toasts.error(e instanceof Error ? e.message : store_get($$store_subs ??= {}, "$t", t)("stale.cleanupFailed"));
|
||||
} finally {
|
||||
bulkCleaning = false;
|
||||
}
|
||||
}
|
||||
head("r4vrn", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("stale.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-6"><div class="flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("stale.title"))}</h1> `);
|
||||
if (containers.length > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<button type="button"${attr("disabled", bulkCleaning, true)} class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-danger)] px-4 py-2.5 text-sm font-medium text-[var(--color-danger)] transition-colors hover:bg-[var(--color-danger-light)] disabled:opacity-50 active:animate-press">`);
|
||||
if (bulkCleaning) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
IconLoader($$renderer2, { size: 16 });
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
IconTrash($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("stale.cleanupAll"))}</button>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(3));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
SkeletonCard($$renderer2);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> `);
|
||||
ConfirmDialog($$renderer2, {
|
||||
open: confirmSingleId !== "",
|
||||
title: store_get($$store_subs ??= {}, "$t", t)("stale.cleanup"),
|
||||
message: store_get($$store_subs ??= {}, "$t", t)("stale.confirmCleanup"),
|
||||
confirmLabel: store_get($$store_subs ??= {}, "$t", t)("stale.cleanup"),
|
||||
confirmVariant: "danger",
|
||||
onconfirm: handleConfirmCleanup,
|
||||
oncancel: () => {
|
||||
confirmSingleId = "";
|
||||
}
|
||||
});
|
||||
$$renderer2.push(`<!----> `);
|
||||
ConfirmDialog($$renderer2, {
|
||||
open: confirmBulk,
|
||||
title: store_get($$store_subs ??= {}, "$t", t)("stale.cleanupAll"),
|
||||
message: store_get($$store_subs ??= {}, "$t", t)("stale.confirmBulkCleanup"),
|
||||
confirmLabel: store_get($$store_subs ??= {}, "$t", t)("stale.cleanupAll"),
|
||||
confirmVariant: "danger",
|
||||
onconfirm: handleConfirmBulkCleanup,
|
||||
oncancel: () => {
|
||||
confirmBulk = false;
|
||||
}
|
||||
});
|
||||
$$renderer2.push(`<!---->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
const ssr = false;
|
||||
export {
|
||||
ssr
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
import { h as head, e as escape_html, s as store_get, a as attr, u as unsubscribe_stores } from "../../../chunks/index.js";
|
||||
import { F as FormField } from "../../../chunks/FormField.js";
|
||||
import { I as IconSearch, E as EntityPicker } from "../../../chunks/EntityPicker.js";
|
||||
import "../../../chunks/toast.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let imageUrl = "";
|
||||
let inspecting = false;
|
||||
let errors = {};
|
||||
let showImagePicker = false;
|
||||
let imagePickerItems = [];
|
||||
function selectPickedImage(value) {
|
||||
imageUrl = value;
|
||||
showImagePicker = false;
|
||||
}
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("2t7dow", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("quickDeploy.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="mx-auto max-w-2xl space-y-6"><div><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("quickDeploy.title"))}</h1> <p class="mt-1 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("quickDeploy.description"))}</p></div> <div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]"><h2 class="mb-4 text-base font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("quickDeploy.step1"))}</h2> <div class="flex gap-3"><div class="flex-1">`);
|
||||
FormField($$renderer3, {
|
||||
label: store_get($$store_subs ??= {}, "$t", t)("quickDeploy.imageUrl"),
|
||||
name: "imageUrl",
|
||||
placeholder: "registry.example.com/org/app:tag",
|
||||
required: true,
|
||||
error: errors.imageUrl ?? "",
|
||||
helpText: store_get($$store_subs ??= {}, "$t", t)("quickDeploy.imageUrlHelp"),
|
||||
disabled: inspecting,
|
||||
get value() {
|
||||
return imageUrl;
|
||||
},
|
||||
set value($$value) {
|
||||
imageUrl = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!----></div> <div class="flex items-start gap-2 pt-[26px]"><button type="button"${attr("title", store_get($$store_subs ??= {}, "$t", t)("quickDeploy.browseImages"))}${attr("aria-label", store_get($$store_subs ??= {}, "$t", t)("quickDeploy.browseImages"))} class="rounded-lg border border-[var(--border-primary)] p-2 text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)] transition-colors">`);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
IconSearch($$renderer3, { size: 16 });
|
||||
}
|
||||
$$renderer3.push(`<!--]--></button> <button${attr("disabled", !imageUrl.trim(), true)} class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-info)] px-4 py-2 text-sm font-medium text-white transition-all duration-150 hover:bg-[var(--color-info-dark)] disabled:cursor-not-allowed disabled:opacity-50 active:animate-press">`);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
IconSearch($$renderer3, { size: 16 });
|
||||
$$renderer3.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("quickDeploy.inspect"))}`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></button></div></div> `);
|
||||
EntityPicker($$renderer3, {
|
||||
items: imagePickerItems,
|
||||
current: imageUrl,
|
||||
title: store_get($$store_subs ??= {}, "$t", t)("quickDeploy.selectImage"),
|
||||
placeholder: store_get($$store_subs ??= {}, "$t", t)("entityPicker.search"),
|
||||
onselect: selectPickedImage,
|
||||
onclose: () => {
|
||||
showImagePicker = false;
|
||||
},
|
||||
get open() {
|
||||
return showImagePicker;
|
||||
},
|
||||
set open($$value) {
|
||||
showImagePicker = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!----></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,126 @@
|
||||
import { f as ensure_array_like, b as attr_class, g as stringify, e as escape_html, s as store_get, a as attr, u as unsubscribe_stores, i as derived } from "../../../chunks/index.js";
|
||||
import { o as onDestroy } from "../../../chunks/index-server.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
function EventLogFilter($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const {
|
||||
severities,
|
||||
sources,
|
||||
dateRange,
|
||||
searchText,
|
||||
stats
|
||||
} = $$props;
|
||||
const allSeverities = ["info", "warn", "error"];
|
||||
const allSources = ["deploy", "container", "proxy", "system"];
|
||||
const dateRangeOptions = [
|
||||
{ value: "1h", labelKey: "events.filter.lastHour" },
|
||||
{ value: "24h", labelKey: "events.filter.last24h" },
|
||||
{ value: "7d", labelKey: "events.filter.last7d" },
|
||||
{ value: "all", labelKey: "events.filter.allTime" }
|
||||
];
|
||||
const severityStyles = {
|
||||
info: {
|
||||
active: "bg-blue-100 text-blue-700 ring-1 ring-blue-300 dark:bg-blue-900/40 dark:text-blue-300 dark:ring-blue-700",
|
||||
inactive: "bg-[var(--surface-card-hover)] text-[var(--text-tertiary)] line-through decoration-1",
|
||||
dot: "bg-blue-500"
|
||||
},
|
||||
warn: {
|
||||
active: "bg-amber-100 text-amber-700 ring-1 ring-amber-300 dark:bg-amber-900/40 dark:text-amber-300 dark:ring-amber-700",
|
||||
inactive: "bg-[var(--surface-card-hover)] text-[var(--text-tertiary)] line-through decoration-1",
|
||||
dot: "bg-amber-500"
|
||||
},
|
||||
error: {
|
||||
active: "bg-red-100 text-red-700 ring-1 ring-red-300 dark:bg-red-900/40 dark:text-red-300 dark:ring-red-700",
|
||||
inactive: "bg-[var(--surface-card-hover)] text-[var(--text-tertiary)] line-through decoration-1",
|
||||
dot: "bg-red-500"
|
||||
}
|
||||
};
|
||||
const activeFilterCount = derived(() => (severities.length < allSeverities.length ? 1 : 0) + (sources.length < allSources.length ? 1 : 0) + 0 + (searchText.trim() !== "" ? 1 : 0));
|
||||
$$renderer2.push(`<div class="space-y-3"><div class="flex items-center gap-2 flex-wrap"><!--[-->`);
|
||||
const each_array = ensure_array_like(allSeverities);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let sev = each_array[$$index];
|
||||
const active = severities.includes(sev);
|
||||
const style = severityStyles[sev];
|
||||
$$renderer2.push(`<button type="button"${attr_class(`inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium transition-all duration-150 select-none cursor-pointer ${stringify(active ? style.active : style.inactive)}`)}><span${attr_class(`h-1.5 w-1.5 rounded-full ${stringify(active ? style.dot : "bg-[var(--text-tertiary)] opacity-40")}`)}></span> ${escape_html(store_get($$store_subs ??= {}, "$t", t)(`events.severity.${sev}`))} `);
|
||||
if (stats) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span${attr_class(`tabular-nums font-semibold ${stringify(active ? "" : "opacity-50")}`)}>${escape_html(stats[sev] ?? 0)}</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="h-4 w-px bg-[var(--border-primary)] mx-0.5 hidden sm:block"></div> <!--[-->`);
|
||||
const each_array_1 = ensure_array_like(allSources);
|
||||
for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
|
||||
let src = each_array_1[$$index_1];
|
||||
const active = sources.includes(src);
|
||||
$$renderer2.push(`<button type="button"${attr_class(`inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium transition-all duration-150 select-none cursor-pointer ${stringify(active ? "bg-[var(--surface-card)] text-[var(--text-primary)] ring-1 ring-[var(--border-primary)] shadow-[var(--shadow-sm)]" : "bg-[var(--surface-card-hover)] text-[var(--text-tertiary)] line-through decoration-1")}`)}>${escape_html(store_get($$store_subs ??= {}, "$t", t)(`events.source.${src}`))}</button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="flex-1"></div> `);
|
||||
if (activeFilterCount() > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<button type="button" class="inline-flex items-center gap-1 rounded-full px-2 py-1 text-xs font-medium text-[var(--text-tertiary)] hover:text-[var(--text-primary)] hover:bg-[var(--surface-card-hover)] transition-colors"><svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"></path><path d="m6 6 12 12"></path></svg> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("events.filter.clear"))}</button>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> <div class="flex items-center gap-2 flex-wrap"><div class="inline-flex items-center rounded-lg bg-[var(--surface-card-hover)] p-0.5"><!--[-->`);
|
||||
const each_array_2 = ensure_array_like(dateRangeOptions);
|
||||
for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
|
||||
let opt = each_array_2[$$index_2];
|
||||
$$renderer2.push(`<button type="button"${attr_class(`rounded-md px-2.5 py-1 text-xs font-medium transition-all duration-150 ${stringify(dateRange === opt.value ? "bg-[var(--surface-card)] text-[var(--text-primary)] shadow-[var(--shadow-sm)]" : "text-[var(--text-tertiary)] hover:text-[var(--text-secondary)]")}`)}>${escape_html(store_get($$store_subs ??= {}, "$t", t)(opt.labelKey))}</button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> <div class="relative flex-1 min-w-[180px] max-w-sm"><svg class="absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-[var(--text-tertiary)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg> <input type="text"${attr("placeholder", store_get($$store_subs ??= {}, "$t", t)("events.filter.search"))}${attr("value", searchText)} class="w-full rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] py-1.5 pl-8 pr-3 text-xs text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-400)] focus:outline-none focus:ring-1 focus:ring-[var(--color-brand-400)] transition-colors"/></div></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let stats = { info: 0, warn: 0, error: 0, total: 0 };
|
||||
let pendingNewEvents = [];
|
||||
let severities = ["info", "warn", "error"];
|
||||
let sources = ["deploy", "container", "proxy", "system"];
|
||||
let dateRange = "all";
|
||||
let searchText = "";
|
||||
let sseConnection = null;
|
||||
onDestroy(() => {
|
||||
sseConnection?.close();
|
||||
sseConnection = null;
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-4"><div class="flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("events.title"))}</h1> `);
|
||||
if (stats.total > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="text-xs text-[var(--text-tertiary)] tabular-nums">${escape_html(stats.total)} total</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> `);
|
||||
EventLogFilter($$renderer2, {
|
||||
severities,
|
||||
sources,
|
||||
dateRange,
|
||||
searchText,
|
||||
stats
|
||||
});
|
||||
$$renderer2.push(`<!----> `);
|
||||
if (pendingNewEvents.length > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<button type="button" class="w-full rounded-lg bg-[var(--color-brand-600)] px-4 py-2 text-sm font-medium text-white shadow-sm transition-all hover:bg-[var(--color-brand-700)] animate-fade-in">${escape_html(pendingNewEvents.length)} ${escape_html(store_get($$store_subs ??= {}, "$t", t)("events.newEvents"))}</button>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="flex items-center justify-center py-16"><svg class="h-5 w-5 animate-spin text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
const ssr = false;
|
||||
export {
|
||||
ssr
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import { e as escape_html, s as store_get, a as attr, u as unsubscribe_stores } from "../../../chunks/index.js";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "../../../chunks/exports.js";
|
||||
import "../../../chunks/utils.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "../../../chunks/root.js";
|
||||
import "../../../chunks/state.svelte.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
import "../../../chunks/theme.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let username = "";
|
||||
let password = "";
|
||||
let loading = false;
|
||||
$$renderer2.push(`<div class="flex min-h-screen items-center justify-center bg-[var(--surface-page)] px-4"><div class="w-full max-w-sm"><div class="rounded-2xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-8 shadow-[var(--shadow-lg)]"><div class="mb-6 text-center"><div class="mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--color-brand-600)] shadow-md"><svg class="h-6 w-6 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-2.25-1.313M21 7.5v2.25m0-2.25l-2.25 1.313M3 7.5l2.25-1.313M3 7.5l2.25 1.313M3 7.5v2.25m9 3l2.25-1.313M12 12.75l-2.25-1.313M12 12.75V15m0 6.75l2.25-1.313M12 21.75V19.5m0 2.25l-2.25-1.313m0-16.875L12 2.25l2.25 1.313M21 14.25v2.25l-2.25 1.313m-13.5 0L3 16.5v-2.25"></path></svg></div> <h1 class="mt-4 text-xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.title"))}</h1> <p class="mt-1 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.subtitle"))}</p></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <form class="space-y-4"><div class="flex flex-col gap-1.5"><label for="username" class="text-sm font-medium text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.username"))}</label> <input id="username" type="text"${attr("value", username)} required="" autocomplete="username" class="w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2.5 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"/></div> <div class="flex flex-col gap-1.5"><label for="password" class="text-sm font-medium text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.password"))}</label> <input id="password" type="password"${attr("value", password)} required="" autocomplete="current-password" class="w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2.5 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"/></div> <button type="submit"${attr("disabled", loading, true)} class="w-full inline-flex items-center justify-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)] focus:ring-offset-2 disabled:opacity-50 active:animate-press">`);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.signIn"))}`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></button></form> <div class="mt-5"><div class="relative"><div class="absolute inset-0 flex items-center"><div class="w-full border-t border-[var(--border-primary)]"></div></div> <div class="relative flex justify-center text-xs"><span class="bg-[var(--surface-card)] px-3 text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.or"))}</span></div></div> <button class="mt-4 w-full rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] px-4 py-2.5 text-sm font-medium text-[var(--text-secondary)] shadow-sm transition-all duration-150 hover:bg-[var(--surface-card-hover)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)] focus:ring-offset-2">${escape_html(store_get($$store_subs ??= {}, "$t", t)("login.ssoButton"))}</button></div></div></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import { h as head, e as escape_html, s as store_get, f as ensure_array_like, u as unsubscribe_stores } from "../../../../chunks/index.js";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "../../../../chunks/exports.js";
|
||||
import "../../../../chunks/utils.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "../../../../chunks/root.js";
|
||||
import "../../../../chunks/state.svelte.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
import { S as Skeleton } from "../../../../chunks/Skeleton.js";
|
||||
import "../../../../chunks/toast.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("ffmenf", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.project"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<div class="space-y-6"><div class="flex items-start justify-between"><div class="space-y-2">`);
|
||||
Skeleton($$renderer3, { width: "4rem", height: "0.875rem" });
|
||||
$$renderer3.push(`<!----> `);
|
||||
Skeleton($$renderer3, { width: "12rem", height: "1.75rem" });
|
||||
$$renderer3.push(`<!----> `);
|
||||
Skeleton($$renderer3, { width: "16rem", height: "0.875rem" });
|
||||
$$renderer3.push(`<!----></div></div> <div class="grid grid-cols-4 gap-4"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(4));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
Skeleton($$renderer3, { height: "3rem" });
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div></div>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]-->`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import { h as head, e as escape_html, s as store_get, a as attr, g as stringify, u as unsubscribe_stores, i as derived } from "../../../../../chunks/index.js";
|
||||
import { p as page } from "../../../../../chunks/stores.js";
|
||||
import "../../../../../chunks/toast.js";
|
||||
import { t } from "../../../../../chunks/index2.js";
|
||||
import { I as IconChevronRight } from "../../../../../chunks/IconChevronRight.js";
|
||||
import { S as Skeleton } from "../../../../../chunks/Skeleton.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const projectId = derived(() => store_get($$store_subs ??= {}, "$page", page).params.id);
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("1fdiw6z", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("envEditor.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="space-y-6"><div><div class="flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]"><a${attr("href", `/projects/${stringify(projectId())}`)} class="hover:text-[var(--text-link)] transition-colors">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.project"))}</a> `);
|
||||
IconChevronRight($$renderer3, { size: 14 });
|
||||
$$renderer3.push(`<!----></div> <h1 class="mt-1 text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("envEditor.title"))}</h1> <p class="mt-1 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("envEditor.description"))}</p></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<div class="space-y-4">`);
|
||||
Skeleton($$renderer3, { width: "16rem", height: "2.5rem" });
|
||||
$$renderer3.push(`<!----> `);
|
||||
Skeleton($$renderer3, { height: "12rem" });
|
||||
$$renderer3.push(`<!----></div>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
import { h as head, a as attr, g as stringify, e as escape_html, s as store_get, f as ensure_array_like, b as attr_class, u as unsubscribe_stores, i as derived } from "../../../../../chunks/index.js";
|
||||
import { p as page } from "../../../../../chunks/stores.js";
|
||||
import "../../../../../chunks/toast.js";
|
||||
import { t } from "../../../../../chunks/index2.js";
|
||||
import { I as IconChevronRight } from "../../../../../chunks/IconChevronRight.js";
|
||||
import { S as Skeleton } from "../../../../../chunks/Skeleton.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let scopeInfos = [];
|
||||
const projectId = derived(() => store_get($$store_subs ??= {}, "$page", page).params.id ?? "");
|
||||
const scopeColors = {
|
||||
instance: {
|
||||
bg: "bg-amber-50 dark:bg-amber-900/30",
|
||||
text: "text-amber-700 dark:text-amber-400"
|
||||
},
|
||||
stage: {
|
||||
bg: "bg-blue-50 dark:bg-blue-900/30",
|
||||
text: "text-blue-700 dark:text-blue-400"
|
||||
},
|
||||
project: {
|
||||
bg: "bg-emerald-50 dark:bg-emerald-900/30",
|
||||
text: "text-emerald-700 dark:text-emerald-400"
|
||||
},
|
||||
project_named: {
|
||||
bg: "bg-violet-50 dark:bg-violet-900/30",
|
||||
text: "text-violet-700 dark:text-violet-400"
|
||||
},
|
||||
named: {
|
||||
bg: "bg-purple-50 dark:bg-purple-900/30",
|
||||
text: "text-purple-700 dark:text-purple-400"
|
||||
},
|
||||
ephemeral: {
|
||||
bg: "bg-gray-100 dark:bg-gray-800",
|
||||
text: "text-gray-600 dark:text-gray-400"
|
||||
}
|
||||
};
|
||||
function scopeColor(scope) {
|
||||
return scopeColors[scope] ?? scopeColors.project;
|
||||
}
|
||||
head("15zmna7", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeEditor.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-6"><div><div class="flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]"><a${attr("href", `/projects/${stringify(projectId())}`)} class="hover:text-[var(--text-link)] transition-colors">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.project"))}</a> `);
|
||||
IconChevronRight($$renderer2, { size: 14 });
|
||||
$$renderer2.push(`<!----></div> <h1 class="mt-1 text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeEditor.title"))}</h1> <p class="mt-1 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeEditor.description"))}</p></div> `);
|
||||
if (scopeInfos.length > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(scopeInfos);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let info = each_array[$$index];
|
||||
const colors = scopeColor(info.scope);
|
||||
$$renderer2.push(`<div${attr_class(`rounded-lg border border-[var(--border-primary)] p-3 ${stringify(colors.bg)}`)}><div class="flex items-center gap-2"><span${attr_class(`rounded-full px-2 py-0.5 text-xs font-semibold ${stringify(colors.text)} ${stringify(colors.bg)}`)}>${escape_html(info.scope)}</span> `);
|
||||
if (info.needs_name) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="text-[10px] text-[var(--text-tertiary)]">(${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeEditor.requiresName"))})</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> <p class="mt-1.5 text-xs text-[var(--text-secondary)]">${escape_html(info.description)}</p> <code class="mt-1 block text-[10px] text-[var(--text-tertiary)]">${escape_html(info.path_example)}</code></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
Skeleton($$renderer2, { height: "12rem" });
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import { h as head, a as attr, g as stringify, e as escape_html, s as store_get, b as attr_class, f as ensure_array_like, u as unsubscribe_stores, i as derived } from "../../../../../../../chunks/index.js";
|
||||
import { p as page } from "../../../../../../../chunks/stores.js";
|
||||
import "../../../../../../../chunks/toast.js";
|
||||
import { t } from "../../../../../../../chunks/index2.js";
|
||||
import { I as IconChevronRight } from "../../../../../../../chunks/IconChevronRight.js";
|
||||
import { S as Skeleton } from "../../../../../../../chunks/Skeleton.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const projectId = derived(() => store_get($$store_subs ??= {}, "$page", page).params.id ?? "");
|
||||
const breadcrumbs = derived(() => () => {
|
||||
return [];
|
||||
});
|
||||
head("8w09c1", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeBrowser.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-4"><div><div class="flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]"><a${attr("href", `/projects/${stringify(projectId())}`)} class="hover:text-[var(--text-link)] transition-colors">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.project"))}</a> `);
|
||||
IconChevronRight($$renderer2, { size: 14 });
|
||||
$$renderer2.push(`<!----> <a${attr("href", `/projects/${stringify(projectId())}/volumes`)} class="hover:text-[var(--text-link)] transition-colors">${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeEditor.title"))}</a> `);
|
||||
IconChevronRight($$renderer2, { size: 14 });
|
||||
$$renderer2.push(`<!----></div> <div class="mt-1 flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeBrowser.title"))}</h1> <div class="flex items-center gap-2"><button type="button" class="inline-flex items-center gap-1.5 rounded-lg border border-[var(--border-primary)] px-3 py-2 text-xs font-medium text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] transition-colors">📦 ${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeBrowser.downloadAll"))}</button> <label${attr_class(`inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-[var(--color-brand-600)] px-3 py-2 text-xs font-medium text-white hover:bg-[var(--color-brand-700)] transition-colors ${stringify("")}`)}>`);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("volumeBrowser.upload"))} <input type="file" multiple="" class="hidden"/></label></div></div></div> <nav class="flex items-center gap-1 text-sm"><button type="button"${attr_class(`rounded px-1.5 py-0.5 text-[var(--text-link)] hover:bg-[var(--surface-card-hover)] transition-colors ${stringify("font-semibold")}`)}>/</button> <!--[-->`);
|
||||
const each_array = ensure_array_like(breadcrumbs()());
|
||||
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
||||
let segment = each_array[i];
|
||||
IconChevronRight($$renderer2, { size: 12, class: "text-[var(--text-tertiary)]" });
|
||||
$$renderer2.push(`<!----> <button type="button"${attr_class(`rounded px-1.5 py-0.5 text-[var(--text-link)] hover:bg-[var(--surface-card-hover)] transition-colors ${stringify(i === breadcrumbs()().length - 1 ? "font-semibold text-[var(--text-primary)]" : "")}`)}>${escape_html(segment)}</button>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></nav> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
Skeleton($$renderer2, { height: "16rem" });
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
const ssr = false;
|
||||
export {
|
||||
ssr
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { f as ensure_array_like, h as head, e as escape_html, s as store_get, b as attr_class, u as unsubscribe_stores, g as stringify } from "../../../chunks/index.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
import { I as IconPlus } from "../../../chunks/IconPlus.js";
|
||||
import { S as Skeleton } from "../../../chunks/Skeleton.js";
|
||||
/* empty css */
|
||||
function SkeletonTable($$renderer, $$props) {
|
||||
const { rows = 5, cols = 4 } = $$props;
|
||||
$$renderer.push(`<div class="overflow-hidden rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] shadow-[var(--shadow-sm)]"><div class="border-b border-[var(--border-primary)] bg-[var(--surface-card-hover)] px-6 py-3"><div class="flex gap-6"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(cols));
|
||||
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
||||
each_array[i];
|
||||
Skeleton($$renderer, { width: i === 0 ? "6rem" : "5rem", height: "0.75rem" });
|
||||
}
|
||||
$$renderer.push(`<!--]--></div></div> <!--[-->`);
|
||||
const each_array_1 = ensure_array_like(Array(rows));
|
||||
for (let i = 0, $$length = each_array_1.length; i < $$length; i++) {
|
||||
each_array_1[i];
|
||||
$$renderer.push(`<div class="flex gap-6 border-b border-[var(--border-secondary)] px-6 py-4 last:border-b-0"><!--[-->`);
|
||||
const each_array_2 = ensure_array_like(Array(cols));
|
||||
for (let j = 0, $$length2 = each_array_2.length; j < $$length2; j++) {
|
||||
each_array_2[j];
|
||||
Skeleton($$renderer, { width: j === 0 ? "40%" : "20%", height: "0.875rem" });
|
||||
}
|
||||
$$renderer.push(`<!--]--></div>`);
|
||||
}
|
||||
$$renderer.push(`<!--]--></div>`);
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("rqn88j", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("projects.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="space-y-6"><div class="flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("projects.title"))}</h1> <button type="button"${attr_class(`inline-flex items-center gap-2 rounded-lg ${stringify("bg-[var(--color-brand-600)] text-white shadow-sm hover:bg-[var(--color-brand-700)]")} px-4 py-2.5 text-sm font-medium transition-all duration-150 active:animate-press`)}>`);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
IconPlus($$renderer3, { size: 16 });
|
||||
}
|
||||
$$renderer3.push(`<!--]--> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("projects.addProject"))}</button></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
SkeletonTable($$renderer3, { rows: 4, cols: 5 });
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { h as head, e as escape_html, s as store_get, u as unsubscribe_stores } from "../../../../../chunks/index.js";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "../../../../../chunks/exports.js";
|
||||
import "../../../../../chunks/utils.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "../../../../../chunks/root.js";
|
||||
import "../../../../../chunks/state.svelte.js";
|
||||
import { t } from "../../../../../chunks/index2.js";
|
||||
import { I as IconGlobe } from "../../../../../chunks/IconGlobe.js";
|
||||
import { I as IconLoader } from "../../../../../chunks/IconLoader.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
head("57j31g", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.editTitle"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="mb-6"><a href="/proxies" class="inline-flex items-center gap-1 text-sm text-[var(--text-secondary)] hover:text-[var(--color-brand-600)] transition-colors"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"></path><path d="m12 19-7-7 7-7"></path></svg> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.back"))}</a></div> <div class="mb-6 flex items-center gap-3"><div class="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]">`);
|
||||
IconGlobe($$renderer2, { size: 22 });
|
||||
$$renderer2.push(`<!----></div> <h1 class="text-xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.editTitle"))}</h1></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="flex items-center justify-center py-20">`);
|
||||
IconLoader($$renderer2, { size: 24, class: "text-[var(--color-brand-500)]" });
|
||||
$$renderer2.push(`<!----> <span class="ml-2 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.loading"))}</span></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { h as head, e as escape_html, s as store_get, u as unsubscribe_stores } from "../../../chunks/index.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
import { I as IconGlobe } from "../../../chunks/IconGlobe.js";
|
||||
import { I as IconLoader } from "../../../chunks/IconLoader.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
head("88k8ar", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"><div class="flex items-center gap-3"><div class="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]">`);
|
||||
IconGlobe($$renderer2, { size: 22 });
|
||||
$$renderer2.push(`<!----></div> <div><h1 class="text-xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.title"))}</h1> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div></div> <a href="/proxies/create" class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] active:animate-press"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.create"))}</a></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="flex items-center justify-center py-20">`);
|
||||
IconLoader($$renderer2, {
|
||||
size: 24,
|
||||
class: "animate-spin text-[var(--color-brand-500)]"
|
||||
});
|
||||
$$renderer2.push(`<!----> <span class="ml-2 text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.loading"))}</span></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
import { e as escape_html, s as store_get, u as unsubscribe_stores, f as ensure_array_like, a as attr, i as derived, h as head } from "../../../../chunks/index.js";
|
||||
import "@sveltejs/kit/internal";
|
||||
import "../../../../chunks/exports.js";
|
||||
import "../../../../chunks/utils.js";
|
||||
import "@sveltejs/kit/internal/server";
|
||||
import "../../../../chunks/root.js";
|
||||
import "../../../../chunks/state.svelte.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
import { v as validateProxy } from "../../../../chunks/api.js";
|
||||
import { F as FormField } from "../../../../chunks/FormField.js";
|
||||
import { I as IconCheck } from "../../../../chunks/IconCheck.js";
|
||||
import { I as IconX } from "../../../../chunks/IconX.js";
|
||||
import { I as IconLoader } from "../../../../chunks/IconLoader.js";
|
||||
import { I as IconGlobe } from "../../../../chunks/IconGlobe.js";
|
||||
function ValidationChecklist($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const { result, loading = false } = $$props;
|
||||
const stepLabelKeys = {
|
||||
syntax: "proxies.validation.syntax",
|
||||
dns: "proxies.validation.dns",
|
||||
tcp: "proxies.validation.tcp",
|
||||
http: "proxies.validation.http"
|
||||
};
|
||||
function getStepLabel(name) {
|
||||
const key = stepLabelKeys[name];
|
||||
return key ? store_get($$store_subs ??= {}, "$t", t)(key) : name;
|
||||
}
|
||||
if (loading || result) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] p-4"><h4 class="text-sm font-medium text-[var(--text-primary)] mb-3">${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.validation.title"))}</h4> `);
|
||||
if (loading && !result) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="flex items-center gap-2 text-sm text-[var(--text-secondary)]">`);
|
||||
IconLoader($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----> <span>${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.validation.checking"))}</span></div>`);
|
||||
} else if (result) {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
$$renderer2.push(`<ul class="space-y-2"><!--[-->`);
|
||||
const each_array = ensure_array_like(result.steps);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let step = each_array[$$index];
|
||||
$$renderer2.push(`<li><div class="flex items-center gap-2">`);
|
||||
if (step.passed) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-950">`);
|
||||
IconCheck($$renderer2, { size: 14, class: "text-emerald-600 dark:text-emerald-400" });
|
||||
$$renderer2.push(`<!----></span> <span class="text-sm text-[var(--text-primary)]">${escape_html(getStepLabel(step.name))}</span> `);
|
||||
if (step.message) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="text-xs text-[var(--text-tertiary)]">— ${escape_html(step.message)}</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`<span class="flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-red-100 dark:bg-red-950">`);
|
||||
IconX($$renderer2, { size: 14, class: "text-red-600 dark:text-red-400" });
|
||||
$$renderer2.push(`<!----></span> <span class="text-sm text-[var(--text-primary)]">${escape_html(getStepLabel(step.name))}</span> `);
|
||||
if (step.message) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<span class="text-xs text-[var(--text-tertiary)]">— ${escape_html(step.message)}</span>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div> `);
|
||||
if (!step.passed && step.hint) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<p class="ml-7 mt-1 text-xs text-amber-600 dark:text-amber-400">${escape_html(step.hint)}</p>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></li>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></ul>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function ProxyForm($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
const { proxy } = $$props;
|
||||
let destinationUrl = proxy?.destination_url ?? "";
|
||||
let port = proxy?.destination_port?.toString() ?? "";
|
||||
let domain = proxy?.domain ?? "";
|
||||
let validationResult = null;
|
||||
let validating = false;
|
||||
let validationTimer = null;
|
||||
const portNum = derived(() => parseInt(port, 10));
|
||||
const portValid = derived(() => !isNaN(portNum()) && portNum() >= 1 && portNum() <= 65535);
|
||||
const canSubmit = derived(() => destinationUrl.trim().length > 0 && port.trim().length > 0 && portValid() && domain.trim().length > 0 && true);
|
||||
const title = derived(
|
||||
() => store_get($$store_subs ??= {}, "$t", t)("proxies.form.title")
|
||||
);
|
||||
const submitLabel = derived(
|
||||
() => store_get($$store_subs ??= {}, "$t", t)("proxies.form.create")
|
||||
);
|
||||
function suggestDomain(dest) {
|
||||
if (!dest) return "";
|
||||
try {
|
||||
const withScheme = dest.includes("://") ? dest : `http://${dest}`;
|
||||
const url = new URL(withScheme);
|
||||
const host = url.hostname;
|
||||
const cleaned = host.replace(/^(www|api|app)\./, "").replace(/\.\w+$/, "").replace(/[^a-z0-9.-]/gi, "-").toLowerCase();
|
||||
return cleaned || "";
|
||||
} catch {
|
||||
return dest.replace(/[^a-z0-9.-]/gi, "-").toLowerCase();
|
||||
}
|
||||
}
|
||||
function scheduleValidation() {
|
||||
if (validationTimer !== null) {
|
||||
clearTimeout(validationTimer);
|
||||
}
|
||||
validationResult = null;
|
||||
if (!destinationUrl.trim() || !port.trim() || !portValid()) {
|
||||
return;
|
||||
}
|
||||
validationTimer = setTimeout(
|
||||
() => {
|
||||
runValidation();
|
||||
},
|
||||
300
|
||||
);
|
||||
}
|
||||
async function runValidation() {
|
||||
if (!destinationUrl.trim() || !portValid()) return;
|
||||
validating = true;
|
||||
try {
|
||||
validationResult = await validateProxy(destinationUrl.trim(), portNum());
|
||||
} catch {
|
||||
validationResult = null;
|
||||
} finally {
|
||||
validating = false;
|
||||
}
|
||||
}
|
||||
function handleDestinationInput() {
|
||||
{
|
||||
const suggested = suggestDomain(destinationUrl);
|
||||
if (!domain || domain === suggestDomain(destinationUrl.slice(0, -1))) {
|
||||
domain = suggested;
|
||||
}
|
||||
}
|
||||
scheduleValidation();
|
||||
}
|
||||
function handlePortInput() {
|
||||
scheduleValidation();
|
||||
}
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
$$renderer3.push(`<div class="space-y-6"><h3 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(title())}</h3> <form class="space-y-4">`);
|
||||
FormField($$renderer3, {
|
||||
label: store_get($$store_subs ??= {}, "$t", t)("proxies.form.destination"),
|
||||
name: "destination_url",
|
||||
placeholder: "192.168.1.100 or http://my-service",
|
||||
required: true,
|
||||
oninput: handleDestinationInput,
|
||||
get value() {
|
||||
return destinationUrl;
|
||||
},
|
||||
set value($$value) {
|
||||
destinationUrl = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!----> `);
|
||||
FormField($$renderer3, {
|
||||
label: store_get($$store_subs ??= {}, "$t", t)("proxies.form.port"),
|
||||
name: "destination_port",
|
||||
type: "number",
|
||||
placeholder: "8080",
|
||||
required: true,
|
||||
error: port && !portValid() ? store_get($$store_subs ??= {}, "$t", t)("validation.invalidPort") : "",
|
||||
oninput: handlePortInput,
|
||||
get value() {
|
||||
return port;
|
||||
},
|
||||
set value($$value) {
|
||||
port = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!----> `);
|
||||
FormField($$renderer3, {
|
||||
label: store_get($$store_subs ??= {}, "$t", t)("proxies.form.domain"),
|
||||
name: "domain",
|
||||
placeholder: "my-service.example.com",
|
||||
required: true,
|
||||
helpText: store_get($$store_subs ??= {}, "$t", t)("proxies.form.domainHelp"),
|
||||
get value() {
|
||||
return domain;
|
||||
},
|
||||
set value($$value) {
|
||||
domain = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!----> <div class="space-y-2">`);
|
||||
ValidationChecklist($$renderer3, { result: validationResult, loading: validating });
|
||||
$$renderer3.push(`<!----> <button type="button" class="inline-flex items-center gap-1.5 rounded-lg border border-[var(--border-primary)] px-3 py-1.5 text-sm font-medium text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"${attr("disabled", !destinationUrl.trim() || !portValid() || validating, true)}>`);
|
||||
if (validating) {
|
||||
$$renderer3.push("<!--[0-->");
|
||||
IconLoader($$renderer3, { size: 14 });
|
||||
$$renderer3.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.validating"))}`);
|
||||
} else {
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
$$renderer3.push(`${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.validate"))}`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></button></div> `);
|
||||
if (validationResult && !validationResult.valid) {
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<p class="text-xs text-amber-600 dark:text-amber-400">Validation reported issues but you can still create the proxy.</p>`);
|
||||
} else {
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--> <div class="flex items-center justify-between pt-2"><div>`);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div> <div class="flex items-center gap-3"><button type="button" class="rounded-lg px-4 py-2 text-sm font-medium text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] transition-colors">${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.cancel"))}</button> <button type="submit" class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-[var(--color-brand-700)] transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-brand-600)] disabled:opacity-50 disabled:cursor-not-allowed"${attr("disabled", !canSubmit(), true)}>`);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--> ${escape_html(submitLabel())}</button></div></div></form></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]-->`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
head("1eyu80y", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="mb-6"><a href="/proxies" class="inline-flex items-center gap-1 text-sm text-[var(--text-secondary)] hover:text-[var(--color-brand-600)] transition-colors"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"></path><path d="m12 19-7-7 7-7"></path></svg> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("common.back"))}</a></div> <div class="mb-6 flex items-center gap-3"><div class="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]">`);
|
||||
IconGlobe($$renderer2, { size: 22 });
|
||||
$$renderer2.push(`<!----></div> <h1 class="text-xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("proxies.form.title"))}</h1></div> <div class="mx-auto max-w-2xl rounded-2xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]">`);
|
||||
ProxyForm($$renderer2, {});
|
||||
$$renderer2.push(`<!----></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
import { a as attr, b as attr_class, c as clsx, e as escape_html, s as store_get, f as ensure_array_like, g as stringify, u as unsubscribe_stores, i as derived } from "../../../chunks/index.js";
|
||||
import { p as page } from "../../../chunks/stores.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
import { I as IconSettings } from "../../../chunks/IconSettings.js";
|
||||
function IconKey($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="7.5" cy="15.5" r="5.5"></circle><path d="m21 2-9.3 9.3"></path><path d="M18.5 5.5 21 3"></path><path d="m15 8 2.5 2.5"></path></svg>`);
|
||||
}
|
||||
function IconShield($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path></svg>`);
|
||||
}
|
||||
function IconDatabase($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5v14a9 3 0 0 0 18 0V5"></path><path d="M3 12a9 3 0 0 0 18 0"></path></svg>`);
|
||||
}
|
||||
function _layout($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let { children } = $$props;
|
||||
const navItems = [
|
||||
{
|
||||
href: "/settings",
|
||||
labelKey: "settings.general",
|
||||
icon: "general"
|
||||
},
|
||||
{
|
||||
href: "/settings/registries",
|
||||
labelKey: "settings.registries",
|
||||
icon: "registries"
|
||||
},
|
||||
{
|
||||
href: "/settings/credentials",
|
||||
labelKey: "settings.credentials",
|
||||
icon: "credentials"
|
||||
},
|
||||
{
|
||||
href: "/settings/auth",
|
||||
labelKey: "settings.authentication",
|
||||
icon: "auth"
|
||||
}
|
||||
];
|
||||
let currentPath = derived(() => store_get($$store_subs ??= {}, "$page", page).url.pathname);
|
||||
function isActive(href) {
|
||||
if (href === "/settings") return currentPath() === "/settings";
|
||||
return currentPath().startsWith(href);
|
||||
}
|
||||
$$renderer2.push(`<div class="mx-auto max-w-4xl"><h1 class="mb-6 text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settings.title"))}</h1> <div class="flex flex-col gap-6 sm:flex-row"><nav class="w-full flex-shrink-0 sm:w-48"><ul class="flex gap-1 overflow-x-auto sm:flex-col sm:space-y-0.5"><!--[-->`);
|
||||
const each_array = ensure_array_like(navItems);
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
let item = each_array[$$index];
|
||||
$$renderer2.push(`<li><a${attr("href", item.href)}${attr_class(`flex items-center gap-2.5 whitespace-nowrap rounded-lg px-3 py-2 text-sm font-medium transition-all duration-150 ${stringify(isActive(item.href) ? "bg-[var(--color-brand-50)] text-[var(--color-brand-700)] shadow-sm" : "text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)]")}`)}>`);
|
||||
if (item.icon === "general") {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
IconSettings($$renderer2, {
|
||||
size: 16,
|
||||
class: isActive(item.href) ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)]"
|
||||
});
|
||||
} else if (item.icon === "registries") {
|
||||
$$renderer2.push("<!--[1-->");
|
||||
IconDatabase($$renderer2, {
|
||||
size: 16,
|
||||
class: isActive(item.href) ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)]"
|
||||
});
|
||||
} else if (item.icon === "credentials") {
|
||||
$$renderer2.push("<!--[2-->");
|
||||
IconKey($$renderer2, {
|
||||
size: 16,
|
||||
class: isActive(item.href) ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)]"
|
||||
});
|
||||
} else if (item.icon === "auth") {
|
||||
$$renderer2.push("<!--[3-->");
|
||||
IconShield($$renderer2, {
|
||||
size: 16,
|
||||
class: isActive(item.href) ? "text-[var(--color-brand-600)]" : "text-[var(--text-tertiary)]"
|
||||
});
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> ${escape_html(store_get($$store_subs ??= {}, "$t", t)(item.labelKey))}</a></li>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></ul></nav> <div class="flex-1 min-w-0">`);
|
||||
children($$renderer2);
|
||||
$$renderer2.push(`<!----></div></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_layout as default
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import { h as head, e as escape_html, s as store_get, f as ensure_array_like, u as unsubscribe_stores } from "../../../chunks/index.js";
|
||||
import { E as EntityPicker } from "../../../chunks/EntityPicker.js";
|
||||
import "../../../chunks/toast.js";
|
||||
import { t } from "../../../chunks/index2.js";
|
||||
import { S as Skeleton } from "../../../chunks/Skeleton.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let sslCertificateId = 0;
|
||||
let certPickerOpen = false;
|
||||
let certPickerItems = [];
|
||||
function handleCertSelect(value) {
|
||||
const id = parseInt(value, 10);
|
||||
sslCertificateId = id;
|
||||
const item = certPickerItems.find((i) => i.value === value);
|
||||
item?.label ?? "";
|
||||
certPickerOpen = false;
|
||||
}
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("1i19ct2", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsGeneral.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="space-y-6">`);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<div class="space-y-4">`);
|
||||
Skeleton($$renderer3, { height: "2rem", width: "12rem" });
|
||||
$$renderer3.push(`<!----> <div class="grid grid-cols-2 gap-4"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(6));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
Skeleton($$renderer3, { height: "4rem" });
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div></div>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div> `);
|
||||
EntityPicker($$renderer3, {
|
||||
items: certPickerItems,
|
||||
current: String(sslCertificateId),
|
||||
title: store_get($$store_subs ??= {}, "$t", t)("settingsGeneral.selectCertificate"),
|
||||
onselect: handleCertSelect,
|
||||
onclose: () => {
|
||||
certPickerOpen = false;
|
||||
},
|
||||
get open() {
|
||||
return certPickerOpen;
|
||||
},
|
||||
set open($$value) {
|
||||
certPickerOpen = $$value;
|
||||
$$settled = false;
|
||||
}
|
||||
});
|
||||
$$renderer3.push(`<!---->`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
import { e as escape_html, a as attr, s as store_get, f as ensure_array_like, b as attr_class, g as stringify, u as unsubscribe_stores } from "../../../../chunks/index.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
import { I as IconTrash } from "../../../../chunks/IconTrash.js";
|
||||
import { I as IconPlus } from "../../../../chunks/IconPlus.js";
|
||||
function EmptyState($$renderer, $$props) {
|
||||
const {
|
||||
title,
|
||||
description = "",
|
||||
actionLabel = "",
|
||||
actionHref = "",
|
||||
onaction,
|
||||
icon = "projects"
|
||||
} = $$props;
|
||||
$$renderer.push(`<div class="flex flex-col items-center justify-center rounded-xl border-2 border-dashed border-[var(--border-primary)] px-6 py-16 text-center animate-fade-in"><div class="mb-4 flex h-16 w-16 items-center justify-center rounded-2xl bg-[var(--color-brand-50)]">`);
|
||||
if (icon === "projects") {
|
||||
$$renderer.push("<!--[0-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path><path d="M12 10v6"></path><path d="M9 13h6"></path></svg>`);
|
||||
} else if (icon === "instances") {
|
||||
$$renderer.push("<!--[1-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg>`);
|
||||
} else if (icon === "deploys") {
|
||||
$$renderer.push("<!--[2-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z"></path></svg>`);
|
||||
} else if (icon === "registries") {
|
||||
$$renderer.push("<!--[3-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5v14a9 3 0 0 0 18 0V5"></path><path d="M3 12a9 3 0 0 0 18 0"></path></svg>`);
|
||||
} else if (icon === "volumes") {
|
||||
$$renderer.push("<!--[4-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="22" x2="2" y1="12" y2="12"></line><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg>`);
|
||||
} else if (icon === "users") {
|
||||
$$renderer.push("<!--[5-->");
|
||||
$$renderer.push(`<svg class="h-8 w-8 text-[var(--color-brand-500)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>`);
|
||||
} else {
|
||||
$$renderer.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer.push(`<!--]--></div> <h3 class="text-base font-semibold text-[var(--text-primary)]">${escape_html(title)}</h3> `);
|
||||
if (description) {
|
||||
$$renderer.push("<!--[0-->");
|
||||
$$renderer.push(`<p class="mt-1 max-w-sm text-sm text-[var(--text-secondary)]">${escape_html(description)}</p>`);
|
||||
} else {
|
||||
$$renderer.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer.push(`<!--]--> `);
|
||||
if (actionLabel) {
|
||||
$$renderer.push("<!--[0-->");
|
||||
if (actionHref) {
|
||||
$$renderer.push("<!--[0-->");
|
||||
$$renderer.push(`<a${attr("href", actionHref)} class="mt-4 inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] active:animate-press"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg> ${escape_html(actionLabel)}</a>`);
|
||||
} else if (onaction) {
|
||||
$$renderer.push("<!--[1-->");
|
||||
$$renderer.push(`<button type="button" class="mt-4 inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] active:animate-press"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg> ${escape_html(actionLabel)}</button>`);
|
||||
} else {
|
||||
$$renderer.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer.push(`<!--]-->`);
|
||||
} else {
|
||||
$$renderer.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer.push(`<!--]--></div>`);
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let settings = {
|
||||
auth_mode: "local"
|
||||
};
|
||||
let users = [];
|
||||
let saving = false;
|
||||
let newUsername = "";
|
||||
let newPassword = "";
|
||||
let newEmail = "";
|
||||
let newRole = "viewer";
|
||||
$$renderer2.push(`<div class="space-y-6"><div><h2 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.title"))}</h2> <p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.description"))}</p></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]"><h3 class="text-base font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.authMode"))}</h3> <div class="mt-4 flex gap-4"><label class="flex items-center gap-2 cursor-pointer"><input type="radio"${attr("checked", settings.auth_mode === "local", true)} value="local" class="h-4 w-4 text-[var(--color-brand-600)] focus:ring-[var(--color-brand-500)]"/> <span class="text-sm font-medium text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.local"))}</span></label> <label class="flex items-center gap-2 cursor-pointer"><input type="radio"${attr("checked", settings.auth_mode === "oidc", true)} value="oidc" class="h-4 w-4 text-[var(--color-brand-600)] focus:ring-[var(--color-brand-500)]"/> <span class="text-sm font-medium text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.oidc"))}</span></label></div></div> `);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <button${attr("disabled", saving, true)} class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm hover:bg-[var(--color-brand-700)] disabled:opacity-50 transition-colors active:animate-press">`);
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]--> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.saveSettings"))}</button> <div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]"><h3 class="text-base font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.localUsers"))}</h3> `);
|
||||
if (users.length > 0) {
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="mt-4 overflow-hidden rounded-xl border border-[var(--border-primary)]"><table class="min-w-full divide-y divide-[var(--border-primary)]"><thead class="bg-[var(--surface-card-hover)]"><tr><th class="px-4 py-2.5 text-left text-xs font-medium uppercase text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.username"))}</th><th class="px-4 py-2.5 text-left text-xs font-medium uppercase text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.email"))}</th><th class="px-4 py-2.5 text-left text-xs font-medium uppercase text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.role"))}</th><th class="px-4 py-2.5 text-left text-xs font-medium uppercase text-[var(--text-tertiary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.created"))}</th><th class="px-4 py-2.5"></th></tr></thead><tbody class="divide-y divide-[var(--border-secondary)]"><!--[-->`);
|
||||
const each_array_1 = ensure_array_like(users);
|
||||
for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
|
||||
let user = each_array_1[$$index_1];
|
||||
$$renderer2.push(`<tr class="hover:bg-[var(--surface-card-hover)] transition-colors"><td class="px-4 py-2.5 text-sm text-[var(--text-primary)]">${escape_html(user.username)}</td><td class="px-4 py-2.5 text-sm text-[var(--text-secondary)]">${escape_html(user.email || "-")}</td><td class="px-4 py-2.5"><span${attr_class(`inline-flex rounded-full px-2 py-0.5 text-xs font-semibold ${stringify(user.role === "admin" ? "bg-purple-50 text-purple-700" : "bg-gray-100 text-gray-700")}`)}>${escape_html(user.role)}</span></td><td class="px-4 py-2.5 text-sm text-[var(--text-secondary)]">${escape_html(user.created_at)}</td><td class="px-4 py-2.5 text-right"><button class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-red-50 hover:text-red-600 transition-colors">`);
|
||||
IconTrash($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----></button></td></tr>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></tbody></table></div>`);
|
||||
} else {
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
$$renderer2.push(`<div class="mt-4">`);
|
||||
EmptyState($$renderer2, {
|
||||
title: store_get($$store_subs ??= {}, "$t", t)("empty.noUsers"),
|
||||
description: store_get($$store_subs ??= {}, "$t", t)("empty.noUsersDesc"),
|
||||
icon: "users"
|
||||
});
|
||||
$$renderer2.push(`<!----></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--> <div class="mt-6 border-t border-[var(--border-primary)] pt-4"><h4 class="text-sm font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.addUser"))}</h4> <div class="mt-3 grid grid-cols-2 gap-3"><input type="text"${attr("value", newUsername)}${attr("placeholder", store_get($$store_subs ??= {}, "$t", t)("settingsAuth.username"))} class="rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"/> <input type="password"${attr("value", newPassword)}${attr("placeholder", store_get($$store_subs ??= {}, "$t", t)("settingsAuth.password"))} class="rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"/> <input type="email"${attr("value", newEmail)}${attr("placeholder", `${stringify(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.email"))} (optional)`)} class="rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"/> `);
|
||||
$$renderer2.select(
|
||||
{
|
||||
value: newRole,
|
||||
class: "rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-3 py-2 text-sm text-[var(--text-primary)] focus:border-[var(--color-brand-500)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-500)]"
|
||||
},
|
||||
($$renderer3) => {
|
||||
$$renderer3.option({ value: "viewer" }, ($$renderer4) => {
|
||||
$$renderer4.push(`${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.viewer"))}`);
|
||||
});
|
||||
$$renderer3.option({ value: "admin" }, ($$renderer4) => {
|
||||
$$renderer4.push(`${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.admin"))}`);
|
||||
});
|
||||
}
|
||||
);
|
||||
$$renderer2.push(`</div> <button class="mt-3 inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm hover:bg-[var(--color-brand-700)] transition-colors active:animate-press">`);
|
||||
IconPlus($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsAuth.addUser"))}</button></div></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
import { h as head, e as escape_html, s as store_get, u as unsubscribe_stores } from "../../../../chunks/index.js";
|
||||
import { S as Skeleton } from "../../../../chunks/Skeleton.js";
|
||||
import "../../../../chunks/toast.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("5z23cl", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsCredentials.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="space-y-6"><div><h2 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsCredentials.title"))}</h2> <p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsCredentials.description"))}</p></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<div class="space-y-4">`);
|
||||
Skeleton($$renderer3, { height: "12rem" });
|
||||
$$renderer3.push(`<!----></div>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
import { h as head, e as escape_html, s as store_get, f as ensure_array_like, u as unsubscribe_stores } from "../../../../chunks/index.js";
|
||||
import { S as Skeleton } from "../../../../chunks/Skeleton.js";
|
||||
import "../../../../chunks/toast.js";
|
||||
import { t } from "../../../../chunks/index2.js";
|
||||
import { I as IconPlus } from "../../../../chunks/IconPlus.js";
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let $$settled = true;
|
||||
let $$inner_renderer;
|
||||
function $$render_inner($$renderer3) {
|
||||
head("p19oey", $$renderer3, ($$renderer4) => {
|
||||
$$renderer4.title(($$renderer5) => {
|
||||
$$renderer5.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsRegistries.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer3.push(`<div class="space-y-6"><div class="flex items-center justify-between"><div><h2 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsRegistries.title"))}</h2> <p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsRegistries.description"))}</p></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<button class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm hover:bg-[var(--color-brand-700)] transition-colors active:animate-press">`);
|
||||
IconPlus($$renderer3, { size: 16 });
|
||||
$$renderer3.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("settingsRegistries.addRegistry"))}</button>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div> `);
|
||||
{
|
||||
$$renderer3.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer3.push(`<!--]--> `);
|
||||
{
|
||||
$$renderer3.push("<!--[0-->");
|
||||
$$renderer3.push(`<div class="space-y-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(2));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
Skeleton($$renderer3, { height: "5rem" });
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
$$renderer3.push(`<!--]--></div>`);
|
||||
}
|
||||
do {
|
||||
$$settled = true;
|
||||
$$inner_renderer = $$renderer2.copy();
|
||||
$$render_inner($$inner_renderer);
|
||||
} while (!$$settled);
|
||||
$$renderer2.subsume($$inner_renderer);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
import "./chunks/root.js";
|
||||
import { s, a, b } from "./chunks/environment.js";
|
||||
import { g, o, c, s as s2, a as a2, b as b2 } from "./chunks/internal.js";
|
||||
export {
|
||||
g as get_hooks,
|
||||
o as options,
|
||||
s as set_assets,
|
||||
a as set_building,
|
||||
c as set_manifest,
|
||||
b as set_prerendering,
|
||||
s2 as set_private_env,
|
||||
a2 as set_public_env,
|
||||
b2 as set_read_implementation
|
||||
};
|
||||
@@ -0,0 +1,168 @@
|
||||
export const manifest = (() => {
|
||||
function __memo(fn) {
|
||||
let value;
|
||||
return () => value ??= (value = fn());
|
||||
}
|
||||
|
||||
return {
|
||||
appDir: "_app",
|
||||
appPath: "_app",
|
||||
assets: new Set([]),
|
||||
mimeTypes: {},
|
||||
_: {
|
||||
client: {start:"_app/immutable/entry/start.BU-sFgwv.js",app:"_app/immutable/entry/app.C3eO1cEh.js",imports:["_app/immutable/entry/start.BU-sFgwv.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/entry/app.C3eO1cEh.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/BoGS7hWi.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
|
||||
nodes: [
|
||||
__memo(() => import('./nodes/0.js')),
|
||||
__memo(() => import('./nodes/1.js')),
|
||||
__memo(() => import('./nodes/2.js')),
|
||||
__memo(() => import('./nodes/3.js')),
|
||||
__memo(() => import('./nodes/4.js')),
|
||||
__memo(() => import('./nodes/5.js')),
|
||||
__memo(() => import('./nodes/6.js')),
|
||||
__memo(() => import('./nodes/7.js')),
|
||||
__memo(() => import('./nodes/8.js')),
|
||||
__memo(() => import('./nodes/9.js')),
|
||||
__memo(() => import('./nodes/10.js')),
|
||||
__memo(() => import('./nodes/11.js')),
|
||||
__memo(() => import('./nodes/12.js')),
|
||||
__memo(() => import('./nodes/13.js')),
|
||||
__memo(() => import('./nodes/14.js')),
|
||||
__memo(() => import('./nodes/15.js')),
|
||||
__memo(() => import('./nodes/16.js')),
|
||||
__memo(() => import('./nodes/17.js')),
|
||||
__memo(() => import('./nodes/18.js')),
|
||||
__memo(() => import('./nodes/19.js'))
|
||||
],
|
||||
remotes: {
|
||||
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
id: "/",
|
||||
pattern: /^\/$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 3 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/containers/stale",
|
||||
pattern: /^\/containers\/stale\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 4 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/deploy",
|
||||
pattern: /^\/deploy\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 5 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/events",
|
||||
pattern: /^\/events\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 6 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/login",
|
||||
pattern: /^\/login\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 7 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects",
|
||||
pattern: /^\/projects\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 8 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]",
|
||||
pattern: /^\/projects\/([^/]+?)\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 9 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/env",
|
||||
pattern: /^\/projects\/([^/]+?)\/env\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 10 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/volumes",
|
||||
pattern: /^\/projects\/([^/]+?)\/volumes\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 11 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/volumes/[volId]/browse",
|
||||
pattern: /^\/projects\/([^/]+?)\/volumes\/([^/]+?)\/browse\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false},{"name":"volId","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 12 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies",
|
||||
pattern: /^\/proxies\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 13 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies/create",
|
||||
pattern: /^\/proxies\/create\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 14 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies/[id]/edit",
|
||||
pattern: /^\/proxies\/([^/]+?)\/edit\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 15 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings",
|
||||
pattern: /^\/settings\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 16 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/auth",
|
||||
pattern: /^\/settings\/auth\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 17 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/credentials",
|
||||
pattern: /^\/settings\/credentials\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 18 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/registries",
|
||||
pattern: /^\/settings\/registries\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 19 },
|
||||
endpoint: null
|
||||
}
|
||||
],
|
||||
prerendered_routes: new Set([]),
|
||||
matchers: async () => {
|
||||
|
||||
return { };
|
||||
},
|
||||
server_assets: {}
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,168 @@
|
||||
export const manifest = (() => {
|
||||
function __memo(fn) {
|
||||
let value;
|
||||
return () => value ??= (value = fn());
|
||||
}
|
||||
|
||||
return {
|
||||
appDir: "_app",
|
||||
appPath: "_app",
|
||||
assets: new Set([]),
|
||||
mimeTypes: {},
|
||||
_: {
|
||||
client: {start:"_app/immutable/entry/start.BU-sFgwv.js",app:"_app/immutable/entry/app.C3eO1cEh.js",imports:["_app/immutable/entry/start.BU-sFgwv.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/entry/app.C3eO1cEh.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/BoGS7hWi.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
|
||||
nodes: [
|
||||
__memo(() => import('./nodes/0.js')),
|
||||
__memo(() => import('./nodes/1.js')),
|
||||
__memo(() => import('./nodes/2.js')),
|
||||
__memo(() => import('./nodes/3.js')),
|
||||
__memo(() => import('./nodes/4.js')),
|
||||
__memo(() => import('./nodes/5.js')),
|
||||
__memo(() => import('./nodes/6.js')),
|
||||
__memo(() => import('./nodes/7.js')),
|
||||
__memo(() => import('./nodes/8.js')),
|
||||
__memo(() => import('./nodes/9.js')),
|
||||
__memo(() => import('./nodes/10.js')),
|
||||
__memo(() => import('./nodes/11.js')),
|
||||
__memo(() => import('./nodes/12.js')),
|
||||
__memo(() => import('./nodes/13.js')),
|
||||
__memo(() => import('./nodes/14.js')),
|
||||
__memo(() => import('./nodes/15.js')),
|
||||
__memo(() => import('./nodes/16.js')),
|
||||
__memo(() => import('./nodes/17.js')),
|
||||
__memo(() => import('./nodes/18.js')),
|
||||
__memo(() => import('./nodes/19.js'))
|
||||
],
|
||||
remotes: {
|
||||
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
id: "/",
|
||||
pattern: /^\/$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 3 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/containers/stale",
|
||||
pattern: /^\/containers\/stale\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 4 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/deploy",
|
||||
pattern: /^\/deploy\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 5 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/events",
|
||||
pattern: /^\/events\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 6 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/login",
|
||||
pattern: /^\/login\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 7 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects",
|
||||
pattern: /^\/projects\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 8 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]",
|
||||
pattern: /^\/projects\/([^/]+?)\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 9 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/env",
|
||||
pattern: /^\/projects\/([^/]+?)\/env\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 10 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/volumes",
|
||||
pattern: /^\/projects\/([^/]+?)\/volumes\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 11 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/projects/[id]/volumes/[volId]/browse",
|
||||
pattern: /^\/projects\/([^/]+?)\/volumes\/([^/]+?)\/browse\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false},{"name":"volId","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 12 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies",
|
||||
pattern: /^\/proxies\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 13 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies/create",
|
||||
pattern: /^\/proxies\/create\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 14 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/proxies/[id]/edit",
|
||||
pattern: /^\/proxies\/([^/]+?)\/edit\/?$/,
|
||||
params: [{"name":"id","optional":false,"rest":false,"chained":false}],
|
||||
page: { layouts: [0,], errors: [1,], leaf: 15 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings",
|
||||
pattern: /^\/settings\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 16 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/auth",
|
||||
pattern: /^\/settings\/auth\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 17 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/credentials",
|
||||
pattern: /^\/settings\/credentials\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 18 },
|
||||
endpoint: null
|
||||
},
|
||||
{
|
||||
id: "/settings/registries",
|
||||
pattern: /^\/settings\/registries\/?$/,
|
||||
params: [],
|
||||
page: { layouts: [0,2,], errors: [1,,], leaf: 19 },
|
||||
endpoint: null
|
||||
}
|
||||
],
|
||||
prerendered_routes: new Set([]),
|
||||
matchers: async () => {
|
||||
|
||||
return { };
|
||||
},
|
||||
server_assets: {}
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 0;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/+layout.ts";
|
||||
export const imports = ["_app/immutable/nodes/0.BMqZW0X_.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/CnPWu_ZO.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/BSEsuAwr.js","_app/immutable/chunks/BlV-f-zB.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/CcoMVVg8.js","_app/immutable/chunks/DrzuxmSv.js","_app/immutable/chunks/Hsiz6fBZ.js","_app/immutable/chunks/CWCQOKDd.js","_app/immutable/chunks/CvtQ6g1S.js","_app/immutable/chunks/DPFeFjvi.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/Bpb8V1MF.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/0.DnmtykcB.css"];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 1;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/1.Bdu_R2Hn.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSEsuAwr.js","_app/immutable/chunks/BlV-f-zB.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 10;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/projects/_id_/env/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/10.DFEGHcUu.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/Icw0y4KW.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/CPatcLwq.js","_app/immutable/chunks/CpnAtA5t.js","_app/immutable/chunks/BberSjRt.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/CexodXHl.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 11;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/projects/_id_/volumes/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/11.DMrjUtpD.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/Icw0y4KW.js","_app/immutable/chunks/BphdEXYy.js","_app/immutable/chunks/BvIWRct8.js","_app/immutable/chunks/CPatcLwq.js","_app/immutable/chunks/BE_zO38m.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 12;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/projects/_id_/volumes/_volId_/browse/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/projects/[id]/volumes/[volId]/browse/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/12.BO7G7YPE.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/BoGS7hWi.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/Icw0y4KW.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/BE_zO38m.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 13;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/proxies/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/proxies/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/13.DJV70kty.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/BphdEXYy.js","_app/immutable/chunks/CPatcLwq.js","_app/immutable/chunks/CpnAtA5t.js","_app/immutable/chunks/CnPWu_ZO.js","_app/immutable/chunks/Icw0y4KW.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/BvIWRct8.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/DrzuxmSv.js","_app/immutable/chunks/BFW91e3Y.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 14;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/proxies/create/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/proxies/create/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/14.udJGaOK1.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSEsuAwr.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/BlV-f-zB.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DsQCf6vC.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/C8zo5-Sk.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/DrzuxmSv.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 15;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/proxies/_id_/edit/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/proxies/[id]/edit/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/15.BC8amYnm.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DsQCf6vC.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/C8zo5-Sk.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/DrzuxmSv.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 16;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/settings/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/16.DrkZ20qh.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/BxXVdbgr.js","_app/immutable/chunks/BoGS7hWi.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/BvIWRct8.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/DhEbbC3M.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/BE_zO38m.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/EntityPicker.D4Qf6tQ2.css"];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 17;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/settings/auth/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/17.CjAaIU5M.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/DTyrBG6r.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 18;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/settings/credentials/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/18.C3f1k8vs.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/CPatcLwq.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 19;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/settings/registries/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/19.CiwgThsf.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/CPatcLwq.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 2;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/settings/_layout.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/2.DWWtnNKd.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CnPWu_ZO.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/CWCQOKDd.js","_app/immutable/chunks/DqoiTw6k.js","_app/immutable/chunks/DhEbbC3M.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 3;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/3.C0WC8trC.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/BPqRr2-s.js","_app/immutable/chunks/ip4Jv8C8.js","_app/immutable/chunks/BSEsuAwr.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/CvtQ6g1S.js","_app/immutable/chunks/Hsiz6fBZ.js","_app/immutable/chunks/DVE7XZFM.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 4;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/containers/stale/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/containers/stale/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/4.BxW_ZYFP.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/DVE7XZFM.js","_app/immutable/chunks/C8zo5-Sk.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/ip4Jv8C8.js","_app/immutable/chunks/BSEsuAwr.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/CjZL2MYp.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 5;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/deploy/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/5.C24PPPF_.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/BxXVdbgr.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/BoGS7hWi.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/BvIWRct8.js","_app/immutable/chunks/CjZL2MYp.js","_app/immutable/chunks/Hsiz6fBZ.js","_app/immutable/chunks/BFW91e3Y.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/EntityPicker.D4Qf6tQ2.css"];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
export const index = 6;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/events/_page.svelte.js')).default;
|
||||
export const universal = {
|
||||
"ssr": false,
|
||||
"prerender": false
|
||||
};
|
||||
export const universal_id = "src/routes/events/+page.ts";
|
||||
export const imports = ["_app/immutable/nodes/6.CEvKoBqC.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/BoGS7hWi.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/DPFeFjvi.js","_app/immutable/chunks/CexodXHl.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 7;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/login/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/7.DneEC9SR.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CcoMVVg8.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/DTyrBG6r.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 8;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/projects/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/8.BQus6eSQ.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/BvIWRct8.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/BxXVdbgr.js","_app/immutable/chunks/BoGS7hWi.js","_app/immutable/chunks/R0-LJft-.js"];
|
||||
export const stylesheets = ["_app/immutable/assets/EntityPicker.D4Qf6tQ2.css"];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
export const index = 9;
|
||||
let component_cache;
|
||||
export const component = async () => component_cache ??= (await import('../entries/pages/projects/_id_/_page.svelte.js')).default;
|
||||
export const imports = ["_app/immutable/nodes/9.g1C7u4k3.js","_app/immutable/chunks/BJdXET8u.js","_app/immutable/chunks/DKemW7Dm.js","_app/immutable/chunks/BSXRhUWv.js","_app/immutable/chunks/CZnXUJhL.js","_app/immutable/chunks/ecfdBtDb.js","_app/immutable/chunks/kfynmD3Z.js","_app/immutable/chunks/DgtbvmBB.js","_app/immutable/chunks/Bxa5VUw6.js","_app/immutable/chunks/DELaSNrV.js","_app/immutable/chunks/CWhLh9u1.js","_app/immutable/chunks/phMGo29-.js","_app/immutable/chunks/Bpb8V1MF.js","_app/immutable/chunks/DTyrBG6r.js","_app/immutable/chunks/BPqRr2-s.js","_app/immutable/chunks/BE_zO38m.js","_app/immutable/chunks/C8zo5-Sk.js","_app/immutable/chunks/CGCp4lb_.js","_app/immutable/chunks/scnZuc49.js","_app/immutable/chunks/BphdEXYy.js","_app/immutable/chunks/CexodXHl.js","_app/immutable/chunks/Hsiz6fBZ.js","_app/immutable/chunks/C6FeVxU4.js","_app/immutable/chunks/LFhQE6G2.js","_app/immutable/chunks/R0-LJft-.js","_app/immutable/chunks/Icw0y4KW.js","_app/immutable/chunks/DqoiTw6k.js","_app/immutable/chunks/BFW91e3Y.js","_app/immutable/chunks/DVE7XZFM.js","_app/immutable/chunks/CPatcLwq.js","_app/immutable/chunks/DfwQ65vN.js","_app/immutable/chunks/BberSjRt.js","_app/immutable/chunks/CjZL2MYp.js"];
|
||||
export const stylesheets = [];
|
||||
export const fonts = [];
|
||||
@@ -0,0 +1,557 @@
|
||||
import { get_request_store, with_request_store } from "@sveltejs/kit/internal/server";
|
||||
import { parse } from "devalue";
|
||||
import { error, json } from "@sveltejs/kit";
|
||||
import { s as stringify_remote_arg, M as MUTATIVE_METHODS, c as create_field_proxy, n as normalize_issue, a as set_nested_value, f as flatten_issues, d as deep_set, b as stringify, e as create_remote_key, h as handle_error_and_jsonify } from "./chunks/shared.js";
|
||||
import { ValidationError, HttpError, SvelteKitError } from "@sveltejs/kit/internal";
|
||||
import { B as BROWSER } from "./chunks/false.js";
|
||||
import { c as base, d as app_dir, p as prerendering } from "./chunks/environment.js";
|
||||
function create_validator(validate_or_fn, maybe_fn) {
|
||||
if (!maybe_fn) {
|
||||
return (arg) => {
|
||||
if (arg !== void 0) {
|
||||
error(400, "Bad Request");
|
||||
}
|
||||
};
|
||||
}
|
||||
if (validate_or_fn === "unchecked") {
|
||||
return (arg) => arg;
|
||||
}
|
||||
if ("~standard" in validate_or_fn) {
|
||||
return async (arg) => {
|
||||
const { event, state } = get_request_store();
|
||||
const result = await validate_or_fn["~standard"].validate(arg);
|
||||
if (result.issues) {
|
||||
error(
|
||||
400,
|
||||
await state.handleValidationError({
|
||||
issues: result.issues,
|
||||
event
|
||||
})
|
||||
);
|
||||
}
|
||||
return result.value;
|
||||
};
|
||||
}
|
||||
throw new Error(
|
||||
'Invalid validator passed to remote function. Expected "unchecked" or a Standard Schema (https://standardschema.dev)'
|
||||
);
|
||||
}
|
||||
async function get_response(info, arg, state, get_result) {
|
||||
await 0;
|
||||
const cache = get_cache(info, state);
|
||||
return cache[stringify_remote_arg(arg, state.transport)] ??= get_result();
|
||||
}
|
||||
function parse_remote_response(data, transport) {
|
||||
const revivers = {};
|
||||
for (const key in transport) {
|
||||
revivers[key] = transport[key].decode;
|
||||
}
|
||||
return parse(data, revivers);
|
||||
}
|
||||
async function run_remote_function(event, state, allow_cookies, get_input, fn) {
|
||||
const store = {
|
||||
event: {
|
||||
...event,
|
||||
setHeaders: () => {
|
||||
throw new Error("setHeaders is not allowed in remote functions");
|
||||
},
|
||||
cookies: {
|
||||
...event.cookies,
|
||||
set: (name, value, opts) => {
|
||||
if (!allow_cookies) {
|
||||
throw new Error("Cannot set cookies in `query` or `prerender` functions");
|
||||
}
|
||||
if (opts.path && !opts.path.startsWith("/")) {
|
||||
throw new Error("Cookies set in remote functions must have an absolute path");
|
||||
}
|
||||
return event.cookies.set(name, value, opts);
|
||||
},
|
||||
delete: (name, opts) => {
|
||||
if (!allow_cookies) {
|
||||
throw new Error("Cannot delete cookies in `query` or `prerender` functions");
|
||||
}
|
||||
if (opts.path && !opts.path.startsWith("/")) {
|
||||
throw new Error("Cookies deleted in remote functions must have an absolute path");
|
||||
}
|
||||
return event.cookies.delete(name, opts);
|
||||
}
|
||||
}
|
||||
},
|
||||
state: {
|
||||
...state,
|
||||
is_in_remote_function: true
|
||||
}
|
||||
};
|
||||
const input = await with_request_store(store, get_input);
|
||||
return with_request_store(store, () => fn(input));
|
||||
}
|
||||
function get_cache(info, state = get_request_store().state) {
|
||||
let cache = state.remote_data?.get(info);
|
||||
if (cache === void 0) {
|
||||
cache = {};
|
||||
(state.remote_data ??= /* @__PURE__ */ new Map()).set(info, cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
// @__NO_SIDE_EFFECTS__
|
||||
function command(validate_or_fn, maybe_fn) {
|
||||
const fn = maybe_fn ?? validate_or_fn;
|
||||
const validate = create_validator(validate_or_fn, maybe_fn);
|
||||
const __ = { type: "command", id: "", name: "" };
|
||||
const wrapper = (arg) => {
|
||||
const { event, state } = get_request_store();
|
||||
if (!state.allows_commands) {
|
||||
const disallowed_method = !MUTATIVE_METHODS.includes(event.request.method);
|
||||
throw new Error(
|
||||
`Cannot call a command (\`${__.name}(${maybe_fn ? "..." : ""})\`) ${disallowed_method ? `from a ${event.request.method} handler or ` : ""}during server-side rendering`
|
||||
);
|
||||
}
|
||||
state.refreshes ??= {};
|
||||
const promise = Promise.resolve(
|
||||
run_remote_function(event, state, true, () => validate(arg), fn)
|
||||
);
|
||||
promise.updates = () => {
|
||||
throw new Error(`Cannot call '${__.name}(...).updates(...)' on the server`);
|
||||
};
|
||||
return (
|
||||
/** @type {ReturnType<RemoteCommand<Input, Output>>} */
|
||||
promise
|
||||
);
|
||||
};
|
||||
Object.defineProperty(wrapper, "__", { value: __ });
|
||||
Object.defineProperty(wrapper, "pending", {
|
||||
get: () => 0
|
||||
});
|
||||
return wrapper;
|
||||
}
|
||||
// @__NO_SIDE_EFFECTS__
|
||||
function form(validate_or_fn, maybe_fn) {
|
||||
const fn = maybe_fn ?? validate_or_fn;
|
||||
const schema = !maybe_fn || validate_or_fn === "unchecked" ? null : (
|
||||
/** @type {any} */
|
||||
validate_or_fn
|
||||
);
|
||||
function create_instance(key) {
|
||||
const instance = {};
|
||||
instance.method = "POST";
|
||||
Object.defineProperty(instance, "enhance", {
|
||||
value: () => {
|
||||
return { action: instance.action, method: instance.method };
|
||||
}
|
||||
});
|
||||
const __ = {
|
||||
type: "form",
|
||||
name: "",
|
||||
id: "",
|
||||
fn: async (data, meta, form_data) => {
|
||||
const output = {};
|
||||
output.submission = true;
|
||||
const { event, state } = get_request_store();
|
||||
const validated = await schema?.["~standard"].validate(data);
|
||||
if (meta.validate_only) {
|
||||
return validated?.issues?.map((issue) => normalize_issue(issue, true)) ?? [];
|
||||
}
|
||||
if (validated?.issues !== void 0) {
|
||||
handle_issues(output, validated.issues, form_data);
|
||||
} else {
|
||||
if (validated !== void 0) {
|
||||
data = validated.value;
|
||||
}
|
||||
state.refreshes ??= {};
|
||||
const issue = create_issues();
|
||||
try {
|
||||
output.result = await run_remote_function(
|
||||
event,
|
||||
state,
|
||||
true,
|
||||
() => data,
|
||||
(data2) => !maybe_fn ? fn() : fn(data2, issue)
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof ValidationError) {
|
||||
handle_issues(output, e.issues, form_data);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!event.isRemoteRequest) {
|
||||
get_cache(__, state)[""] ??= output;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
};
|
||||
Object.defineProperty(instance, "__", { value: __ });
|
||||
Object.defineProperty(instance, "action", {
|
||||
get: () => `?/remote=${__.id}`,
|
||||
enumerable: true
|
||||
});
|
||||
Object.defineProperty(instance, "fields", {
|
||||
get() {
|
||||
return create_field_proxy(
|
||||
{},
|
||||
() => get_cache(__)?.[""]?.input ?? {},
|
||||
(path, value) => {
|
||||
const cache = get_cache(__);
|
||||
const data = cache[""];
|
||||
if (data?.submission) {
|
||||
return;
|
||||
}
|
||||
if (path.length === 0) {
|
||||
(cache[""] ??= {}).input = value;
|
||||
return;
|
||||
}
|
||||
const input = data?.input ?? {};
|
||||
deep_set(input, path.map(String), value);
|
||||
(cache[""] ??= {}).input = input;
|
||||
},
|
||||
() => flatten_issues(get_cache(__)?.[""]?.issues ?? [])
|
||||
);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(instance, "result", {
|
||||
get() {
|
||||
try {
|
||||
return get_cache(__)?.[""]?.result;
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(instance, "pending", {
|
||||
get: () => 0
|
||||
});
|
||||
Object.defineProperty(instance, "preflight", {
|
||||
// preflight is a noop on the server
|
||||
value: () => instance
|
||||
});
|
||||
Object.defineProperty(instance, "validate", {
|
||||
value: () => {
|
||||
throw new Error("Cannot call validate() on the server");
|
||||
}
|
||||
});
|
||||
if (key == void 0) {
|
||||
Object.defineProperty(instance, "for", {
|
||||
/** @type {RemoteForm<any, any>['for']} */
|
||||
value: (key2) => {
|
||||
const { state } = get_request_store();
|
||||
const cache_key = __.id + "|" + JSON.stringify(key2);
|
||||
let instance2 = (state.form_instances ??= /* @__PURE__ */ new Map()).get(cache_key);
|
||||
if (!instance2) {
|
||||
instance2 = create_instance(key2);
|
||||
instance2.__.id = `${__.id}/${encodeURIComponent(JSON.stringify(key2))}`;
|
||||
instance2.__.name = __.name;
|
||||
state.form_instances.set(cache_key, instance2);
|
||||
}
|
||||
return instance2;
|
||||
}
|
||||
});
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
return create_instance();
|
||||
}
|
||||
function handle_issues(output, issues, form_data) {
|
||||
output.issues = issues.map((issue) => normalize_issue(issue, true));
|
||||
if (form_data) {
|
||||
output.input = {};
|
||||
for (let key of form_data.keys()) {
|
||||
if (/^[.\]]?_/.test(key)) continue;
|
||||
const is_array = key.endsWith("[]");
|
||||
const values = form_data.getAll(key).filter((value) => typeof value === "string");
|
||||
if (is_array) key = key.slice(0, -2);
|
||||
set_nested_value(
|
||||
/** @type {Record<string, any>} */
|
||||
output.input,
|
||||
key,
|
||||
is_array ? values : values[0]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
function create_issues() {
|
||||
return (
|
||||
/** @type {InvalidField<any>} */
|
||||
new Proxy(
|
||||
/** @param {string} message */
|
||||
(message) => {
|
||||
if (typeof message !== "string") {
|
||||
throw new Error(
|
||||
"`invalid` should now be imported from `@sveltejs/kit` to throw validation issues. The second parameter provided to the form function (renamed to `issue`) is still used to construct issues, e.g. `invalid(issue.field('message'))`. For more info see https://github.com/sveltejs/kit/pulls/14768"
|
||||
);
|
||||
}
|
||||
return create_issue(message);
|
||||
},
|
||||
{
|
||||
get(target, prop) {
|
||||
if (typeof prop === "symbol") return (
|
||||
/** @type {any} */
|
||||
target[prop]
|
||||
);
|
||||
return create_issue_proxy(prop, []);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
function create_issue(message, path = []) {
|
||||
return {
|
||||
message,
|
||||
path
|
||||
};
|
||||
}
|
||||
function create_issue_proxy(key, path) {
|
||||
const new_path = [...path, key];
|
||||
const issue_func = (message) => create_issue(message, new_path);
|
||||
return new Proxy(issue_func, {
|
||||
get(target, prop) {
|
||||
if (typeof prop === "symbol") return (
|
||||
/** @type {any} */
|
||||
target[prop]
|
||||
);
|
||||
if (/^\d+$/.test(prop)) {
|
||||
return create_issue_proxy(parseInt(prop, 10), new_path);
|
||||
}
|
||||
return create_issue_proxy(prop, new_path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// @__NO_SIDE_EFFECTS__
|
||||
function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
||||
const maybe_fn = typeof fn_or_options === "function" ? fn_or_options : void 0;
|
||||
const options = maybe_options ?? (maybe_fn ? void 0 : fn_or_options);
|
||||
const fn = maybe_fn ?? validate_or_fn;
|
||||
const validate = create_validator(validate_or_fn, maybe_fn);
|
||||
const __ = {
|
||||
type: "prerender",
|
||||
id: "",
|
||||
name: "",
|
||||
has_arg: !!maybe_fn,
|
||||
inputs: options?.inputs,
|
||||
dynamic: options?.dynamic
|
||||
};
|
||||
const wrapper = (arg) => {
|
||||
const promise = (async () => {
|
||||
const { event, state } = get_request_store();
|
||||
const payload = stringify_remote_arg(arg, state.transport);
|
||||
const id = __.id;
|
||||
const url = `${base}/${app_dir}/remote/${id}${payload ? `/${payload}` : ""}`;
|
||||
if (!state.prerendering && !BROWSER && !event.isRemoteRequest) {
|
||||
try {
|
||||
return await get_response(__, arg, state, async () => {
|
||||
const key = stringify_remote_arg(arg, state.transport);
|
||||
const cache = get_cache(__, state);
|
||||
const promise3 = cache[key] ??= fetch(new URL(url, event.url.origin).href).then(
|
||||
async (response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Prerendered response not found");
|
||||
}
|
||||
const prerendered = await response.json();
|
||||
if (prerendered.type === "error") {
|
||||
error(prerendered.status, prerendered.error);
|
||||
}
|
||||
return prerendered.result;
|
||||
}
|
||||
);
|
||||
return parse_remote_response(await promise3, state.transport);
|
||||
});
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
if (state.prerendering?.remote_responses.has(url)) {
|
||||
return (
|
||||
/** @type {Promise<any>} */
|
||||
state.prerendering.remote_responses.get(url)
|
||||
);
|
||||
}
|
||||
const promise2 = get_response(
|
||||
__,
|
||||
arg,
|
||||
state,
|
||||
() => run_remote_function(event, state, false, () => validate(arg), fn)
|
||||
);
|
||||
if (state.prerendering) {
|
||||
state.prerendering.remote_responses.set(url, promise2);
|
||||
}
|
||||
const result = await promise2;
|
||||
if (state.prerendering) {
|
||||
const body = { type: "result", result: stringify(result, state.transport) };
|
||||
state.prerendering.dependencies.set(url, {
|
||||
body: JSON.stringify(body),
|
||||
response: json(body)
|
||||
});
|
||||
}
|
||||
return result;
|
||||
})();
|
||||
promise.catch(() => {
|
||||
});
|
||||
return (
|
||||
/** @type {RemoteResource<Output>} */
|
||||
promise
|
||||
);
|
||||
};
|
||||
Object.defineProperty(wrapper, "__", { value: __ });
|
||||
return wrapper;
|
||||
}
|
||||
// @__NO_SIDE_EFFECTS__
|
||||
function query(validate_or_fn, maybe_fn) {
|
||||
const fn = maybe_fn ?? validate_or_fn;
|
||||
const validate = create_validator(validate_or_fn, maybe_fn);
|
||||
const __ = { type: "query", id: "", name: "" };
|
||||
const wrapper = (arg) => {
|
||||
if (prerendering) {
|
||||
throw new Error(
|
||||
`Cannot call query '${__.name}' while prerendering, as prerendered pages need static data. Use 'prerender' from $app/server instead`
|
||||
);
|
||||
}
|
||||
const { event, state } = get_request_store();
|
||||
const get_remote_function_result = () => run_remote_function(event, state, false, () => validate(arg), fn);
|
||||
const promise = get_response(__, arg, state, get_remote_function_result);
|
||||
promise.catch(() => {
|
||||
});
|
||||
promise.set = (value) => update_refresh_value(get_refresh_context(__, "set", arg), value);
|
||||
promise.refresh = () => {
|
||||
const refresh_context = get_refresh_context(__, "refresh", arg);
|
||||
const is_immediate_refresh = !refresh_context.cache[refresh_context.cache_key];
|
||||
const value = is_immediate_refresh ? promise : get_remote_function_result();
|
||||
return update_refresh_value(refresh_context, value, is_immediate_refresh);
|
||||
};
|
||||
promise.withOverride = () => {
|
||||
throw new Error(`Cannot call '${__.name}.withOverride()' on the server`);
|
||||
};
|
||||
return (
|
||||
/** @type {RemoteQuery<Output>} */
|
||||
promise
|
||||
);
|
||||
};
|
||||
Object.defineProperty(wrapper, "__", { value: __ });
|
||||
return wrapper;
|
||||
}
|
||||
// @__NO_SIDE_EFFECTS__
|
||||
function batch(validate_or_fn, maybe_fn) {
|
||||
const fn = maybe_fn ?? validate_or_fn;
|
||||
const validate = create_validator(validate_or_fn, maybe_fn);
|
||||
const __ = {
|
||||
type: "query_batch",
|
||||
id: "",
|
||||
name: "",
|
||||
run: async (args, options) => {
|
||||
const { event, state } = get_request_store();
|
||||
return run_remote_function(
|
||||
event,
|
||||
state,
|
||||
false,
|
||||
async () => Promise.all(args.map(validate)),
|
||||
async (input) => {
|
||||
const get_result = await fn(input);
|
||||
return Promise.all(
|
||||
input.map(async (arg, i) => {
|
||||
try {
|
||||
return { type: "result", data: get_result(arg, i) };
|
||||
} catch (error2) {
|
||||
return {
|
||||
type: "error",
|
||||
error: await handle_error_and_jsonify(event, state, options, error2),
|
||||
status: error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
let batching = { args: [], resolvers: [] };
|
||||
const wrapper = (arg) => {
|
||||
if (prerendering) {
|
||||
throw new Error(
|
||||
`Cannot call query.batch '${__.name}' while prerendering, as prerendered pages need static data. Use 'prerender' from $app/server instead`
|
||||
);
|
||||
}
|
||||
const { event, state } = get_request_store();
|
||||
const get_remote_function_result = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
batching.args.push(arg);
|
||||
batching.resolvers.push({ resolve, reject });
|
||||
if (batching.args.length > 1) return;
|
||||
setTimeout(async () => {
|
||||
const batched = batching;
|
||||
batching = { args: [], resolvers: [] };
|
||||
try {
|
||||
return await run_remote_function(
|
||||
event,
|
||||
state,
|
||||
false,
|
||||
async () => Promise.all(batched.args.map(validate)),
|
||||
async (input) => {
|
||||
const get_result = await fn(input);
|
||||
for (let i = 0; i < batched.resolvers.length; i++) {
|
||||
try {
|
||||
batched.resolvers[i].resolve(get_result(input[i], i));
|
||||
} catch (error2) {
|
||||
batched.resolvers[i].reject(error2);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error2) {
|
||||
for (const resolver of batched.resolvers) {
|
||||
resolver.reject(error2);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
};
|
||||
const promise = get_response(__, arg, state, get_remote_function_result);
|
||||
promise.catch(() => {
|
||||
});
|
||||
promise.set = (value) => update_refresh_value(get_refresh_context(__, "set", arg), value);
|
||||
promise.refresh = () => {
|
||||
const refresh_context = get_refresh_context(__, "refresh", arg);
|
||||
const is_immediate_refresh = !refresh_context.cache[refresh_context.cache_key];
|
||||
const value = is_immediate_refresh ? promise : get_remote_function_result();
|
||||
return update_refresh_value(refresh_context, value, is_immediate_refresh);
|
||||
};
|
||||
promise.withOverride = () => {
|
||||
throw new Error(`Cannot call '${__.name}.withOverride()' on the server`);
|
||||
};
|
||||
return (
|
||||
/** @type {RemoteQuery<Output>} */
|
||||
promise
|
||||
);
|
||||
};
|
||||
Object.defineProperty(wrapper, "__", { value: __ });
|
||||
return wrapper;
|
||||
}
|
||||
Object.defineProperty(query, "batch", { value: batch, enumerable: true });
|
||||
function get_refresh_context(__, action, arg) {
|
||||
const { state } = get_request_store();
|
||||
const { refreshes } = state;
|
||||
if (!refreshes) {
|
||||
const name = __.type === "query_batch" ? `query.batch '${__.name}'` : `query '${__.name}'`;
|
||||
throw new Error(
|
||||
`Cannot call ${action} on ${name} because it is not executed in the context of a command/form remote function`
|
||||
);
|
||||
}
|
||||
const cache = get_cache(__, state);
|
||||
const cache_key = stringify_remote_arg(arg, state.transport);
|
||||
const refreshes_key = create_remote_key(__.id, cache_key);
|
||||
return { __, state, refreshes, refreshes_key, cache, cache_key };
|
||||
}
|
||||
function update_refresh_value({ __, refreshes, refreshes_key, cache, cache_key }, value, is_immediate_refresh = false) {
|
||||
const promise = Promise.resolve(value);
|
||||
if (!is_immediate_refresh) {
|
||||
cache[cache_key] = promise;
|
||||
}
|
||||
if (__.id) {
|
||||
refreshes[refreshes_key] = promise;
|
||||
}
|
||||
return promise.then(() => {
|
||||
});
|
||||
}
|
||||
export {
|
||||
command,
|
||||
form,
|
||||
prerender,
|
||||
query
|
||||
};
|
||||
Reference in New Issue
Block a user