Compare commits
8 Commits
58f5af27db
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
e5af5cb2a3
|
|||
|
a1cecd6de4
|
|||
|
053aa97983
|
|||
|
7d86903565
|
|||
|
32b3102070
|
|||
|
1dc6e8b4f9
|
|||
|
1299fc4dd3
|
|||
|
309b0c618f
|
@@ -22,6 +22,24 @@ steps:
|
||||
depends_on:
|
||||
- Install
|
||||
|
||||
- name: Send Prettier Status Notification (failure)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_tests_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Prettier failure 💩"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Prettier
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
- name: Lint
|
||||
image: node:22-bookworm-slim
|
||||
commands:
|
||||
@@ -38,6 +56,24 @@ steps:
|
||||
depends_on:
|
||||
- Lint
|
||||
|
||||
- name: Send Lint Status Notification (failure)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_tests_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Lint failure 💩"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Lint
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
- name: Build
|
||||
image: node:22-bookworm-slim
|
||||
commands:
|
||||
@@ -46,23 +82,41 @@ steps:
|
||||
depends_on:
|
||||
- Tests & Coverage
|
||||
|
||||
# build-full:
|
||||
# image: node:22-bookworm-slim
|
||||
# commands:
|
||||
# - apt-get update
|
||||
# - apt-get install -y --no-install-recommends ca-certificates libasound2 libatk-bridge2.0-0 libatk1.0-0 libcups2 libdrm2 libgbm1 libgtk-3-0 libnss3 libxcomposite1 libxdamage1 libxfixes3 libxkbcommon0 libxrandr2
|
||||
# - rm -rf /var/lib/apt/lists/*
|
||||
# - corepack enable && corepack prepare pnpm@latest --activate
|
||||
# - pnpm run critical-css:install
|
||||
# - pnpm run build:full
|
||||
# depends_on:
|
||||
# - build
|
||||
- name: Send Build Status Notification (failure)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_tests_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Build failure 💩"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Build
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
# e2e:
|
||||
# image: node:22-bookworm-slim
|
||||
# commands:
|
||||
# - corepack enable && corepack prepare pnpm@latest --activate
|
||||
# - pnpm exec playwright install chromium --with-deps
|
||||
# - pnpm run test:e2e
|
||||
# depends_on:
|
||||
# - build
|
||||
- name: Send CI Pipeline Status Notification (success)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_tests_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] CI pipeline success 🎉"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Install
|
||||
- Lint
|
||||
- Prettier
|
||||
- Build
|
||||
when:
|
||||
- status: [success]
|
||||
|
||||
@@ -55,12 +55,16 @@ steps:
|
||||
- name: Send Build Status Notification (success)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
DISCORD_WEBHOOK_URL:
|
||||
from_secret: discord_webhook_url
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_pushes_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"username":"WoodpeckerBot","content":"[%s - Build #%s] Docker images build success 🎉"}' "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" "$DISCORD_WEBHOOK_URL"
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Docker images build success 🎉"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Docker image build (qr-api + qr-web)
|
||||
when:
|
||||
@@ -69,12 +73,16 @@ steps:
|
||||
- name: Send Build Status Notification (failure)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
DISCORD_WEBHOOK_URL:
|
||||
from_secret: discord_webhook_url
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_pushes_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"username":"WoodpeckerBot","content":"[%s - Build #%s] Docker images build failure 💩"}' "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" "$DISCORD_WEBHOOK_URL"
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Docker images build failure 💩"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Docker image build (qr-api + qr-web)
|
||||
when:
|
||||
@@ -103,12 +111,16 @@ steps:
|
||||
- name: Send Deploy Status Notification (success)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
DISCORD_WEBHOOK_URL:
|
||||
from_secret: discord_webhook_url
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_pushes_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"username":"WoodpeckerBot","content":"[%s - Build #%s] Production Deploy success 🎉"}' "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" "$DISCORD_WEBHOOK_URL"
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Production Deploy success 🎉"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Trigger Portainer stack redeploy
|
||||
when:
|
||||
@@ -117,12 +129,16 @@ steps:
|
||||
- name: Send Deploy Status Notification (failure)
|
||||
image: curlimages/curl
|
||||
environment:
|
||||
DISCORD_WEBHOOK_URL:
|
||||
from_secret: discord_webhook_url
|
||||
MATTERMOST_BOT_ACCESS_TOKEN:
|
||||
from_secret: mattermost_bot_access_token
|
||||
MATTERMOST_CHANNEL_ID:
|
||||
from_secret: mattermost_pushes_channel_id
|
||||
MATTERMOST_POST_API_URL:
|
||||
from_secret: mattermost_post_api_url
|
||||
commands:
|
||||
- |
|
||||
BODY=$(printf '{"username":"WoodpeckerBot","content":"[%s - Build #%s] Production Deploy failure 💩"}' "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" "$DISCORD_WEBHOOK_URL"
|
||||
BODY=$(printf '{"channel_id":"%s","message":"[%s - Build #%s] Production Deploy failure 💩"}' "$MATTERMOST_CHANNEL_ID" "$CI_REPO" "$CI_PIPELINE_NUMBER")
|
||||
curl -sS -X POST -H "Content-Type: application/json" -d "$BODY" -H "Authorization: Bearer $MATTERMOST_BOT_ACCESS_TOKEN" $MATTERMOST_POST_API_URL
|
||||
depends_on:
|
||||
- Trigger Portainer stack redeploy
|
||||
when:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Portainer stack: registry-based images (no build). Use with CI/CD webhook redeploy.
|
||||
# Set in Portainer stack env (or .env): REGISTRY, IMAGE_TAG (defaults below).
|
||||
# Images: ${REGISTRY}/mifi-holdings/shorty-qr-api:${IMAGE_TAG}, shorty-qr-web:${IMAGE_TAG}
|
||||
|
||||
services:
|
||||
kutt_db:
|
||||
image: postgres:16-alpine
|
||||
@@ -64,24 +63,27 @@ services:
|
||||
start_period: 40s
|
||||
environment:
|
||||
ADMIN_EMAILS: ${ADMIN_EMAILS:?Set ADMIN_EMAILS}
|
||||
DEFAULT_DOMAIN: mifi.me
|
||||
CUSTOM_DOMAIN_USE_HTTPS: 'true'
|
||||
DEFAULT_DOMAIN: ${DEFAULT_DOMAIN:?Set DEFAULT_DOMAIN}
|
||||
DB_CLIENT: pg
|
||||
DB_HOST: kutt_db
|
||||
DB_PORT: '5432'
|
||||
DB_USER: ${DB_USER:-kutt}
|
||||
DB_PASSWORD: ${DB_PASSWORD:?Set DB_PASSWORD}
|
||||
DB_POOL_MIN: '2'
|
||||
DB_POOL_MAX: '10'
|
||||
DB_NAME: ${DB_NAME:-kutt}
|
||||
DISALLOW_ANONYMOUS_LINKS: 'true'
|
||||
DISALLOW_REGISTRATION: 'true'
|
||||
LINK_LENGTH: 6
|
||||
JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET}
|
||||
MAIL_ENABLED: 'true'
|
||||
MAIL_HOST: 'mail.mifi.holdings'
|
||||
MAIL_PORT: '465'
|
||||
MAIL_HOST: ${MAIL_HOST:?Set MAIL_HOST}
|
||||
MAIL_PORT: ${MAIL_PORT:?Set MAIL_PORT}
|
||||
MAIL_SECURE: 'true'
|
||||
MAIL_USER: 'mailbot@mifi.ventures'
|
||||
MAIL_FROM: 'mifi Holdings Shorty <noreply@mifi.holdings>'
|
||||
MAIL_PASSWORD: '${SMTP_PASSWORD:?Set SMTP_PASSWORD}'
|
||||
MAIL_USER: ${MAIL_USER:?Set MAIL_USER}
|
||||
MAIL_FROM: ${MAIL_FROM:?Set MAIL_FROM}
|
||||
MAIL_PASSWORD: '${MAIL_PASSWORD:?Set MAIL_PASSWORD}'
|
||||
NODE_ENV: production
|
||||
# OIDC_ENABLED: 'true'
|
||||
# OIDC_ISSUER: 'https://git.mifi.dev'
|
||||
@@ -90,18 +92,24 @@ services:
|
||||
REDIS_ENABLED: 'true'
|
||||
REDIS_HOST: kutt_redis
|
||||
REDIS_PORT: '6379'
|
||||
SITE_DOMAIN: link.mifi.me
|
||||
SITE_NAME: 'mifi Shorty'
|
||||
SERVER_CNAME_ADDRESS: ${SERVER_CNAME_ADDRESS:-${DEFAULT_DOMAIN}}
|
||||
SITE_NAME: ${SITE_NAME:-Kutt}
|
||||
labels:
|
||||
- 'traefik.enable=true'
|
||||
- 'docker.network=marina-net'
|
||||
- 'traefik.http.routers.kutt-mifi.rule=Host(`mifi.me`)'
|
||||
- 'traefik.http.routers.kutt-mifi.rule=Host(`${DEFAULT_DOMAIN}`)'
|
||||
- 'traefik.http.routers.kutt-mifi.entrypoints=websecure'
|
||||
- 'traefik.http.routers.kutt-mifi.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.kutt-mifi.service=kutt-short'
|
||||
- 'traefik.http.services.kutt-short.loadbalancer.server.port=3000'
|
||||
# Backend timeout: use transport from file provider (see traefik-kutt-timeout.example.yml).
|
||||
- 'traefik.http.services.kutt-short.loadbalancer.serversTransport=kutt-long-timeout@file'
|
||||
# UI
|
||||
- 'traefik.http.routers.kutt-mifi-ui.rule=Host(`${SERVER_CNAME_ADDRESS}`)'
|
||||
- 'traefik.http.routers.kutt-mifi-ui.entrypoints=websecure'
|
||||
- 'traefik.http.routers.kutt-mifi-ui.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.kutt-mifi-ui.service=kutt-short-ui'
|
||||
- 'traefik.http.services.kutt-short-ui.loadbalancer.server.port=3000'
|
||||
- 'traefik.http.services.kutt-short-ui.loadbalancer.serversTransport=kutt-long-timeout@file'
|
||||
|
||||
qr_api:
|
||||
image: ${REGISTRY:-git.mifi.dev}/mifi-holdings/shorty-qr-api:${IMAGE_TAG:-latest}
|
||||
@@ -140,7 +148,7 @@ services:
|
||||
# Use service_started so the stack can deploy even if qr_api is still broken; switch to service_healthy once qr_api image is fixed.
|
||||
depends_on:
|
||||
qr_api:
|
||||
condition: service_started
|
||||
condition: service_healthy
|
||||
environment:
|
||||
QR_API_URL: http://qr_api:8080
|
||||
healthcheck:
|
||||
@@ -148,7 +156,7 @@ services:
|
||||
- CMD
|
||||
- node
|
||||
- -e
|
||||
- 'require("http").get("http://0.0.0.0:3000/", {timeout: 5000}, (r) => { r.resume(); process.exit(r.statusCode >= 200 && r.statusCode < 500 ? 0 : 1); }).on("error", () => process.exit(1))'
|
||||
- 'require("http").get("http://localhost:3000/", {timeout: 5000}, (r) => { r.resume(); process.exit(r.statusCode >= 200 && r.statusCode < 500 ? 0 : 1); }).on("error", () => process.exit(1))'
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
@@ -76,11 +76,7 @@ services:
|
||||
- 'traefik.http.routers.kutt-mifi.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.kutt-mifi.service=kutt-short'
|
||||
- 'traefik.http.services.kutt-short.loadbalancer.server.port=3000'
|
||||
- 'traefik.http.routers.kutt-link.rule=Host(`link.mifi.me`)'
|
||||
- 'traefik.http.routers.kutt-link.entrypoints=websecure'
|
||||
- 'traefik.http.routers.kutt-link.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.routers.kutt-link.service=kutt'
|
||||
- 'traefik.http.services.kutt.loadbalancer.server.port=3000'
|
||||
- 'traefik.http.services.kutt-short.loadbalancer.serversTransport=kutt-long-timeout@file'
|
||||
|
||||
qr_api:
|
||||
build:
|
||||
@@ -131,7 +127,7 @@ services:
|
||||
- CMD
|
||||
- node
|
||||
- -e
|
||||
- 'require("http").get("http://0.0.0.0:3000/", {timeout: 5000}, (r) => { r.resume(); process.exit(r.statusCode >= 200 && r.statusCode < 500 ? 0 : 1); }).on("error", () => process.exit(1))'
|
||||
- 'require("http").get("http://localhost:3000/", {timeout: 5000}, (r) => { r.resume(); process.exit(r.statusCode >= 200 && r.statusCode < 500 ? 0 : 1); }).on("error", () => process.exit(1))'
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
@@ -35,7 +35,10 @@ describe('shortenUrl', () => {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': 'test-key',
|
||||
},
|
||||
body: JSON.stringify({ target: 'https://example.com' }),
|
||||
body: JSON.stringify({
|
||||
target: 'https://example.com',
|
||||
domain: 'mifi.me',
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -54,6 +57,7 @@ describe('shortenUrl', () => {
|
||||
expect.objectContaining({
|
||||
body: JSON.stringify({
|
||||
target: 'https://example.com',
|
||||
domain: 'mifi.me',
|
||||
customurl: 'myslug',
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -18,14 +18,23 @@ export async function shortenUrl(
|
||||
}
|
||||
|
||||
const base = env.KUTT_BASE_URL.replace(/\/$/, '');
|
||||
const apiKey = env.KUTT_API_KEY.trim();
|
||||
|
||||
// Extract domain from SHORT_DOMAIN (e.g., "https://mifi.me" -> "mifi.me")
|
||||
const domain = env.SHORT_DOMAIN.replace(/^https?:\/\//, '').replace(
|
||||
/\/$/,
|
||||
'',
|
||||
);
|
||||
|
||||
const res = await fetch(`${base}/api/v2/links`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': env.KUTT_API_KEY,
|
||||
'X-API-Key': apiKey,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
target: body.targetUrl,
|
||||
domain: domain,
|
||||
...(body.customSlug && { customurl: body.customSlug }),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/pnpm-lock.yaml* ./
|
||||
RUN pnpm install --prod
|
||||
|
||||
@@ -1020,19 +1020,7 @@ export function Editor({ id }: EditorProps) {
|
||||
updateProject({ recipeJson: JSON.stringify(r) });
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Shape"
|
||||
data={[
|
||||
{ value: 'square', label: 'Square' },
|
||||
{ value: 'circle', label: 'Circle' },
|
||||
]}
|
||||
value={recipe.shape ?? 'square'}
|
||||
onChange={(v) => {
|
||||
const r = { ...recipe };
|
||||
r.shape = (v as 'square' | 'circle') ?? 'square';
|
||||
updateProject({ recipeJson: JSON.stringify(r) });
|
||||
}}
|
||||
/>
|
||||
{/* Shape select removed - circle shape has rendering issues in qr-code-styling library */}
|
||||
<Group grow>
|
||||
<NumberInput
|
||||
label="Margin"
|
||||
|
||||
@@ -127,14 +127,13 @@ describe('buildQrStylingOptions', () => {
|
||||
).toEqual(g);
|
||||
});
|
||||
|
||||
it('uses imageOptions and shape from recipe', () => {
|
||||
it('uses imageOptions from recipe (shape always square)', () => {
|
||||
const opts = buildQrStylingOptions({
|
||||
imageOptions: {
|
||||
hideBackgroundDots: false,
|
||||
imageSize: 0.5,
|
||||
margin: 5,
|
||||
},
|
||||
shape: 'circle',
|
||||
});
|
||||
expect(
|
||||
(opts.imageOptions as { hideBackgroundDots: boolean })
|
||||
@@ -144,7 +143,8 @@ describe('buildQrStylingOptions', () => {
|
||||
0.5,
|
||||
);
|
||||
expect((opts.imageOptions as { margin: number }).margin).toBe(5);
|
||||
expect(opts.shape).toBe('circle');
|
||||
// shape is always 'square' (circle has rendering issues in qr-code-styling)
|
||||
expect(opts.shape).toBe('square');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export function buildQrStylingOptions(
|
||||
data: overrides.data ?? recipe.data ?? ' ',
|
||||
image: overrides.image,
|
||||
type: 'canvas',
|
||||
shape: recipe.shape ?? 'square',
|
||||
shape: 'square', // circle shape has rendering issues in qr-code-styling library
|
||||
margin: recipe.margin ?? 0,
|
||||
qrOptions: {
|
||||
type: 'canvas',
|
||||
|
||||
@@ -53,7 +53,7 @@ export interface RecipeOptions {
|
||||
type?: string;
|
||||
gradient?: QrGradient;
|
||||
};
|
||||
shape?: 'square' | 'circle';
|
||||
// shape removed - circle shape has rendering issues in qr-code-styling library
|
||||
margin?: number;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user