chore: deploy to Cloudflare Pages and update branding

- Add Cloudflare Pages deployment for landing page (snapotter.com) and
  docs (docs.snapotter.com)
- Create deploy-landing.yml and update deploy-docs.yml workflows
- Update CI to ignore apps/landing/** paths
- Fix logo transparency (remove white background) across all apps
- Recreate social-preview.png with SnapOtter branding
- Update all docs URLs from GitHub Pages to docs.snapotter.com
- Update VitePress config: light theme default, fix llms.txt paths
- Add .vitepress/cache/ and .env.* to gitignore
This commit is contained in:
SnapOtter
2026-04-24 18:06:29 +08:00
parent fbaa603d03
commit 0309e0f680
174 changed files with 970 additions and 926 deletions
+1 -1
View File
@@ -5,6 +5,6 @@ export default defineConfig({
out: "./drizzle",
dialect: "sqlite",
dbCredentials: {
url: process.env.DB_PATH || "./data/ashim.db",
url: process.env.DB_PATH || "./data/snapotter.db",
},
});
+4 -4
View File
@@ -1,5 +1,5 @@
{
"name": "@ashim/api",
"name": "@snapotter/api",
"version": "1.15.9",
"private": true,
"type": "module",
@@ -12,9 +12,9 @@
"clean": "rm -rf dist"
},
"dependencies": {
"@ashim/ai": "workspace:*",
"@ashim/image-engine": "workspace:*",
"@ashim/shared": "workspace:*",
"@snapotter/ai": "workspace:*",
"@snapotter/image-engine": "workspace:*",
"@snapotter/shared": "workspace:*",
"@fastify/cors": "^11.0.0",
"@fastify/multipart": "^9.0.0",
"@fastify/rate-limit": "^10.2.0",
+4 -4
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { isGpuAvailable } from "@ashim/ai";
import { APP_VERSION } from "@ashim/shared";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
import { isGpuAvailable } from "@snapotter/ai";
import { APP_VERSION } from "@snapotter/shared";
import { eq } from "drizzle-orm";
import Fastify from "fastify";
import { env } from "./config.js";
@@ -230,7 +230,7 @@ try {
const gpu = isGpuAvailable();
console.log(
[
`ashim v${APP_VERSION} running on port ${env.PORT}`,
`SnapOtter v${APP_VERSION} running on port ${env.PORT}`,
gpu
? "[INFO] GPU detected — AI tools will use CUDA acceleration"
: "[WARN] No GPU detected — AI tools will use CPU (slower)",
@@ -275,7 +275,7 @@ async function shutdown(signal: string) {
}
try {
const { shutdownDispatcher } = await import("@ashim/ai");
const { shutdownDispatcher } = await import("@snapotter/ai");
shutdownDispatcher();
console.log("Python dispatcher shut down");
} catch {
+2 -2
View File
@@ -21,12 +21,12 @@ const envSchema = z.object({
CONCURRENT_JOBS: z.coerce.number().default(0),
MAX_MEGAPIXELS: z.coerce.number().default(0),
RATE_LIMIT_PER_MIN: z.coerce.number().default(0),
DB_PATH: z.string().default("./data/ashim.db"),
DB_PATH: z.string().default("./data/snapotter.db"),
FILES_STORAGE_PATH: z.string().default("./data/files"),
WORKSPACE_PATH: z.string().default("./tmp/workspace"),
DEFAULT_THEME: z.enum(["light", "dark"]).default("light"),
DEFAULT_LOCALE: z.string().default("en"),
APP_NAME: z.string().default("ashim"),
APP_NAME: z.string().default("snapotter"),
CORS_ORIGIN: z.string().default(""),
MAX_USERS: z.coerce.number().default(0),
LOG_LEVEL: z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info"),
+2 -2
View File
@@ -10,8 +10,8 @@ import {
writeFileSync,
} from "node:fs";
import { join } from "node:path";
import type { FeatureBundleState, FeatureStatus } from "@ashim/shared";
import { FEATURE_BUNDLES, TOOL_BUNDLE_MAP } from "@ashim/shared";
import type { FeatureBundleState, FeatureStatus } from "@snapotter/shared";
import { FEATURE_BUNDLES, TOOL_BUNDLE_MAP } from "@snapotter/shared";
// ── Paths ───────────────────────────────────────────────────────────────
+3 -3
View File
@@ -1,9 +1,9 @@
openapi: 3.1.0
info:
title: ashim API
title: SnapOtter API
version: 1.15.9
description: |
REST API for ashim, a self-hosted image processing platform with 30+ tools.
REST API for SnapOtter, a self-hosted image processing platform with 30+ tools.
## Authentication
@@ -16,7 +16,7 @@ info:
Endpoints marked with a lock icon require authentication. Admin-only endpoints are noted in their description.
license:
name: AGPL-3.0
url: https://github.com/ashim-hq/ashim/blob/main/LICENSE
url: https://github.com/snapotter-hq/snapotter/blob/main/LICENSE
servers:
- url: /
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Permission, Role } from "@ashim/shared";
import type { Permission, Role } from "@snapotter/shared";
import { eq } from "drizzle-orm";
import type { FastifyReply, FastifyRequest } from "fastify";
import { db, schema } from "./db/index.js";
+1 -1
View File
@@ -9,7 +9,7 @@
*/
import { randomUUID } from "node:crypto";
import { extname } from "node:path";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import archiver from "archiver";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import PQueue from "p-queue";
+2 -2
View File
@@ -11,8 +11,8 @@ import { spawn } from "node:child_process";
import crypto from "node:crypto";
import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from "node:fs";
import { join } from "node:path";
import { shutdownDispatcher } from "@ashim/ai";
import { ANALYTICS_EVENTS, FEATURE_BUNDLES } from "@ashim/shared";
import { shutdownDispatcher } from "@snapotter/ai";
import { ANALYTICS_EVENTS, FEATURE_BUNDLES } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { trackEvent } from "../lib/analytics.js";
import {
+1 -1
View File
@@ -9,7 +9,7 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { ANALYTICS_EVENTS, getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { ANALYTICS_EVENTS, getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import archiver from "archiver";
import { eq } from "drizzle-orm";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
+1 -1
View File
@@ -1,5 +1,5 @@
import { randomUUID } from "node:crypto";
import type { Permission } from "@ashim/shared";
import type { Permission } from "@snapotter/shared";
import { eq, sql } from "drizzle-orm";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
+1 -1
View File
@@ -1,7 +1,7 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { extname, join } from "node:path";
import { ANALYTICS_EVENTS, getBundleForTool, TOOL_BUNDLE_MAP, TOOLS } from "@ashim/shared";
import { ANALYTICS_EVENTS, getBundleForTool, TOOL_BUNDLE_MAP, TOOLS } from "@snapotter/shared";
import { eq } from "drizzle-orm";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { blurFaces } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { blurFaces } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
@@ -6,7 +6,7 @@ import {
grayscale,
invert,
sepia,
} from "@ashim/image-engine";
} from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { colorize } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { colorize } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,4 +1,4 @@
import { compress } from "@ashim/image-engine";
import { compress } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
@@ -1,7 +1,7 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { seamCarve } from "@ashim/ai";
import { seamCarve } from "@snapotter/ai";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
+1 -1
View File
@@ -1,5 +1,5 @@
import { extname } from "node:path";
import { convert } from "@ashim/image-engine";
import { convert } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,4 +1,4 @@
import { crop } from "@ashim/image-engine";
import { crop } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { enhanceFaces } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { enhanceFaces } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { inpaint } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { inpaint } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
@@ -1,4 +1,4 @@
import { analyzeImage, applyCorrections } from "@ashim/image-engine";
import { analyzeImage, applyCorrections } from "@snapotter/image-engine";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,4 +1,4 @@
import { TOOLS } from "@ashim/shared";
import { TOOLS } from "@snapotter/shared";
import { eq } from "drizzle-orm";
import type { FastifyInstance } from "fastify";
import { db, schema } from "../../db/index.js";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { noiseRemoval } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { noiseRemoval } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
+2 -2
View File
@@ -1,7 +1,7 @@
import { randomUUID } from "node:crypto";
import { basename } from "node:path";
import { extractText } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { extractText } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { formatZodErrors } from "../../lib/errors.js";
@@ -1,5 +1,5 @@
import { extname } from "node:path";
import { optimizeForWeb } from "@ashim/image-engine";
import { optimizeForWeb } from "@snapotter/image-engine";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+7 -2
View File
@@ -1,8 +1,13 @@
import { randomUUID } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { detectFaceLandmarks, removeBackground } from "@ashim/ai";
import { getBundleForTool, PASSPORT_SPECS, PRINT_LAYOUTS, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { detectFaceLandmarks, removeBackground } from "@snapotter/ai";
import {
getBundleForTool,
PASSPORT_SPECS,
PRINT_LAYOUTS,
TOOL_BUNDLE_MAP,
} from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { removeRedEye } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { removeRedEye } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { removeBackground } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { removeBackground } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { resize } from "@ashim/image-engine";
import { resize } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { restorePhoto } from "@ashim/ai";
import { getBundleForTool } from "@ashim/shared";
import { restorePhoto } from "@snapotter/ai";
import { getBundleForTool } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,4 +1,4 @@
import { flip, rotate } from "@ashim/image-engine";
import { flip, rotate } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,4 +1,4 @@
import { sharpenAdvanced } from "@ashim/image-engine";
import { sharpenAdvanced } from "@snapotter/image-engine";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,5 +1,5 @@
import { detectFaces } from "@ashim/ai";
import { SMART_CROP_FACE_PRESETS } from "@ashim/shared";
import { detectFaces } from "@snapotter/ai";
import { SMART_CROP_FACE_PRESETS } from "@snapotter/shared";
import type { FastifyInstance } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+1 -1
View File
@@ -1,5 +1,5 @@
import { basename } from "node:path";
import { parseExif, parseGps, parseXmp, stripMetadata } from "@ashim/image-engine";
import { parseExif, parseGps, parseXmp, stripMetadata } from "@snapotter/image-engine";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";
+2 -2
View File
@@ -1,8 +1,8 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
import { basename, join } from "node:path";
import { upscale } from "@ashim/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@ashim/shared";
import { upscale } from "@snapotter/ai";
import { getBundleForTool, TOOL_BUNDLE_MAP } from "@snapotter/shared";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { z } from "zod";