Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 18.18.0
node-version: 24.4.0
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- run: pnpm biome ci
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CopyMarkdownButton } from "@/components/copy-markdown-button";
import { getPageImage, getLLMText, source } from "@/lib/source";
import { getLLMText, getPageImage, source } from "@/lib/source";
import { getMDXComponents } from "@/mdx-components";
import {
DocsBody,
Expand Down
4 changes: 1 addition & 3 deletions apps/docs/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ const baseUrl = "https://docs.dokploy.com";

export function GET() {
const pages = source.getPages();
const docsPages = pages.filter(
(page) => !page.url.startsWith("/docs/api/"),
);
const docsPages = pages.filter((page) => !page.url.startsWith("/docs/api/"));

const lines = [
"# Dokploy Documentation",
Expand Down
5 changes: 1 addition & 4 deletions apps/docs/content/docs/core/dns-providers/meta.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"title": "DNS Providers",
"pages": [
"cloudflare",
"route53"
]
"pages": ["cloudflare", "route53"]
}
9 changes: 1 addition & 8 deletions apps/docs/content/docs/core/secrets-providers/meta.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
{
"title": "Secrets Providers",
"pages": [
"hashicorp",
"infisical",
"aws",
"doppler",
"azure",
"scaleway"
]
"pages": ["hashicorp", "infisical", "aws", "doppler", "azure", "scaleway"]
}
4 changes: 3 additions & 1 deletion apps/docs/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const config = {
reactStrictMode: true,
output: "standalone",
outputFileTracingIncludes: {
"/**": ["../../node_modules/.pnpm/@swc+helpers@*/node_modules/@swc/helpers/**"],
"/**": [
"../../node_modules/.pnpm/@swc+helpers@*/node_modules/@swc/helpers/**",
],
},
images: {
remotePatterns: [
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/scripts/fix-api-paths.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Converts slash notation (/tag/operation) to dot notation (/tag.operation)
* so they match our OpenAPI schema paths and display the real API path.
*/
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
import { readFileSync, readdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";

const API_DOCS_DIR = join(process.cwd(), "content", "docs", "api");
Expand All @@ -17,7 +17,7 @@ for (const name of readdirSync(API_DOCS_DIR)) {
const newContent = content.replace(/"path":"(\/[^"]+)"/g, (_, path) => {
// Convert /tag/operation or /tag/op/subop to /tag.operation or /tag.op.subop to match schema
if (path.includes("/") && !path.includes(".")) {
const dotPath = "/" + path.slice(1).replace(/\//g, ".");
const dotPath = `/${path.slice(1).replace(/\//g, ".")}`;
totalFixed++;
return `"path":"${dotPath}"`;
}
Expand Down
27 changes: 16 additions & 11 deletions apps/docs/scripts/fix-openapi.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
import { readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";

const openapiPath = join(process.cwd(), "public", "openapi.json");

Expand All @@ -10,7 +10,10 @@ try {

let unwrapped = false;
// If the spec is nested (e.g. result.data.json from a migrated/source API), use the inner spec
if (openapi.result?.data?.json && typeof openapi.result.data.json === "object") {
if (
openapi.result?.data?.json &&
typeof openapi.result.data.json === "object"
) {
openapi = openapi.result.data.json;
unwrapped = true;
console.log("✓ Unwrapped nested OpenAPI spec (result.data.json)");
Expand All @@ -28,8 +31,8 @@ try {
}

// Remove old Authorization scheme
if (openapi.components.securitySchemes["Authorization"]) {
delete openapi.components.securitySchemes["Authorization"];
if (openapi.components.securitySchemes.Authorization) {
openapi.components.securitySchemes.Authorization = undefined;
securityFixed = true;
}

Expand All @@ -45,7 +48,7 @@ try {

// Replace global security from Authorization to x-api-key
if (openapi.security) {
openapi.security = openapi.security.filter((sec) => !sec["Authorization"]);
openapi.security = openapi.security.filter((sec) => !sec.Authorization);
} else {
openapi.security = [];
}
Expand All @@ -59,10 +62,10 @@ try {
// Replace Authorization with x-api-key in all operation security
for (const [path, pathItem] of Object.entries(openapi.paths || {})) {
for (const [method, operation] of Object.entries(pathItem)) {
if (operation && operation.security) {
if (operation?.security) {
// Replace Authorization with x-api-key
operation.security = operation.security.map((sec) => {
if (sec["Authorization"] !== undefined) {
if (sec.Authorization !== undefined) {
securityFixed = true;
return { "x-api-key": [] };
}
Expand All @@ -77,7 +80,7 @@ try {
for (const [method, operation] of Object.entries(pathItem)) {
if (operation.responses) {
for (const [status, response] of Object.entries(operation.responses)) {
if (response.content && response.content["application/json"]) {
if (response.content?.["application/json"]) {
const content = response.content["application/json"];
// Check if schema is completely empty or missing
if (Object.keys(content).length === 0 || !content.schema) {
Expand Down Expand Up @@ -105,7 +108,7 @@ try {
let removed = 0;
for (const pathKey of Object.keys(openapi.paths || {})) {
if (pathKey.includes("/") && !pathKey.includes(".")) {
const dotKey = "/" + pathKey.slice(1).replace(/\//g, ".");
const dotKey = `/${pathKey.slice(1).replace(/\//g, ".")}`;
if (openapi.paths[dotKey]) {
delete openapi.paths[pathKey];
removed++;
Expand All @@ -114,7 +117,9 @@ try {
}
if (removed > 0) {
writeFileSync(openapiPath, JSON.stringify(openapi, null, 2));
console.log(`✓ Removed ${removed} slash path alias(es), keeping dot paths only`);
console.log(
`✓ Removed ${removed} slash path alias(es), keeping dot paths only`,
);
}

if (!(unwrapped || fixed > 0 || securityFixed) && removed === 0) {
Expand Down
6 changes: 2 additions & 4 deletions apps/website/app/api/docker-stats/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ export async function GET() {
{ pull_count: cachedPulls.count },
{
headers: {
"Cache-Control":
"public, s-maxage=1800, stale-while-revalidate=3600",
"Cache-Control": "public, s-maxage=1800, stale-while-revalidate=3600",
},
},
);
Expand Down Expand Up @@ -45,8 +44,7 @@ export async function GET() {
{ pull_count: pullCount },
{
headers: {
"Cache-Control":
"public, s-maxage=1800, stale-while-revalidate=3600",
"Cache-Control": "public, s-maxage=1800, stale-while-revalidate=3600",
},
},
);
Expand Down
10 changes: 3 additions & 7 deletions apps/website/app/api/github-contributors/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export async function GET() {
{ contributors_count: cachedContributors.count },
{
headers: {
"Cache-Control":
"public, s-maxage=1800, stale-while-revalidate=3600",
"Cache-Control": "public, s-maxage=1800, stale-while-revalidate=3600",
},
},
);
Expand Down Expand Up @@ -43,9 +42,7 @@ export async function GET() {

if (linkHeader) {
// Parse last page number from Link header: <...?page=N>; rel="last"
const lastMatch = linkHeader.match(
/[&?]page=(\d+)[^>]*>;\s*rel="last"/,
);
const lastMatch = linkHeader.match(/[&?]page=(\d+)[^>]*>;\s*rel="last"/);
if (lastMatch) {
count = Number.parseInt(lastMatch[1], 10);
}
Expand All @@ -60,8 +57,7 @@ export async function GET() {
{ contributors_count: count },
{
headers: {
"Cache-Control":
"public, s-maxage=1800, stale-while-revalidate=3600",
"Cache-Control": "public, s-maxage=1800, stale-while-revalidate=3600",
},
},
);
Expand Down
4 changes: 2 additions & 2 deletions apps/website/app/api/og/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export async function GET(request: NextRequest) {
label: "Dokploy - Open Source Templates",
});

return new Response(ogImage, {
return new Response(new Uint8Array(ogImage), {
headers: {
"Content-Type": "image/png",
"Cache-Control": "public, max-age=86400, stale-while-revalidate",
Expand Down Expand Up @@ -65,7 +65,7 @@ export async function GET(request: NextRequest) {
readingTime: post.reading_time,
});

return new Response(ogImage, {
return new Response(new Uint8Array(ogImage), {
headers: {
"Content-Type": "image/png",
"Cache-Control": "public, max-age=31536000, immutable",
Expand Down
8 changes: 4 additions & 4 deletions apps/website/app/blog/[slug]/components/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export async function highlight(code: string, lang: BundledLanguage) {
lang,
theme: "houston",
});
return toJsxRuntime(out, {
Fragment: react.Fragment,
jsx: jsxRuntime.jsx,
jsxs: jsxRuntime.jsxs
return toJsxRuntime(out, {
Fragment: react.Fragment,
jsx: jsxRuntime.jsx,
jsxs: jsxRuntime.jsxs,
}) as JSX.Element;
}
31 changes: 15 additions & 16 deletions apps/website/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,20 @@ export default async function BlogPostPage({ params }: Props) {
const scripts = doc.querySelectorAll(
'script[type="application/ld+json"], script',
);
scripts.forEach((script) => script.remove());
for (const script of scripts) script.remove();
const unwantedElements = doc.querySelectorAll("style, meta, link");
unwantedElements.forEach((el) => el.remove());
for (const el of unwantedElements) el.remove();
return doc.body.innerHTML;
} else {
return html
.replace(
/<script[^>]*type="application\/ld\+json"[^>]*>[\s\S]*?<\/script>/gi,
"",
)
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
.replace(/<meta[^>]*>/gi, "")
.replace(/<link[^>]*>/gi, "");
}
return html
.replace(
/<script[^>]*type="application\/ld\+json"[^>]*>[\s\S]*?<\/script>/gi,
"",
)
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
.replace(/<meta[^>]*>/gi, "")
.replace(/<link[^>]*>/gi, "");
};

const turndownService = new TurndownService({
Expand Down Expand Up @@ -189,7 +188,7 @@ export default async function BlogPostPage({ params }: Props) {
),
img: ({ node, src, alt }) => (
<ZoomableImage
src={src || ""}
src={typeof src === "string" ? src : ""}
alt={alt || ""}
className="mx-auto max-w-lg overflow-hidden rounded-lg border border-border object-cover max-lg:w-64"
/>
Expand All @@ -199,9 +198,9 @@ export default async function BlogPostPage({ params }: Props) {
children,
inline,
}: {
className: string;
children: React.ReactNode;
inline: boolean;
className?: string;
children?: React.ReactNode;
inline?: boolean;
}) => {
if (inline || !className || !/language-(\w+)/.test(className)) {
return (
Expand Down
8 changes: 4 additions & 4 deletions apps/website/app/comparison/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Container } from "@/components/Container";
import { CallToAction } from "@/components/CallToAction";
import { Container } from "@/components/Container";
import { Testimonials } from "@/components/Testimonials";
import AnimatedGridPattern from "@/components/ui/animated-grid-pattern";
import { Button } from "@/components/ui/button";
import { ArrowRight, GitBranch, Activity, Users, Gauge } from "lucide-react";
import Link from "next/link";
import { Activity, ArrowRight, Gauge, GitBranch, Users } from "lucide-react";
import type { Metadata } from "next";
import Link from "next/link";

export const metadata: Metadata = {
title: "Dokploy Vs. and PaaS Comparison Pages | Dokploy",
description:
"How does Dokploy compare to other application deployment, database management, and PaaS solutions? Learn on our \"Dokploy vs.\" alternative comparison pages.",
'How does Dokploy compare to other application deployment, database management, and PaaS solutions? Learn on our "Dokploy vs." alternative comparison pages.',
};

const competitors = [
Expand Down
2 changes: 1 addition & 1 deletion apps/website/app/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { Container } from "@/components/Container";
import { ContactForm } from "@/components/ContactForm";
import { Container } from "@/components/Container";
import AnimatedGridPattern from "@/components/ui/animated-grid-pattern";
import { cn } from "@/lib/utils";
import { useState } from "react";
Expand Down
18 changes: 11 additions & 7 deletions apps/website/app/deploy-ai/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import { Container } from "@/components/Container";
import AnimatedGridPattern from "@/components/ui/animated-grid-pattern";
import { Button } from "@/components/ui/button";
import {
Activity,
Bot,
Boxes,
Activity,
Users,
FlaskConical,
KeyRound,
MousePointerClick,
Network,
KeyRound,
ShieldCheck,
FlaskConical,
Rocket,
ShieldCheck,
Sparkles,
Users,
} from "lucide-react";
import Link from "next/link";
import type { Metadata } from "next";
import Link from "next/link";

export const metadata: Metadata = {
title: "Deploy AI Apps Securely with Dokploy",
Expand Down Expand Up @@ -133,7 +133,11 @@ export default function DeployAIPage() {
className="rounded-full bg-[#5965F2] hover:bg-[#4A55E0]"
asChild
>
<Link href="/contact" aria-label="Contact Us" className="text-white">
<Link
href="/contact"
aria-label="Contact Us"
className="text-white"
>
Contact Us
</Link>
</Button>
Expand Down
Loading
Loading