Merge branch 'master' into BUDI-9296/new-screen-as-modal

This commit is contained in:
Adria Navarro 2025-05-16 17:06:58 +02:00 committed by GitHub
commit fded47b163
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 630 additions and 45 deletions

View File

@ -1,6 +1,6 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "3.11.0",
"version": "3.11.1",
"npmClient": "yarn",
"concurrency": 20,
"command": {

View File

@ -64,9 +64,9 @@
--rounded-medium: 8px;
--rounded-large: 16px;
--font-sans: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI,
--font-sans: "Source Sans 3", -apple-system, BlinkMacSystemFont, Segoe UI,
"Inter", "Helvetica Neue", Arial, "Noto Sans", sans-serif;
--font-accent: "Source Sans Pro", -apple-system, BlinkMacSystemFont, Segoe UI,
--font-accent: "Source Sans 3", -apple-system, BlinkMacSystemFont, Segoe UI,
"Inter", "Helvetica Neue", Arial, "Noto Sans", sans-serif;
--font-serif: "Georgia", Cambria, Times New Roman, Times, serif;
--font-mono: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",

View File

@ -0,0 +1,15 @@
@font-face{
font-family: "Source Sans 3";
font-weight: 200 900;
font-style: normal;
font-stretch: normal;
src: url("/builder/fonts/source-sans-3/SourceSans3VF-Upright.ttf.woff2") format("woff2-variations");
}
@font-face{
font-family: "Source Sans 3";
font-weight: 200 900;
font-style: italic;
font-stretch: normal;
src: url("/builder/fonts/source-sans-3/SourceSans3VF-Italic.ttf.woff2") format("woff2-variations");
}

View File

@ -5,9 +5,7 @@
<meta charset='utf8'>
<meta name='viewport' content='width=device-width'>
<title>Budibase</title>
<link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-3/source-sans-3.css" rel="stylesheet" />
<link href="/builder/fonts/remixicon.css" rel="stylesheet" />
</head>

View File

@ -61,7 +61,6 @@
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.11.2",
"@dagrejs/dagre": "1.1.4",
"@fontsource/source-sans-pro": "^5.0.3",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",

View File

@ -100,6 +100,20 @@
comp: ExecuteScriptV2,
fullWidth: true,
},
[SchemaFieldTypes.LONGFORM]: {
comp: DrawerBindableInput,
props: (opts: FieldProps = {} as FieldProps) => {
const { key, field } = opts
return {
title: field.title ?? getFieldLabel(key, field),
panel: AutomationBindingPanel,
type: field.customType,
updateOnChange: false,
multiline: true,
placeholder: field?.description,
}
},
},
[SchemaFieldTypes.BOOL]: {
comp: Checkbox,
},
@ -309,7 +323,7 @@
*/
const getFieldType = (
field: BaseIOStructure,
block?: AutomationStep | AutomationTrigger
block: AutomationStep | AutomationTrigger
) => {
// Direct customType map
const customType = field.customType && customTypeToSchema[field.customType]

View File

@ -57,7 +57,7 @@
</script>
{#if customLayout}
<!-- Render custom layout 1 or more components in a custom layout -->
<!-- Render 1 or more components in a custom layout -->
<AutomationCustomLayout {context} {bindings} {block} layout={customLayout} />
{:else}
<!-- Render Automation Step Schema > [string, BaseIOStructure][] -->

View File

@ -47,7 +47,8 @@
"icon",
"embed",
"backgroundimage",
"embeddedmap"
"embeddedmap",
"codegenerator"
]
},
{

View File

@ -180,7 +180,7 @@
}
thead th {
font-family: "Source Sans Pro";
font-family: "Source Sans 3";
color: var(--lightText);
white-space: nowrap;
padding: 12px;

View File

@ -24,6 +24,7 @@ export enum DataMode {
}
export enum SchemaFieldTypes {
LONGFORM = "longform",
JSON = "json",
ENUM = "enum",
BOOL = "boolean",
@ -160,6 +161,7 @@ export const customTypeToSchema: Record<string, SchemaFieldTypes> = {
export const typeToSchema: Partial<Record<AutomationIOType, SchemaFieldTypes>> =
{
[AutomationIOType.BOOLEAN]: SchemaFieldTypes.BOOL,
[AutomationIOType.LONGFORM]: SchemaFieldTypes.LONGFORM,
[AutomationIOType.DATE]: SchemaFieldTypes.DATE,
[AutomationIOType.JSON]: SchemaFieldTypes.JSON,
[AutomationIOType.ATTACHMENT]: SchemaFieldTypes.FILE,

View File

@ -17,7 +17,7 @@ const copyFonts = dest =>
viteStaticCopy({
targets: [
{
src: "../../node_modules/@fontsource/source-sans-pro",
src: "./assets/source-sans-3",
dest,
},
{

View File

@ -4558,6 +4558,108 @@
]
}
},
"codegenerator": {
"name": "Barcode/QR Generator",
"icon": "Vignette",
"new": true,
"settings": [
{
"type": "radio",
"label": "Barcode/QR",
"key": "codeType",
"options": ["QR Code", "Barcode"],
"defaultValue": "QR Code"
},
{
"type": "select",
"label": "Size",
"key": "size",
"defaultValue": 200,
"required": true,
"options": [
{
"label": "X Small",
"value": 75
},
{
"label": "Small",
"value": 150
},
{
"label": "Medium",
"value": 200
},
{
"label": "Large",
"value": 250
},
{
"label": "X Large",
"value": 300
},
{
"label": "XX Large",
"value": 350
},
{
"label": "XXX Large",
"value": 400
}
]
},
{
"type": "text",
"key": "value",
"label": "Value",
"defaultValue": "https://docs.budibase.com/"
},
{
"type": "boolean",
"key": "showValue",
"label": "Display value",
"defaultValue": true
},
{
"section": true,
"name": "Customisation",
"settings": [
{
"type": "boolean",
"key": "showLogo",
"label": "Show Logo",
"defaultValue": true
},
{
"type": "text",
"key": "customLogo",
"label": "Logo",
"dependsOn": {
"setting": "showLogo",
"value": true
}
}
]
},
{
"section": true,
"name": "Appearance",
"settings": [
{
"type": "color",
"label": "Primary color",
"key": "primColor",
"defaultValue": "#000",
"dependsOn": {
"setting": "codeType",
"value": "QR Code",
"invert": false
}
}
]
}
]
},
"signaturesinglefield": {
"name": "Signature",
"icon": "AnnotatePen",
@ -5545,12 +5647,26 @@
"wide": true
},
{
"label": "",
"type": "filterConfiguration",
"key": "filterConfig",
"nested": true,
"dependsOn": "targetComponent",
"resetOn": "targetComponent"
"type": "select",
"label": "Size",
"showInBar": true,
"key": "size",
"options": [
{
"label": "Small",
"value": "S"
},
{
"label": "Medium",
"value": "M"
},
{
"label": "Large",
"value": "L"
}
],
"defaultValue": "M",
"wide": true
},
{
"type": "boolean",
@ -5563,6 +5679,14 @@
"label": "Clear filters",
"key": "showClear",
"defaultValue": false
},
{
"label": "",
"type": "filterConfiguration",
"key": "filterConfig",
"nested": true,
"dependsOn": "targetComponent",
"resetOn": "targetComponent"
}
]
},

View File

@ -35,7 +35,9 @@
"sanitize-html": "^2.13.0",
"screenfull": "^6.0.1",
"shortid": "^2.2.15",
"svelte-spa-router": "^4.0.1"
"svelte-spa-router": "^4.0.1",
"jsbarcode": "^3.11.6",
"@svelte-put/qr": "^1.2.1"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "1.4.0",

View File

@ -0,0 +1,155 @@
<script lang="ts">
import { getContext } from "svelte"
import { onMount } from "svelte"
import JsBarcode from "jsbarcode"
import { createQrSvgString } from "@svelte-put/qr"
export let value: string
export let codeType: "QR Code" | "Barcode"
export let showValue: boolean
export let showLogo: boolean
export let customLogo: string | undefined
export let size: number
export let primColor: string
const { styleable } = getContext("sdk")
const component = getContext("component")
let barcodeElement: SVGSVGElement
function generateBarcode() {
if (barcodeElement && value) {
JsBarcode(barcodeElement, value, {
displayValue: false, // Hide the library's built in value, optionally display it later
width: size / 100,
height: size,
})
}
}
let qrContainer: HTMLElement
const generateQr = () => {
if (qrContainer && codeType === "QR Code" && value) {
const svg = createQrSvgString({
data: value,
logo: showLogo ? customLogo : "",
moduleFill: primColor,
anchorOuterFill: primColor,
anchorInnerFill: primColor,
width: size,
height: size,
})
qrContainer.innerHTML = svg
}
}
onMount(() => {
if (codeType === "Barcode") {
generateBarcode()
} else {
generateQr()
}
})
$: if (codeType === "Barcode" && value && barcodeElement && size) {
generateBarcode()
}
$: if (
codeType === "QR Code" &&
value &&
qrContainer &&
(showLogo !== undefined || customLogo !== undefined || size || primColor)
) {
generateQr()
}
</script>
<div
class="overall"
use:styleable={$component.styles}
styles="border: 3px solid red; width: 100px; height: 200px;"
>
{#if value}
{#if codeType === "QR Code"}
<div class="qr-container">
<div bind:this={qrContainer} />
<div class="qr-value" style="color: {primColor}; max-width: {size}px;">
{showValue ? value : ""}
</div>
</div>
{:else}
<div class="barcode-container">
<div class="logo-and-barcode" style="height: {size}px, width: 100%">
{#if showLogo && customLogo}
<img
class="custom-logo"
src={customLogo}
alt="logo"
style="height: {size}px"
/>
{/if}
{#if value}
<svg class="barcode" bind:this={barcodeElement} height={size} />
{/if}
</div>
{#if showValue}
<div class="barcode-value">
<p>{value}</p>
</div>
{/if}
</div>
{/if}
{:else}
<p>
Please add a value to generate your {codeType === "QR Code"
? "QR Code"
: "Barcode"}
</p>
{/if}
</div>
<style>
.overall {
display: flex;
flex-direction: row;
justify-content: center;
}
.qr-value {
word-wrap: break-word;
overflow-wrap: break-word;
text-align: center;
}
.qr-container {
display: flex;
flex-direction: column;
align-items: center;
}
.barcode-container {
max-width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
padding: 12px;
background-color: white;
}
.logo-and-barcode {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
overflow: hidden;
}
.logo-and-barcode img {
margin-left: 10px;
}
.barcode-value p {
margin: 0;
color: black;
}
</style>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { getContext } from "svelte"
import { getContext, onDestroy } from "svelte"
import { Pagination, ProgressCircle } from "@budibase/bbui"
import { fetchData, QueryUtils } from "@budibase/frontend-core"
import type {
@ -175,6 +175,10 @@
interval = setInterval(fetch.refresh, Math.max(10000, autoRefresh * 1000))
}
}
onDestroy(() => {
clearInterval(interval) // Clears auto-refresh when navigating away
})
</script>
<div use:styleable={$component.styles} class="container">

View File

@ -32,6 +32,7 @@
export let showClear: boolean | undefined = false
export let filterConfig: FilterConfig[] | undefined = []
export let targetComponent: any
export let size: string | undefined = "M"
const memoFilters = memo({} as Record<string, SearchFilter>)
const component = getContext("component")
@ -405,6 +406,7 @@
{#each visibleFilters || [] as config}
{@const filter = $memoFilters[config.field]}
<FilterButton
{size}
{config}
{filter}
{schema}
@ -424,7 +426,7 @@
/>
{/each}
{#if showClear && Object.keys(filters).length}
<Button size={"S"} secondary on:click={clearAll}>Clear all</Button>
<Button {size} secondary on:click={clearAll}>Clear all</Button>
{/if}
</Container>
</div>

View File

@ -170,7 +170,7 @@
}}
>
<svg
class="spectrum-Icon spectrum-Icon--sizeS"
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
focusable="false"
aria-hidden="true"
aria-label={icon}
@ -200,7 +200,7 @@
z-index: 1;
}
.toggle-wrap svg {
width: 12px;
scale: 90%;
pointer-events: none;
}
.filter-button-wrap.inactive .spectrum-Button .spectrum-Icon {
@ -212,6 +212,17 @@
display: flex;
gap: var(--spacing-xs);
}
.spectrum-Button--sizeM,
.spectrum-Button--sizeL {
gap: var(--spacing-s);
}
.spectrum-Button--sizeL {
padding-left: calc(1em * 0.9);
padding-right: calc(1em * 0.9);
}
.spectrum-Button.is-disabled {
cursor: default;
}

View File

@ -38,6 +38,7 @@ export { default as textv2 } from "./Text.svelte"
export { default as filter } from "./filter/Filter.svelte"
export { default as accordion } from "./Accordion.svelte"
export { default as singlerowprovider } from "./SingleRowProvider.svelte"
export { default as codegenerator } from "./CodeGenerator.svelte"
export * from "./charts"
export * from "./forms"
export * from "./blocks"

View File

@ -100,7 +100,7 @@
mix-blend-mode: multiply;
background: rgb(0 0 0);
font-size: 30px;
font-family: Source Sans Pro;
font-family: Source Sans 3;
-webkit-font-smoothing: antialiased;
}

@ -1 +1 @@
Subproject commit f2cbe5aff7645eb9b0b4e864924a1e1171ad85bf
Subproject commit 271b8677c3ea814395cd67a10137900ec3a34dc7

View File

@ -39,9 +39,10 @@
<link rel="icon" type="image/png" href="/builder/bblogo.png" />
{/if}
<link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
<link
href="/builder/fonts/source-sans-3/source-sans-3.css"
rel="stylesheet"
/>
<link href="/builder/fonts/remixicon.css" rel="stylesheet" />
<style>
@ -65,7 +66,7 @@
height: 100vh;
width: 100vw;
display: none;
font-family: "Source Sans Pro", sans-serif;
font-family: "Source Sans 3", sans-serif;
flex-direction: column;
justify-content: center;
align-items: center;

View File

@ -1,9 +1,7 @@
<html lang="en">
<head>
<title>Budibase Builder Preview</title>
<link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
<link href="/builder/fonts/source-sans-3/source-sans-3.css" rel="stylesheet" />
<link href="/builder/fonts/remixicon.css" rel="stylesheet" />
<style>
html, body {

View File

@ -41,7 +41,7 @@ export async function run({
try {
let response
const llm = await ai.getLLM(inputs.model)
const llm = await ai.getLLM({ model: inputs.model })
response = llm
? (await llm.prompt(inputs.prompt)).message
: await legacyOpenAIPrompt(inputs)

View File

@ -43,8 +43,10 @@ export const definition: AutomationStepDefinition = {
title: "Email Subject",
},
contents: {
type: AutomationIOType.STRING,
title: "HTML Contents",
type: AutomationIOType.LONGFORM,
title: "Message",
description:
"Use markdown or HTML for rich text formatting: **bold**, _italics_, # Headings, * Bullets, <br> for line breaks, and more.",
},
addInvite: {
type: AutomationIOType.BOOLEAN,

View File

@ -16,6 +16,7 @@ export enum AutomationIOType {
DATE = "date",
DATETIME = "datetime",
ATTACHMENT = "attachment",
LONGFORM = "longform",
}
export enum AutomationCustomIOType {

View File

@ -95,6 +95,7 @@ export type AIColumnSchema =
export interface LLMConfigOptions {
model: string
apiKey?: string
maxTokens?: number
}
export interface LLMProviderConfig extends LLMConfigOptions {

View File

@ -54,6 +54,7 @@
"dotenv": "8.6.0",
"email-validator": "^2.0.4",
"global-agent": "3.0.0",
"http-graceful-shutdown": "^3.1.12",
"ical-generator": "4.1.0",
"joi": "17.6.0",
"jsonwebtoken": "9.0.2",
@ -68,6 +69,7 @@
"koa-static": "5.0.0",
"koa-useragent": "^4.1.0",
"lodash": "4.17.21",
"marked": "^15.0.11",
"node-fetch": "2.6.7",
"nodemailer": "6.9.9",
"passport-google-oauth": "2.0.0",
@ -75,8 +77,7 @@
"pouchdb": "7.3.0",
"pouchdb-all-dbs": "1.1.1",
"server-destroy": "1.0.1",
"uuid": "^8.3.2",
"http-graceful-shutdown": "^3.1.12"
"uuid": "^8.3.2"
},
"devDependencies": {
"@jest/types": "^29.6.3",
@ -92,6 +93,7 @@
"@types/server-destroy": "1.0.1",
"@types/supertest": "2.0.14",
"@types/uuid": "8.3.4",
"cheerio": "^1.0.0",
"jest": "29.7.0",
"maildev": "^2.2.1",
"nock": "^13.5.4",

View File

@ -9,6 +9,7 @@ import {
stopMailserver,
} from "../../../../tests/mocks/email"
import { objectStore } from "@budibase/backend-core"
import * as cheerio from "cheerio"
describe("/api/global/email", () => {
const config = new TestConfiguration()
@ -266,4 +267,118 @@ describe("/api/global/email", () => {
`DTEND:${formatDate(endTime)}`
)
})
it("Should parse valid markdown content from automation steps into valid HTML.", async () => {
// Basic verification that the markdown is being processed.
const email = await captureEmail(mailserver, async () => {
const res = await config.api.emails.sendEmail({
email: "to@example.com",
subject: "Test",
userId: config.user!._id,
contents: `test@home.com [Call Me!](tel:1111111)`,
purpose: EmailTemplatePurpose.CUSTOM,
})
expect(res.message).toBeDefined()
})
const $ = cheerio.load(email.html)
// Verify the email body rendered
const emailBody = $("td.email-body").first()
expect(emailBody.length).toBe(1)
// Verify a valid link was generated and is queryable
const emailLink = $("a[href^='mailto:']").first()
expect(emailLink.length).toBe(1)
expect(emailLink.text()).toBe("test@home.com")
// Verify the markdown link has been built correctly
const phoneLink = $("a[href^='tel:']").first()
expect(phoneLink.length).toBe(1)
expect(phoneLink.text()).toBe("Call Me!")
expect(phoneLink.attr("href")).toBe("tel:1111111")
})
it("Should ignore invalid markdown content and return nothing", async () => {
// The only failure case for a parse with marked is 'undefined'
// It should be caught and resolve to nothing.
const email = await captureEmail(mailserver, async () => {
const res = await config.api.emails.sendEmail({
email: "to@example.com",
subject: "Test",
userId: config.user!._id,
contents: undefined,
purpose: EmailTemplatePurpose.CUSTOM,
})
expect(res.message).toBeDefined()
})
const $ = cheerio.load(email.html)
const emailBody = $("td.email-body").first()
expect(emailBody.length).toBe(1)
const bodyText = emailBody.text().trim()
expect(bodyText).toBe("")
})
it("Should render a mixture of content. Plain text, markdown and HTML", async () => {
// A more involved check to ensure all content types are still respected
const email = await captureEmail(mailserver, async () => {
const res = await config.api.emails.sendEmail({
email: "to@example.com",
subject: "Test",
userId: config.user!._id,
contents: `<div class="html-content"><strong>Some content</strong></div>
# A heading
- This should be list entry 1
- This should be list entry 2
Some plain text`,
purpose: EmailTemplatePurpose.CUSTOM,
})
expect(res.message).toBeDefined()
})
const $ = cheerio.load(email.html)
const emailBody = $("td.email-body").first()
expect(emailBody.length).toBe(1)
const divEle = emailBody.find("div.html-content").first()
expect(divEle.length).toBe(1)
expect(divEle.text()).toBe("Some content")
const heading = emailBody.find("h1").first()
expect(heading.length).toBe(1)
expect(heading.text()).toBe("A heading")
// Both list items rendered
const listEles = emailBody.find("ul li")
expect(listEles.length).toBe(2)
const plainText = emailBody.find("p")
expect(plainText.length).toBe(1)
expect(plainText.text()).toBe("Some plain text")
})
it("Should only parse markdown content for the CUSTOM email template used in automation steps", async () => {
const email = await captureEmail(mailserver, async () => {
const res = await config.api.emails.sendEmail({
email: "to@example.com",
subject: "Test",
userId: config.user!._id,
purpose: EmailTemplatePurpose.INVITATION,
})
expect(res.message).toBeDefined()
})
const $ = cheerio.load(email.html)
const emailBody = $("td.email-body").first()
expect(emailBody.length).toBe(1)
const heading = emailBody.find("h1").first()
expect(heading.length).toBe(1)
// The email should not be parsed as markdown.
expect(heading.text()).toBe("Hi, to@example.com!")
})
})

View File

@ -47,7 +47,7 @@
body,
td,
th {
font-family: "Source Sans Pro", Helvetica, Arial, sans-serif;
font-family: "Source Sans 3", Helvetica, Arial, sans-serif;
}
h1 {

View File

@ -12,6 +12,7 @@ import {
import { configs, cache, objectStore, HTTPError } from "@budibase/backend-core"
import ical from "ical-generator"
import _ from "lodash"
import { marked } from "marked"
import nodemailer from "nodemailer"
import SMTPTransport from "nodemailer/lib/smtp-transport"
@ -97,7 +98,10 @@ async function buildEmail(
}
context = {
...context,
contents,
contents:
purpose === EmailTemplatePurpose.CUSTOM
? marked.parse(contents || "")
: contents,
email,
name,
user: user || {},

145
yarn.lock
View File

@ -3279,11 +3279,6 @@
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d"
integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==
"@fontsource/source-sans-pro@^5.0.3":
version "5.0.3"
resolved "https://registry.yarnpkg.com/@fontsource/source-sans-pro/-/source-sans-pro-5.0.3.tgz#7d6e84a8169ba12fa5e6ce70757aa2ca7e74d855"
integrity sha512-mQnjuif/37VxwRloHZ+wQdoozd2VPWutbFSt1AuSkk7nFXIBQxHJLw80rgCF/osL0t7N/3Gx1V7UJuOX2zxzhQ==
"@fortawesome/fontawesome-common-types@6.4.2":
version "6.4.2"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz#1766039cad33f8ad87f9467b98e0d18fbc8f01c5"
@ -6102,6 +6097,13 @@
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-4.3.1.tgz#d333fa41909f691c8750b5c15ad9ba029df2248e"
integrity sha512-rX6Iasu9BsFMVgEN0vGRPm9dmSxva+IK/uqQAa9HM0lliwqUiFrJxrFXHHpiAgNuux/U4srEJwbSpGzfF+CegQ==
"@svelte-put/qr@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@svelte-put/qr/-/qr-1.2.1.tgz#d785848c7b38ceb076df743b97cfed641dab86da"
integrity sha512-VIAze6mCVWdiyq6xnMFhbD3dbTvz9CDFVN3lVkDvx6SYFcstgHuIyb7Pi3aJIr2ClDc4U+W2U+SGhFuQBskvBg==
dependencies:
qrcode-generator "^1.4.4"
"@svelte-put/shortcut@^3.1.0":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@svelte-put/shortcut/-/shortcut-3.1.1.tgz#aba4d7407024d5cff38727e12925c8f81e877079"
@ -8539,6 +8541,11 @@ body-parser@1.20.3:
type-is "~1.6.18"
unpipe "1.0.0"
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
boolean@^3.0.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
@ -8999,6 +9006,35 @@ check-error@^1.0.3:
dependencies:
get-func-name "^2.0.2"
cheerio-select@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==
dependencies:
boolbase "^1.0.0"
css-select "^5.1.0"
css-what "^6.1.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.0.1"
cheerio@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0.tgz#1ede4895a82f26e8af71009f961a9b8cb60d6a81"
integrity sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==
dependencies:
cheerio-select "^2.1.0"
dom-serializer "^2.0.0"
domhandler "^5.0.3"
domutils "^3.1.0"
encoding-sniffer "^0.2.0"
htmlparser2 "^9.1.0"
parse5 "^7.1.2"
parse5-htmlparser2-tree-adapter "^7.0.0"
parse5-parser-stream "^7.1.2"
undici "^6.19.5"
whatwg-mimetype "^4.0.0"
chokidar@3.5.3, chokidar@^3.5.2, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@ -9766,6 +9802,17 @@ css-line-break@^2.1.0:
dependencies:
utrie "^1.0.2"
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"
css-tree@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
@ -9774,6 +9821,11 @@ css-tree@^2.3.1:
mdn-data "2.0.30"
source-map-js "^1.0.1"
css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
css.escape@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
@ -10669,7 +10721,7 @@ domexception@^4.0.0:
dependencies:
webidl-conversions "^7.0.0"
domhandler@^5.0.1, domhandler@^5.0.2:
domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
@ -10692,6 +10744,15 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.1"
domutils@^3.1.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
dot-prop@^5.1.0, dot-prop@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
@ -10884,6 +10945,14 @@ encoding-down@^6.3.0:
level-codec "^9.0.0"
level-errors "^2.0.0"
encoding-sniffer@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz#799569d66d443babe82af18c9f403498365ef1d5"
integrity sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==
dependencies:
iconv-lite "^0.6.3"
whatwg-encoding "^3.1.1"
encoding@^0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
@ -10957,6 +11026,11 @@ entities@^4.2.0, entities@^4.3.0, entities@^4.4.0, entities@^4.5.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
entities@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.0.tgz#09c9e29cb79b0a6459a9b9db9efb418ac5bb8e51"
integrity sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
@ -13116,6 +13190,16 @@ htmlparser2@^8.0.0:
domutils "^3.0.1"
entities "^4.3.0"
htmlparser2@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.1.0"
entities "^4.5.0"
http-assert@^1.3.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
@ -14650,6 +14734,11 @@ js-yaml@^3.10.0, js-yaml@^3.13.1, js-yaml@^3.14.1:
argparse "^1.0.7"
esprima "^4.0.0"
jsbarcode@^3.11.6:
version "3.11.6"
resolved "https://registry.yarnpkg.com/jsbarcode/-/jsbarcode-3.11.6.tgz#96e8fbc3395476e162982a6064b98a09b5ea02c0"
integrity sha512-G5TKGyKY1zJo0ZQKFM1IIMfy0nF2rs92BLlCz+cU4/TazIc4ZH+X1GYeDRt7TKjrYqmPfTjwTBkU/QnQlsYiuA==
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -15971,6 +16060,11 @@ map-obj@^4.0.0:
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
marked@^15.0.11:
version "15.0.11"
resolved "https://registry.yarnpkg.com/marked/-/marked-15.0.11.tgz#08a8d12c285e16259e44287b89ce0d871c9d55e8"
integrity sha512-1BEXAU2euRCG3xwgLVT1y0xbJEld1XOrmRJpUwRCcy7rxhSCwMrmEu9LXoPhHSCJG41V7YcQ2mjKRr5BA3ITIA==
marked@^15.0.8:
version "15.0.8"
resolved "https://registry.yarnpkg.com/marked/-/marked-15.0.8.tgz#39873a3fdf91a520111e48aeb2ef3746d58d7166"
@ -16942,6 +17036,13 @@ npmlog@^6.0.0, npmlog@^6.0.2:
gauge "^4.0.3"
set-blocking "^2.0.0"
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
nunjucks@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-3.2.4.tgz#f0878eef528ce7b0aa35d67cc6898635fd74649e"
@ -17607,6 +17708,21 @@ parse-url@^8.1.0:
dependencies:
parse-path "^7.0.0"
parse5-htmlparser2-tree-adapter@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz#b5a806548ed893a43e24ccb42fbb78069311e81b"
integrity sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==
dependencies:
domhandler "^5.0.3"
parse5 "^7.0.0"
parse5-parser-stream@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz#d7c20eadc37968d272e2c02660fff92dd27e60e1"
integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==
dependencies:
parse5 "^7.0.0"
parse5@6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
@ -17617,6 +17733,13 @@ parse5@^1.5.1:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
integrity sha512-w2jx/0tJzvgKwZa58sj2vAYq/S/K1QJfIB3cWYea/Iu1scFPDQQ3IQiVZTHWtRBwAjv2Yd7S/xeZf3XqLDb3bA==
parse5@^7.0.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05"
integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==
dependencies:
entities "^6.0.0"
parse5@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
@ -18739,6 +18862,11 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==
qrcode-generator@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7"
integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==
qs@6.13.0, qs@^6.10.3, qs@^6.11.0, qs@^6.4.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
@ -21600,6 +21728,11 @@ undici@^5.28.4:
dependencies:
"@fastify/busboy" "^2.0.0"
undici@^6.19.5:
version "6.21.2"
resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.2.tgz#49c5884e8f9039c65a89ee9018ef3c8e2f1f4928"
integrity sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"