fix assets transform in prod
@@ -23,6 +23,7 @@
|
||||
"@sveltejs/adapter-static": "^2.0.3",
|
||||
"@sveltejs/kit": "^1.24.1",
|
||||
"@types/compression": "^1.7.3",
|
||||
"@types/glob": "^8.1.0",
|
||||
"@types/markdown-it": "^13.0.1",
|
||||
"@types/morgan": "^1.9.6",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
@@ -30,6 +31,7 @@
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-svelte": "^2.33.1",
|
||||
"glob": "^10.3.10",
|
||||
"openapi-types": "^12.1.3",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.1",
|
||||
|
||||
35
pnpm-lock.yaml
generated
@@ -13,7 +13,7 @@ dependencies:
|
||||
version: 0.1.0-next.9
|
||||
'@appwrite.io/repo':
|
||||
specifier: github:appwrite/appwrite
|
||||
version: github.com/appwrite/appwrite/8a4302ffe6173e6b1256da5e7c86042d73983cdb
|
||||
version: github.com/appwrite/appwrite/030f9629a69f7db0f3da3e76d1805383bb3a3acd
|
||||
'@splinetool/viewer':
|
||||
specifier: 0.9.455
|
||||
version: 0.9.455
|
||||
@@ -61,6 +61,9 @@ devDependencies:
|
||||
'@types/compression':
|
||||
specifier: ^1.7.3
|
||||
version: 1.7.3
|
||||
'@types/glob':
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0
|
||||
'@types/markdown-it':
|
||||
specifier: ^13.0.1
|
||||
version: 13.0.1
|
||||
@@ -82,6 +85,9 @@ devDependencies:
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^2.33.1
|
||||
version: 2.33.2(eslint@8.49.0)(svelte@4.2.0)
|
||||
glob:
|
||||
specifier: ^10.3.10
|
||||
version: 10.3.10
|
||||
openapi-types:
|
||||
specifier: ^12.1.3
|
||||
version: 12.1.3
|
||||
@@ -876,6 +882,13 @@ packages:
|
||||
'@types/node': 20.5.0
|
||||
dev: true
|
||||
|
||||
/@types/glob@8.1.0:
|
||||
resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==}
|
||||
dependencies:
|
||||
'@types/minimatch': 5.1.2
|
||||
'@types/node': 20.5.0
|
||||
dev: true
|
||||
|
||||
/@types/http-errors@2.0.2:
|
||||
resolution: {integrity: sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==}
|
||||
dev: true
|
||||
@@ -922,6 +935,10 @@ packages:
|
||||
resolution: {integrity: sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ==}
|
||||
dev: true
|
||||
|
||||
/@types/minimatch@5.1.2:
|
||||
resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
|
||||
dev: true
|
||||
|
||||
/@types/morgan@1.9.6:
|
||||
resolution: {integrity: sha512-xfKogz5WcKww2DAiVT9zxMgrqQt+Shq8tDVeLT+otoj6dJnkRkyJxMF51mHtUc3JCPKGk5x1EBU0buuGpfftlQ==}
|
||||
dependencies:
|
||||
@@ -1525,7 +1542,7 @@ packages:
|
||||
dependencies:
|
||||
'@npmcli/fs': 3.1.0
|
||||
fs-minipass: 3.0.3
|
||||
glob: 10.3.4
|
||||
glob: 10.3.10
|
||||
lru-cache: 7.18.3
|
||||
minipass: 7.0.3
|
||||
minipass-collect: 1.0.2
|
||||
@@ -2649,13 +2666,13 @@ packages:
|
||||
is-glob: 4.0.3
|
||||
dev: true
|
||||
|
||||
/glob@10.3.4:
|
||||
resolution: {integrity: sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==}
|
||||
/glob@10.3.10:
|
||||
resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
foreground-child: 3.1.1
|
||||
jackspeak: 2.3.1
|
||||
jackspeak: 2.3.6
|
||||
minimatch: 9.0.3
|
||||
minipass: 7.0.3
|
||||
path-scurry: 1.10.1
|
||||
@@ -3105,8 +3122,8 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/jackspeak@2.3.1:
|
||||
resolution: {integrity: sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==}
|
||||
/jackspeak@2.3.6:
|
||||
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
@@ -5553,8 +5570,8 @@ packages:
|
||||
engines: {node: '>=12.20'}
|
||||
dev: true
|
||||
|
||||
github.com/appwrite/appwrite/8a4302ffe6173e6b1256da5e7c86042d73983cdb:
|
||||
resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/8a4302ffe6173e6b1256da5e7c86042d73983cdb}
|
||||
github.com/appwrite/appwrite/030f9629a69f7db0f3da3e76d1805383bb3a3acd:
|
||||
resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/030f9629a69f7db0f3da3e76d1805383bb3a3acd}
|
||||
name: '@appwrite.io/repo'
|
||||
version: 0.0.0
|
||||
dev: false
|
||||
|
||||
37
scripts/transform-images.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { existsSync } from 'fs';
|
||||
import { globSync } from 'glob';
|
||||
import path from 'path';
|
||||
import sharp from 'sharp';
|
||||
|
||||
console.log('Transforming images...');
|
||||
|
||||
const inputFormats = ['png', 'jpg', 'svg'];
|
||||
const outputFormats = ['png', 'jpg'];
|
||||
const files = globSync(`./static/assets/**/*.{${inputFormats.join(',')}}`);
|
||||
|
||||
console.log('Found files:', files);
|
||||
|
||||
files.forEach((file) => {
|
||||
const fileName = path.basename(file, path.extname(file));
|
||||
const fileDir = path.dirname(file);
|
||||
|
||||
console.log('Transforming file:', file);
|
||||
|
||||
outputFormats.forEach((format) => {
|
||||
const outputFile = path.join(fileDir, `${fileName}.${format}`);
|
||||
|
||||
if (!existsSync(outputFile)) {
|
||||
sharp(file)
|
||||
.toFormat(format)
|
||||
.toFile(outputFile, (err) => {
|
||||
if (err) {
|
||||
console.error(`Error transforming file ${file} to ${format}:`, err);
|
||||
} else {
|
||||
console.log(`Transformed file ${file} to ${format}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(`File ${outputFile} already exists. Skipping transformation.`);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const formats = ['webp', 'jpeg', 'png', 'tiff', 'avif'] as const;
|
||||
|
||||
const filenameMap: Record<ImageFormat, string> = {
|
||||
webp: 'webp',
|
||||
jpeg: 'jpg',
|
||||
png: 'png',
|
||||
tiff: 'tiff',
|
||||
avif: 'avif'
|
||||
};
|
||||
|
||||
const getFilename = (imgUrl: string, format: ImageFormat) => {
|
||||
const filename = imgUrl.split('/').pop() ?? '';
|
||||
const ext = filename.split('.').pop() ?? '';
|
||||
if (ext === filenameMap[format]) return filename;
|
||||
return filename.replace(ext, filenameMap[format]);
|
||||
};
|
||||
|
||||
export type ImageFormat = (typeof formats)[number];
|
||||
|
||||
const isFormat = (format: unknown): format is ImageFormat => {
|
||||
return typeof format === 'string' && formats.includes(format as ImageFormat);
|
||||
};
|
||||
|
||||
export const GET = async ({ fetch, url }) => {
|
||||
const img = url.searchParams.get('img');
|
||||
const format = url.searchParams.get('format') || 'webp';
|
||||
if (!img) throw error(400, 'Missing image parameter');
|
||||
if (!isFormat(format)) throw error(400, 'Invalid format parameter');
|
||||
|
||||
try {
|
||||
const fetchedImg = await fetch(img);
|
||||
const imgBuffer = await fetchedImg.arrayBuffer();
|
||||
return new Response(await sharp(imgBuffer).toFormat(format).toBuffer(), {
|
||||
headers: {
|
||||
'Content-Type': `image/${format}`,
|
||||
'Content-Disposition': `attachment; filename="${getFilename(img, format)}"`
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
throw error(400, 'Invalid image URL');
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
import { visible } from '$lib/actions';
|
||||
import { Main } from '$lib/layouts';
|
||||
import { copy } from '$lib/utils/copy';
|
||||
import { getImageUrl } from '$lib/utils/image';
|
||||
|
||||
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
|
||||
import { TITLE_SUFFIX } from '$routes/titles';
|
||||
import FooterNav from '../../lib/components/FooterNav.svelte';
|
||||
@@ -178,7 +178,7 @@
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl('/assets/logotype/white.svg', 'png')}
|
||||
href="/assets/logotype/white.png"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
@@ -206,7 +206,7 @@
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl('/assets/logotype/black.svg', 'png')}
|
||||
href="/assets/logotype/black.png"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
@@ -275,7 +275,7 @@
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl('/assets/logomark/logo.svg', 'png')}
|
||||
href="/assets/logomark/logo.png"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
@@ -303,7 +303,7 @@
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl('/assets/logomark/logo.svg', 'png')}
|
||||
href="/assets/logomark/logo.png"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
@@ -429,14 +429,11 @@
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl(
|
||||
'/assets/visuals/dashboard.png',
|
||||
'jpeg'
|
||||
)}
|
||||
href="/assets/visuals/dashboard.jpg"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
<span>JPEG</span>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
@@ -457,11 +454,11 @@
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl('/assets/visuals/auth.png', 'jpeg')}
|
||||
href="/assets/visuals/auth.jpg"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
<span>JPEG</span>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
@@ -482,14 +479,11 @@
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl(
|
||||
'/assets/visuals/databases.png',
|
||||
'jpeg'
|
||||
)}
|
||||
href="/assets/visuals/databases.jpg"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
<span>JPEG</span>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
@@ -511,14 +505,11 @@
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl(
|
||||
'/assets/visuals/storage.png',
|
||||
'jpeg'
|
||||
)}
|
||||
href="/assets/visuals/storage.jpg"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
<span>JPEG</span>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
@@ -540,14 +531,11 @@
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
href={getImageUrl(
|
||||
'/assets/visuals/functions.png',
|
||||
'jpeg'
|
||||
)}
|
||||
href="/assets/visuals/functions.jpg"
|
||||
download
|
||||
>
|
||||
<span class="aw-icon-download" aria-label="download" />
|
||||
<span>JPEG</span>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="aw-button is-secondary"
|
||||
|
||||
BIN
static/assets/logomark/co-brand.jpg
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
static/assets/logomark/co-brand.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
static/assets/logomark/logo.jpg
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
static/assets/logomark/logo.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
static/assets/logotype/black.jpg
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
static/assets/logotype/black.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
static/assets/logotype/co-brand.jpg
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
static/assets/logotype/co-brand.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
static/assets/logotype/white.jpg
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/assets/logotype/white.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
static/assets/visuals/auth.jpg
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
static/assets/visuals/dashboard.jpg
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
static/assets/visuals/databases.jpg
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
static/assets/visuals/functions.jpg
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
static/assets/visuals/storage.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |