Spaces:
Running
Running
Commit
·
db39944
0
Parent(s):
init
Browse files- .gitignore +24 -0
- .npmrc +1 -0
- .prettierignore +4 -0
- .prettierrc +8 -0
- .vscode/settings.json +1 -0
- README.md +38 -0
- bun.lockb +0 -0
- eslint.config.js +33 -0
- package-lock.json +0 -0
- package.json +48 -0
- postcss.config.js +6 -0
- src/app.css +3 -0
- src/app.d.ts +13 -0
- src/app.html +12 -0
- src/lib/components/CodeBlock.svelte +76 -0
- src/lib/components/Navbar.svelte +15 -0
- src/lib/config.ts +2 -0
- src/lib/index.ts +1 -0
- src/lib/types.ts +7 -0
- src/lib/utils.ts +8 -0
- src/routes/+layout.svelte +11 -0
- src/routes/+page.server.ts +7 -0
- src/routes/+page.svelte +32 -0
- src/routes/[slug]/+page.svelte +19 -0
- src/routes/[slug]/+page.ts +17 -0
- src/routes/api/snippets/+server.ts +26 -0
- src/snippets/leakage.md +64 -0
- src/snippets/summarize.md +38 -0
- static/leakage-query-image.png +0 -0
- svelte.config.js +32 -0
- tailwind.config.js +9 -0
- tsconfig.json +26 -0
- vite.config.ts +9 -0
.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
node_modules
|
2 |
+
|
3 |
+
# Output
|
4 |
+
.output
|
5 |
+
.vercel
|
6 |
+
/.svelte-kit
|
7 |
+
/build
|
8 |
+
|
9 |
+
# OS
|
10 |
+
.DS_Store
|
11 |
+
Thumbs.db
|
12 |
+
|
13 |
+
# Env
|
14 |
+
.env
|
15 |
+
.env.*
|
16 |
+
!.env.example
|
17 |
+
!.env.test
|
18 |
+
|
19 |
+
# Vite
|
20 |
+
vite.config.js.timestamp-*
|
21 |
+
vite.config.ts.timestamp-*
|
22 |
+
|
23 |
+
# Virtual Environment
|
24 |
+
**/venv/
|
.npmrc
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
engine-strict=true
|
.prettierignore
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Package Managers
|
2 |
+
package-lock.json
|
3 |
+
pnpm-lock.yaml
|
4 |
+
yarn.lock
|
.prettierrc
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"useTabs": true,
|
3 |
+
"singleQuote": true,
|
4 |
+
"trailingComma": "none",
|
5 |
+
"printWidth": 100,
|
6 |
+
"plugins": ["prettier-plugin-svelte"],
|
7 |
+
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
8 |
+
}
|
.vscode/settings.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{}
|
README.md
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# create-svelte
|
2 |
+
|
3 |
+
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
|
4 |
+
|
5 |
+
## Creating a project
|
6 |
+
|
7 |
+
If you're seeing this, you've probably already done this step. Congrats!
|
8 |
+
|
9 |
+
```bash
|
10 |
+
# create a new project in the current directory
|
11 |
+
npm create svelte@latest
|
12 |
+
|
13 |
+
# create a new project in my-app
|
14 |
+
npm create svelte@latest my-app
|
15 |
+
```
|
16 |
+
|
17 |
+
## Developing
|
18 |
+
|
19 |
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
20 |
+
|
21 |
+
```bash
|
22 |
+
npm run dev
|
23 |
+
|
24 |
+
# or start the server and open the app in a new browser tab
|
25 |
+
npm run dev -- --open
|
26 |
+
```
|
27 |
+
|
28 |
+
## Building
|
29 |
+
|
30 |
+
To create a production version of your app:
|
31 |
+
|
32 |
+
```bash
|
33 |
+
npm run build
|
34 |
+
```
|
35 |
+
|
36 |
+
You can preview the production build with `npm run preview`.
|
37 |
+
|
38 |
+
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
bun.lockb
ADDED
Binary file (145 kB). View file
|
|
eslint.config.js
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import js from '@eslint/js';
|
2 |
+
import ts from 'typescript-eslint';
|
3 |
+
import svelte from 'eslint-plugin-svelte';
|
4 |
+
import prettier from 'eslint-config-prettier';
|
5 |
+
import globals from 'globals';
|
6 |
+
|
7 |
+
/** @type {import('eslint').Linter.FlatConfig[]} */
|
8 |
+
export default [
|
9 |
+
js.configs.recommended,
|
10 |
+
...ts.configs.recommended,
|
11 |
+
...svelte.configs['flat/recommended'],
|
12 |
+
prettier,
|
13 |
+
...svelte.configs['flat/prettier'],
|
14 |
+
{
|
15 |
+
languageOptions: {
|
16 |
+
globals: {
|
17 |
+
...globals.browser,
|
18 |
+
...globals.node
|
19 |
+
}
|
20 |
+
}
|
21 |
+
},
|
22 |
+
{
|
23 |
+
files: ['**/*.svelte'],
|
24 |
+
languageOptions: {
|
25 |
+
parserOptions: {
|
26 |
+
parser: ts.parser
|
27 |
+
}
|
28 |
+
}
|
29 |
+
},
|
30 |
+
{
|
31 |
+
ignores: ['build/', '.svelte-kit/', 'dist/']
|
32 |
+
}
|
33 |
+
];
|
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "tutorials",
|
3 |
+
"version": "0.0.1",
|
4 |
+
"private": true,
|
5 |
+
"scripts": {
|
6 |
+
"dev": "vite dev",
|
7 |
+
"build": "vite build",
|
8 |
+
"preview": "vite preview",
|
9 |
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
10 |
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
11 |
+
"lint": "prettier --check . && eslint .",
|
12 |
+
"format": "prettier --write ."
|
13 |
+
},
|
14 |
+
"devDependencies": {
|
15 |
+
"@iconify/json": "^2.2.230",
|
16 |
+
"@sveltejs/adapter-auto": "^3.0.0",
|
17 |
+
"@sveltejs/kit": "^2.0.0",
|
18 |
+
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
19 |
+
"@types/eslint": "^8.56.7",
|
20 |
+
"autoprefixer": "^10.4.19",
|
21 |
+
"eslint": "^9.0.0",
|
22 |
+
"eslint-config-prettier": "^9.1.0",
|
23 |
+
"eslint-plugin-svelte": "^2.36.0",
|
24 |
+
"globals": "^15.0.0",
|
25 |
+
"postcss": "^8.4.39",
|
26 |
+
"prettier": "^3.1.1",
|
27 |
+
"prettier-plugin-svelte": "^3.1.2",
|
28 |
+
"shiki": "^1.17.6",
|
29 |
+
"svelte": "^4.2.7",
|
30 |
+
"svelte-check": "^3.6.0",
|
31 |
+
"tailwindcss": "^3.4.6",
|
32 |
+
"tslib": "^2.4.1",
|
33 |
+
"typescript": "^5.0.0",
|
34 |
+
"typescript-eslint": "^8.0.0-alpha.20",
|
35 |
+
"unplugin-icons": "^0.19.0",
|
36 |
+
"vite": "^5.0.3"
|
37 |
+
},
|
38 |
+
"type": "module",
|
39 |
+
"dependencies": {
|
40 |
+
"@shikijs/markdown-it": "^1.17.6",
|
41 |
+
"@tailwindcss/typography": "^0.5.15",
|
42 |
+
"highlight.js": "^11.10.0",
|
43 |
+
"mdsvex": "^0.11.2",
|
44 |
+
"remark-gfm": "^4.0.0",
|
45 |
+
"svelte-icons": "^2.1.0",
|
46 |
+
"svelte-tiny-virtual-list": "^2.1.2"
|
47 |
+
}
|
48 |
+
}
|
postcss.config.js
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default {
|
2 |
+
plugins: {
|
3 |
+
tailwindcss: {},
|
4 |
+
autoprefixer: {},
|
5 |
+
},
|
6 |
+
}
|
src/app.css
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
@tailwind base;
|
2 |
+
@tailwind components;
|
3 |
+
@tailwind utilities;
|
src/app.d.ts
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// See https://kit.svelte.dev/docs/types#app
|
2 |
+
// for information about these interfaces
|
3 |
+
declare global {
|
4 |
+
namespace App {
|
5 |
+
// interface Error {}
|
6 |
+
// interface Locals {}
|
7 |
+
// interface PageData {}
|
8 |
+
// interface PageState {}
|
9 |
+
// interface Platform {}
|
10 |
+
}
|
11 |
+
}
|
12 |
+
|
13 |
+
export {};
|
src/app.html
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8" />
|
5 |
+
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
7 |
+
%sveltekit.head%
|
8 |
+
</head>
|
9 |
+
<body data-sveltekit-preload-data="hover">
|
10 |
+
<div style="display: contents">%sveltekit.body%</div>
|
11 |
+
</body>
|
12 |
+
</html>
|
src/lib/components/CodeBlock.svelte
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import hljs from 'highlight.js/lib/core';
|
3 |
+
import sql from 'highlight.js/lib/languages/sql';
|
4 |
+
import FaRegCopy from 'svelte-icons/fa/FaRegCopy.svelte';
|
5 |
+
import FaCheck from 'svelte-icons/fa/FaCheck.svelte';
|
6 |
+
import FaChevronDown from 'svelte-icons/fa/FaChevronDown.svelte';
|
7 |
+
import 'highlight.js/styles/atom-one-dark.css';
|
8 |
+
|
9 |
+
hljs.registerLanguage('sql', sql);
|
10 |
+
|
11 |
+
export let code: string;
|
12 |
+
export let language: string;
|
13 |
+
|
14 |
+
let highlightedCode: string;
|
15 |
+
let isCopied = false;
|
16 |
+
let isExpanded = false;
|
17 |
+
let codeWrapper: HTMLElement;
|
18 |
+
let shouldShowExpand = false;
|
19 |
+
|
20 |
+
$: highlightedCode = hljs.highlight(code, { language }).value;
|
21 |
+
$: if (codeWrapper) {
|
22 |
+
shouldShowExpand = codeWrapper.scrollHeight > 192;
|
23 |
+
}
|
24 |
+
|
25 |
+
function copyCode() {
|
26 |
+
navigator.clipboard.writeText(code);
|
27 |
+
isCopied = true;
|
28 |
+
setTimeout(() => (isCopied = false), 2000);
|
29 |
+
}
|
30 |
+
</script>
|
31 |
+
|
32 |
+
<div class="rounded-lg overflow-hidden shadow-lg bg-transparent text-white">
|
33 |
+
<div class="flex justify-end p-2 bg-[#1E1E1E] border-b border-[#2F2E2E]">
|
34 |
+
<button
|
35 |
+
on:click={copyCode}
|
36 |
+
class="p-[1px] rounded-md text-gray-400 hover:text-white transition-colors duration-200 focus:outline-none focus:ring-1 focus:ring-white"
|
37 |
+
aria-label="Copy code"
|
38 |
+
>
|
39 |
+
<div class="w-3 h-3">
|
40 |
+
{#if isCopied}
|
41 |
+
<FaCheck class="text-green-500" />
|
42 |
+
{:else}
|
43 |
+
<FaRegCopy />
|
44 |
+
{/if}
|
45 |
+
</div>
|
46 |
+
</button>
|
47 |
+
</div>
|
48 |
+
<div class="relative" bind:this={codeWrapper}>
|
49 |
+
<pre
|
50 |
+
class="transition-all duration-300 ease-in-out overflow-hidden"
|
51 |
+
class:max-h-48={!isExpanded && shouldShowExpand}
|
52 |
+
><code class="hljs language-{language} text-xs font-mono block">{@html highlightedCode}</code></pre>
|
53 |
+
|
54 |
+
{#if !isExpanded && shouldShowExpand}
|
55 |
+
<div class="absolute inset-x-0 bottom-0 h-6 bg-gradient-to-t from-gray-900 to-transparent pointer-events-none"></div>
|
56 |
+
<button
|
57 |
+
on:click={() => (isExpanded = true)}
|
58 |
+
class="absolute inset-x-0 bottom-0 h-6 flex items-center justify-center text-gray-400 text-xs hover:text-gray-300 transition-colors duration-200"
|
59 |
+
>
|
60 |
+
<div class="w-3 h-3">
|
61 |
+
<FaChevronDown />
|
62 |
+
</div>
|
63 |
+
</button>
|
64 |
+
{/if}
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
|
68 |
+
<style>
|
69 |
+
pre {
|
70 |
+
scrollbar-width: none;
|
71 |
+
-ms-overflow-style: none;
|
72 |
+
}
|
73 |
+
pre::-webkit-scrollbar {
|
74 |
+
display: none;
|
75 |
+
}
|
76 |
+
</style>
|
src/lib/components/Navbar.svelte
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import { page } from '$app/stores';
|
3 |
+
</script>
|
4 |
+
|
5 |
+
<nav class="p-4">
|
6 |
+
<div class="container mx-auto">
|
7 |
+
<a
|
8 |
+
href="/"
|
9 |
+
class="font-bold text-xl"
|
10 |
+
class:active={$page.url.pathname === '/'}
|
11 |
+
>
|
12 |
+
DuckDB Snippets
|
13 |
+
</a>
|
14 |
+
</div>
|
15 |
+
</nav>
|
src/lib/config.ts
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
export const title = 'SQL Snippets'
|
2 |
+
export const description = 'DuckDB SQL Snippets for the Hugging Face SQL Console'
|
src/lib/index.ts
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
// place files you want to import through the `$lib` alias in this folder.
|
src/lib/types.ts
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export interface Snippet {
|
2 |
+
id: string
|
3 |
+
title: string
|
4 |
+
slug: string
|
5 |
+
description: string
|
6 |
+
code: string
|
7 |
+
}
|
src/lib/utils.ts
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
type DateStyle = Intl.DateTimeFormatOptions['dateStyle']
|
2 |
+
|
3 |
+
export function formatDate(date: string, dateStyle: DateStyle = 'medium', locales = 'en') {
|
4 |
+
// Safari is mad about dashes in the date
|
5 |
+
const dateToFormat = new Date(date.replaceAll('-', '/'))
|
6 |
+
const dateFormatter = new Intl.DateTimeFormat(locales, { dateStyle })
|
7 |
+
return dateFormatter.format(dateToFormat)
|
8 |
+
}
|
src/routes/+layout.svelte
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script>
|
2 |
+
import '../app.css';
|
3 |
+
import Navbar from '../lib/components/Navbar.svelte';
|
4 |
+
</script>
|
5 |
+
|
6 |
+
<div class="flex flex-col min-h-screen font-inter">
|
7 |
+
<main class="flex-grow">
|
8 |
+
<Navbar />
|
9 |
+
<slot />
|
10 |
+
</main>
|
11 |
+
</div>
|
src/routes/+page.server.ts
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import type { Snippet } from '$lib/types'
|
2 |
+
|
3 |
+
export async function load({ fetch }) {
|
4 |
+
const response = await fetch('api/snippets')
|
5 |
+
const snippets: Snippet[] = await response.json()
|
6 |
+
return { snippets }
|
7 |
+
}
|
src/routes/+page.svelte
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import * as config from '$lib/config'
|
3 |
+
import type { Snippet } from '$lib/types'
|
4 |
+
import CodeBlock from '$lib/components/CodeBlock.svelte'
|
5 |
+
|
6 |
+
export let data: { snippets: Snippet[] }
|
7 |
+
</script>
|
8 |
+
|
9 |
+
<svelte:head>
|
10 |
+
<title>{config.title} in DuckDB</title>
|
11 |
+
<meta name="description" content="A collection of snippets for DuckDB." />
|
12 |
+
</svelte:head>
|
13 |
+
|
14 |
+
<section class="max-w-2xl mx-auto px-4 py-8">
|
15 |
+
<h1 class="text-5xl mt-20 font-bold text-center tracking-tight text-slate-800 mb-8">{config.title}</h1>
|
16 |
+
<p class="text-base text-center text-slate-600 mb-8">{config.description}</p>
|
17 |
+
<ul class="space-y-12">
|
18 |
+
{#each data.snippets as snippet}
|
19 |
+
<li class="bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300">
|
20 |
+
<div class="p-4">
|
21 |
+
<a href={`${snippet.slug}`} class="block mb-4 hover:underline transition-colors duration-300">
|
22 |
+
<h2 class="text-2xl font-bold transition-colors duration-300">{snippet.title}</h2>
|
23 |
+
</a>
|
24 |
+
<p class="text-sm text-slate-700 font-mono mb-6">{snippet.description}</p>
|
25 |
+
{#if snippet.code}
|
26 |
+
<CodeBlock code={snippet.code} language="sql" />
|
27 |
+
{/if}
|
28 |
+
</div>
|
29 |
+
</li>
|
30 |
+
{/each}
|
31 |
+
</ul>
|
32 |
+
</section>
|
src/routes/[slug]/+page.svelte
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import type { PageData } from './$types'
|
3 |
+
|
4 |
+
export let data: PageData
|
5 |
+
</script>
|
6 |
+
|
7 |
+
<!-- SEO -->
|
8 |
+
<svelte:head>
|
9 |
+
<title>{data.snippet.title}</title>
|
10 |
+
<meta property="og:type" content="article" />
|
11 |
+
<meta property="og:title" content={data.snippet.title} />
|
12 |
+
<meta name="description" content={data.snippet.description} />
|
13 |
+
</svelte:head>
|
14 |
+
|
15 |
+
<article class="max-w-3xl mx-auto px-4 py-8">
|
16 |
+
<div class="prose max-w-none">
|
17 |
+
<svelte:component this={data.content} />
|
18 |
+
</div>
|
19 |
+
</article>
|
src/routes/[slug]/+page.ts
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { error } from '@sveltejs/kit'
|
2 |
+
|
3 |
+
export async function load({ params }) {
|
4 |
+
try {
|
5 |
+
const snippet = await import(`../../snippets/${params.slug}.md`)
|
6 |
+
if (!snippet) {
|
7 |
+
throw error(404, `Could not find snippet ${params.slug}`)
|
8 |
+
}
|
9 |
+
|
10 |
+
return {
|
11 |
+
snippet: snippet.metadata,
|
12 |
+
content: snippet.default
|
13 |
+
}
|
14 |
+
} catch {
|
15 |
+
throw error(404, `Could not find snippet ${params.slug}`)
|
16 |
+
}
|
17 |
+
}
|
src/routes/api/snippets/+server.ts
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { json } from '@sveltejs/kit'
|
2 |
+
import type { Snippet } from '$lib/types'
|
3 |
+
|
4 |
+
async function getSnippets() {
|
5 |
+
const snippets: Snippet[] = []
|
6 |
+
|
7 |
+
const paths = import.meta.glob('/src/snippets/*.md', { eager: true })
|
8 |
+
|
9 |
+
for (const path in paths) {
|
10 |
+
const file = paths[path]
|
11 |
+
const slug = path.split('/').at(-1)?.replace('.md', '')
|
12 |
+
|
13 |
+
if (file && typeof file === 'object' && 'metadata' in file && slug) {
|
14 |
+
const metadata = file.metadata as Omit<Snippet, 'slug'>
|
15 |
+
const snippet = { ...metadata, slug } satisfies Snippet
|
16 |
+
snippets.push(snippet)
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
return snippets.sort((a, b) => a.title.localeCompare(b.title))
|
21 |
+
}
|
22 |
+
|
23 |
+
export async function GET() {
|
24 |
+
const snippets = await getSnippets()
|
25 |
+
return json(snippets)
|
26 |
+
}
|
src/snippets/leakage.md
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
id: "duckdb-leakage-detection"
|
3 |
+
title: "Leakage Detection"
|
4 |
+
slug: "duckdb-leakage-detection-query"
|
5 |
+
description: "Detect data leakage between train and test datasets by calculating the overlap percentage."
|
6 |
+
code: |
|
7 |
+
WITH
|
8 |
+
overlapping_rows AS (
|
9 |
+
SELECT COUNT(*) AS overlap_count
|
10 |
+
FROM train
|
11 |
+
INTERSECT
|
12 |
+
SELECT COUNT(*) AS overlap_count
|
13 |
+
FROM test
|
14 |
+
),
|
15 |
+
total_unique_rows AS (
|
16 |
+
SELECT COUNT(*) AS total_count
|
17 |
+
FROM (
|
18 |
+
SELECT * FROM train
|
19 |
+
UNION
|
20 |
+
SELECT * FROM test
|
21 |
+
) combined
|
22 |
+
)
|
23 |
+
SELECT
|
24 |
+
overlap_count,
|
25 |
+
total_count,
|
26 |
+
(overlap_count * 100.0 / total_count) AS overlap_percentage
|
27 |
+
FROM overlapping_rows, total_unique_rows;
|
28 |
+
---
|
29 |
+
|
30 |
+
# DuckDB Leakage Detection Query
|
31 |
+
|
32 |
+
This snippet demonstrates how to use DuckDB to detect potential data leakage between train and test datasets by calculating the overlap percentage.
|
33 |
+
|
34 |
+
```sql
|
35 |
+
WITH
|
36 |
+
overlapping_rows AS (
|
37 |
+
SELECT COUNT(*) AS overlap_count
|
38 |
+
FROM train
|
39 |
+
INTERSECT
|
40 |
+
SELECT COUNT(*) AS overlap_count
|
41 |
+
FROM test
|
42 |
+
),
|
43 |
+
total_unique_rows AS (
|
44 |
+
SELECT COUNT(*) AS total_count
|
45 |
+
FROM (
|
46 |
+
SELECT * FROM train
|
47 |
+
UNION
|
48 |
+
SELECT * FROM test
|
49 |
+
) combined
|
50 |
+
)
|
51 |
+
SELECT
|
52 |
+
overlap_count,
|
53 |
+
total_count,
|
54 |
+
(overlap_count * 100.0 / total_count) AS overlap_percentage
|
55 |
+
FROM overlapping_rows, total_unique_rows;
|
56 |
+
```
|
57 |
+
|
58 |
+
There is a very good in depth explanation of leakage in public datasets in this [article](https://huggingface.co/blog/lbourdois/lle).
|
59 |
+
|
60 |
+
# Example Query
|
61 |
+
|
62 |
+
You can check out this [link](https://huggingface.co/datasets/stanfordnlp/imdb?sql_console=true&sql=WITH%0A++++overlapping_rows+AS+%28%0A++++++++SELECT+COUNT%28*%29+AS+overlap_count%0A++++++++FROM+train%0A++++++++INTERSECT%0A++++++++SELECT+COUNT%28*%29+AS+overlap_count%0A++++++++FROM+test%0A++++%29%2C%0A++++total_unique_rows+AS+%28%0A++++++++SELECT+COUNT%28*%29+AS+total_count%0A++++++++FROM+%28%0A++++++++++++SELECT+*+FROM+train%0A++++++++++++UNION%0A++++++++++++SELECT+*+FROM+test%0A++++++++%29+combined%0A++++%29%0ASELECT%0A++++overlap_count%2C%0A++++total_count%2C%0A++++%28overlap_count+*+100.0+%2F+total_count%29+AS+overlap_percentage%0AFROM+overlapping_rows%2C+total_unique_rows%3B%0A) for the leakage query for the IMDB dataset.
|
63 |
+
|
64 |
+

|
src/snippets/summarize.md
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
id: "duckdb-summarize"
|
3 |
+
title: "Summarize"
|
4 |
+
slug: "duckdb-summarize-query"
|
5 |
+
description: "Summarize a specific table or columns for a quick overview of the dataset's structure and statistics."
|
6 |
+
code: |
|
7 |
+
-- summarize a specific table
|
8 |
+
SUMMARIZE my_table
|
9 |
+
|
10 |
+
-- summarize a specific column
|
11 |
+
SUMMARIZE my_table.my_column
|
12 |
+
---
|
13 |
+
|
14 |
+
# DuckDB Summarize Query
|
15 |
+
|
16 |
+
This snippet demonstrates how to use the `SUMMARIZE` function in DuckDB to calculate aggregate statistics for a dataset.
|
17 |
+
|
18 |
+
```sql
|
19 |
+
-- summarize a specific table
|
20 |
+
SUMMARIZE my_table
|
21 |
+
|
22 |
+
-- summarize a specific column
|
23 |
+
SUMMARIZE my_table.my_column
|
24 |
+
```
|
25 |
+
|
26 |
+
The `SUMMARIZE` command in DuckDB provides a comprehensive overview of your data by computing various aggregates for each column:
|
27 |
+
|
28 |
+
- `min` and `max`: The minimum and maximum values in the column.
|
29 |
+
- `approx_unique`: An approximation of the number of unique values.
|
30 |
+
- `avg`: The average value for numeric columns.
|
31 |
+
- `std`: The standard deviation for numeric columns.
|
32 |
+
- `q25`, `q50`, `q75`: The 25th, 50th (median), and 75th percentiles.
|
33 |
+
- `count`: The total number of rows.
|
34 |
+
- `null_percentage`: The percentage of NULL values in the column.
|
35 |
+
|
36 |
+
This command is particularly useful for quick data exploration and understanding the distribution of values across your dataset.
|
37 |
+
|
38 |
+
You can read more about the `SUMMARIZE` command in the DuckDB documentation [here](https://duckdb.org/docs/guides/meta/summarize.html).
|
static/leakage-query-image.png
ADDED
![]() |
svelte.config.js
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import adapter from '@sveltejs/adapter-auto'
|
2 |
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
3 |
+
|
4 |
+
import { mdsvex, escapeSvelte } from 'mdsvex'
|
5 |
+
import { createHighlighter } from 'shiki'
|
6 |
+
|
7 |
+
/** @type {import('mdsvex').MdsvexOptions} */
|
8 |
+
const mdsvexOptions = {
|
9 |
+
extensions: ['.md'],
|
10 |
+
highlight: {
|
11 |
+
highlighter: async (code, lang = 'text') => {
|
12 |
+
const highlighter = await createHighlighter({
|
13 |
+
themes: ['github-dark'],
|
14 |
+
langs: [ 'sql']
|
15 |
+
})
|
16 |
+
await highlighter.loadLanguage('sql')
|
17 |
+
const html = escapeSvelte(highlighter.codeToHtml(code, { lang, theme: 'github-dark' }))
|
18 |
+
return `{@html \`${html}\` }`
|
19 |
+
}
|
20 |
+
},
|
21 |
+
}
|
22 |
+
|
23 |
+
/** @type {import('@sveltejs/kit').Config} */
|
24 |
+
const config = {
|
25 |
+
extensions: ['.svelte', '.md'],
|
26 |
+
preprocess: [vitePreprocess(), mdsvex(mdsvexOptions)],
|
27 |
+
kit: {
|
28 |
+
adapter: adapter()
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
export default config
|
tailwind.config.js
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @type {import('tailwindcss').Config} */
|
2 |
+
export default {
|
3 |
+
content: ['./src/**/*.{html,js,svelte,ts}'],
|
4 |
+
theme: {
|
5 |
+
extend: {},
|
6 |
+
},
|
7 |
+
plugins: [require('@tailwindcss/typography')]
|
8 |
+
}
|
9 |
+
|
tsconfig.json
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"extends": "./.svelte-kit/tsconfig.json",
|
3 |
+
"compilerOptions": {
|
4 |
+
"types": [
|
5 |
+
"unplugin-icons/types/svelte"
|
6 |
+
],
|
7 |
+
"paths": {
|
8 |
+
"$lib": ["./src/lib"],
|
9 |
+
"$lib/*": ["./src/lib/*"]
|
10 |
+
},
|
11 |
+
"allowJs": true,
|
12 |
+
"checkJs": true,
|
13 |
+
"esModuleInterop": true,
|
14 |
+
"forceConsistentCasingInFileNames": true,
|
15 |
+
"resolveJsonModule": true,
|
16 |
+
"skipLibCheck": true,
|
17 |
+
"sourceMap": true,
|
18 |
+
"strict": true,
|
19 |
+
"moduleResolution": "bundler"
|
20 |
+
}
|
21 |
+
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
22 |
+
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
|
23 |
+
//
|
24 |
+
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
25 |
+
// from the referenced tsconfig.json - TypeScript does not merge them in
|
26 |
+
}
|
vite.config.ts
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { sveltekit } from '@sveltejs/kit/vite';
|
2 |
+
import { defineConfig } from 'vite';
|
3 |
+
import Icons from 'unplugin-icons/vite'
|
4 |
+
|
5 |
+
export default defineConfig({
|
6 |
+
plugins: [sveltekit(), Icons({ compiler: 'svelte' })]
|
7 |
+
});
|
8 |
+
|
9 |
+
|