mirror of
https://github.com/rajnandan1/kener.git
synced 2026-06-23 04:10:22 +00:00
chore: Update documentation layout and enhance API reference with new metadata and server URL variable
This commit is contained in:
@@ -8,4 +8,33 @@
|
||||
let { children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Kener Documentation</title>
|
||||
<!-- social preview og.jpg -->
|
||||
<meta property="og:image" content="/og.jpg" />
|
||||
<meta property="og:title" content="Kener Documentation" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Comprehensive documentation for Kener, the open-source status page generator. Learn how to set up, customize, and manage your own status page with Kener."
|
||||
/>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Kener Documentation" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Comprehensive documentation for Kener, the open-source status page generator. Learn how to set up, customize, and manage your own status page with Kener."
|
||||
/>
|
||||
<meta name="twitter:image" content="/og.jpg" />
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Q3MLRXCBFT"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag("js", new Date());
|
||||
|
||||
gtag("config", "G-Q3MLRXCBFT");
|
||||
</script>
|
||||
</svelte:head>
|
||||
|
||||
{@render children()}
|
||||
|
||||
+137
-117
@@ -1,4 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { Badge } from "$lib/components/ui/badge/index.js";
|
||||
import { Button } from "$lib/components/ui/button/index.js";
|
||||
import * as Card from "$lib/components/ui/card/index.js";
|
||||
import { Separator } from "$lib/components/ui/separator/index.js";
|
||||
import type { DocsConfig, DocsPage } from "$lib/types/docs";
|
||||
import { base } from "$app/paths";
|
||||
import ArrowRight from "@lucide/svelte/icons/arrow-right";
|
||||
@@ -255,82 +259,88 @@
|
||||
<div class="flex items-center gap-3 sm:gap-6">
|
||||
{#if data.config.footerLinks}
|
||||
{#each data.config.footerLinks.slice(0, 3) as link (link.url)}
|
||||
<a
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-muted-foreground hover:text-foreground hidden text-sm no-underline transition-colors duration-200 sm:inline"
|
||||
class="text-muted-foreground hover:text-foreground hidden sm:inline-flex"
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
</Button>
|
||||
{/each}
|
||||
{/if}
|
||||
<button
|
||||
class="text-muted-foreground hover:bg-accent hover:text-foreground flex h-9 w-9 cursor-pointer items-center justify-center rounded border-none bg-transparent transition-all duration-200"
|
||||
onclick={toggleMode}
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<Button variant="ghost" size="icon" onclick={toggleMode} aria-label="Toggle theme">
|
||||
{#if mode.current === "dark"}
|
||||
<Sun class="h-5 w-5" />
|
||||
{:else}
|
||||
<Moon class="h-5 w-5" />
|
||||
{/if}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="bg-background min-h-screen bg-(image:--docs-home-hero-gradient) px-6 py-20 text-center md:py-24">
|
||||
<div class="mx-auto mt-20 max-w-[980px]">
|
||||
<div
|
||||
class="bg-background/80 border-border mb-6 inline-flex items-center gap-2 rounded-full border px-4 py-2 text-xs font-medium backdrop-blur"
|
||||
>
|
||||
<Shield class="h-3.5 w-3.5" />
|
||||
Production-ready status page platform
|
||||
</div>
|
||||
<h1 class="text-foreground mb-6 text-4xl leading-tight font-extrabold tracking-tight md:text-6xl">
|
||||
Build trust with
|
||||
<span class="from-primary to-accent-foreground bg-linear-to-r bg-clip-text text-transparent"
|
||||
>{data.config.name}</span
|
||||
>
|
||||
documentation that actually gets used
|
||||
</h1>
|
||||
<p class="text-muted-foreground mx-auto mb-10 max-w-[760px] text-base leading-relaxed md:text-xl">
|
||||
From quick setup to advanced operations, Kener gives you open-source monitoring, incident workflows,
|
||||
notifications, maintenance scheduling, embeds, and automation APIs—all in one modern platform.
|
||||
</p>
|
||||
|
||||
<div class="mb-10 flex flex-wrap justify-center gap-3 md:gap-4">
|
||||
{#each getCtaButtons() as button (button.title)}
|
||||
<a
|
||||
href={getHref(button.href)}
|
||||
rel="external"
|
||||
class={[
|
||||
"inline-flex items-center gap-2 rounded px-6 py-3 text-sm font-semibold no-underline transition-all duration-200 md:px-7 md:py-3.5 md:text-base",
|
||||
button.primary
|
||||
? "bg-primary text-primary-foreground shadow-lg hover:-translate-y-0.5 hover:shadow-xl"
|
||||
: "bg-background text-foreground border-border hover:bg-accent hover:border-accent-foreground border"
|
||||
]}
|
||||
<section class="bg-background min-h-screen bg-(image:--docs-home-hero-gradient) px-6 py-20 md:py-24">
|
||||
<div class="mx-auto mt-20 grid max-w-[1200px] items-center gap-10 lg:grid-cols-2">
|
||||
<div class="text-center lg:text-left">
|
||||
<Badge variant="secondary" class="mb-6 inline-flex items-center gap-2 px-3 py-1 text-xs">
|
||||
<Shield class="h-3.5 w-3.5" />
|
||||
Production-ready status page platform
|
||||
</Badge>
|
||||
<h1 class="text-foreground mb-6 text-2xl leading-tight font-bold tracking-tight md:text-4xl">
|
||||
Build trust with
|
||||
<span class="from-primary to-accent-foreground bg-linear-to-r bg-clip-text text-transparent"
|
||||
>{data.config.name}</span
|
||||
>
|
||||
{button.title}
|
||||
{#if button.primary}
|
||||
<ArrowRight class="h-4 w-4" />
|
||||
{/if}
|
||||
</a>
|
||||
{/each}
|
||||
documentation that actually gets used
|
||||
</h1>
|
||||
<p class="text-muted-foreground mb-8 max-w-[760px] text-sm leading-relaxed md:text-base">
|
||||
From quick setup to advanced operations, Kener gives you open-source monitoring, incident workflows,
|
||||
notifications, maintenance scheduling, embeds, and automation APIs—all in one modern platform.
|
||||
</p>
|
||||
|
||||
<div class="mb-8 flex flex-wrap justify-center gap-3 md:gap-4 lg:justify-start">
|
||||
{#each getCtaButtons() as button (button.title)}
|
||||
<Button href={getHref(button.href)} variant={button.primary ? "default" : "outline"} size="lg">
|
||||
{button.title}
|
||||
{#if button.primary}
|
||||
<ArrowRight class="h-4 w-4" />
|
||||
{/if}
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if getMetrics().length > 0}
|
||||
<div class="grid max-w-[920px] grid-cols-2 gap-3 sm:grid-cols-4">
|
||||
{#each getMetrics() as metric (metric.label)}
|
||||
<Card.Root class="bg-card/70 backdrop-blur">
|
||||
<Card.Content class="px-4 py-3">
|
||||
<p class="text-foreground text-lg font-bold md:text-xl">{metric.value}</p>
|
||||
<p class="text-muted-foreground text-xs tracking-wide uppercase">{metric.label}</p>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="mx-auto grid max-w-[920px] grid-cols-2 gap-3 sm:grid-cols-4">
|
||||
{#each getMetrics() as metric (metric.label)}
|
||||
<div class="bg-card/70 border-border rounded-lg border px-4 py-3 backdrop-blur">
|
||||
<p class="text-foreground text-lg font-bold md:text-xl">{metric.value}</p>
|
||||
<p class="text-muted-foreground text-xs tracking-wide uppercase">{metric.label}</p>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="overflow-hidden rounded-md border-2 shadow-xl">
|
||||
<img
|
||||
src="/og.jpg"
|
||||
alt="Kener documentation preview"
|
||||
class="bg-muted h-auto w-full rounded-md object-cover"
|
||||
loading="eager"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="mx-auto max-w-[1200px] px-6">
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
<section class="bg-background px-6 py-20 md:py-24">
|
||||
<div class="mx-auto mb-10 max-w-[1200px] text-center">
|
||||
<h2 class="text-foreground mb-3 text-3xl font-bold tracking-tight md:text-4xl">
|
||||
@@ -344,30 +354,34 @@
|
||||
|
||||
<div class="mx-auto grid max-w-[1200px] grid-cols-1 gap-5 sm:grid-cols-2 xl:grid-cols-3">
|
||||
{#each coreFeatures as feature (feature.title)}
|
||||
<div
|
||||
class="bg-card border-border hover:border-accent-foreground rounded-lg border p-6 transition-all duration-300 hover:-translate-y-1 hover:shadow-lg"
|
||||
<Card.Root
|
||||
class="hover:border-accent-foreground transition-all duration-300 hover:-translate-y-1 hover:shadow-lg"
|
||||
>
|
||||
<div class="mb-4 flex items-start justify-between gap-4">
|
||||
<div class="bg-accent text-accent-foreground inline-flex h-11 w-11 items-center justify-center rounded-md">
|
||||
<feature.icon class="h-5 w-5" />
|
||||
</div>
|
||||
{#if feature.href}
|
||||
<a
|
||||
rel="external"
|
||||
href={getHref(feature.href)}
|
||||
class="text-muted-foreground hover:text-foreground text-xs font-medium no-underline transition-colors"
|
||||
<Card.Header>
|
||||
<div class="mb-2 flex items-start justify-between gap-4">
|
||||
<div
|
||||
class="bg-accent text-accent-foreground inline-flex h-11 w-11 items-center justify-center rounded-md"
|
||||
>
|
||||
Learn more →
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<h3 class="text-foreground mb-2 text-lg font-semibold">{feature.title}</h3>
|
||||
<p class="text-muted-foreground text-sm leading-relaxed">{feature.description}</p>
|
||||
</div>
|
||||
<feature.icon class="h-5 w-5" />
|
||||
</div>
|
||||
{#if feature.href}
|
||||
<Button href={getHref(feature.href)} variant="ghost" size="sm" class="text-xs">Learn more →</Button>
|
||||
{/if}
|
||||
</div>
|
||||
<Card.Title class="text-lg">{feature.title}</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<p class="text-muted-foreground text-sm leading-relaxed">{feature.description}</p>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="mx-auto max-w-[1200px] px-6">
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
<section class="bg-muted/30 px-6 py-20 md:py-24">
|
||||
<div class="mx-auto mb-10 max-w-[1200px]">
|
||||
<h2 class="text-foreground text-center text-3xl font-bold tracking-tight md:text-4xl">
|
||||
@@ -380,28 +394,32 @@
|
||||
|
||||
<div class="mx-auto grid max-w-[1200px] grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-3">
|
||||
{#each advancedFeatures as feature (feature.title)}
|
||||
<div
|
||||
class="bg-background border-border rounded-lg border p-6 shadow-sm transition-all duration-300 hover:shadow-md"
|
||||
>
|
||||
<div class="mb-4 flex items-center justify-between gap-3">
|
||||
<div class="bg-accent text-accent-foreground inline-flex h-10 w-10 items-center justify-center rounded-md">
|
||||
<feature.icon class="h-5 w-5" />
|
||||
</div>
|
||||
{#if feature.tag}
|
||||
<span
|
||||
class="bg-accent text-accent-foreground rounded-full px-2.5 py-1 text-[11px] font-semibold tracking-wide uppercase"
|
||||
<Card.Root class="bg-background shadow-sm transition-all duration-300 hover:shadow-md">
|
||||
<Card.Header>
|
||||
<div class="mb-2 flex items-center justify-between gap-3">
|
||||
<div
|
||||
class="bg-accent text-accent-foreground inline-flex h-10 w-10 items-center justify-center rounded-md"
|
||||
>
|
||||
{feature.tag}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<h3 class="text-foreground mb-2 text-lg font-semibold">{feature.title}</h3>
|
||||
<p class="text-muted-foreground text-sm leading-relaxed">{feature.description}</p>
|
||||
</div>
|
||||
<feature.icon class="h-5 w-5" />
|
||||
</div>
|
||||
{#if feature.tag}
|
||||
<Badge variant="secondary" class="text-[11px] tracking-wide uppercase">{feature.tag}</Badge>
|
||||
{/if}
|
||||
</div>
|
||||
<Card.Title class="text-lg">{feature.title}</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content>
|
||||
<p class="text-muted-foreground text-sm leading-relaxed">{feature.description}</p>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="mx-auto max-w-[1200px] px-6">
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
<section class="bg-background px-6 py-20 md:py-24">
|
||||
<div class="mx-auto mb-10 max-w-[1200px]">
|
||||
<h2 class="text-foreground text-center text-3xl font-bold tracking-tight md:text-4xl">Explore by topic</h2>
|
||||
@@ -412,45 +430,45 @@
|
||||
|
||||
<div class="mx-auto grid max-w-[1200px] grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3">
|
||||
{#each getGroupHighlights() as group (group.group)}
|
||||
<div class="bg-card border-border rounded-lg border p-6">
|
||||
<h3 class="text-foreground mb-3 text-lg font-semibold">{group.group}</h3>
|
||||
<div class="space-y-2">
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title class="text-lg">{group.group}</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-2">
|
||||
{#each group.pages as page (page.slug)}
|
||||
<a
|
||||
<Button
|
||||
href={getHref(`/docs/${page.slug}`)}
|
||||
class="text-muted-foreground hover:text-foreground hover:bg-accent flex items-center justify-between rounded px-2.5 py-2 text-sm no-underline transition-colors"
|
||||
variant="ghost"
|
||||
class="text-muted-foreground hover:text-foreground flex w-full items-center justify-between"
|
||||
>
|
||||
<span>{page.title}</span>
|
||||
<ArrowRight class="h-3.5 w-3.5" />
|
||||
</a>
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/each}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bg-background px-6 pb-6">
|
||||
<div class="mx-auto max-w-[1200px]">
|
||||
<div
|
||||
class="bg-card border-border flex flex-col items-center justify-between gap-4 rounded-xl border px-6 py-6 text-center md:flex-row md:text-left"
|
||||
>
|
||||
<div>
|
||||
<h3 class="text-foreground text-lg font-semibold">Need help or want to contribute?</h3>
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Join the community, browse examples, and help shape Kener's future.
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href="https://github.com/rajnandan1/kener"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="bg-primary text-primary-foreground inline-flex items-center gap-2 rounded px-4 py-2.5 text-sm font-semibold no-underline transition-transform duration-200 hover:-translate-y-0.5"
|
||||
<Card.Root>
|
||||
<Card.Content
|
||||
class="flex flex-col items-center justify-between gap-4 px-6 py-6 text-center md:flex-row md:text-left"
|
||||
>
|
||||
<Github class="h-4 w-4" />
|
||||
Star on GitHub
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-foreground text-lg font-semibold">Need help or want to contribute?</h3>
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Join the community, browse examples, and help shape Kener's future.
|
||||
</p>
|
||||
</div>
|
||||
<Button href="https://github.com/rajnandan1/kener" target="_blank" rel="noopener noreferrer">
|
||||
<Github class="h-4 w-4" />
|
||||
Star on GitHub
|
||||
</Button>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -460,14 +478,16 @@
|
||||
{#if data.config.footerLinks}
|
||||
<div class="flex flex-wrap items-center justify-center gap-4 md:gap-6">
|
||||
{#each data.config.footerLinks as link (link.url)}
|
||||
<a
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-muted-foreground hover:text-foreground text-sm no-underline transition-colors duration-200"
|
||||
class="text-muted-foreground hover:text-foreground h-auto p-0"
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -6,18 +6,32 @@ import { asset } from "$app/paths";
|
||||
const render = ScalarApiReference({
|
||||
url: asset("/api-references/v4.json"),
|
||||
hideModels: true,
|
||||
hideTestRequestButton: true,
|
||||
hideTestRequestButton: false,
|
||||
theme: "kepler",
|
||||
darkMode: true,
|
||||
layout: "modern",
|
||||
persistAuth: true,
|
||||
hideClientButton: true,
|
||||
proxyUrl: "https://proxy.scalar.com",
|
||||
customCss: `
|
||||
section.introduction-section {
|
||||
background-image: url("https://kener.ing/logo96.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left 0px top 20px;
|
||||
background-size: 48px 48px;
|
||||
}
|
||||
`,
|
||||
metaData: {
|
||||
title: "Kener API Reference",
|
||||
description: "Kener free open source status page API Reference",
|
||||
ogDescription: "Kener free open source status page API Reference",
|
||||
ogTitle: "Kener API Reference",
|
||||
ogImage: "https://kener.ing/newbg.png",
|
||||
ogImage: "https://kener.ing/og.jpg",
|
||||
|
||||
twitterCard: "summary_large_image",
|
||||
twitterTitle: "Kener API Reference",
|
||||
twitterDescription: "Kener free open source status page API Reference",
|
||||
twitterImage: "https://kener.ing/newbg.png",
|
||||
twitterImage: "https://kener.ing/og.jpg",
|
||||
},
|
||||
favicon: "https://kener.ing/logo96.png",
|
||||
});
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
import Plus from "@lucide/svelte/icons/plus";
|
||||
import { onMount } from "svelte";
|
||||
import { toast } from "svelte-sonner";
|
||||
import { IsValidURL } from "$lib/clientTools";
|
||||
import { resolve } from "$app/paths";
|
||||
import clientResolver from "$lib/client/resolver.js";
|
||||
import type { DataRetentionPolicy, EventDisplaySettings } from "$lib/types/site.js";
|
||||
@@ -90,12 +89,36 @@
|
||||
});
|
||||
|
||||
let eventDisplaySettings = $state<EventDisplaySettings>(structuredClone(defaultEventDisplaySettings));
|
||||
let currentOrigin = $state("");
|
||||
|
||||
function parseOriginOnlyURL(value: string): URL | null {
|
||||
try {
|
||||
const trimmedValue = value.trim();
|
||||
if (!trimmedValue) return null;
|
||||
|
||||
const url = new URL(trimmedValue);
|
||||
if (!url.hostname || !["http:", "https:"].includes(url.protocol)) return null;
|
||||
if (url.username || url.password) return null;
|
||||
if (url.pathname !== "/" || url.search || url.hash) return null;
|
||||
|
||||
return url;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const parsedSiteOriginURL = $derived(parseOriginOnlyURL(siteData.siteURL));
|
||||
const isOriginOnlySiteURL = $derived(parsedSiteOriginURL !== null);
|
||||
const enteredSiteOrigin = $derived(parsedSiteOriginURL?.origin ?? "");
|
||||
const hasOriginMismatch = $derived(
|
||||
Boolean(currentOrigin && enteredSiteOrigin && currentOrigin !== enteredSiteOrigin)
|
||||
);
|
||||
|
||||
// Validation
|
||||
const isValidSiteInfo = $derived(
|
||||
siteData.siteName.trim().length > 0 &&
|
||||
siteData.siteURL.trim().length > 0 &&
|
||||
IsValidURL(siteData.siteURL) &&
|
||||
isOriginOnlySiteURL &&
|
||||
siteData.home.trim().length > 0
|
||||
);
|
||||
|
||||
@@ -522,6 +545,7 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
currentOrigin = window.location.origin;
|
||||
void fetchSiteData();
|
||||
});
|
||||
</script>
|
||||
@@ -553,7 +577,20 @@
|
||||
<div class="space-y-2">
|
||||
<Label for="siteURL">Site URL *</Label>
|
||||
<Input id="siteURL" type="url" bind:value={siteData.siteURL} placeholder="https://status.example.com" />
|
||||
<p class="text-muted-foreground text-xs">Effective URL: {siteData.siteURL}{clientResolver(resolve, "/")}</p>
|
||||
{#if siteData.siteURL.trim().length > 0 && !isOriginOnlySiteURL}
|
||||
<p class="text-destructive text-xs">
|
||||
Invalid site URL. Please enter only protocol + domain (no path, query, or hash).
|
||||
</p>
|
||||
{/if}
|
||||
{#if siteData.siteURL.trim().length > 0 && isOriginOnlySiteURL && hasOriginMismatch}
|
||||
<p class="text-xs text-amber-600 dark:text-amber-400">
|
||||
Warning: Entered origin ({enteredSiteOrigin}) does not match current origin ({currentOrigin}).
|
||||
</p>
|
||||
{/if}
|
||||
<p class="text-muted-foreground text-xs">
|
||||
Effective URL: {(isOriginOnlySiteURL ? enteredSiteOrigin : siteData.siteURL) +
|
||||
clientResolver(resolve, "/")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://your-kener.com"
|
||||
"url": "{serverUrl}",
|
||||
"variables": {
|
||||
"serverUrl": {
|
||||
"default": "https://your-kener.com",
|
||||
"description": "Base URL for your Kener deployment"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"security": [
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 92 KiB |
Reference in New Issue
Block a user