@gblikas/querykit 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.cursor/BUGBOT.md +21 -0
  2. package/.cursor/rules/01-project-structure.mdc +77 -0
  3. package/.cursor/rules/02-typescript-standards.mdc +105 -0
  4. package/.cursor/rules/03-testing-standards.mdc +78 -0
  5. package/.cursor/rules/04-query-language.mdc +79 -0
  6. package/.cursor/rules/05-solid-principles.mdc +118 -0
  7. package/.cursor/rules/liqe-readme-docs.mdc +438 -0
  8. package/.devcontainer/devcontainer.json +25 -0
  9. package/.eslintignore +1 -0
  10. package/.eslintrc.js +39 -0
  11. package/.github/dependabot.yml +12 -0
  12. package/.github/workflows/ci.yml +114 -0
  13. package/.github/workflows/publish.yml +61 -0
  14. package/.husky/pre-commit +30 -0
  15. package/.prettierrc +10 -0
  16. package/CONTRIBUTING.md +187 -0
  17. package/LICENSE +674 -0
  18. package/README.md +237 -0
  19. package/dist/adapters/drizzle/index.d.ts +122 -0
  20. package/dist/adapters/drizzle/index.js +166 -0
  21. package/dist/adapters/index.d.ts +7 -0
  22. package/dist/adapters/index.js +25 -0
  23. package/dist/adapters/types.d.ts +60 -0
  24. package/dist/adapters/types.js +8 -0
  25. package/dist/index.d.ts +75 -0
  26. package/dist/index.js +118 -0
  27. package/dist/parser/index.d.ts +2 -0
  28. package/dist/parser/index.js +18 -0
  29. package/dist/parser/parser.d.ts +51 -0
  30. package/dist/parser/parser.js +201 -0
  31. package/dist/parser/types.d.ts +68 -0
  32. package/dist/parser/types.js +5 -0
  33. package/dist/query/builder.d.ts +61 -0
  34. package/dist/query/builder.js +188 -0
  35. package/dist/query/index.d.ts +2 -0
  36. package/dist/query/index.js +18 -0
  37. package/dist/query/types.d.ts +79 -0
  38. package/dist/query/types.js +2 -0
  39. package/dist/security/index.d.ts +2 -0
  40. package/dist/security/index.js +18 -0
  41. package/dist/security/types.d.ts +181 -0
  42. package/dist/security/types.js +43 -0
  43. package/dist/security/validator.d.ts +191 -0
  44. package/dist/security/validator.js +344 -0
  45. package/dist/translators/drizzle/index.d.ts +73 -0
  46. package/dist/translators/drizzle/index.js +260 -0
  47. package/dist/translators/index.d.ts +8 -0
  48. package/dist/translators/index.js +27 -0
  49. package/dist/translators/sql/index.d.ts +108 -0
  50. package/dist/translators/sql/index.js +252 -0
  51. package/dist/translators/types.d.ts +39 -0
  52. package/dist/translators/types.js +8 -0
  53. package/examples/qk-next/README.md +35 -0
  54. package/examples/qk-next/app/favicon.ico +0 -0
  55. package/examples/qk-next/app/globals.css +122 -0
  56. package/examples/qk-next/app/layout.tsx +121 -0
  57. package/examples/qk-next/app/page.tsx +813 -0
  58. package/examples/qk-next/app/providers.tsx +80 -0
  59. package/examples/qk-next/components/aurora-background.tsx +12 -0
  60. package/examples/qk-next/components/github-stars.tsx +51 -0
  61. package/examples/qk-next/components/mode-toggle.tsx +27 -0
  62. package/examples/qk-next/components/reactbits/blocks/Backgrounds/Aurora/Aurora.tsx +217 -0
  63. package/examples/qk-next/components/reactbits/blocks/Backgrounds/LightRays/LightRays.tsx +474 -0
  64. package/examples/qk-next/components/theme-provider.tsx +11 -0
  65. package/examples/qk-next/components/ui/card.tsx +92 -0
  66. package/examples/qk-next/components/ui/command.tsx +184 -0
  67. package/examples/qk-next/components/ui/dialog.tsx +143 -0
  68. package/examples/qk-next/components/ui/drawer.tsx +135 -0
  69. package/examples/qk-next/components/ui/hover-card.tsx +44 -0
  70. package/examples/qk-next/components/ui/icons.tsx +148 -0
  71. package/examples/qk-next/components/ui/sonner.tsx +26 -0
  72. package/examples/qk-next/components/ui/table.tsx +117 -0
  73. package/examples/qk-next/components.json +21 -0
  74. package/examples/qk-next/eslint.config.mjs +21 -0
  75. package/examples/qk-next/jsrepo.json +13 -0
  76. package/examples/qk-next/lib/utils.ts +6 -0
  77. package/examples/qk-next/next.config.ts +8 -0
  78. package/examples/qk-next/package.json +48 -0
  79. package/examples/qk-next/pnpm-lock.yaml +5558 -0
  80. package/examples/qk-next/postcss.config.mjs +5 -0
  81. package/examples/qk-next/public/file.svg +1 -0
  82. package/examples/qk-next/public/globe.svg +1 -0
  83. package/examples/qk-next/public/next.svg +1 -0
  84. package/examples/qk-next/public/vercel.svg +1 -0
  85. package/examples/qk-next/public/window.svg +1 -0
  86. package/examples/qk-next/tsconfig.json +42 -0
  87. package/examples/qk-next/types/sonner.d.ts +3 -0
  88. package/jest.config.js +26 -0
  89. package/package.json +51 -0
  90. package/src/adapters/drizzle/drizzle-adapter.test.ts +115 -0
  91. package/src/adapters/drizzle/index.ts +299 -0
  92. package/src/adapters/index.ts +11 -0
  93. package/src/adapters/types.ts +72 -0
  94. package/src/index.ts +194 -0
  95. package/src/integration.test.ts +202 -0
  96. package/src/parser/index.ts +2 -0
  97. package/src/parser/parser.test.ts +1056 -0
  98. package/src/parser/parser.ts +268 -0
  99. package/src/parser/types.ts +97 -0
  100. package/src/query/builder.test.ts +272 -0
  101. package/src/query/builder.ts +274 -0
  102. package/src/query/index.ts +2 -0
  103. package/src/query/types.ts +107 -0
  104. package/src/security/index.ts +2 -0
  105. package/src/security/types.ts +210 -0
  106. package/src/security/validator.test.ts +459 -0
  107. package/src/security/validator.ts +395 -0
  108. package/src/security.test.ts +366 -0
  109. package/src/translators/drizzle/drizzle-translator.test.ts +128 -0
  110. package/src/translators/drizzle/index.test.ts +45 -0
  111. package/src/translators/drizzle/index.ts +346 -0
  112. package/src/translators/index.ts +14 -0
  113. package/src/translators/sql/index.test.ts +45 -0
  114. package/src/translators/sql/index.ts +331 -0
  115. package/src/translators/sql/sql-translator.test.ts +419 -0
  116. package/src/translators/types.ts +44 -0
  117. package/src/types/sonner.d.ts +3 -0
  118. package/tsconfig.json +34 -0
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+
3
+ import { PGlite } from '@electric-sql/pglite';
4
+ import { PGliteProvider } from '@electric-sql/pglite-react';
5
+ import { PGliteWithLive } from '@electric-sql/pglite/live';
6
+ import { JSX, useEffect, useState } from 'react';
7
+
8
+ // Create a PGlite instance with async initialization
9
+ let dbInstance: PGlite | null = null;
10
+ let isInitializing = false;
11
+
12
+ const initializeDb = async (): Promise<PGlite> => {
13
+ if (dbInstance) {
14
+ return dbInstance;
15
+ }
16
+
17
+ if (isInitializing) {
18
+ // Wait for the current initialization to complete
19
+ while (!dbInstance && isInitializing) {
20
+ await new Promise(resolve => setTimeout(resolve, 50));
21
+ }
22
+ return dbInstance!;
23
+ }
24
+
25
+ isInitializing = true;
26
+
27
+ try {
28
+ console.log('Initializing PGlite...');
29
+ dbInstance = new PGlite();
30
+ console.log('PGlite initialized successfully');
31
+ return dbInstance;
32
+ } catch (error) {
33
+ console.error('Failed to initialize PGlite:', error);
34
+ throw error;
35
+ } finally {
36
+ isInitializing = false;
37
+ }
38
+ };
39
+
40
+ export function Providers({
41
+ children
42
+ }: {
43
+ children: React.ReactNode;
44
+ }): JSX.Element {
45
+ const [db, setDb] = useState<PGlite | null>(null);
46
+ const [isReady, setIsReady] = useState(false);
47
+
48
+ useEffect(() => {
49
+ const setupDb = async (): Promise<void> => {
50
+ try {
51
+ const database = await initializeDb();
52
+ setDb(database);
53
+ setIsReady(true);
54
+ } catch (error) {
55
+ console.error('Database initialization failed:', error);
56
+ }
57
+ };
58
+
59
+ void setupDb();
60
+ }, []);
61
+
62
+ if (!isReady || !db) {
63
+ return (
64
+ <div className="min-h-screen flex items-center justify-center p-6">
65
+ <div className="text-center">
66
+ <div className="text-lg font-semibold">Initializing Database...</div>
67
+ <div className="text-sm text-muted-foreground mt-2">
68
+ Setting up PGlite in your browser
69
+ </div>
70
+ </div>
71
+ </div>
72
+ );
73
+ }
74
+
75
+ return (
76
+ <PGliteProvider db={db as unknown as PGliteWithLive}>
77
+ {children}
78
+ </PGliteProvider>
79
+ );
80
+ }
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+
3
+ import { JSX } from 'react';
4
+ import Aurora from '@/components/reactbits/blocks/Backgrounds/Aurora/Aurora';
5
+
6
+ export default function AuroraBackground(): JSX.Element {
7
+ // Force dark-mode palette regardless of theme
8
+ const colorStops = ['#0ea5e9', '#7c3aed', '#22d3ee']; // sky-500 → violet-600 → cyan-400
9
+ return (
10
+ <Aurora amplitude={1.0} blend={0.6} speed={0.4} colorStops={colorStops} />
11
+ );
12
+ }
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Icons } from '@/components/ui/icons';
5
+
6
+ type StarsResponse = {
7
+ stargazers_count?: number;
8
+ };
9
+
10
+ export function GitHubStars() {
11
+ const [stars, setStars] = React.useState<number | null>(null);
12
+ const [isLoading, setIsLoading] = React.useState<boolean>(true);
13
+
14
+ React.useEffect(() => {
15
+ let isMounted = true;
16
+ const fetchStars = async () => {
17
+ try {
18
+ const res = await fetch(
19
+ 'https://api.github.com/repos/gblikas/querykit',
20
+ {
21
+ headers: { Accept: 'application/vnd.github+json' },
22
+ cache: 'force-cache'
23
+ }
24
+ );
25
+ const data: StarsResponse = await res.json();
26
+ if (isMounted) {
27
+ const count =
28
+ typeof data.stargazers_count === 'number'
29
+ ? data.stargazers_count
30
+ : null;
31
+ setStars(count);
32
+ }
33
+ } catch {
34
+ if (isMounted) setStars(null);
35
+ } finally {
36
+ if (isMounted) setIsLoading(false);
37
+ }
38
+ };
39
+ void fetchStars();
40
+ return () => {
41
+ isMounted = false;
42
+ };
43
+ }, []);
44
+
45
+ return (
46
+ <span className="inline-flex items-center gap-1">
47
+ <Icons.gitHub className="h-4 w-4" aria-hidden="true" />
48
+ {isLoading ? <span>—</span> : <span>{stars ?? '—'}</span>}
49
+ </span>
50
+ );
51
+ }
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Sunrise, Sunset } from 'lucide-react';
5
+ import { useTheme } from 'next-themes';
6
+
7
+ export function ModeToggle() {
8
+ const { resolvedTheme, setTheme } = useTheme();
9
+
10
+ const handleToggle = React.useCallback(() => {
11
+ const next = resolvedTheme === 'dark' ? 'light' : 'dark';
12
+ setTheme(next);
13
+ }, [resolvedTheme, setTheme]);
14
+
15
+ return (
16
+ <button
17
+ type="button"
18
+ onClick={handleToggle}
19
+ className="relative inline-flex h-9 w-9 items-center justify-center rounded-md border bg-background hover:bg-accent transition-colors"
20
+ aria-label="Toggle theme"
21
+ title="Toggle theme"
22
+ >
23
+ <Sunset className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
24
+ <Sunrise className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
25
+ </button>
26
+ );
27
+ }
@@ -0,0 +1,217 @@
1
+ /*
2
+ Installed from https://reactbits.dev/ts/tailwind/
3
+ */
4
+
5
+ import { useEffect, useRef } from 'react';
6
+ import { Renderer, Program, Mesh, Color, Triangle } from 'ogl';
7
+
8
+ const VERT = `#version 300 es
9
+ in vec2 position;
10
+ void main() {
11
+ gl_Position = vec4(position, 0.0, 1.0);
12
+ }
13
+ `;
14
+
15
+ const FRAG = `#version 300 es
16
+ precision highp float;
17
+
18
+ uniform float uTime;
19
+ uniform float uAmplitude;
20
+ uniform vec3 uColorStops[3];
21
+ uniform vec2 uResolution;
22
+ uniform float uBlend;
23
+
24
+ out vec4 fragColor;
25
+
26
+ vec3 permute(vec3 x) {
27
+ return mod(((x * 34.0) + 1.0) * x, 289.0);
28
+ }
29
+
30
+ float snoise(vec2 v){
31
+ const vec4 C = vec4(
32
+ 0.211324865405187, 0.366025403784439,
33
+ -0.577350269189626, 0.024390243902439
34
+ );
35
+ vec2 i = floor(v + dot(v, C.yy));
36
+ vec2 x0 = v - i + dot(i, C.xx);
37
+ vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
38
+ vec4 x12 = x0.xyxy + C.xxzz;
39
+ x12.xy -= i1;
40
+ i = mod(i, 289.0);
41
+
42
+ vec3 p = permute(
43
+ permute(i.y + vec3(0.0, i1.y, 1.0))
44
+ + i.x + vec3(0.0, i1.x, 1.0)
45
+ );
46
+
47
+ vec3 m = max(
48
+ 0.5 - vec3(
49
+ dot(x0, x0),
50
+ dot(x12.xy, x12.xy),
51
+ dot(x12.zw, x12.zw)
52
+ ),
53
+ 0.0
54
+ );
55
+ m = m * m;
56
+ m = m * m;
57
+
58
+ vec3 x = 2.0 * fract(p * C.www) - 1.0;
59
+ vec3 h = abs(x) - 0.5;
60
+ vec3 ox = floor(x + 0.5);
61
+ vec3 a0 = x - ox;
62
+ m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
63
+
64
+ vec3 g;
65
+ g.x = a0.x * x0.x + h.x * x0.y;
66
+ g.yz = a0.yz * x12.xz + h.yz * x12.yw;
67
+ return 130.0 * dot(m, g);
68
+ }
69
+
70
+ struct ColorStop {
71
+ vec3 color;
72
+ float position;
73
+ };
74
+
75
+ #define COLOR_RAMP(colors, factor, finalColor) { \
76
+ int index = 0; \
77
+ for (int i = 0; i < 2; i++) { \
78
+ ColorStop currentColor = colors[i]; \
79
+ bool isInBetween = currentColor.position <= factor; \
80
+ index = int(mix(float(index), float(i), float(isInBetween))); \
81
+ } \
82
+ ColorStop currentColor = colors[index]; \
83
+ ColorStop nextColor = colors[index + 1]; \
84
+ float range = nextColor.position - currentColor.position; \
85
+ float lerpFactor = (factor - currentColor.position) / range; \
86
+ finalColor = mix(currentColor.color, nextColor.color, lerpFactor); \
87
+ }
88
+
89
+ void main() {
90
+ vec2 uv = gl_FragCoord.xy / uResolution;
91
+
92
+ ColorStop colors[3];
93
+ colors[0] = ColorStop(uColorStops[0], 0.0);
94
+ colors[1] = ColorStop(uColorStops[1], 0.5);
95
+ colors[2] = ColorStop(uColorStops[2], 1.0);
96
+
97
+ vec3 rampColor;
98
+ COLOR_RAMP(colors, uv.x, rampColor);
99
+
100
+ float height = snoise(vec2(uv.x * 2.0 + uTime * 0.1, uTime * 0.25)) * 0.5 * uAmplitude;
101
+ height = exp(height);
102
+ height = (uv.y * 2.0 - height + 0.2);
103
+ float intensity = 0.6 * height;
104
+
105
+ float midPoint = 0.20;
106
+ float auroraAlpha = smoothstep(midPoint - uBlend * 0.5, midPoint + uBlend * 0.5, intensity);
107
+
108
+ vec3 auroraColor = intensity * rampColor;
109
+
110
+ fragColor = vec4(auroraColor * auroraAlpha, auroraAlpha);
111
+ }
112
+ `;
113
+
114
+ interface AuroraProps {
115
+ colorStops?: string[];
116
+ amplitude?: number;
117
+ blend?: number;
118
+ time?: number;
119
+ speed?: number;
120
+ }
121
+
122
+ export default function Aurora(props: AuroraProps) {
123
+ const {
124
+ colorStops = ['#5227FF', '#7cff67', '#5227FF'],
125
+ amplitude = 1.0,
126
+ blend = 0.5
127
+ } = props;
128
+ const propsRef = useRef<AuroraProps>(props);
129
+ propsRef.current = props;
130
+
131
+ const ctnDom = useRef<HTMLDivElement>(null);
132
+
133
+ useEffect(() => {
134
+ const ctn = ctnDom.current;
135
+ if (!ctn) return;
136
+
137
+ const renderer = new Renderer({
138
+ alpha: true,
139
+ premultipliedAlpha: true,
140
+ antialias: true
141
+ });
142
+ const gl = renderer.gl;
143
+ gl.clearColor(0, 0, 0, 0);
144
+ gl.enable(gl.BLEND);
145
+ gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
146
+ gl.canvas.style.backgroundColor = 'transparent';
147
+
148
+ let program: Program | undefined = undefined;
149
+
150
+ function resize() {
151
+ if (!ctn) return;
152
+ const width = ctn.offsetWidth;
153
+ const height = ctn.offsetHeight;
154
+ renderer.setSize(width, height);
155
+ if (program) {
156
+ program.uniforms.uResolution.value = [width, height];
157
+ }
158
+ }
159
+ window.addEventListener('resize', resize);
160
+
161
+ const geometry = new Triangle(gl);
162
+ if (geometry.attributes.uv) {
163
+ delete geometry.attributes.uv;
164
+ }
165
+
166
+ const colorStopsArray = colorStops.map(hex => {
167
+ const c = new Color(hex);
168
+ return [c.r, c.g, c.b];
169
+ });
170
+
171
+ program = new Program(gl, {
172
+ vertex: VERT,
173
+ fragment: FRAG,
174
+ uniforms: {
175
+ uTime: { value: 0 },
176
+ uAmplitude: { value: amplitude },
177
+ uColorStops: { value: colorStopsArray },
178
+ uResolution: { value: [ctn.offsetWidth, ctn.offsetHeight] },
179
+ uBlend: { value: blend }
180
+ }
181
+ });
182
+
183
+ const mesh = new Mesh(gl, { geometry, program });
184
+ ctn.appendChild(gl.canvas);
185
+
186
+ let animateId = 0;
187
+ const update = (t: number) => {
188
+ animateId = requestAnimationFrame(update);
189
+ const { time = t * 0.01, speed = 1.0 } = propsRef.current;
190
+ if (program) {
191
+ program.uniforms.uTime.value = time * speed * 0.1;
192
+ program.uniforms.uAmplitude.value = propsRef.current.amplitude ?? 1.0;
193
+ program.uniforms.uBlend.value = propsRef.current.blend ?? blend;
194
+ const stops = propsRef.current.colorStops ?? colorStops;
195
+ program.uniforms.uColorStops.value = stops.map((hex: string) => {
196
+ const c = new Color(hex);
197
+ return [c.r, c.g, c.b];
198
+ });
199
+ renderer.render({ scene: mesh });
200
+ }
201
+ };
202
+ animateId = requestAnimationFrame(update);
203
+
204
+ resize();
205
+
206
+ return () => {
207
+ cancelAnimationFrame(animateId);
208
+ window.removeEventListener('resize', resize);
209
+ if (ctn && gl.canvas.parentNode === ctn) {
210
+ ctn.removeChild(gl.canvas);
211
+ }
212
+ gl.getExtension('WEBGL_lose_context')?.loseContext();
213
+ };
214
+ }, [amplitude]);
215
+
216
+ return <div ref={ctnDom} className="w-full h-full" />;
217
+ }