Skip to content

Commit 65a8e87

Browse files
committed
feat(vue): initial to svg feature by vue template
1 parent ae4e78a commit 65a8e87

29 files changed

+594
-653
lines changed

.github/workflows/ci.yml

-47
This file was deleted.

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ node_modules
33
*.log
44

55
# Bundle
6-
bin
76
dist
87

98
# Docs
109
docs/.vitepress/cache
1110
urls.txt
11+
examples/*/images/**/*
1212

1313
# Mac OS
1414
.DS_Store

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ ignore-workspace-root-check=true
22
shell-emulator=true
33
public-hoist-pattern[]=*vite*
44
public-hoist-pattern[]=*eslint*
5+
public-hoist-pattern[]=*@vue*

bin/x-satori.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env node
2+
'use strict'
3+
import '../dist/cli.mjs'

build.config.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import { defineBuildConfig } from 'unbuild'
22

33
export default defineBuildConfig({
44
entries: [
5+
'src/cli',
6+
'src/vue',
7+
'src/astro',
58
'src/index',
69
],
710
declaration: true,
811
clean: true,
912
rollup: {
10-
emitCJS: true,
1113
inlineDependencies: true,
12-
esbuild: {
13-
minify: true,
14-
sourceMap: true,
14+
replace: {
15+
values: {
16+
__VUE_OPTIONS_API__: true,
17+
__VUE_PROD_DEVTOOLS__: false,
18+
},
1519
},
1620
},
1721
})

examples/vue/.npmrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ignore-workspace-root-check=true
2+
shell-emulator=true
3+
public-hoist-pattern[]=*vite*
4+
public-hoist-pattern[]=*eslint*
5+
public-hoist-pattern[]=*@vue*

examples/vue/Template.vue

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script setup lang="ts">
2+
defineProps<{ title: string; desc: string; site: string; }>()
3+
</script>
4+
5+
<template>
6+
<div
7+
style='background-image: linear-gradient(120deg, rgb(27, 26, 28), rgb(6, 6, 7) 30%, rgb(25, 95, 60) 70%, rgb(16, 15, 16));color: #ffffff;'
8+
tw="w-full h-full text-1.4rem flex flex-col items-center justify-between px-2rem py-2rem"
9+
>
10+
<div tw="flex w-full">
11+
<svg height="72" viewBox="0 0 24 24">
12+
<defs><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="19.78" x2="10.749" y1="11.04" y2="20.16"><stop offset="0" stop-color="#fff" /><stop offset="1" stop-color="#ababab" /></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="13.669" x2="7.911" y1="2.441" y2="19.191"><stop offset="0" stop-color="#fff" /><stop offset="1" stop-color="#ababab" /></linearGradient><clipPath id="a"><path d="M6.621 6.548h16.145v19H6.621z" /></clipPath><clipPath id="c"><path d="M0-4.236h15.108v30H0z" /></clipPath></defs><path clip-path="url(#a)" d="M15.105 12.55c.019.115.04.266.065.453.024.188.036.382.036.583 0 .442-.063.867-.188 1.275a3.145 3.145 0 0 1-.568 1.08c-.255.312-.57.56-.944.742-.374.182-.81.273-1.31.273-.365 0-.691-.06-.98-.18a2.018 2.018 0 0 1-.726-.504 2.242 2.242 0 0 1-.454-.77 2.909 2.909 0 0 1-.158-.98c0-.527.11-1.027.33-1.497.222-.47.52-.902.894-1.296a7.225 7.225 0 0 1 1.303-1.073 9.111 9.111 0 0 1 1.562-.814 9.933 9.933 0 0 1 1.678-.51 7.955 7.955 0 0 1 1.634-.18 8.9 8.9 0 0 1 1.8.172 9.242 9.242 0 0 1 1.642.504c.374-.163.756-.312 1.145-.446.388-.135.79-.211 1.202-.23l.029.086c-.135 0-.298.024-.49.072a5.368 5.368 0 0 0-1.138.44c-.172.09-.302.179-.388.265.365.211.657.483.878.814.221.331.331.713.331 1.145 0 .412-.103.765-.31 1.058a2.706 2.706 0 0 1-.777.735 4.13 4.13 0 0 1-1.022.46 9.04 9.04 0 0 1-1.059.252l-.014.03c.298.037.588.083.871.136.283.053.538.142.763.266.226.125.406.3.54.526.135.226.202.526.202.9a3.02 3.02 0 0 1-.338 1.433c-.226.427-.526.79-.9 1.087a4.143 4.143 0 0 1-1.268.684c-.47.158-.95.238-1.44.238a2.54 2.54 0 0 1-.619-.08 1.949 1.949 0 0 1-.569-.237 1.394 1.394 0 0 1-.417-.404 1.003 1.003 0 0 1-.166-.575.91.91 0 0 1 .26-.649.84.84 0 0 1 .633-.273c.288 0 .542.096.763.288a1.11 1.11 0 0 0-.425.432 1.215 1.215 0 0 0-.136.576c0 .25.067.437.201.562.135.124.327.187.576.187a1.8 1.8 0 0 0 1.023-.31c.307-.206.566-.465.777-.777.211-.313.375-.656.49-1.03.115-.375.173-.73.173-1.066 0-.633-.166-1.096-.497-1.39-.331-.292-.843-.438-1.534-.438l.015-.116a4.18 4.18 0 0 0 1.05-.194 3.09 3.09 0 0 0 .93-.475c.273-.207.496-.466.67-.778.172-.312.258-.684.258-1.116 0-.269-.048-.526-.144-.77a1.622 1.622 0 0 0-.46-.641 5.97 5.97 0 0 0-1.296 1.483c-.384.605-.766 1.25-1.145 1.937-.38.686-.775 1.377-1.188 2.073a10.54 10.54 0 0 1-1.419 1.887 6.595 6.595 0 0 1-1.85 1.368c-.7.35-1.526.526-2.477.526-.307 0-.607-.041-.9-.123a2.61 2.61 0 0 1-.785-.36 1.969 1.969 0 0 1-.561-.583 1.463 1.463 0 0 1-.216-.792c0-.279.074-.518.223-.72.149-.202.377-.303.684-.303.22 0 .396.068.526.202s.194.302.194.504a.654.654 0 0 1-.173.46c-.115.126-.23.198-.345.217a.768.768 0 0 0-.015.173c0 .393.127.684.382.87.254.188.626.282 1.116.282.653 0 1.226-.178 1.72-.533a6.052 6.052 0 0 0 1.361-1.39c.413-.57.812-1.21 1.196-1.915.384-.706.794-1.406 1.23-2.102.438-.696.925-1.354 1.462-1.973a6.578 6.578 0 0 1 1.887-1.505 3.807 3.807 0 0 0-1.325-.655c-.5-.14-.994-.209-1.483-.209a6.76 6.76 0 0 0-2.117.36c-.73.24-1.394.588-1.994 1.044a5.73 5.73 0 0 0-1.476 1.656c-.384.648-.576 1.38-.576 2.196 0 .23.03.47.093.72s.161.478.295.684c.135.207.303.377.504.511.202.135.437.202.706.202a1.97 1.97 0 0 0 1-.252c.294-.168.546-.394.757-.677a3.11 3.11 0 0 0 .482-.98c.11-.369.166-.75.166-1.144 0-.23-.01-.43-.029-.598a46.06 46.06 0 0 0-.058-.482l.159-.014Z" fill="url(#b)" /><path clip-path="url(#c)" d="M15.108 12.625c-.154.252-.333.518-.536.798-.202.28-.43.532-.682.756-.252.224-.522.41-.809.557-.287.147-.591.22-.913.22-.35 0-.707-.105-1.071-.315-.252-.14-.48-.35-.682-.63a7.12 7.12 0 0 1-.546-.882 17.7 17.7 0 0 1-.441-.903 7.872 7.872 0 0 0-.347-.693c-.322.112-.64.196-.955.252a5.448 5.448 0 0 1-.956.084c-.462 0-.928-.056-1.396-.168a2.576 2.576 0 0 1-1.208-.65 5.65 5.65 0 0 0-.798.671 7.048 7.048 0 0 0-.693.798c-.07 0-.105-.049-.105-.147.238-.28.48-.539.724-.777a7.4 7.4 0 0 1 .767-.65c-.448-.49-.672-1.1-.672-1.828 0-.448.087-.913.262-1.396.175-.483.4-.956.672-1.418.274-.462.571-.9.893-1.312.322-.413.637-.767.945-1.06a5.3 5.3 0 0 1 3.675-1.513c.07 0 .115.014.136.042a.14.14 0 0 1 .032.084c0 .042-.014.063-.042.063a.973.973 0 0 0-.189-.02h-.147c-.336 0-.672.08-1.008.24a4.53 4.53 0 0 0-.945.61c-.294.245-.56.504-.798.777s-.441.514-.609.724c-.196.266-.403.574-.62.924-.216.35-.416.718-.598 1.103a7.648 7.648 0 0 0-.452 1.218 4.79 4.79 0 0 0-.178 1.291c0 .364.07.721.21 1.071.476-.322.931-.535 1.365-.64.434-.105.791-.158 1.071-.158.154 0 .318.01.493.032.176.02.361.073.557.157.196.084.399.214.609.389.21.175.42.416.63.724a4.999 4.999 0 0 0 1.386-1.04 7.732 7.732 0 0 0 1.785-3.076c.168-.56.252-1.085.252-1.575 0-.448-.053-.864-.158-1.25a2.497 2.497 0 0 0-.472-.955 1.746 1.746 0 0 0-.388-.325 1.35 1.35 0 0 0-.41-.179c-.07-.028-.105-.049-.105-.063 0-.028.035-.042.105-.042.112 0 .245.004.399.01.154.008.294.011.42.011.084 0 .178.01.284.032a.63.63 0 0 1 .283.136c.21.168.413.417.609.746s.294.794.294 1.396c0 .42-.077.914-.231 1.48a7.43 7.43 0 0 1-.735 1.733A8.669 8.669 0 0 1 11.78 9.79a6.94 6.94 0 0 1-1.922 1.386c.084.126.182.29.294.494.112.203.238.42.378.65.14.232.294.466.462.704.168.238.343.462.525.672.406.462.826.693 1.26.693.084 0 .203-.014.357-.042.154-.028.325-.101.514-.22.19-.12.396-.305.62-.557.224-.252.448-.602.672-1.05.028-.042.063-.049.105-.02.042.027.063.07.063.125Zm-6.111-1.239-.304-.472a2.253 2.253 0 0 0-.378-.441 1.8 1.8 0 0 0-.525-.326 1.952 1.952 0 0 0-.746-.126c-.35 0-.686.06-1.008.179a4.965 4.965 0 0 0-.945.472c.238.392.574.658 1.008.798.434.14.861.21 1.281.21.532 0 1.071-.098 1.617-.294Z" fill="url(#d)" />
13+
</svg>
14+
</div>
15+
<div tw="w-full flex relative mt--20 px-30 flex-col justify-center items-center">
16+
<div tw="text-2.8rem font-bold" style="white-space: pre-wrap;" v-html="title" />
17+
<div tw="text-1.6rem text-neutral-400" style="white-space: pre-wrap;" v-html="desc" />
18+
</div>
19+
<div tw="w-full flex items-center justify-end">
20+
<div tw="flex items-center text-zinc-500 text-0.9rem">
21+
<span tw="text-neutral-500 border-b border-neutral-400 ml-2" v-html="site" />
22+
<svg fill="white" height="20" viewBox="0 0 32 32" tw="mx-1">
23+
<path d="M27.562 26L17.17 8.928l2.366-3.888L17.828 4L16 7.005L14.17 4l-1.708 1.04l2.366 3.888L4.438 26H2v2h28v-2ZM16 10.85L25.22 26H17v-8h-2v8H6.78Z" />
24+
</svg>
25+
<span>Powered by Vitesse ✘ QB</span>
26+
</div>
27+
</div>
28+
</div>
29+
</template>

examples/vue/font/Inter-Bold.woff

140 KB
Binary file not shown.

examples/vue/font/Inter-Medium.woff

139 KB
Binary file not shown.

examples/vue/font/NotoSansSC-Bold.otf

8.31 MB
Binary file not shown.
8.11 MB
Binary file not shown.
641 KB
Binary file not shown.

examples/vue/image/og.svg

+1
Loading

examples/vue/package.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "demo-vue",
3+
"version": "1.0.0",
4+
"type": "module",
5+
"description": "vue SFC file to Open Graph SVG or PNG by satori",
6+
"scripts": {
7+
"to:svg": "tsx to-svg.mts",
8+
"to:png": "tsx to-png.mts"
9+
},
10+
"dependencies": {
11+
"vue": "^3.2.47"
12+
},
13+
"devDependencies": {
14+
"tsx": "^3.12.5",
15+
"x-satori": "workspace:*"
16+
}
17+
}

examples/vue/to-png.mts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
(async function () {
3+
console.log(1)
4+
}()).catch((err: Error) => {
5+
console.error(err)
6+
process.exit(1)
7+
})

examples/vue/to-svg.mts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { genVueSatoriSVG, UserConfig } from 'x-satori/vue'
2+
import { fileURLToPath } from 'node:url'
3+
import { readFile, writeFile } from 'node:fs/promises'
4+
import { dirname, resolve } from 'pathe'
5+
6+
(async function () {
7+
const _dirname = typeof __dirname !== 'undefined'
8+
? __dirname
9+
: dirname(fileURLToPath(import.meta.url))
10+
const _output = resolve(_dirname, './image/og.svg')
11+
12+
const templateStr = await readFile(resolve(_dirname, './Template.vue'), 'utf8')
13+
const opt: UserConfig = {
14+
height: 628,
15+
width: 1200,
16+
fonts: [
17+
{
18+
name: 'Inter',
19+
data: await readFile(resolve(_dirname, './font/Inter-Medium.woff')),
20+
weight: 400,
21+
style: 'normal',
22+
},
23+
{
24+
name: 'Inter',
25+
data: await readFile(resolve(_dirname, './font/Inter-Bold.woff')),
26+
weight: 700,
27+
style: 'normal',
28+
},
29+
{
30+
name: 'Noto Sans Symbols',
31+
data: await readFile(resolve(_dirname, './font/NotoSansSymbols2-Regular.ttf')),
32+
weight: 700,
33+
style: 'normal',
34+
},
35+
],
36+
props: {
37+
title: 'hello world',
38+
desc: 'examples',
39+
site: 'https://qbb.sh'
40+
}
41+
}
42+
const strSVG = await genVueSatoriSVG(opt, templateStr)
43+
44+
await writeFile(_output, strSVG)
45+
}()).catch((err: Error) => {
46+
console.error(err)
47+
process.exit(1)
48+
})

examples/vue/tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"jsx": "preserve",
4+
// Enable top-level await, and other modern ESM features.
5+
"target": "ESNext",
6+
"module": "ESNext",
7+
// Enable node-style module resolution, for things like npm package imports.
8+
"moduleResolution": "node",
9+
// Enable JSON imports.
10+
"resolveJsonModule": true,
11+
// Enable stricter transpilation for better output.
12+
"isolatedModules": true,
13+
// Astro will directly run your TypeScript code, no transpilation needed.
14+
"noEmit": true
15+
}
16+
}

package.json

+28-14
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,68 @@
1515
"cli"
1616
],
1717
"exports": {
18+
"./*": "./*",
1819
".": {
1920
"types": "./dist/index.d.ts",
20-
"require": "./dist/index.cjs",
2121
"import": "./dist/index.mjs"
2222
},
23+
"./vue": {
24+
"types": "./dist/vue.d.ts",
25+
"import": "./dist/vue.mjs"
26+
},
27+
"./astro": {
28+
"types": "./dist/astro.d.ts",
29+
"import": "./dist/astro.mjs"
30+
},
2331
"./package.json": "./package.json"
2432
},
25-
"main": "./dist/index.cjs",
33+
"main": "./dist/index.mjs",
2634
"module": "./dist/index.mjs",
2735
"types": "./dist/index.d.ts",
2836
"bin": {
29-
"x-satori": "dist/index.cjs"
37+
"x-satori": "bin/x-satori.mjs"
3038
},
3139
"files": [
32-
"dist"
40+
"dist",
41+
"bin"
3342
],
3443
"scripts": {
35-
"dev": "unbuild --stub && vitest",
36-
"build": "unbuild",
44+
"dev": "unbuild --stub",
45+
"build": "unbuild && cpx src/yoga.wasm dist/shared",
3746
"start": "x-satori",
3847
"cz": "czg",
3948
"lint": "eslint .",
40-
"test": "vitest run",
41-
"postinstall": "simple-git-hooks",
49+
"postinstall": "simple-git-hooks && cpx node_modules/yoga-wasm-web/dist/yoga.wasm src",
4250
"prepack": "npm run build",
4351
"release": "run-s release:bump release:publish",
4452
"release:bump": "bumpp -y -c 'build: :bookmark: publish v%s'",
45-
"release:publish": "pnpm publish"
53+
"release:publish": "pnpm publish",
54+
"demo:vue:svg": "pnpm -C examples/vue to:svg",
55+
"demo:vue:png": "pnpm -C examples/vue to:png"
56+
},
57+
"dependencies": {
58+
"@vue/compiler-sfc": "^3.2.47",
59+
"satori": "^0.4.2",
60+
"satori-html": "^0.3.2",
61+
"yoga-wasm-web": "^0.3.3"
4662
},
4763
"devDependencies": {
4864
"@antfu/eslint-config": "^0.35.3",
65+
"@rollup/plugin-replace": "^5.0.2",
4966
"@types/node": "^18.15.3",
5067
"bumpp": "^9.0.0",
51-
"cz-git": "^1.6.0",
68+
"cpx2": "^4.2.2",
5269
"czg": "^1.6.0",
5370
"eslint": "^8.36.0",
54-
"fast-glob": "^3.2.12",
55-
"fs-extra": "^11.1.0",
5671
"lint-staged": "^13.2.0",
5772
"npm-run-all": "^4.1.5",
5873
"pathe": "^1.1.0",
5974
"pnpm": "^7.29.1",
60-
"rimraf": "^4.4.0",
6175
"simple-git-hooks": "^2.8.1",
6276
"tsx": "^3.12.5",
6377
"typescript": "^4.9.5",
6478
"unbuild": "^1.1.2",
65-
"vitest": "^0.29.2",
79+
"vue": "^3.2.47",
6680
"x-satori": "workspace:*"
6781
},
6882
"simple-git-hooks": {

0 commit comments

Comments
 (0)