39 Commits

Author SHA1 Message Date
renovate[bot]
c6b20ed076 Add renovate.json 2023-07-20 19:56:42 +00:00
Guz
6fdad98663 fix: typo 2023-07-20 16:15:31 -03:00
Guz
681f9ba788 Merge pull request #23 from LoredDev/changeset-release/main
🦋 Release branch
2023-07-07 15:42:23 -03:00
github-actions[bot]
6ca1fc7fbc ci: 👷🦋 version packages 2023-07-07 18:42:04 +00:00
Guz013
10c6db7ebc fix: 🐛 release branch workflow triggers 2023-07-07 15:40:47 -03:00
Guz
c93c979e3f chore: 🚀 release changes
🦋 Release branch
2023-07-07 15:37:44 -03:00
github-actions[bot]
280117e9ec ci: 👷🦋 version packages 2023-07-07 18:36:56 +00:00
Guz013
386c556650 fix: 🐛 (hopefully) workflow triggers 2023-07-07 15:35:52 -03:00
Guz013
1fb8a0185e ci: 👷 simplified release branch workflow 2023-07-07 15:35:14 -03:00
Guz013
c0341eac68 chore: 🔧 👷 code style in workflows 2023-07-07 15:17:05 -03:00
Guz013
f5b43337a6 ci: 👷 deploy and check code in release branch 2023-07-07 15:12:21 -03:00
Guz013
51424bf3f7 ci: 👷 workflow triggers 2023-07-07 15:08:32 -03:00
Guz013
2c4f38f916 ci: 👷 loredflow workflows 2023-07-07 14:59:25 -03:00
Guz013
e951837f36 chore: 🔧 rename workflows 2023-07-07 14:59:03 -03:00
Guz013
4b103e2804 chore: 🔧 fix package access 2023-07-07 14:58:06 -03:00
Guz
d173651b50 fix: rtl checkbox hotfix 2023-07-03 19:44:26 -03:00
Guz
1dd662c425 Merge pull request #18 from LoredDev/changeset-release/main
🦋 Changeset: Version packages
2023-07-03 17:25:16 -03:00
github-actions[bot]
1cca8a1623 chore: 🔗🦋 version packages 2023-07-03 20:14:12 +00:00
Guz
8f552ad600 Merge pull request #21 from LoredDev/main
Update dev branch
2023-07-03 17:13:10 -03:00
Guz
cc928a45a4 Merge pull request #20 from LoredDev/banner-editor@dev
Feature: web editor
2023-07-03 17:11:38 -03:00
Guz013
2612c4a0f3 chore: 🔧 add changesets 2023-07-03 17:08:14 -03:00
Guz013
66101be6c0 feat: banner editor, MVP 2023-07-03 17:03:32 -03:00
Guz013
63f4d24317 chore(banners): 🔧 remove unused comment 2023-07-03 17:02:58 -03:00
Guz013
65ead53191 feat: banner component 2023-07-03 17:02:19 -03:00
Guz013
41c6f275ad feat(banners): expose helper functions 2023-07-03 16:41:21 -03:00
Guz013
890b768a4e refactor(banners): ♻️ make node apis lazy-loaded 2023-07-03 16:39:51 -03:00
Guz013
e83de84f5c fix(ci): 🐛 👷 disable husky in release workflow 2023-06-29 17:29:49 -03:00
Guz
8c81704f8b Merge pull request #17 from LoredDev/dev
Update production workflows
2023-06-29 17:19:30 -03:00
Guz013
8380a980ba chore(ci): 🔧 👷 workflows triggering 2023-06-29 17:17:28 -03:00
Guz013
9b7a3aed62 fix(ci): 🐛 👷 git hooks on changeset script 2023-06-29 17:08:25 -03:00
Guz
827eb80d0f Merge pull request #16 from LoredDev/dev
Push to production
2023-06-29 16:55:06 -03:00
Guz
07013dfc0f Merge pull request #15 from LoredDev/rest-api
Feature: Rest API
2023-06-29 16:49:05 -03:00
Guz013
56eb8af91b chore: 🔧 add changeset 2023-06-29 16:37:24 -03:00
Guz013
48bd5ee419 fix(api): 🐛 banner custom colors 2023-06-29 16:35:05 -03:00
Guz013
16897f956a fix: 🐛 update previews 2023-06-29 15:20:05 -03:00
Guz013
16a13c2c6a feat(api): add basic rest api 2023-06-29 15:16:38 -03:00
Guz013
aecb212d0c chore: 🔧 update auto imports config 2023-06-29 15:13:14 -03:00
Guz013
5e4a6ccc3f chore(deps): 🔗 migrate to svelte 4 2023-06-29 14:11:08 -03:00
Guz
07a627db9f Merge pull request #14 from LoredDev/main
update development branch
2023-06-27 17:46:24 -03:00
39 changed files with 676 additions and 180 deletions

View File

@@ -4,8 +4,8 @@
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"access": "public",
"baseBranch": "dev",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": {

View File

@@ -233,6 +233,9 @@ module.exports = {
'xml',
'jsconfig',
'vitest',
'matcher',
'minimalistic',
'xmlns',
],
minLength: 4,
}],

View File

@@ -5,8 +5,16 @@ on:
branches:
- dev
- main
- changeset-release/main
pull_request:
types: [opened, synchronize, reopened]
branches:
- dev
- main
- changeset-release/main
types:
- opened
- synchronize
- reopened
jobs:
linting:

View File

@@ -1,14 +1,22 @@
name: ▲ Deploy preview to Vercel
name: ▲ Deploy preview
on:
push:
branches:
- dev
pull_request:
types: [opened, synchronize, reopened]
branches:
- dev
- main
- changeset-release/main
types:
- opened
- synchronize
- reopened
jobs:
deploy:
if: github.repository == 'loreddev/marknow'
uses: loreddev/.github/.github/workflows/vercel-deploy.yml@main
secrets: inherit
with:

View File

@@ -1,12 +1,18 @@
name: ▲ Deploy to Vercel
name: ▲ Deploy
on:
push:
workflow_run:
workflows:
- 🧪 Code checking
- 🎉 Release
types:
- completed
branches:
- main
jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository == 'loreddev/marknow' }}
uses: loreddev/.github/.github/workflows/vercel-deploy.yml@main
secrets: inherit
with:

View File

@@ -8,6 +8,7 @@ on:
jobs:
mirror:
if: github.repository == 'loreddev/marknow'
uses: loreddev/.github/.github/workflows/mirrors.yml@main
secrets: inherit
with:

49
.github/workflows/release-branch.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: 🦋 Release branch
on:
push:
branches:
- dev
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
update-release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
name: Update/Create release branch
env:
HUSKY: 0
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup environment
uses: ./.github/actions/pnpm-setup
- name: Update release PR
id: changesets
uses: loreddev/changeset-action@main
with:
branch: main
commit: 'ci: 👷🦋 version packages'
title: 🦋 Release branch
publish: pnpm run release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update dev branch
if: steps.changesets.outputs.hasChangesets == 'false'
uses: devmasx/merge-branch@master
with:
type: now
from_branch: changeset-release/main
target_branch: dev
message: 'ci: 👷 update dev branch'
github_token: ${{ secrets.GITHUB_TOKEN }}

34
.github/workflows/release-preview.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: 👷 Release preview
on:
workflow_run:
workflows:
- 🧪 Code checking
types:
- completed
branches:
- dev
jobs:
release:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository == 'loreddev/marknow' }}
name: Release preview
env:
HUSKY: 0
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup environment
uses: ./.github/actions/pnpm-setup
- name: Update versions
run: pnpm changeset version --snapshot next
- name: Release packages
run: pnpm run release --tag next
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -1,33 +0,0 @@
name: 🎉 Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
if: github.repository == 'loreddev/marknow'
permissions:
contents: write
pull-requests: write
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup environment
uses: ./.github/actions/pnpm-setup
- name: Create Release PR or Public to NPM
id: changesets
uses: changesets/action@v1
with:
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -34,6 +34,9 @@
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"svelte.plugin.svelte.compilerWarnings": {
"missing-declaration": "ignore"
}
}
}

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023-preset Gustavo "Guz" L. de Mello
Copyright (c) 2023-present Gustavo "Guz" L. de Mello
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -35,6 +35,7 @@
"linear": true,
"onDestroy": true,
"onMount": true,
"pastSvg": true,
"quadIn": true,
"quadInOut": true,
"quadOut": true,
@@ -55,14 +56,6 @@
"tick": true,
"tweened": true,
"writable": true,
"csr": true,
"ssr": true,
"render": true,
"banner": true,
"Banner": true,
"load": true,
"data": true,
"PageData": true,
"GET": true
"encodeSvg": true
}
}

View File

@@ -3,4 +3,8 @@ module.exports = {
extends: [
'./.eslintrc-auto-import.json',
],
rules: {
'@typescript-eslint/no-throw-literal': 'off',
'import/default': 'warn',
},
};

11
apps/www/CHANGELOG.md Normal file
View File

@@ -0,0 +1,11 @@
# @marknow/www
## 1.0.0
### Major Changes
- 2612c4a: Created the basic web editor for the banners. It is just a minimal viable product, and in some way still a proof-of-concept.
### Minor Changes
- 56eb8af: Added a simple rest api for creating the banners

View File

@@ -1,7 +1,7 @@
{
"name": "@marknow/www",
"type": "module",
"version": "0.0.0",
"version": "1.0.0",
"private": true,
"packageManager": "pnpm@8.0.0",
"license": "MIT OR Apache-2.0",
@@ -26,7 +26,7 @@
"@marknow/banners": "workspace:*",
"@poppanator/sveltekit-svg": "^3.0.1",
"@sveltejs/adapter-vercel": "^3.0.1",
"@sveltejs/kit": "^1.20.2",
"@sveltejs/kit": "^1.20.4",
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11",
"@unocss/extractor-svelte": "^0.52.7",
@@ -34,11 +34,11 @@
"rehype-external-links": "^2.1.0",
"sass": "^1.63.6",
"satori": "^0.10.1",
"svelte": "^3.59.1",
"svelte": "^4.0.0",
"svelte-check": "^3.4.3",
"svelte-preprocess": "^5.0.4",
"svelte-preprocess": "^5.0.3",
"tslib": "^2.5.3",
"typescript": "^5.1.3",
"typescript": "^5.0.0",
"unocss": "^0.52.7",
"unocss-preset-radix": "^2.5.1",
"unocss-preset-scrollbar": "^0.2.1",

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" un-bg="#0d1117">
<div style="display: contents">%sveltekit.body%</div>
<body data-sveltekit-preload-data="hover" style="margin: 0; overflow: hidden;">
<div style="display: contents; position: absolute;">%sveltekit.body%</div>
</body>
</html>

View File

@@ -1,7 +1,7 @@
// generated by unplugin-svelte-components
// We suggest you to commit this file into source control
declare global {
const Test: typeof import("./Test.svelte")["default"]
const Banner: typeof import("./components/Banner.svelte")["default"]
}
export {}

View File

@@ -0,0 +1,37 @@
<script lang="ts">
import type { BannerOptions } from '@marknow/banners';
import newBanner from '@marknow/banners';
export let options: BannerOptions;
async function loadSvg() {
const bannerSvg = newBanner(options);
pastSvg.set((await bannerSvg).svg);
return bannerSvg;
}
</script>
<picture un-w="1000px" un-h="280px" un-relative>
{#await loadSvg()}
<img src={`data:image/svg+xml, ${encodeSvg(get(pastSvg))}`} alt="Resulting banner">
<div un-m="l-2">
<span un-i-svg-spinners-blocks-shuffle-3 un-inline-block un-m="r-1">
Spinner
</span>Creating svg
</div>
{:then banner}
<img src={`data:image/svg+xml, ${encodeSvg(banner.svg)}`} alt="Resulting banner">
{/await}
</picture>
<style>
:global(#bannerHtml) {
padding: 0 !important;
height: var(--height) !important;
}
:global(#bannerHtml > div > div > div:first-child) {
margin: 0 0 0 2.5em !important;
}
</style>

View File

@@ -4,8 +4,6 @@
// Generated by unplugin-auto-import
export {}
declare global {
const Banner: typeof import('./Banner')['default']
const GET: typeof import('../routes/api.svg/+server')['GET']
const afterUpdate: typeof import('svelte')['afterUpdate']
const backIn: typeof import('svelte/easing')['backIn']
const backInOut: typeof import('svelte/easing')['backInOut']
@@ -20,16 +18,15 @@ declare global {
const circOut: typeof import('svelte/easing')['circOut']
const createEventDispatcher: typeof import('svelte')['createEventDispatcher']
const crossfade: typeof import('svelte/transition')['crossfade']
const csr: typeof import('../routes/+page')['csr']
const cubicIn: typeof import('svelte/easing')['cubicIn']
const cubicInOut: typeof import('svelte/easing')['cubicInOut']
const cubicOut: typeof import('svelte/easing')['cubicOut']
const data: typeof import('../routes/+page.svelte')['data']
const derived: typeof import('svelte/store')['derived']
const draw: typeof import('svelte/transition')['draw']
const elasticIn: typeof import('svelte/easing')['elasticIn']
const elasticInOut: typeof import('svelte/easing')['elasticInOut']
const elasticOut: typeof import('svelte/easing')['elasticOut']
const encodeSvg: typeof import('./utils')['encodeSvg']
const expoIn: typeof import('svelte/easing')['expoIn']
const expoInOut: typeof import('svelte/easing')['expoInOut']
const expoOut: typeof import('svelte/easing')['expoOut']
@@ -41,9 +38,9 @@ declare global {
const getContext: typeof import('svelte')['getContext']
const hasContext: typeof import('svelte')['hasContext']
const linear: typeof import('svelte/easing')['linear']
const load: typeof import('../routes/+page')['load']
const onDestroy: typeof import('svelte')['onDestroy']
const onMount: typeof import('svelte')['onMount']
const pastSvg: typeof import('./state')['pastSvg']
const quadIn: typeof import('svelte/easing')['quadIn']
const quadInOut: typeof import('svelte/easing')['quadInOut']
const quadOut: typeof import('svelte/easing')['quadOut']
@@ -54,7 +51,6 @@ declare global {
const quintInOut: typeof import('svelte/easing')['quintInOut']
const quintOut: typeof import('svelte/easing')['quintOut']
const readable: typeof import('svelte/store')['readable']
const render: typeof import('./render')['default']
const scale: typeof import('svelte/transition')['scale']
const setContext: typeof import('svelte')['setContext']
const sineIn: typeof import('svelte/easing')['sineIn']
@@ -62,7 +58,6 @@ declare global {
const sineOut: typeof import('svelte/easing')['sineOut']
const slide: typeof import('svelte/transition')['slide']
const spring: typeof import('svelte/motion')['spring']
const ssr: typeof import('../routes/+page')['ssr']
const tick: typeof import('svelte')['tick']
const tweened: typeof import('svelte/motion')['tweened']
const writable: typeof import('svelte/store')['writable']

View File

@@ -0,0 +1 @@
export const pastSvg = writable('');

17
apps/www/src/lib/utils.ts Normal file
View File

@@ -0,0 +1,17 @@
/**
* @author Taylor Hunt
* @see {@link https://codepen.io/tigt/post/optimizing-svgs-in-data-uris}
* @see {@link https://gist.github.com/jennyknuth/222825e315d45a738ed9d6e04c7a88d0}
*/
export function encodeSvg(svg: string) {
return svg.replace('<svg', (~svg.indexOf('xmlns') ? '<svg' : '<svg xmlns="http://www.w3.org/2000/svg"'))
.replace(/"/g, '\'')
.replace(/%/g, '%25')
.replace(/#/g, '%23')
.replace(/{/g, '%7B')
.replace(/}/g, '%7D')
.replace(/</g, '%3C')
.replace(/>/g, '%3E')
.replace(/\s+/g, ' ');
}

View File

@@ -0,0 +1,11 @@
import type { ParamMatcher } from '@sveltejs/kit';
export const match = ((param) => {
if (
param === 'horizontal.svg'
|| param === 'vertical.svg'
|| param === 'horizontal'
|| param === 'vertical'
) return true;
else return false;
}) satisfies ParamMatcher;

View File

@@ -4,6 +4,13 @@
import '../app.css';
</script>
<div un-bg="#0d1117">
<main
un-w="screen"
un-h="screen"
un-bg="black"
un-text="white"
un-font="sans"
un-flex="~ justify-center items-center"
>
<slot />
</div>
</main>

View File

@@ -1,22 +1,191 @@
<main un-grid="~ rows-4">
<div un-h="sm" un-flex="~ justify-center items-center" un-bg="#33578a">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<img src="/api.svg" alt="">
</div>
<div un-h="sm" un-flex="~ justify-center items-center" un-bg="#0d1117">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<img src="/api.svg" alt="">
</div>
<div un-h="sm" un-flex="~ justify-center items-center" un-bg="#ffffff">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<img src="/api.svg" alt="">
</div>
<div un-h="sm" un-flex="~ justify-center items-center" un-bg="#0a0c10">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<img src="/api.svg" alt="">
</div>
<div un-h="sm" un-flex="~ justify-center items-center" un-bg="#22272e">
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
<img src="/api.svg" alt="">
</div>
</main>
<script lang="ts">
import type { PageData } from './$types';
import { page } from '$app/stores';
export let data: PageData;
let title = 'Hello World';
let subtitle = 'Welcome to marknow';
let iconName = 'solar:book-bookmark-minimalistic-bold';
let foreground = '#000000';
let background = '#ffffff';
let isVertical = false;
let isRtl = false;
const id = writable(Math.random());
let copied = false;
$: url = new URL(
`${$page.url.protocol}//${$page.url.host}/v1/banners/${
isVertical ? 'vertical' : 'horizontal'
}.svg?title=${title}${subtitle ? `&subtitle=${subtitle}` : ''}${
iconName ? `&icon=${iconName}` : ''
}${
foreground !== '#000000'
? `&foreground=${foreground.replace('#', '')}`
: ''
}${
background !== '#ffffff'
? `&background=${background.replace('#', '')}`
: ''
}${isRtl ? '&rtl=true' : ''}`,
);
</script>
<div un-h="sm" un-flex="~">
<section un-flex="~ col" un-m="r-5" un-w="20em" un-max-w="20em">
<div un-flex="~ col">
<label un-text="sm" for="title-input">Title</label>
<textarea
type="text"
name="title text"
id="title-input"
un-p="2"
un-font="bold"
un-min-h="1em"
un-max-h="5em"
un-resize-y
un-outline="0"
bind:value={title}
on:input={() => ($id = Math.random())}
/>
</div>
<div un-m="t-3" un-flex="~ col">
<label un-text="sm" for="subtitle-input">Subtitle</label>
<textarea
type="text"
name="subtitle text"
id="subtitle-input"
un-p="2"
un-font="bold"
un-min-h="4em"
un-max-h="9em"
un-resize-y
un-outline="0"
bind:value={subtitle}
on:input={() => ($id = Math.random())}
/>
</div>
<div un-m="t-3" un-flex="~ col">
<label un-text="sm" for="icon-input">Iconify Icon</label>
<input
type="text"
name="icon name"
id="icon-input"
un-p="2"
un-font="bold"
un-outline="0"
bind:value={iconName}
on:input={() => ($id = Math.random())}
/>
</div>
<div un-m="t-3">
<input
type="color"
class="p-0 w-1.5em h-1.5em b-0 rounded-md bg-transparent"
name="foreground color"
id="foreground-input"
bind:value={foreground}
on:input={() => ($id = Math.random())}
/>
<label un-text="sm" for="foreground-input">Foreground color</label>
<input
type="color"
class="p-0 w-1.5em h-1.5em b-0 rounded-md bg-transparent"
name="background color"
id="background-input"
bind:value={background}
on:input={() => ($id = Math.random())}
/>
<label un-text="sm" for="background-input">Background color</label>
</div>
<div un-m="t-3">
<input
type="checkbox"
name="vertical layout"
id="vertical-input"
bind:checked={isVertical}
on:input={() => ($id = Math.random())}
/>
<label un-text="sm" for="vertical-input">Vertical layout</label>
<input
un-m="l-5"
type="checkbox"
name="right to left"
id="rtl-input"
bind:checked={isRtl}
on:input={() => ($id = Math.random())}
/>
<label un-text="sm" for="rtl-input">Right-to-Left</label>
</div>
</section>
<section un-flex="~ col">
{#key isVertical || isRtl}
{#key $id}
<Banner
options={{
title,
subtitle,
fonts: data.banner.fonts,
layout: isVertical ? 'vertical' : 'horizontal',
colors: { background, foreground },
icon: iconName,
rtl: isRtl,
}}
/>
{/key}
{/key}
<button
un-m="1em"
un-appearance-none
un-bg="transparent"
un-text="white opacity-50 start"
un-border="0"
un-max-w="1000px"
un-cursor="pointer"
un-relative
on:click={() => {
navigator.clipboard.writeText(url.toString());
copied = true;
}}
data-tooltip-target
on:mouseleave={() => (copied = false)}
>
<p
id="tooltip"
role="tooltip"
un-absolute
un-invisible
un-top="-3em"
un-z="1"
un-transition="all"
un-opacity="0"
un-transform="translate-y-5px"
>
<span un-i-solar-clipboard-add-bold un-inline-block un-m="r-1">
Pointer
</span>
{#if copied}
Copied to clipboard!
{:else}
Copy to clipboard
{/if}
</p>
<code>{url}</code>
</button>
</section>
</div>
<style>
input[type="text"],
textarea {
@apply bg-transparent b-0 bg-white text-black rounded-md font-sans;
}
[data-tooltip-target]:hover > [role="tooltip"] {
transform: translateY(0);
opacity: 1;
visibility: visible;
}
</style>

View File

@@ -0,0 +1,19 @@
import type { BannerOptions } from '@marknow/banners';
import type { PageLoad } from './$types';
export const load = (async ({ fetch }) => {
const fonts: BannerOptions['fonts'] = {
title: {
data: await (await fetch('/Mona-Sans-SemiBold.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 600,
},
subtitle: {
data: await (await fetch('/Mona-Sans-Regular.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 400,
},
};
return { banner: { fonts } };
}) satisfies PageLoad;

View File

@@ -1,38 +0,0 @@
import type { RequestHandler } from '@sveltejs/kit';
import newBanner from '@marknow/banners';
export const GET = (async ({ fetch }): Promise<Response> => {
const banner = await newBanner({
title: 'Hello world',
subtitle: 'This is a test!',
icon: 'solar:hand-shake-bold-duotone',
colors: {
background: '#000000',
foreground: '#ffffff',
},
fonts: {
title: {
data: await (await fetch('/Mona-Sans-SemiBold.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 600,
style: 'normal',
},
subtitle: {
data: await (await fetch('/Mona-Sans-Regular.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 400,
style: 'normal',
},
},
libConfig: {
fetcher: fetch,
},
});
return new Response(`${banner.toString()}`, {
status: 200,
headers: {
'Content-type': 'image/svg+xml',
},
});
}) satisfies RequestHandler;

View File

@@ -0,0 +1,50 @@
import type { BannerOptions } from '@marknow/banners';
import createBanner from '@marknow/banners';
import { type RequestHandler, error } from '@sveltejs/kit';
export const GET = (async ({ params, url, fetch }) => {
const title: string | null = url.searchParams.get('title');
if (!title)
throw error(400, { message: 'Please provide a title parameter for the banner' });
const layout = <BannerOptions['layout']>params.layout?.replace('.svg', '');
const subtitle: string | undefined = url.searchParams.get('subtitle') ?? undefined;
const icon: string | undefined = url.searchParams.get('icon') ?? undefined;
const rtl: boolean = url.searchParams.get('rtl') !== 'false' && url.searchParams.get('rtl') !== null;
const colors: BannerOptions['colors'] = {
foreground: `#${url.searchParams.get('foreground') ?? '000000'}`,
background: `#${url.searchParams.get('background') ?? 'ffffff'}`,
};
const banner = await createBanner({
title,
layout,
subtitle,
icon,
rtl,
colors,
fonts: {
title: {
data: await (await fetch('/Mona-Sans-SemiBold.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 600,
},
subtitle: {
data: await (await fetch('/Mona-Sans-Regular.woff')).arrayBuffer(),
name: 'Mona Sans',
weight: 400,
},
},
libConfig: {
fetcher: fetch,
},
});
return new Response(banner.svg, {
headers: {
'Content-type': 'image/svg+xml',
},
status: 200,
});
}) satisfies RequestHandler;

View File

@@ -46,7 +46,8 @@ export default defineConfig({
}),
],
dirs: [
'./src/lib',
'./src/lib/components',
'./src/routes',
],
importPathTransform: (importPath) => {
if (path.extname(importPath) === '.svg')
@@ -69,7 +70,7 @@ export default defineConfig({
'svelte/transition',
],
dirs: [
'./src/**/*',
'./src/lib/*',
],
dts: './src/lib/imports.d.ts',
eslintrc: {

View File

@@ -17,7 +17,7 @@
"build:pkg": "turbo run build --filter='./packages/*'",
"dev": "turbo run dev --filter=\"@marknow/www\"",
"preview": "turbo run preview --filter=\"@marknow/www\"",
"release": "pnpm run build:pkg && changeset publish --access public"
"release": "pnpm run build:pkg && changeset publish"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.5",

View File

@@ -0,0 +1,7 @@
# @marknow/banners
## 1.1.0
### Minor Changes
- 2612c4a: Exposed helper functions of the package, so it can be easier to integrate in things like the live editor.

View File

@@ -1,7 +1,7 @@
{
"name": "@marknow/banners",
"type": "module",
"version": "1.0.0",
"version": "1.1.0",
"private": false,
"source": "./src/index.js",
"description": "",
@@ -42,5 +42,8 @@
},
"directories": {
"test": "tests"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -14,9 +14,6 @@
* MIT OR Apache-2.0
*/
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
/**
* @param {import('./types').Reader | undefined} [reader=import('node:fs').readFile]
* The function to be used as reader of the local files.
@@ -28,6 +25,8 @@ import { fileURLToPath } from 'node:url';
* @access protected
*/
export async function getMonaSansFonts(reader) {
const { dirname, join } = await import('node:path');
const { fileURLToPath } = await import('node:url');
reader ||= (await import('node:fs/promises')).readFile;
const __filename = fileURLToPath(import.meta.url);

View File

@@ -29,7 +29,7 @@
* @returns {string}
*
* @module \@marknow/banners
* @access protected
* @access public
*/
export default function html({
dimensions,

View File

@@ -29,7 +29,7 @@
* @returns {Promise<string>}
*
* @module \@marknow/banners
* @access protected
* @access public
*/
export async function getIcon(icon, fetcher = fetch) {
if (!isIconName(icon) && !isValidUrl(icon)) {

View File

@@ -19,6 +19,8 @@
* MIT OR Apache-2.0
*/
import type { BannerOptions, Colors, Fetcher, Font } from './types'
/**
* The banner constructor function. Use the options to customize the
* appearance of the resulting banner.
@@ -64,6 +66,88 @@
* @module \@marknow/banners
* @access public
*/
export default function banner({ title, subtitle, icon, layout, config, }: import('./types').BannerOptions): Promise<import('./types').Banner>;
export default function banner(options: BannerOptions): Promise<import('./types').Banner>;
export type { BannerOptions, Banner } from './types'
/**
* Constructor of the HTML banner converted to VNodes to be used in satori.
* Use the properties to customize and complete it.
*
* @typedef {{
* dimensions: { width: number, height: number },
* fonts: { title: Font, subtitle: Font },
* layout: 'vertical' | 'horizontal',
* colors: Colors,
* rtl: boolean,
* }} Props
* @param {Props} properties
* Properties to be applied on the html.
*
* @returns {string}
*
* @module \@marknow/banners
* @access public
*/
export function bannerHtml(properties: {
dimensions: { width: number, height: number },
layout: 'vertical' | 'horizontal'
fonts: { title: Font, subtitle: Font },
layout: 'vertical' | 'horizontal',
colors: Colors,
rtl: boolean,
}): string;
/**
* Utility function used to get a SVG icon from Iconify OR from an url passed as the icon.
*
* If the `icon` parameter is not a valid icon name or url,
* it returns the `icon` itself.
*
* @param {string} icon
* The icon's name or url endpoint.
*
* @param {import('./types').Fetcher | undefined} [fetcher=globalThis.fetch]
* Fetch function to be used.
*
* @returns {Promise<string>}
*
* @module \@marknow/banners
* @access public
*/
export function getIcon(icon: string, fetcher?: Fetcher): Promise<string>
/**
* Utility function used to set the icons SVG width and height to the specified dimensions.
*
* @param {string} svg
* The svg string.
*
* @param {{width?: string | number, height?: string | number}} dimensions
* The dimensions values, if type number it is converted to pixels.
*
* @returns {string}
*
* @module \@marknow/banners
* @access protected
*/
export function setIconDimensions(
svg: string,
dimensions: {
width?: string | number,
height?: string | number
}
): string
/**
* Small utility function used to truncate long texts on the banner
*
* @param {string} string - Text string to be truncated.
* @param {number} maxChar - Maximum number of characters.
*
* @returns {string}
*
* @module \@marknow/banners
* @access package
*/
export function truncateText(string: string, maxChar: number): string;
export type { BannerOptions, Banner };

View File

@@ -67,7 +67,7 @@ import { getIcon, setIconDimensions } from './icons';
* @module \@marknow/banners
* @access public
*/
export default async function banner({
export async function banner({
title,
fonts,
icon = '',
@@ -133,3 +133,5 @@ export default async function banner({
function truncateText(string, maxChar) {
return string.length > maxChar ? `${string.slice(0, maxChar)}...` : string;
}
export { bannerHtml, getIcon, setIconDimensions, banner as default, truncateText };

View File

@@ -6,7 +6,7 @@ describe('Iconify icons', async () => {
const result = await banner({
title: 'Hello World',
subtitle: 'This is a test',
// eslint-disable-next-line spellcheck/spell-checker
icon: 'solar:test-tube-minimalistic-bold-duotone',
});
expect(result.toString()).toMatchFileSnapshot('./__snapshots__/icons-withIconifyIcon.svg');

119
pnpm-lock.yaml generated
View File

@@ -64,13 +64,13 @@ importers:
version: link:../../packages/banners
'@poppanator/sveltekit-svg':
specifier: ^3.0.1
version: 3.0.1(svelte@3.59.1)(vite@4.3.9)
version: 3.0.1(svelte@4.0.1)(vite@4.3.9)
'@sveltejs/adapter-vercel':
specifier: ^3.0.1
version: 3.0.1(@sveltejs/kit@1.20.2)
version: 3.0.1(@sveltejs/kit@1.21.0)
'@sveltejs/kit':
specifier: ^1.20.2
version: 1.20.2(svelte@3.59.1)(vite@4.3.9)
specifier: ^1.20.4
version: 1.21.0(svelte@4.0.1)(vite@4.3.9)
'@typescript-eslint/eslint-plugin':
specifier: ^5.59.11
version: 5.59.11(@typescript-eslint/parser@5.59.11)(eslint@8.43.0)(typescript@5.1.3)
@@ -82,7 +82,7 @@ importers:
version: 0.52.7
mdsvex:
specifier: ^0.10.6
version: 0.10.6(svelte@3.59.1)
version: 0.10.6(svelte@4.0.1)
rehype-external-links:
specifier: ^2.1.0
version: 2.1.0
@@ -93,19 +93,19 @@ importers:
specifier: ^0.10.1
version: 0.10.1
svelte:
specifier: ^3.59.1
version: 3.59.1
specifier: ^4.0.0
version: 4.0.1
svelte-check:
specifier: ^3.4.3
version: 3.4.3(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@3.59.1)
version: 3.4.3(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@4.0.1)
svelte-preprocess:
specifier: ^5.0.4
version: 5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@3.59.1)(typescript@5.1.3)
specifier: ^5.0.3
version: 5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@4.0.1)(typescript@5.1.3)
tslib:
specifier: ^2.5.3
version: 2.5.3
typescript:
specifier: ^5.1.3
specifier: ^5.0.0
version: 5.1.3
unocss:
specifier: ^0.52.7
@@ -2520,13 +2520,13 @@ packages:
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
dev: true
/@poppanator/sveltekit-svg@3.0.1(svelte@3.59.1)(vite@4.3.9):
/@poppanator/sveltekit-svg@3.0.1(svelte@4.0.1)(vite@4.3.9):
resolution: {integrity: sha512-bRvOZEwQLiM6bVnQ5Gj9Af11ifeuf1BS58wUXeMqc4YfzhENzqfT5SxZVwfQXrPOLYnVUmzxe+cxPXAXDgquJA==}
peerDependencies:
svelte: 3.x
vite: '>=3.x'
dependencies:
svelte: 3.59.1
svelte: 4.0.1
svgo: 3.0.2
vite: 4.3.9(@types/node@14.18.33)(sass@1.63.6)
dev: true
@@ -2678,12 +2678,12 @@ packages:
string.prototype.matchall: 4.0.8
dev: true
/@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.20.2):
/@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.21.0):
resolution: {integrity: sha512-PBY3YRm7Q7Prax07mxD/rvcho2CntGkYncAIkz2DtG5NTcVG5JZ1RM627it5zYYtc2/RB3YjMkZuCMBqDCiPkA==}
peerDependencies:
'@sveltejs/kit': ^1.5.0
dependencies:
'@sveltejs/kit': 1.20.2(svelte@3.59.1)(vite@4.3.9)
'@sveltejs/kit': 1.21.0(svelte@4.0.1)(vite@4.3.9)
'@vercel/nft': 0.22.6
esbuild: 0.17.19
transitivePeerDependencies:
@@ -2691,8 +2691,8 @@ packages:
- supports-color
dev: true
/@sveltejs/kit@1.20.2(svelte@3.59.1)(vite@4.3.9):
resolution: {integrity: sha512-MtR1i+HtmYWcRgtubw1GQqT/+CWXL/z24PegE0xYAdObbhdr7YtEfmoe705D/JZMtMmoPXrmSk4W0MfL5A3lYw==}
/@sveltejs/kit@1.21.0(svelte@4.0.1)(vite@4.3.9):
resolution: {integrity: sha512-CBsYoI34SjtOQp0eG85dmVnvTR3Pjs8VgAQhO0CgQja9BIorKl808F1X8EunPhCcyek5r5lKQE1Mmbi0RuzHqA==}
engines: {node: ^16.14 || >=18}
hasBin: true
requiresBuild: true
@@ -2700,7 +2700,7 @@ packages:
svelte: ^3.54.0 || ^4.0.0-next.0
vite: ^4.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 2.4.1(svelte@3.59.1)(vite@4.3.9)
'@sveltejs/vite-plugin-svelte': 2.4.1(svelte@4.0.1)(vite@4.3.9)
'@types/cookie': 0.5.1
cookie: 0.5.0
devalue: 4.3.2
@@ -2711,15 +2711,14 @@ packages:
sade: 1.8.1
set-cookie-parser: 2.6.0
sirv: 2.0.3
svelte: 3.59.1
tiny-glob: 0.2.9
svelte: 4.0.1
undici: 5.22.1
vite: 4.3.9(@types/node@14.18.33)(sass@1.63.6)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte-inspector@1.0.2(@sveltejs/vite-plugin-svelte@2.4.1)(svelte@3.59.1)(vite@4.3.9):
/@sveltejs/vite-plugin-svelte-inspector@1.0.2(@sveltejs/vite-plugin-svelte@2.4.1)(svelte@4.0.1)(vite@4.3.9):
resolution: {integrity: sha512-Cy1dUMcYCnDVV/hPLXa43YZJ2jGKVW5rA0xuNL9dlmYhT0yoS1g7+FOFSRlgk0BXKk/Oc7grs+8BVA5Iz2fr8A==}
engines: {node: ^14.18.0 || >= 16}
peerDependencies:
@@ -2727,28 +2726,28 @@ packages:
svelte: ^3.54.0 || ^4.0.0-next.0
vite: ^4.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 2.4.1(svelte@3.59.1)(vite@4.3.9)
'@sveltejs/vite-plugin-svelte': 2.4.1(svelte@4.0.1)(vite@4.3.9)
debug: 4.3.4
svelte: 3.59.1
svelte: 4.0.1
vite: 4.3.9(@types/node@14.18.33)(sass@1.63.6)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte@2.4.1(svelte@3.59.1)(vite@4.3.9):
/@sveltejs/vite-plugin-svelte@2.4.1(svelte@4.0.1)(vite@4.3.9):
resolution: {integrity: sha512-bNNKvoRY89ptY7udeBSCmTdCVwkjmMcZ0j/z9J5MuedT8jPjq0zrknAo/jF1sToAza4NVaAgR9AkZoD9oJJmnA==}
engines: {node: ^14.18.0 || >= 16}
peerDependencies:
svelte: ^3.54.0 || ^4.0.0-next.0
vite: ^4.0.0
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 1.0.2(@sveltejs/vite-plugin-svelte@2.4.1)(svelte@3.59.1)(vite@4.3.9)
'@sveltejs/vite-plugin-svelte-inspector': 1.0.2(@sveltejs/vite-plugin-svelte@2.4.1)(svelte@4.0.1)(vite@4.3.9)
debug: 4.3.4
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.0
svelte: 3.59.1
svelte-hmr: 0.15.2(svelte@3.59.1)
svelte: 4.0.1
svelte-hmr: 0.15.2(svelte@4.0.1)
vite: 4.3.9(@types/node@14.18.33)(sass@1.63.6)
vitefu: 0.2.4(vite@4.3.9)
transitivePeerDependencies:
@@ -2983,7 +2982,7 @@ packages:
grapheme-splitter: 1.0.4
ignore: 5.2.4
natural-compare-lite: 1.4.0
semver: 7.5.3
semver: 7.5.1
tsutils: 3.21.0(typescript@5.1.3)
typescript: 5.1.3
transitivePeerDependencies:
@@ -3906,6 +3905,12 @@ packages:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
/aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
dependencies:
dequal: 2.0.3
dev: true
/array-buffer-byte-length@1.0.0:
resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
dependencies:
@@ -4032,6 +4037,12 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/axobject-query@3.2.1:
resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
dependencies:
dequal: 2.0.3
dev: true
/babel-plugin-macros@3.1.0:
resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
engines: {node: '>=10', npm: '>=6'}
@@ -4515,6 +4526,16 @@ packages:
resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==}
dev: true
/code-red@1.0.3:
resolution: {integrity: sha512-kVwJELqiILQyG5aeuyKFbdsI1fmQy1Cmf7dQ8eGmVuJoaRVdwey7WaMknr2ZFeVSYSKT0rExsa8EGw0aoI/1QQ==}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
'@types/estree': 1.0.1
acorn: 8.9.0
estree-walker: 3.0.3
periscopic: 3.1.0
dev: true
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -7581,6 +7602,10 @@ packages:
engines: {node: '>=14'}
dev: true
/locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
dev: true
/locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -7884,7 +7909,7 @@ packages:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
dev: true
/mdsvex@0.10.6(svelte@3.59.1):
/mdsvex@0.10.6(svelte@4.0.1):
resolution: {integrity: sha512-aGRDY0r5jx9+OOgFdyB9Xm3EBr9OUmcrTDPWLB7a7g8VPRxzPy4MOBmcVYgz7ErhAJ7bZ/coUoj6aHio3x/2mA==}
peerDependencies:
svelte: 3.x
@@ -7892,7 +7917,7 @@ packages:
'@types/unist': 2.0.6
prism-svelte: 0.4.7
prismjs: 1.29.0
svelte: 3.59.1
svelte: 4.0.1
vfile-message: 2.0.4
dev: true
@@ -10553,7 +10578,7 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/svelte-check@3.4.3(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@3.59.1):
/svelte-check@3.4.3(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@4.0.1):
resolution: {integrity: sha512-O07soQFY3X0VDt+bcGc6D5naz0cLtjwnmNP9JsEBPVyMemFEqUhL2OdLqvkl5H/u8Jwm50EiAU4BPRn5iin/kg==}
hasBin: true
peerDependencies:
@@ -10565,8 +10590,8 @@ packages:
import-fresh: 3.3.0
picocolors: 1.0.0
sade: 1.8.1
svelte: 3.59.1
svelte-preprocess: 5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@3.59.1)(typescript@5.1.3)
svelte: 4.0.1
svelte-preprocess: 5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@4.0.1)(typescript@5.1.3)
typescript: 5.1.3
transitivePeerDependencies:
- '@babel/core'
@@ -10594,16 +10619,16 @@ packages:
espree: 9.5.2
dev: true
/svelte-hmr@0.15.2(svelte@3.59.1):
/svelte-hmr@0.15.2(svelte@4.0.1):
resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
engines: {node: ^12.20 || ^14.13.1 || >= 16}
peerDependencies:
svelte: ^3.19.0 || ^4.0.0-next.0
dependencies:
svelte: 3.59.1
svelte: 4.0.1
dev: true
/svelte-preprocess@5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@3.59.1)(typescript@5.1.3):
/svelte-preprocess@5.0.4(@babel/core@7.22.5)(postcss@8.4.24)(sass@1.63.6)(svelte@4.0.1)(typescript@5.1.3):
resolution: {integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==}
engines: {node: '>= 14.10.0'}
requiresBuild: true
@@ -10649,13 +10674,27 @@ packages:
sass: 1.63.6
sorcery: 0.11.0
strip-indent: 3.0.0
svelte: 3.59.1
svelte: 4.0.1
typescript: 5.1.3
dev: true
/svelte@3.59.1:
resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==}
engines: {node: '>= 8'}
/svelte@4.0.1:
resolution: {integrity: sha512-7n2u7A5cu8xCY6MBiXh/Mg6Lh3+Mw2qXlTDBYhzvCvmSM4L4gc4MVo540UtGcjqBiA48E1VDW+EUpBr7iuBlPg==}
engines: {node: '>=16'}
dependencies:
'@ampproject/remapping': 2.2.1
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.18
acorn: 8.9.0
aria-query: 5.3.0
axobject-query: 3.2.1
code-red: 1.0.3
css-tree: 2.3.1
estree-walker: 3.0.3
is-reference: 3.0.1
locate-character: 3.0.0
magic-string: 0.30.0
periscopic: 3.1.0
dev: true
/svgo@2.8.0:

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}