Basic Docs and publish.yml changes for pnpm v

This commit is contained in:
Shivam Meena
2023-06-10 19:23:58 +05:30
parent 34c0233058
commit 8b2d6652dd
18 changed files with 250 additions and 274 deletions

View File

@@ -16,7 +16,7 @@ jobs:
name: Install pnpm name: Install pnpm
id: pnpm-install id: pnpm-install
with: with:
version: 7 version: 8.6.1
- run: pnpm install - run: pnpm install
- run: pnpm build - run: pnpm build
#- run: pnpm test #- run: pnpm test

View File

@@ -7,8 +7,9 @@ Dynamically generate Open Graph images from an HTML+CSS template or Svelte compo
```bash ```bash
pnpm install -D @ethercorps/sveltekit-og pnpm install -D @ethercorps/sveltekit-og
``` ```
> Using with Cloudflare Pages or Workers then you have to provide `url` polyfill by just installing it as `devDependency`. > Using with Cloudflare Pages or Workers then you have to provide `url` polyfill by just installing it as `devDependency`.
>
```bash ```bash
pnpm i -D url pnpm i -D url
``` ```
@@ -45,21 +46,21 @@ const fontFile = await fetch('https://og-playground.vercel.app/inter-latin-ext-4
const fontData: ArrayBuffer = await fontFile.arrayBuffer(); const fontData: ArrayBuffer = await fontFile.arrayBuffer();
export const GET: RequestHandler = async () => { export const GET: RequestHandler = async () => {
return await ImageResponse(template, { return await ImageResponse(template, {
height: 630, height: 630,
width: 1200, width: 1200,
fonts: [ fonts: [
{ {
name: 'Inter Latin', name: 'Inter Latin',
data: fontData, data: fontData,
weight: 400 weight: 400
} }
] ]
}); });
}; };
``` ```
Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes. Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes.
## Example Output ## Example Output
@@ -69,10 +70,9 @@ Then run `npm dev` and visit `localhost:5173/og` to view your generated PNG. Rem
When run in development, image headers contain `cache-control: no-cache, no-store`. In production, image headers contain `'cache-control': 'public, immutable, no-transform, max-age=31536000'`, which caches the image for 1 year. In both cases, the `'content-type': 'image/png'` is used. When run in development, image headers contain `cache-control: no-cache, no-store`. In production, image headers contain `'cache-control': 'public, immutable, no-transform, max-age=31536000'`, which caches the image for 1 year. In both cases, the `'content-type': 'image/png'` is used.
## Styling ## Styling
Notice that our example uses TailwindCSS classes (e.g. `tw="bg-gray-50"`). Alternatively, your HTML can contain style attributes using any of [the subset of CSS supported by Satori](https://github.com/vercel/satori#css). Notice that our example uses TailwindCSS classes (e.g. `tw="bg-gray-50"`). Alternatively, your HTML can contain style attributes using any of [the subset of CSS supported by Satori](https://github.com/vercel/satori#css).
Satori supports only a subset of HTML and CSS. For full details, see [Satoris documentation](https://github.com/vercel/satori#documentation). Notably, Satori only supports flex-based layouts. Satori supports only a subset of HTML and CSS. For full details, see [Satoris documentation](https://github.com/vercel/satori#documentation). Notably, Satori only supports flex-based layouts.
@@ -80,7 +80,7 @@ Satori supports only a subset of HTML and CSS. For full details, see [Satoris
Satori supports `ttf`, `otf`, and `woff` font formats; `woff2` is not supported. To maximize the font parsing speed, `ttf` or `otf` are recommended over `woff`. Satori supports `ttf`, `otf`, and `woff` font formats; `woff2` is not supported. To maximize the font parsing speed, `ttf` or `otf` are recommended over `woff`.
By default, `@ethercorps/sveltekit-og` includes only 'Noto Sans' font. If you need to use other fonts, you can specify them as shown in the example. Notably, you can also import a font file that is stored locally within your project and are not required to use fetch. By default, `@ethercorps/sveltekit-og` includes only 'Noto Sans' font. If you need to use other fonts, you can specify them as shown in the example. Notably, you can also import a font file that is stored locally within your project and are not required to use fetch.
## Examples ## Examples
@@ -101,7 +101,7 @@ ImageResponse(
options : { options : {
width ? : number = 1200 width ? : number = 1200
height ? : number = 630, height ? : number = 630,
backgroundColor ? : string = "#fff" backgroundColor ? : string = "#fff"
fonts ? : { fonts ? : {
name: string, name: string,
data: ArrayBuffer, data: ArrayBuffer,
@@ -142,6 +142,7 @@ componentToImageResponse(
## Changelog ## Changelog
### v1.2.3 Update (Breaking Changes) ### v1.2.3 Update (Breaking Changes)
> Now you have to install dependency by yourself which will make it easier to build for all plateforms. > Now you have to install dependency by yourself which will make it easier to build for all plateforms.
``` ```

View File

@@ -23,7 +23,7 @@
"svelte": "^3.59.1", "svelte": "^3.59.1",
"vite": "^4.3.9", "vite": "^4.3.9",
"url": "^0.11.0", "url": "^0.11.0",
"//":"url package is required to work on cloudflare workers and pages." "//": "url package is required to work on cloudflare workers and pages."
}, },
"type": "module" "type": "module"
} }

View File

@@ -24,7 +24,7 @@
"svelte": "^3.59.1", "svelte": "^3.59.1",
"vite": "^4.3.9", "vite": "^4.3.9",
"url": "^0.11.0", "url": "^0.11.0",
"//":"url package is required to work on cloudflare workers and pages." "//": "url package is required to work on cloudflare workers and pages."
}, },
"type": "module" "type": "module"
} }

View File

@@ -10,6 +10,6 @@
<div>%sveltekit.body%</div> <div>%sveltekit.body%</div>
</body> </body>
<script> <script>
var global = global || window var global = global || window;
</script> </script>
</html> </html>

View File

@@ -15,7 +15,7 @@
"format": "prettier --plugin-search-dir . --write ." "format": "prettier --plugin-search-dir . --write ."
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.34.3", "@playwright/test": "^1.35.0",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/adapter-vercel": "^2.4.3", "@sveltejs/adapter-vercel": "^2.4.3",
"@sveltejs/kit": "1.10.0", "@sveltejs/kit": "1.10.0",
@@ -30,6 +30,7 @@
"postcss": "^8.4.24", "postcss": "^8.4.24",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.1", "prettier-plugin-svelte": "^2.10.1",
"prism-svelte": "^0.5.0",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"svelte": "^3.59.1", "svelte": "^3.59.1",
"svelte-check": "^2.10.3", "svelte-check": "^2.10.3",

57
pnpm-lock.yaml generated
View File

@@ -14,8 +14,8 @@ dependencies:
devDependencies: devDependencies:
'@playwright/test': '@playwright/test':
specifier: ^1.34.3 specifier: ^1.35.0
version: 1.34.3 version: 1.35.0
'@sveltejs/adapter-auto': '@sveltejs/adapter-auto':
specifier: next specifier: next
version: 1.0.0-next.91(@sveltejs/kit@1.10.0) version: 1.0.0-next.91(@sveltejs/kit@1.10.0)
@@ -58,6 +58,9 @@ devDependencies:
prettier-plugin-svelte: prettier-plugin-svelte:
specifier: ^2.10.1 specifier: ^2.10.1
version: 2.10.1(prettier@2.8.8)(svelte@3.59.1) version: 2.10.1(prettier@2.8.8)(svelte@3.59.1)
prism-svelte:
specifier: ^0.5.0
version: 0.5.0
prismjs: prismjs:
specifier: ^1.29.0 specifier: ^1.29.0
version: 1.29.0 version: 1.29.0
@@ -418,13 +421,13 @@ packages:
fastq: 1.15.0 fastq: 1.15.0
dev: true dev: true
/@playwright/test@1.34.3: /@playwright/test@1.35.0:
resolution: {integrity: sha512-zPLef6w9P6T/iT6XDYG3mvGOqOyb6eHaV9XtkunYs0+OzxBtrPAAaHotc0X+PJ00WPPnLfFBTl7mf45Mn8DBmw==} resolution: {integrity: sha512-6qXdd5edCBynOwsz1YcNfgX8tNWeuS9fxy5o59D0rvHXxRtjXRebB4gE4vFVfEMXl/z8zTnAzfOs7aQDEs8G4Q==}
engines: {node: '>=14'} engines: {node: '>=16'}
hasBin: true hasBin: true
dependencies: dependencies:
'@types/node': 20.2.5 '@types/node': 20.2.6
playwright-core: 1.34.3 playwright-core: 1.35.0
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
@@ -560,8 +563,8 @@ packages:
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
dev: true dev: true
/@types/node@20.2.5: /@types/node@20.2.6:
resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==} resolution: {integrity: sha512-GQBWUtGoefMEOx/vu+emHEHU5aw6JdDoEtZhoBrHFPZbA/YNRFfN996XbBASEWdvmLSLyv9FKYppYGyZjCaq/g==}
dev: true dev: true
/@types/pug@2.0.6: /@types/pug@2.0.6:
@@ -572,7 +575,7 @@ packages:
resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==} resolution: {integrity: sha512-jn7qwGFmJHwUSphV8zZneO3GmtlgLsmhs/LQyVvQbIIa+fzGMUiHI4HXJZL3FT8MJmgXWbLGiVVY7ElvHq6vDA==}
deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed. deprecated: This is a stub types definition. sass provides its own type definitions, so you do not need this installed.
dependencies: dependencies:
sass: 1.62.1 sass: 1.63.3
dev: true dev: true
/@types/semver@7.5.0: /@types/semver@7.5.0:
@@ -827,7 +830,7 @@ packages:
postcss: ^8.1.0 postcss: ^8.1.0
dependencies: dependencies:
browserslist: 4.21.7 browserslist: 4.21.7
caniuse-lite: 1.0.30001495 caniuse-lite: 1.0.30001498
fraction.js: 4.2.0 fraction.js: 4.2.0
normalize-range: 0.1.2 normalize-range: 0.1.2
picocolors: 1.0.0 picocolors: 1.0.0
@@ -878,8 +881,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true hasBin: true
dependencies: dependencies:
caniuse-lite: 1.0.30001495 caniuse-lite: 1.0.30001498
electron-to-chromium: 1.4.423 electron-to-chromium: 1.4.427
node-releases: 2.0.12 node-releases: 2.0.12
update-browserslist-db: 1.0.11(browserslist@4.21.7) update-browserslist-db: 1.0.11(browserslist@4.21.7)
dev: true dev: true
@@ -909,8 +912,8 @@ packages:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
dev: false dev: false
/caniuse-lite@1.0.30001495: /caniuse-lite@1.0.30001498:
resolution: {integrity: sha512-F6x5IEuigtUfU5ZMQK2jsy5JqUUlEFRVZq8bO2a+ysq5K7jD6PPc9YXZj78xDNS3uNchesp1Jw47YXEqr+Viyg==} resolution: {integrity: sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw==}
dev: true dev: true
/chalk@4.1.2: /chalk@4.1.2:
@@ -1075,8 +1078,8 @@ packages:
esutils: 2.0.3 esutils: 2.0.3
dev: true dev: true
/electron-to-chromium@1.4.423: /electron-to-chromium@1.4.427:
resolution: {integrity: sha512-y4A7YfQcDGPAeSWM1IuoWzXpg9RY1nwHzHSwRtCSQFp9FgAVDgdWlFf0RbdWfLWQ2WUI+bddUgk5RgTjqRE6FQ==} resolution: {integrity: sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==}
dev: true dev: true
/emoji-regex@10.2.1: /emoji-regex@10.2.1:
@@ -1930,9 +1933,9 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true dev: true
/playwright-core@1.34.3: /playwright-core@1.35.0:
resolution: {integrity: sha512-2pWd6G7OHKemc5x1r1rp8aQcpvDh7goMBZlJv6Co5vCNLVcQJdhxRL09SGaY6HcyHH9aT4tiynZabMofVasBYw==} resolution: {integrity: sha512-muMXyPmIx/2DPrCHOD1H1ePT01o7OdKxKj2ebmCAYvqhUy+Y1bpal7B0rdoxros7YrXI294JT/DWw2LqyiqTPA==}
engines: {node: '>=14'} engines: {node: '>=16'}
hasBin: true hasBin: true
dev: true dev: true
@@ -2026,6 +2029,10 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/prism-svelte@0.5.0:
resolution: {integrity: sha512-db91Bf3pRGKDPz1lAqLFSJXeW13mulUJxhycysFpfXV5MIK7RgWWK2E5aPAa71s8TCzQUXxF5JOV42/iOs6QkA==}
dev: true
/prismjs@1.29.0: /prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -2100,8 +2107,8 @@ packages:
glob: 7.2.3 glob: 7.2.3
dev: true dev: true
/rollup@3.24.0: /rollup@3.24.1:
resolution: {integrity: sha512-OgraHOIg2YpHQTjl0/ymWfFNBEyPucB7lmhXrQUh38qNOegxLapSPFs9sNr0qKR75awW41D93XafoR2QfhBdUQ==} resolution: {integrity: sha512-REHe5dx30ERBRFS0iENPHy+t6wtSEYkjrhwNsLyh3qpRaZ1+aylvMUdMBUHWUD/RjjLmLzEvY8Z9XRlpcdIkHA==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'} engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
optionalDependencies: optionalDependencies:
@@ -2134,8 +2141,8 @@ packages:
rimraf: 2.7.1 rimraf: 2.7.1
dev: true dev: true
/sass@1.62.1: /sass@1.63.3:
resolution: {integrity: sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==} resolution: {integrity: sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
dependencies: dependencies:
@@ -2600,7 +2607,7 @@ packages:
dependencies: dependencies:
esbuild: 0.17.19 esbuild: 0.17.19
postcss: 8.4.24 postcss: 8.4.24
rollup: 3.24.0 rollup: 3.24.1
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true

View File

@@ -3,12 +3,12 @@
@tailwind utilities; @tailwind utilities;
@font-face { @font-face {
font-family: 'Ian Mono'; font-family: 'Ian Mono';
src: url('/iaw-mono-var.woff2') format('woff2'); src: url('/iaw-mono-var.woff2') format('woff2');
} }
@layer base { @layer base {
html { html {
font-family: Ian Mono, monospace; font-family: Ian Mono, monospace;
} }
} }

View File

@@ -1,157 +0,0 @@
<script lang="ts">
import { createEventDispatcher, tick, onMount, onDestroy } from "svelte";
import * as ace from "brace";
import "brace/ext/emmet";
const EDITOR_ID = `svelte-ace-editor-div:${Math.floor(
Math.random() * 10000000000
)}`;
const dispatch = createEventDispatcher<{
init: ace.Editor;
input: string;
selectionChange: any;
blur: void;
changeMode: any;
commandKey: { err: any; hashId: any; keyCode: any };
copy: void;
cursorChange: void;
cut: void;
documentChange: { data: any };
focus: void;
paste: string;
}>();
/**
* translation of vue component to svelte:
* @link https://github.com/chairuosen/vue2-ace-editor/blob/91051422b36482eaf94271f1a263afa4b998f099/index.js
**/
export let value: string = ""; // String, required
export let lang: string = "json"; // String
export let theme: string = "chrome"; // String
export let height: string = "100%"; // null for 100, else integer, used as percent
export let width: string = "100%"; // null for 100, else integer, used as percent
export let options: any = {}; // Object
export let readonly: boolean = false;
let editor: ace.Editor;
let contentBackup: string = "";
const requireEditorPlugins = () => {};
requireEditorPlugins();
onDestroy(() => {
if (editor) {
editor.destroy();
editor.container.remove();
}
});
$: watchValue(value);
function watchValue(val: string) {
if (contentBackup !== val && editor && typeof val === "string") {
editor.session.setValue(val);
contentBackup = val;
}
}
$: watchTheme(theme);
function watchTheme(newTheme: string) {
if (editor) {
editor.setTheme("ace/theme/" + newTheme);
}
}
$: watchMode(lang);
function watchMode(newOption: any) {
if (editor) {
editor.getSession().setMode("ace/mode/" + newOption);
}
}
$: watchOptions(options);
function watchOptions(newOption: any) {
if (editor) {
editor.setOptions(newOption);
}
}
$: watchReadOnlyFlag(readonly);
function watchReadOnlyFlag(flag) {
if (editor) {
editor.setReadOnly(flag);
}
}
const resizeOnNextTick = () =>
tick().then(() => {
if (editor) {
editor.resize();
}
});
$: if (height !== null && width !== null) {
resizeOnNextTick();
}
onMount(() => {
lang = lang || "text";
theme = theme || "chrome";
editor = ace.edit(EDITOR_ID);
dispatch("init", editor);
editor.$blockScrolling = Infinity;
// editor.setOption("enableEmmet", true);
editor.getSession().setMode("ace/mode/" + lang);
editor.setTheme("ace/theme/" + theme);
editor.setValue(value, 1);
editor.setReadOnly(readonly)
contentBackup = value;
setEventCallBacks();
if (options) {
editor.setOptions(options);
}
});
const ValidPxDigitsRegEx = /^\d*$/;
function px(n: string): string {
if (ValidPxDigitsRegEx.test(n)) {
return n + "px";
}
return n;
}
function setEventCallBacks() {
editor.onBlur = () => dispatch("blur");
editor.onChangeMode = (obj) => dispatch("changeMode", obj);
editor.onCommandKey = (err, hashId, keyCode) =>
dispatch("commandKey", { err, hashId, keyCode });
editor.onCopy = () => dispatch("copy");
editor.onCursorChange = () => dispatch("cursorChange");
editor.onCut = () => {
const copyText = editor.getCopyText();
console.log("cut event : ", copyText);
editor.insert("");
dispatch("cut");
};
editor.onDocumentChange = (obj: { data: any }) =>
dispatch("documentChange", obj);
editor.onFocus = () => dispatch("focus");
editor.onPaste = (text) => {
console.log("paste event : ", text);
editor.insert(text);
dispatch("paste", text);
};
editor.onSelectionChange = (obj) => dispatch("selectionChange", obj);
editor.on("change", function () {
const content = editor.getValue();
value = content;
dispatch("input", content);
contentBackup = content;
});
}
</script>
<div style="width:{px(width)};">
<h1 class="font-bold mb-2">Editor</h1>
<div id={EDITOR_ID} style="width:{px(width)};" class="h-[80vh] rounded rounded-lg border border-gray-500"/>
</div>

View File

@@ -1,5 +1,5 @@
<script> <script>
let menuBar = false let menuBar = false;
</script> </script>
<!-- navbar goes here --> <!-- navbar goes here -->
@@ -9,28 +9,42 @@
<div class="flex space-x-4"> <div class="flex space-x-4">
<!-- logo --> <!-- logo -->
<div> <div>
<a href="#" class="flex items-center py-5 px-2 space-x-1 text-gray-700 hover:text-gray-900"> <a
<svg href="#"
viewBox="0 0 75 65" class="flex items-center py-5 px-2 text-gray-700 hover:text-gray-900 space-x-3"
fill="black" >
class="w-4 h-4 rotate-90" <svg viewBox="0 0 75 65" fill="black" class="w-4 h-4 rotate-90">
> <path d="M37.59.25l36.95 64H.64l36.95-64z" />
<path d="M37.59.25l36.95 64H.64l36.95-64z"></path>
</svg> </svg>
<span class="font-bold">Sveltekit-OG Playground</span> <span class="font-bold">Sveltekit-OG</span>
</a> </a>
</div> </div>
</div> </div>
<!-- secondary nav --> <!-- secondary nav -->
<div class="hidden md:flex items-center space-x-1"> <div class="hidden md:flex items-center space-x-1">
<a href="https://github.com/etherCorps/sveltekit-og/#readme" target="_blank" rel="noreferrer" class="py-5 px-3 underline">Docs</a> <a
<a href="https://github.com/etherCorps/sveltekit-og" target="_blank" rel="noreferrer" class="py-5 px-3 underline">Github</a> href="https://github.com/etherCorps/sveltekit-og/#readme"
target="_blank"
rel="noreferrer"
class="py-5 px-3 underline">Docs</a
>
<a
href="https://github.com/etherCorps/sveltekit-og"
target="_blank"
rel="noreferrer"
class="py-5 px-3 underline">Github</a
>
</div> </div>
<!-- mobile button goes here --> <!-- mobile button goes here -->
<div class="md:hidden flex items-center"> <div class="md:hidden flex items-center">
<button class="mobile-menu-button" on:click={() => {menuBar = !menuBar}}> <button
class="mobile-menu-button"
on:click={() => {
menuBar = !menuBar;
}}
>
<svg <svg
class="w-6 h-6" class="w-6 h-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -51,7 +65,7 @@
</div> </div>
<!-- mobile menu --> <!-- mobile menu -->
<div class="mobile-menu {menuBar ? '': 'hidden'} md:hidden"> <div class="mobile-menu {menuBar ? '' : 'hidden'} md:hidden">
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Docs</a> <a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Docs</a>
<a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Github</a> <a href="#" class="block py-2 px-4 text-sm hover:bg-gray-200">Github</a>
</div> </div>

View File

@@ -34,16 +34,16 @@ const ImageResponse = async (htmlTemplate: string, optionsByUser: ImageResponseO
if (!initialized) { if (!initialized) {
await initSvgToPng(); await initSvgToPng();
initialized = true initialized = true;
} }
const defaultConfig: ConvertOptions = { const defaultConfig: ConvertOptions = {
width: options.width, // optional width: options.width, // optional
height: options.height, // optional height: options.height // optional
}; };
if (Object.hasOwn(options, 'backgroundColor')) { if (Object.hasOwn(options, 'backgroundColor')) {
defaultConfig.backgroundColor = options.backgroundColor defaultConfig.backgroundColor = options.backgroundColor;
} }
const png = await svg2png(svg, defaultConfig); const png = await svg2png(svg, defaultConfig);

View File

@@ -1,9 +1,9 @@
<script> <script>
import '../app.css'; import '../app.css';
import Navbar from "../components/Navbar.svelte"; import Navbar from '../components/Navbar.svelte';
</script> </script>
<div class="max-h-screen">
<Navbar/>
<slot />
</div>
<div class="max-h-screen">
<Navbar />
<slot />
</div>

View File

@@ -1,40 +1,129 @@
<script lang="ts"> <script>
import AceEditor from "/src/components/AceEditor.svelte"; import {base} from "$app/paths";
import "brace/mode/html"; import Prism from 'prismjs';
import "brace/theme/chrome"; import 'prism-svelte';
let text = "<h1>hii</h1>"; import 'prismjs/themes/prism-tomorrow.css';
</script> const source = `
/src/routes/new/+server.ts
<div class="grid grid-cols-2 space-x-10 p-10"> import { ImageResponse } from '@ethercorps/sveltekit-og';
<AceEditor style="border: solid" import type { RequestHandler } from '@sveltejs/kit';
on:selectionChange={(obj) => console.log(obj.detail)}
on:paste={(obj) => console.log(obj.detail)} const template = \`
on:input={(obj) => console.log(obj.detail)} <div tw="bg-gray-50 flex w-full h-full items-center justify-center">
on:focus={() => console.log('focus')} <div tw="flex flex-col md:flex-row w-full py-12 px-4 md:items-center justify-between p-8">
on:documentChange={(obj) => console.log(`document change : ${obj.detail}`)} <h2 tw="flex flex-col text-3xl sm:text-4xl font-bold tracking-tight text-gray-900 text-left">
on:cut={() => console.log('cut')} <span>Ready to dive in?</span>
on:cursorChange={() => console.log('cursor change')} <span tw="text-indigo-600">Start your free trial today.</span>
on:copy={() => console.log('copy')} </h2>
on:init={(editor) => console.log(editor.detail)} <div tw="mt-8 flex md:mt-0">
on:commandKey={(obj) => console.log(obj.detail)} <div tw="flex rounded-md shadow">
on:changeMode={(obj) => console.log(`change mode : ${obj.detail}`)} <a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-5 py-3 text-base font-medium text-white">Get started</a>
on:blur={() => console.log('blur')} </div>
lang="html" <div tw="ml-3 flex rounded-md shadow">
theme="chrome" <a href="#" tw="flex items-center justify-center rounded-md border border-transparent bg-white px-5 py-3 text-base font-medium text-indigo-600">Learn more</a>
value={text} </div>
/> </div>
<div class="grid grid-rows-2 mt-8 space-y-4">
<div class="common">
Editor Under Development
</div>
<div class="common">
Coming Soon...
</div> </div>
</div> </div>
</div> \`;
<style> const fontFile400 = await fetch(
.common { 'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff'
@apply border border-gray-800 rounded p-5 );
}
</style> const fontFile700 = await fetch(
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
);
const fontData400: ArrayBuffer = await fontFile400.arrayBuffer();
const fontData700: ArrayBuffer = await fontFile700.arrayBuffer();
export const GET: RequestHandler = async () => {
return await ImageResponse(template, {
height: 250,
width: 500,
fonts: [
{
name: 'Inter Latin',
data: fontData400,
weight: 400
},
{
name: 'Inter Latin',
data: fontData700,
weight: 700
}
]
});
};
`;
const highlightedQuickEg = Prism.highlight(source, Prism.languages.svelte, 'svelte');
</script>
<div class="mx-10 mt-5 space-y-5">
<section id="introduction" class="space-y-3">
<h1 class="font-bold text-2xl">Introduction</h1>
<p class="">
SvelteKit-OG is use to dynamically generate Open Graph images from an HTML+CSS template or
Svelte component using fast and efficient conversion from <br /> HTML > SVG > PNG. Based on Satori.
No headless browser required.
</p>
</section>
<section id="installation" class="space-y-4">
<h1 class="font-bold text-2xl">Installation</h1>
<p>
Use your favourite package manager and add <span class="bg-gray-100 px-2 py-1 rounded-full"
>@ethercorps/sveltekit-og</span
>
as your <span class="bg-gray-100 px-2 py-1 rounded-full">devDependency</span>.
</p>
<div id="pnpm-install-og">
Example:
<code class="border rounded-full bg-gray-100 px-3 py-1.5 text-gray-900">
pnpm i -D @ethercorps/sveltekit-og
</code>
</div>
<div class="border-x-4 border-gray-900 rounded-lg leading-9">
<p class="ml-2">
If you are using it on with <span class="bg-gray-100 px-2 py-1 rounded-full">
cloudflare pages
</span>
or <span class="bg-gray-100 px-2 py-1 rounded-full">cloudflare workers </span> then you have
to provide <span class="bg-gray-100 px-2 py-1 rounded-full">polyfills</span> for
<span class="bg-gray-100 px-2 py-1 rounded-full">url</span>. You can simply add it to your
<span class="bg-gray-100 px-2 py-1 rounded-full">devDependency</span>,
<br /> To install
<code class="border rounded-full bg-gray-100 px-3 py-1.5 text-gray-900">
pnpm i -D url
</code>
</p>
</div>
</section>
<section id="usage" class="space-y-3">
<h1 class="font-bold text-2xl">Usage</h1>
<p class="">
Create a file at <span class="bg-gray-100 px-2 py-1 rounded-full">
/src/routes/og/+server.ts
</span>. Alternatively, you can use JavaScript by removing the types from this example.
</p>
<div class="border-x-4 border-gray-900 rounded-lg w-fit px-2 leading-9">
<p class="ml-2">
Route can be anything but it should have only one file
<span class="bg-gray-100 px-2 py-1 rounded-full"> +server.ts </span>
</p>
</div>
<pre class="bg-gray-100 overflow-auto px-3 py-1.5 rounded-xl"><code class="" >{@html highlightedQuickEg}</code></pre>
<div class="border-x-4 border-gray-900 rounded-lg w-fit px-2 leading-9">
<p class="ml-2">
Then run <span class="bg-gray-100 px-2 py-1 rounded-full"> pnpm run dev </span> and visit <span class="bg-gray-100 px-2 py-1 rounded-full"> localhost:5173/og </span> to view your generated PNG. Remember that hot module reloading does not work with server routes, so if you change your HTML or CSS, hard refresh the route to see changes.
</p>
</div>
<h2 class="font-bold text-xl">
Image Output: <a target="_blank" rel="noreferrer" href="https://sveltekit-og.ethercorps.io/new"> Live </a>
</h2>
</section>
</div>

View File

@@ -1 +1,13 @@
export const ssr = false; export const ssr = false;
const quickUseFile = import.meta.glob(['./new/+server.ts'], {as: 'raw'});
export const load = async () => {
const module = Object.entries(quickUseFile).map(([k, v]) =>
v().then((result) => {
const segments = k.split('/');
return { filename: segments.slice(2).join('/'), source: result };
}));
const code = Promise.all(module);
return {code}
};

View File

@@ -2,7 +2,9 @@ import OG from './OG.svelte';
import { componentToImageResponse } from '$lib'; import { componentToImageResponse } from '$lib';
import type { RequestHandler } from '@sveltejs/kit'; import type { RequestHandler } from '@sveltejs/kit';
const fontFile = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'); const fontFile = await fetch(
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
);
const fontData: ArrayBuffer = await fontFile.arrayBuffer(); const fontData: ArrayBuffer = await fontFile.arrayBuffer();
export const GET: RequestHandler = async () => { export const GET: RequestHandler = async () => {

View File

@@ -1,3 +1,5 @@
`/src/routes/new/+server.ts`
import { ImageResponse } from '$lib'; import { ImageResponse } from '$lib';
import type { RequestHandler } from '@sveltejs/kit'; import type { RequestHandler } from '@sveltejs/kit';
@@ -19,8 +21,12 @@ const template = `
</div> </div>
</div> </div>
`; `;
const fontFile400 = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff'); const fontFile400 = await fetch(
const fontFile700 = await fetch('https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'); 'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-400-normal.woff'
);
const fontFile700 = await fetch(
'https://raw.githubusercontent.com/etherCorps/sveltekit-og/main/static/inter-latin-ext-700-normal.woff'
);
const fontData400: ArrayBuffer = await fontFile400.arrayBuffer(); const fontData400: ArrayBuffer = await fontFile400.arrayBuffer();
const fontData700: ArrayBuffer = await fontFile700.arrayBuffer(); const fontData700: ArrayBuffer = await fontFile700.arrayBuffer();

3
static/logo.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg viewBox="0 0 75 65" fill="black" class="w-4 h-4 rotate-90">
<path d="M37.59.25l36.95 64H.64l36.95-64z" />
</svg>

After

Width:  |  Height:  |  Size: 122 B

View File

@@ -8,13 +8,11 @@ const config: UserConfig = {
}, },
build: { build: {
rollupOptions: { rollupOptions: {
external: ["@resvg/resvg-js"] external: ['@resvg/resvg-js']
} }
}, },
optimizeDeps: { optimizeDeps: {
exclude: [ exclude: ['@resvg/resvg-js']
"@resvg/resvg-js"
]
} }
}; };