diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13604ec..c3bd239 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,8 @@ jobs: - { name: check-frontend, dir: 'apps/frontend', cmd: 'bun run check' } - { name: check-api, dir: 'apps/api', cmd: 'bun run check' } - { name: build-frontend, dir: 'apps/frontend', cmd: 'bun run build' } + - { name: vercel-cache-website, dir: '.', cmd: 'bun scripts/check-vercel-cache.ts website' } + - { name: vercel-cache-docs, dir: '.', cmd: 'bun scripts/check-vercel-cache.ts docs' } steps: - uses: actions/checkout@v4 diff --git a/apps/api/tests/lib/connection-fields.test.ts b/apps/api/tests/lib/connection-fields.test.ts new file mode 100644 index 0000000..108855c --- /dev/null +++ b/apps/api/tests/lib/connection-fields.test.ts @@ -0,0 +1,35 @@ +import { beforeEach, describe, expect, it } from 'bun:test' +import { clearDb } from '../helpers' +import { setExtensionsDelta, buildMergedSchema } from '../../src/lib/manifest-schema' +import { createKind } from '../../src/lib/kinds' +import { parseManifestText } from '../../src/lib/manifest' +import { validateManifest } from '@tabularium/manifest' +import delta from '../../../../deploy/tabularis/connection-fields.json' + +beforeEach(clearDb) + +describe('Tabularis connection_fields operator extension', () => { + for (const scoped of [false, true]) { + it(`preserves the PR #629 contract (kind override=${scoped})`, async () => { + const extensions = { engine: { type: 'string' }, ...delta } + await setExtensionsDelta(extensions) + if (scoped) await createKind({ key: 'driver', label: 'Drivers', description: null, extensionsSchema: extensions }) + const base = { id: 'bigquery', name: 'BigQuery', version: '1.0.0', kind: 'driver', engine: 'bigquery' } + const fields = { host: { hidden: true }, username: { label: 'Project ID', placeholder: 'my-project' } } + expect(parseManifestText(JSON.stringify({ ...base, connection_fields: fields }))).toMatchObject({ + ...base, + connection_fields: fields, + }) + expect(parseManifestText(JSON.stringify(base))).toMatchObject(base) + const schema = buildMergedSchema({ kind: 'driver' }) + for (const invalid of [ + { arbitrary: { hidden: true } }, + { host: { hidden: 'yes' } }, + { host: { label: 'x'.repeat(81) } }, + { host: { placeholder: 'x'.repeat(201) } }, + { password: { secretValue: 'must-not-be-in-manifest' } }, + ]) + expect(validateManifest({ ...base, connection_fields: invalid }, schema).ok).toBe(false) + }) + } +}) diff --git a/apps/docs/vercel.json b/apps/docs/vercel.json new file mode 100644 index 0000000..7ba5c26 --- /dev/null +++ b/apps/docs/vercel.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "framework": "sveltekit", + "outputDirectory": null +} diff --git a/apps/frontend/messages/de.json b/apps/frontend/messages/de.json index 560e26b..9e1f7e4 100644 --- a/apps/frontend/messages/de.json +++ b/apps/frontend/messages/de.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "Noch keine Downloads erfasst.", "plugin_detail_downloads_per_version": "Downloads pro Version", "plugin_detail_downloads_total": "Gesamte Downloads", + "plugin_detail_downloads_unavailable": "Download-Statistiken sind derzeit nicht verfügbar.", "plugin_detail_email_support": "Support per E-Mail", "plugin_detail_featured": "Empfohlen", "plugin_detail_install_subtitle": "Hol dir die neueste, für deine Plattform passende Asset-URL über die Catalog-API:", diff --git a/apps/frontend/messages/en.json b/apps/frontend/messages/en.json index c9c09fc..81e7a98 100644 --- a/apps/frontend/messages/en.json +++ b/apps/frontend/messages/en.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "No downloads recorded yet.", "plugin_detail_downloads_per_version": "Downloads by version", "plugin_detail_downloads_total": "Total downloads", + "plugin_detail_downloads_unavailable": "Download statistics are currently unavailable.", "plugin_detail_email_support": "Email support", "plugin_detail_featured": "Featured", "plugin_detail_install_subtitle": "Resolve the latest platform-matching asset URL via the catalog API:", diff --git a/apps/frontend/messages/es.json b/apps/frontend/messages/es.json index 043d6dc..7bb43f1 100644 --- a/apps/frontend/messages/es.json +++ b/apps/frontend/messages/es.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "Aún no hay descargas registradas.", "plugin_detail_downloads_per_version": "Descargas por versión", "plugin_detail_downloads_total": "Descargas totales", + "plugin_detail_downloads_unavailable": "Las estadísticas de descargas no están disponibles en este momento.", "plugin_detail_email_support": "Soporte por email", "plugin_detail_featured": "Destacado", "plugin_detail_install_subtitle": "Resuelve la URL del asset que coincida con la plataforma más reciente vía la API del catálogo:", diff --git a/apps/frontend/messages/fr.json b/apps/frontend/messages/fr.json index 0538c74..1143a77 100644 --- a/apps/frontend/messages/fr.json +++ b/apps/frontend/messages/fr.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "Aucun téléchargement enregistré pour le moment.", "plugin_detail_downloads_per_version": "Téléchargements par version", "plugin_detail_downloads_total": "Téléchargements totaux", + "plugin_detail_downloads_unavailable": "Les statistiques de téléchargement sont actuellement indisponibles.", "plugin_detail_email_support": "Support par e-mail", "plugin_detail_featured": "Mis en avant", "plugin_detail_install_subtitle": "Résous l'URL de l'asset adapté à la plateforme la plus récente via l'API du catalogue :", diff --git a/apps/frontend/messages/it.json b/apps/frontend/messages/it.json index 9ed1d29..f900b69 100644 --- a/apps/frontend/messages/it.json +++ b/apps/frontend/messages/it.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "Nessun download registrato ancora.", "plugin_detail_downloads_per_version": "Download per versione", "plugin_detail_downloads_total": "Download totali", + "plugin_detail_downloads_unavailable": "Le statistiche dei download non sono al momento disponibili.", "plugin_detail_email_support": "Supporto via email", "plugin_detail_featured": "In evidenza", "plugin_detail_install_subtitle": "Risolvi l'URL dell'asset più recente per la piattaforma tramite l'API del catalogo:", diff --git a/apps/frontend/messages/zh-CN.json b/apps/frontend/messages/zh-CN.json index cba6992..7453730 100644 --- a/apps/frontend/messages/zh-CN.json +++ b/apps/frontend/messages/zh-CN.json @@ -808,6 +808,7 @@ "plugin_detail_downloads_empty": "尚无下载记录。", "plugin_detail_downloads_per_version": "各版本下载量", "plugin_detail_downloads_total": "总下载量", + "plugin_detail_downloads_unavailable": "下载统计信息暂时不可用。", "plugin_detail_email_support": "邮件支持", "plugin_detail_featured": "精选", "plugin_detail_install_subtitle": "通过目录 API 解析最新且匹配当前平台的资源 URL:", diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 3fc101d..28539d2 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -7,6 +7,7 @@ "dev": "NODE_OPTIONS=--no-deprecation vite dev --port 5180", "build": "vite build", "preview": "vite preview", + "test": "bun test tests", "prepare": "svelte-kit sync || echo ''", "check": "paraglide-js compile --project project.inlang --outdir src/lib/paraglide --silent && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "paraglide-js compile --project project.inlang --outdir src/lib/paraglide --silent && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", diff --git a/apps/frontend/src/lib/components/PluginCard.svelte b/apps/frontend/src/lib/components/PluginCard.svelte index 5061579..6707efe 100644 --- a/apps/frontend/src/lib/components/PluginCard.svelte +++ b/apps/frontend/src/lib/components/PluginCard.svelte @@ -3,6 +3,9 @@ import Badge from '$components/ui/Badge.svelte' import VerifiedBadge from '$components/ui/VerifiedBadge.svelte' import Boxes from '@lucide/svelte/icons/boxes' + import Download from '@lucide/svelte/icons/download' + import { formatDownloadCount } from '$lib/downloads' + import { i18n } from '$lib/stores/i18n.svelte' import { m } from '$lib/paraglide/messages' import type { Plugin } from '$lib/types' @@ -53,6 +56,14 @@