From a24c236bbba7182381d00626562720bcd2e0e45a Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Fri, 1 Aug 2025 12:16:58 -0400 Subject: [PATCH 1/7] beginning of draft doc --- .../routes/docs/integrations/gel/index.mdx | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/docs/src/routes/docs/integrations/gel/index.mdx diff --git a/packages/docs/src/routes/docs/integrations/gel/index.mdx b/packages/docs/src/routes/docs/integrations/gel/index.mdx new file mode 100644 index 00000000000..57c232996ea --- /dev/null +++ b/packages/docs/src/routes/docs/integrations/gel/index.mdx @@ -0,0 +1,60 @@ +--- +title: Gel | Integrations +keywords: 'Gel, EdgeDB, database, data, postgres' +contributors: + - nabrams +updated_at: '2024-08-01T18:53:23Z' +created_at: '2025-08-01T23:00:50Z' +--- + +import PackageManagerTabs from '~/components/package-manager-tabs/index.tsx'; + +# Gel Data + +[GelDB](https://www.geldata.com/) Gel is a scalable, integrated data platform on top of Postgres. + +Gel gives the relational model a fresh facelift, solves n+1, simplifies migrations, + +and streamlines your entire database workflow. + +Gel can be used in Qwik with `routeLoader$`, `routeAction$` and `server$` functions. These are Qwik APIs to allow code to execute only on the server-side. + +The easiest way to add Gel to Qwik is using the Qwik CLI command. This will install the required dependencies and create a `db` folder with the drizzle schema. + + + +```shell +pnpm run qwik add gel +``` + + +```shell +npm run qwik add gel +``` + + +```shell +yarn run qwik add gel +``` + + +```shell +bun run qwik add gel +``` + + + +> Gel is a modern data platform built on PostgreSQL that provides a unified interface for managing, querying, and scaling your data. It offers features like real-time analytics, seamless migrations, and integrated workflows to simplify database operations for developers and teams. + +## Auto-generating queries + +Gel lets you automatically generate queries for your database schema by using + +their query language EdgeQL combined with `npm install @gel/generate --save-dev`. + +The following ``s are currently supported: + +- `queries`: Generate typed functions from *.edgeql files +- `interfaces`: Generate interfaces for your schema types +- `edgeql-js`: Generate the query builder + From ec02b33d64d1029319c8b2846b3e3e860e0a3062 Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Wed, 24 Sep 2025 18:33:56 -0400 Subject: [PATCH 2/7] add all base files for user to add gel to their qwik project with simple example db --- starters/features/gel/gel.toml | 7 ++ starters/features/gel/gel/queries/.gitkeep | 0 .../features/gel/gel/queries/getUser.edgeql | 5 ++ .../gel/queries/insertOrUpdateEmail.edgeql | 27 +++++++ .../gel/gel/queries/insertOrUpdateUser.edgeql | 40 ++++++++++ starters/features/gel/gel/schema/default.gel | 29 +++++++ .../gel/gel/schema/migrations/.gitkeep | 0 starters/features/gel/package.json | 22 ++++++ starters/features/gel/src/.gitkeep | 0 starters/features/gel/src/actions/.gitkeep | 0 starters/features/gel/src/actions/client.ts | 75 +++++++++++++++++++ .../features/gel/src/actions/user/.gitkeep | 0 .../features/gel/src/actions/user/index.ts | 9 +++ starters/features/gel/src/hooks/.gitkeep | 0 starters/features/gel/src/hooks/user.hooks.ts | 13 ++++ 15 files changed, 227 insertions(+) create mode 100644 starters/features/gel/gel.toml create mode 100644 starters/features/gel/gel/queries/.gitkeep create mode 100644 starters/features/gel/gel/queries/getUser.edgeql create mode 100644 starters/features/gel/gel/queries/insertOrUpdateEmail.edgeql create mode 100644 starters/features/gel/gel/queries/insertOrUpdateUser.edgeql create mode 100644 starters/features/gel/gel/schema/default.gel create mode 100644 starters/features/gel/gel/schema/migrations/.gitkeep create mode 100644 starters/features/gel/package.json create mode 100644 starters/features/gel/src/.gitkeep create mode 100644 starters/features/gel/src/actions/.gitkeep create mode 100644 starters/features/gel/src/actions/client.ts create mode 100644 starters/features/gel/src/actions/user/.gitkeep create mode 100644 starters/features/gel/src/actions/user/index.ts create mode 100644 starters/features/gel/src/hooks/.gitkeep create mode 100644 starters/features/gel/src/hooks/user.hooks.ts diff --git a/starters/features/gel/gel.toml b/starters/features/gel/gel.toml new file mode 100644 index 00000000000..e2752ceea62 --- /dev/null +++ b/starters/features/gel/gel.toml @@ -0,0 +1,7 @@ +watch = [] + +[instance] +server-version = "6.7" + +[hooks] +schema.update.after = "pnpm generate queries --file" \ No newline at end of file diff --git a/starters/features/gel/gel/queries/.gitkeep b/starters/features/gel/gel/queries/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/starters/features/gel/gel/queries/getUser.edgeql b/starters/features/gel/gel/queries/getUser.edgeql new file mode 100644 index 00000000000..b47fc5bee06 --- /dev/null +++ b/starters/features/gel/gel/queries/getUser.edgeql @@ -0,0 +1,5 @@ +select User { ** +} filter assert_exists(User.name) ?= $name; + +# Filter here is optional. +# If no filter is provided, all Users will be returned. diff --git a/starters/features/gel/gel/queries/insertOrUpdateEmail.edgeql b/starters/features/gel/gel/queries/insertOrUpdateEmail.edgeql new file mode 100644 index 00000000000..d7eab2683ef --- /dev/null +++ b/starters/features/gel/gel/queries/insertOrUpdateEmail.edgeql @@ -0,0 +1,27 @@ +with + NewEmail := ( + insert Email { + address := $address, + provider := $package_version, + user := ( + select User + filter .name = $name + limit 1 + ) + } + unless conflict on .address + else ( + update Email + filter .address = $address + set { + provider := $package_version, + user := ( + select User + filter .name = $name + limit 1 + ) + } + ) + ) + +select NewEmail { ** }; diff --git a/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql b/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql new file mode 100644 index 00000000000..1b6775826f7 --- /dev/null +++ b/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql @@ -0,0 +1,40 @@ +with + NewUser := ( + insert User { + name := $name, + description := $package_version, + has_profile := $has_profile, + } + unless conflict on .name + else ( + update User + filter .name = $name + set { + package_version := $package_version, + description := $package_version, + has_profile := $has_profile, + } + ) + ), + + InsertEmails := ( + for email in array_unpack(>>$dependencies) + union ( + insert Email { + address := email.address, + provider := email.provider, + user := NewUser, + } + unless conflict on (.address) + else ( + update Email + filter .address = email.address + and .user.name = NewUser.name + set { + provider := email.provider, + } + ) + ) + ), + +select NewUser { ** }; diff --git a/starters/features/gel/gel/schema/default.gel b/starters/features/gel/gel/schema/default.gel new file mode 100644 index 00000000000..17dca7eeeda --- /dev/null +++ b/starters/features/gel/gel/schema/default.gel @@ -0,0 +1,29 @@ +// This is where the database schema goes +// Read more here: https://docs.geldata.com/reference/datamodel + + abstract type Timestamped { + last_updated: datetime { + rewrite insert, update using (datetime_of_statement()); + }; + } + +type User extends Timestamped { + errmessage := 'A user with that name already exists!' + required name: str { + constraint exclusive; + }; + description: str; + has_profile: bool; + multi emails: . { + const message = error instanceof Error ? error.message.toLowerCase() : ""; + return ( + message.includes("connection") || + message.includes("timeout") || + message.includes("network") || + message.includes("invalidreferenceerror") + ); +}; + +const createNewClient = (): Executor => { + console.log("Creating new database client"); + return createClient(); +}; + +const closeClient = (): void => { + if (client) { + client = null; + console.log("Database client closed"); + } +}; + +// Main client management functions +export const getClient = (): Executor => { + if (!client) { + closeClient(); + client = createNewClient(); + } + + return client; +}; + +// Regular async function preserves generic types with optional args +export const executeQuery = async ( + queryFn: TArgs extends void + ? (client: Executor) => Promise + : (client: Executor, args: TArgs) => Promise, + args?: TArgs, +): Promise => { + const dbClient = getClient(); + + try { + if (args === undefined) { + return await (queryFn as (client: Executor) => Promise)(dbClient); + } else { + return await (queryFn as (client: Executor, args: TArgs) => Promise)( + dbClient, + args, + ); + } + } catch (error) { + console.error("Database query failed:", error); + + if (isConnectionError(error)) { + console.log("Connection error detected, recreating client..."); + closeClient(); + const newClient = getClient(); + if (args === undefined) { + return await (queryFn as (client: Executor) => Promise)(newClient); + } else { + return await (queryFn as (client: Executor, args: TArgs) => Promise)( + newClient, + args, + ); + } + } + + throw error; + } +}; diff --git a/starters/features/gel/src/actions/user/.gitkeep b/starters/features/gel/src/actions/user/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/starters/features/gel/src/actions/user/index.ts b/starters/features/gel/src/actions/user/index.ts new file mode 100644 index 00000000000..0c92fd53545 --- /dev/null +++ b/starters/features/gel/src/actions/user/index.ts @@ -0,0 +1,9 @@ +import { server$ } from "@qwik.dev/router"; +import { executeQuery } from "../client"; +import * as queries from "../../../gel/queries"; + + +export const getAllUsers = server$(async () => { + return await executeQuery(queries.getAllUsers); +}); + diff --git a/starters/features/gel/src/hooks/.gitkeep b/starters/features/gel/src/hooks/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/starters/features/gel/src/hooks/user.hooks.ts b/starters/features/gel/src/hooks/user.hooks.ts new file mode 100644 index 00000000000..07b39e162f9 --- /dev/null +++ b/starters/features/gel/src/hooks/user.hooks.ts @@ -0,0 +1,13 @@ +import { useSignal, useTask$ } from "@qwik.dev/core"; +import { + getUsers, +} from "~/actions/user"; + +export const useGetUsers = () => { + const signal = useSignal>>([]); + useTask$(async () => { + const result = await getUsers(); + signal.value = result; + }); + return signal; +}; \ No newline at end of file From 3f218d769a3268456b74c3e325cdb0bb299fc0da Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Wed, 24 Sep 2025 18:35:02 -0400 Subject: [PATCH 3/7] meant to delete --- starters/features/gel/gel/queries/insertOrUpdateUser.edgeql | 1 - 1 file changed, 1 deletion(-) diff --git a/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql b/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql index 1b6775826f7..ab499c56e3e 100644 --- a/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql +++ b/starters/features/gel/gel/queries/insertOrUpdateUser.edgeql @@ -29,7 +29,6 @@ with else ( update Email filter .address = email.address - and .user.name = NewUser.name set { provider := email.provider, } From 90fc2118ff5e5a4abc1b9a7940f57db4efdc8b63 Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Thu, 25 Sep 2025 15:40:13 -0400 Subject: [PATCH 4/7] add to tests --- .../Docs/integrations-pages-load.spec.ts | 5 ++ .../tests/Docs/pages-load-test.spec.ts | 1 + .../routes/docs/integrations/gel/index.mdx | 6 ++- packages/docs/src/routes/docs/menu.md | 1 + starters/features/gel/package.json | 54 +++++++++++-------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/e2e/docs-e2e/tests/Docs/integrations-pages-load.spec.ts b/e2e/docs-e2e/tests/Docs/integrations-pages-load.spec.ts index d580c8457b6..aa97902362a 100644 --- a/e2e/docs-e2e/tests/Docs/integrations-pages-load.spec.ts +++ b/e2e/docs-e2e/tests/Docs/integrations-pages-load.spec.ts @@ -35,6 +35,11 @@ test('Integrations Drizzle page loads', async ({ page }) => { await expect(page).toHaveTitle('Drizzle | Integrations 📚 Qwik Documentation'); }); +test('Integrations Gel page loads', async ({ page }) => { + await page.goto('/docs/integrations/gel/'); + await expect(page).toHaveTitle('Gel | Integrations 📚 Qwik Documentation'); +}); + test('Integrations Internationalization page loads', async ({ page }) => { await page.goto('/docs/integrations/i18n/'); await expect(page).toHaveTitle('Internationalization | Integrations 📚 Qwik Documentation'); diff --git a/e2e/docs-e2e/tests/Docs/pages-load-test.spec.ts b/e2e/docs-e2e/tests/Docs/pages-load-test.spec.ts index 1720624cc71..d6b4b3b559f 100644 --- a/e2e/docs-e2e/tests/Docs/pages-load-test.spec.ts +++ b/e2e/docs-e2e/tests/Docs/pages-load-test.spec.ts @@ -102,6 +102,7 @@ test('docs page loads', async ({ page }) => { 'Builder.io', 'Cypress', 'Drizzle', + 'Gel', 'i18n', 'Icons', 'Image Optimization', diff --git a/packages/docs/src/routes/docs/integrations/gel/index.mdx b/packages/docs/src/routes/docs/integrations/gel/index.mdx index 57c232996ea..2d4fd80d4b8 100644 --- a/packages/docs/src/routes/docs/integrations/gel/index.mdx +++ b/packages/docs/src/routes/docs/integrations/gel/index.mdx @@ -3,7 +3,7 @@ title: Gel | Integrations keywords: 'Gel, EdgeDB, database, data, postgres' contributors: - nabrams -updated_at: '2024-08-01T18:53:23Z' +updated_at: '2025-09-25T18:53:23Z' created_at: '2025-08-01T23:00:50Z' --- @@ -19,7 +19,9 @@ and streamlines your entire database workflow. Gel can be used in Qwik with `routeLoader$`, `routeAction$` and `server$` functions. These are Qwik APIs to allow code to execute only on the server-side. -The easiest way to add Gel to Qwik is using the Qwik CLI command. This will install the required dependencies and create a `db` folder with the drizzle schema. +The easiest way to add Gel to Qwik is using the Qwik CLI command. This will install the required dependencies and create a `gel` folder with the gel schema. + +It will also create a `gel.toml` file to configure the gel instance. Everything you need to get started is there. diff --git a/packages/docs/src/routes/docs/menu.md b/packages/docs/src/routes/docs/menu.md index d77d6583a3f..bfd5fda55ee 100644 --- a/packages/docs/src/routes/docs/menu.md +++ b/packages/docs/src/routes/docs/menu.md @@ -65,6 +65,7 @@ - [Builder.io](integrations/builderio/index.mdx) - [Cypress](integrations/cypress/index.mdx) - [Drizzle](integrations/drizzle/index.mdx) +- [Gel](integrations/gel/index.mdx) - [i18n](integrations/i18n/index.mdx) - [Icons](integrations/icons/index.mdx) - [Image Optimization](integrations/image-optimization/index.mdx) diff --git a/starters/features/gel/package.json b/starters/features/gel/package.json index c5ac0fecffa..392ce274e88 100644 --- a/starters/features/gel/package.json +++ b/starters/features/gel/package.json @@ -1,22 +1,34 @@ { - "description": "Gel: Graph Relational Database on top of Postgres", - "__qwik__": { - "displayName": "Integration: GelDB", - "priority": -10, - "docs": [ - "https://www.geldata.com/docs/quickstart" - ] - }, - "viteConfig": {}, - "scripts": { - "gel:generate": "pnpm run gel:generate:queries && pnpm run gel:generate:queries --file && pnpm run gel:generate:interfaces && pnpm run gel:generate:edgeql-js" - }, - "devDependencies": { - "@gel/generate": "^0.6.3", - "@qwik.dev/router": "2.0.0-beta.6", - "@qwik.dev/core": "2.0.0-beta.6" - }, - "dependencies": { - "gel": "2.1.1" - } - } \ No newline at end of file + "description": "Gel: Graph Relational Database on top of Postgres", + "__qwik__": { + "displayName": "Integration: GelDB", + "priority": -10, + "docs": [ + "https://www.geldata.com/docs/quickstart" + ] + }, + "viteConfig": {}, + "nextSteps": { + "title": "Next Steps", + "lines": [ + " Gel was installed with a simple DB schema and some demo routes,", + " now you need to run `npm run gel:migrate` to setup the database.", + "", + "", + "", + " Gel ui was also added which you can access by running `npm run gel:ui`,", + "", + " Check out the Gel docs for more info:", + " - https://www.geldata.com/docs/overview" + ] + }, + "scripts": { + "gel:generate": "pnpm run gel generate:queries && pnpm run gel generate:queries --file && pnpm run gel generate:interfaces && pnpm run gel generate:edgeql-js", + "gel:migrate": "pnpm run gel migrate", + "gel:ui": "pnpm run gel ui" + }, + "dependencies": { + "@gel/generate": "^0.6.4", + "gel": "^2.1.1" + } +} From 9f3045fdf68869cd7954250caa20af001c7dc9ff Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Wed, 1 Oct 2025 18:16:47 -0400 Subject: [PATCH 5/7] fix linting errors --- packages/qwik/src/qwikloader.unit.ts | 1 - starters/features/gel/src/actions/user/index.ts | 2 -- starters/features/gel/src/hooks/user.hooks.ts | 12 +++++------- .../{prettier.config.js => prettier.config.mjs} | 0 4 files changed, 5 insertions(+), 10 deletions(-) rename starters/features/tailwind-v3/{prettier.config.js => prettier.config.mjs} (100%) diff --git a/packages/qwik/src/qwikloader.unit.ts b/packages/qwik/src/qwikloader.unit.ts index 08dede8f7d3..2e201d2a0cf 100644 --- a/packages/qwik/src/qwikloader.unit.ts +++ b/packages/qwik/src/qwikloader.unit.ts @@ -29,7 +29,6 @@ test('qwikloader script', () => { `); expect(qwikLoader).toMatchInlineSnapshot( - //eslint-disable-next-line `"const t=document,e=window,n=new Set,o=new Set([t]);let r;const s=(t,e)=>Array.from(t.querySelectorAll(e)),a=t=>{const e=[];return o.forEach(n=>e.push(...s(n,t))),e},i=t=>{w(t),s(t,"[q\\\\:shadowroot]").forEach(t=>{const e=t.shadowRoot;e&&i(e)})},c=t=>t&&"function"==typeof t.then,l=(t,e,n=e.type)=>{a("[on"+t+"\\\\:"+n+"]").forEach(o=>{b(o,t,e,n)})},f=e=>{if(void 0===e._qwikjson_){let n=(e===t.documentElement?t.body:e).lastElementChild;for(;n;){if("SCRIPT"===n.tagName&&"qwik/json"===n.getAttribute("type")){e._qwikjson_=JSON.parse(n.textContent.replace(/\\\\x3C(\\/?script)/gi,"<$1"));break}n=n.previousElementSibling}}},p=(t,e)=>new CustomEvent(t,{detail:e}),b=async(e,n,o,r=o.type)=>{const s="on"+n+":"+r;e.hasAttribute("preventdefault:"+r)&&o.preventDefault(),e.hasAttribute("stoppropagation:"+r)&&o.stopPropagation();const a=e._qc_,i=a&&a.li.filter(t=>t[0]===s);if(i&&i.length>0){for(const t of i){const n=t[1].getFn([e,o],()=>e.isConnected)(o,e),r=o.cancelBubble;c(n)&&await n,r&&o.stopPropagation()}return}const l=e.getAttribute(s);if(l){const n=e.closest("[q\\\\:container]"),r=n.getAttribute("q:base"),s=n.getAttribute("q:version")||"unknown",a=n.getAttribute("q:manifest-hash")||"dev",i=new URL(r,t.baseURI);for(const p of l.split("\\n")){const l=new URL(p,i),b=l.href,h=l.hash.replace(/^#?([^?[|]*).*$/,"$1")||"default",q=performance.now();let _,d,y;const w=p.startsWith("#"),g={qBase:r,qManifest:a,qVersion:s,href:b,symbol:h,element:e,reqTime:q};if(w){const e=n.getAttribute("q:instance");_=(t["qFuncs_"+e]||[])[Number.parseInt(h)],_||(d="sync",y=Error("sym:"+h))}else{u("qsymbol",g);const t=l.href.split("#")[0];try{const e=import(t);f(n),_=(await e)[h],_||(d="no-symbol",y=Error(\`\${h} not in \${t}\`))}catch(t){d||(d="async"),y=t}}if(!_){u("qerror",{importError:d,error:y,...g}),console.error(y);break}const m=t.__q_context__;if(e.isConnected)try{t.__q_context__=[e,o,l];const n=_(o,e);c(n)&&await n}catch(t){u("qerror",{error:t,...g})}finally{t.__q_context__=m}}}},u=(e,n)=>{t.dispatchEvent(p(e,n))},h=t=>t.replace(/([A-Z])/g,t=>"-"+t.toLowerCase()),q=async t=>{let e=h(t.type),n=t.target;for(l("-document",t,e);n&&n.getAttribute;){const o=b(n,"",t,e);let r=t.cancelBubble;c(o)&&await o,r||(r=r||t.cancelBubble||n.hasAttribute("stoppropagation:"+t.type)),n=t.bubbles&&!0!==r?n.parentElement:null}},_=t=>{l("-window",t,h(t.type))},d=()=>{const s=t.readyState;if(!r&&("interactive"==s||"complete"==s)&&(o.forEach(i),r=1,u("qinit"),(e.requestIdleCallback??e.setTimeout).bind(e)(()=>u("qidle")),n.has("qvisible"))){const t=a("[on\\\\:qvisible]"),e=new IntersectionObserver(t=>{for(const n of t)n.isIntersecting&&(e.unobserve(n.target),b(n.target,"",p("qvisible",n)))});t.forEach(t=>e.observe(t))}},y=(t,e,n,o=!1)=>{t.addEventListener(e,n,{capture:o,passive:!1})},w=(...t)=>{for(const r of t)"string"==typeof r?n.has(r)||(o.forEach(t=>y(t,r,q,!0)),y(e,r,_,!0),n.add(r)):o.has(r)||(n.forEach(t=>y(r,t,q,!0)),o.add(r))};if(!("__q_context__"in t)){t.__q_context__=0;const r=e.qwikevents;r&&(Array.isArray(r)?w(...r):w("click","input")),e.qwikevents={events:n,roots:o,push:w},y(t,"readystatechange",d),d()}"` ); }); diff --git a/starters/features/gel/src/actions/user/index.ts b/starters/features/gel/src/actions/user/index.ts index 0c92fd53545..450db747a5c 100644 --- a/starters/features/gel/src/actions/user/index.ts +++ b/starters/features/gel/src/actions/user/index.ts @@ -2,8 +2,6 @@ import { server$ } from "@qwik.dev/router"; import { executeQuery } from "../client"; import * as queries from "../../../gel/queries"; - export const getAllUsers = server$(async () => { return await executeQuery(queries.getAllUsers); }); - diff --git a/starters/features/gel/src/hooks/user.hooks.ts b/starters/features/gel/src/hooks/user.hooks.ts index 07b39e162f9..4b92c1a0524 100644 --- a/starters/features/gel/src/hooks/user.hooks.ts +++ b/starters/features/gel/src/hooks/user.hooks.ts @@ -1,13 +1,11 @@ -import { useSignal, useTask$ } from "@qwik.dev/core"; -import { - getUsers, -} from "~/actions/user"; +import { useSignal, useTask$ } from "@builder.io/qwik"; +import { getAllUsers } from "../actions/user"; export const useGetUsers = () => { - const signal = useSignal>>([]); + const signal = useSignal>>([]); useTask$(async () => { - const result = await getUsers(); + const result = await getAllUsers(); signal.value = result; }); return signal; -}; \ No newline at end of file +}; diff --git a/starters/features/tailwind-v3/prettier.config.js b/starters/features/tailwind-v3/prettier.config.mjs similarity index 100% rename from starters/features/tailwind-v3/prettier.config.js rename to starters/features/tailwind-v3/prettier.config.mjs From 1c86d2e4fab2f348f22c8b7061fca0797313f536 Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Wed, 1 Oct 2025 18:40:01 -0400 Subject: [PATCH 6/7] fix irrelevant broken tests --- package.json | 3 +- packages/docs/src/routes/api/qwik/api.json | 2 +- packages/docs/src/routes/api/qwik/index.mdx | 2 +- .../src/optimizer/src/qwik-binding-map.ts | 28 ------------------- starters/e2e/e2e.use-id.spec.ts | 3 +- 5 files changed, 6 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 3410b15ea69..8f66b16e139 100644 --- a/package.json +++ b/package.json @@ -235,12 +235,13 @@ "serve.debug": "tsx --require ./scripts/runBefore.ts --inspect-brk --conditions=development starters/dev-server.ts 3300", "start": "pnpm run --stream \"/.*\\.watch/\"", "test": "pnpm build.full && pnpm test.unit && pnpm test.e2e", - "test.e2e": "pnpm test.e2e.chromium && pnpm test.e2e.webkit && test.e2e.integrations", + "test.e2e": "pnpm test.e2e.chromium && pnpm test.e2e.webkit && pnpm test.e2e.integrations", "test.e2e.chromium": "playwright test starters --browser=chromium --config starters/playwright.config.ts", "test.e2e.chromium.debug": "PWDEBUG=1 playwright test starters --browser=chromium --config starters/playwright.config.ts", "test.e2e.city": "playwright test starters/e2e/qwikcity --browser=chromium --config starters/playwright.config.ts", "test.e2e.cli": "pnpm --filter qwik-cli-e2e e2e", "test.e2e.firefox": "playwright test starters --browser=firefox --config starters/playwright.config.ts", + "test.e2e.integrations": "pnpm test.e2e.integrations.chromium && pnpm test.e2e.integrations.webkit", "test.e2e.integrations.chromium": "playwright test e2e/adapters-e2e/tests --project=chromium --config e2e/adapters-e2e/playwright.config.ts", "test.e2e.integrations.webkit": "playwright test e2e/adapters-e2e/tests --project=webkit --config e2e/adapters-e2e/playwright.config.ts", "test.e2e.webkit": "playwright test starters --browser=webkit --config starters/playwright.config.ts", diff --git a/packages/docs/src/routes/api/qwik/api.json b/packages/docs/src/routes/api/qwik/api.json index 91d5fcdccaa..8750f3fe20d 100644 --- a/packages/docs/src/routes/api/qwik/api.json +++ b/packages/docs/src/routes/api/qwik/api.json @@ -1774,7 +1774,7 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\n> Warning: This API is now obsolete.\n> \n> This is no longer needed as the preloading happens automatically in qrl-class.ts. Leave this in your app for a while so it uninstalls existing service workers, but don't use it for new projects.\n> \n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\n\n
\n\n**Returns:**\n\n[JSXNode](#jsxnode)<'script'>", + "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\n> Warning: This API is now obsolete.\n> \n> This is no longer needed as the preloading happens automatically in qrl-class.ts. Leave this in your app for a while so it uninstalls existing service workers, but don't use it for new projects.\n> \n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\n\n
\n\n**Returns:**\n\nJSXNode<'script'>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts", "mdFile": "qwik.prefetchserviceworker.md" }, diff --git a/packages/docs/src/routes/api/qwik/index.mdx b/packages/docs/src/routes/api/qwik/index.mdx index 1ddbfe7a032..0b47efdd79d 100644 --- a/packages/docs/src/routes/api/qwik/index.mdx +++ b/packages/docs/src/routes/api/qwik/index.mdx @@ -3667,7 +3667,7 @@ opts **Returns:** -[JSXNode](#jsxnode)<'script'> +JSXNode<'script'> [Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts) diff --git a/packages/qwik/src/optimizer/src/qwik-binding-map.ts b/packages/qwik/src/optimizer/src/qwik-binding-map.ts index cceeb273668..857c9ae8fff 100644 --- a/packages/qwik/src/optimizer/src/qwik-binding-map.ts +++ b/packages/qwik/src/optimizer/src/qwik-binding-map.ts @@ -11,34 +11,6 @@ export const QWIK_BINDING_MAP = { "abi": null, "platformArchABI": "qwik.darwin-arm64.node" } - ], - "x64": [ - { - "platform": "darwin", - "arch": "x64", - "abi": null, - "platformArchABI": "qwik.darwin-x64.node" - } - ] - }, - "win32": { - "x64": [ - { - "platform": "win32", - "arch": "x64", - "abi": "msvc", - "platformArchABI": "qwik.win32-x64-msvc.node" - } - ] - }, - "linux": { - "x64": [ - { - "platform": "linux", - "arch": "x64", - "abi": "gnu", - "platformArchABI": "qwik.linux-x64-gnu.node" - } ] } }; diff --git a/starters/e2e/e2e.use-id.spec.ts b/starters/e2e/e2e.use-id.spec.ts index d98e732b749..e2ee7279229 100644 --- a/starters/e2e/e2e.use-id.spec.ts +++ b/starters/e2e/e2e.use-id.spec.ts @@ -1,4 +1,5 @@ -import { test, expect, Locator } from "@playwright/test"; +import { test, expect } from "@playwright/test"; +import type { Locator } from "@playwright/test"; test.describe("use-id", () => { test.beforeEach(async ({ page }) => { From 68ffac3d425fb80f1a43479a2633bcd17fb34ecd Mon Sep 17 00:00:00 2001 From: Natalie Abrams Date: Mon, 6 Oct 2025 18:19:01 -0400 Subject: [PATCH 7/7] fixed the integration scripts and implementation to have it initialze gel for user# Please enter the commit message for your changes. Lines starting --- starters/features/gel/dbschema/default.gel | 29 +++++++++++++ starters/features/gel/dbschema/extensions.gel | 33 ++++++++++++++ starters/features/gel/dbschema/futures.gel | 4 ++ .../dbschema/migrations/00001-m1nmosd.edgeql | 35 +++++++++++++++ starters/features/gel/gel/schema/default.gel | 29 ------------- .../gel/gel/schema/migrations/.gitkeep | 0 starters/features/gel/package.json | 43 +++++++++++-------- .../features/gel/{gel => }/queries/.gitkeep | 0 .../gel/{gel => }/queries/getUser.edgeql | 0 .../queries/insertOrUpdateEmail.edgeql | 0 .../queries/insertOrUpdateUser.edgeql | 0 11 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 starters/features/gel/dbschema/default.gel create mode 100644 starters/features/gel/dbschema/extensions.gel create mode 100644 starters/features/gel/dbschema/futures.gel create mode 100644 starters/features/gel/dbschema/migrations/00001-m1nmosd.edgeql delete mode 100644 starters/features/gel/gel/schema/default.gel delete mode 100644 starters/features/gel/gel/schema/migrations/.gitkeep rename starters/features/gel/{gel => }/queries/.gitkeep (100%) rename starters/features/gel/{gel => }/queries/getUser.edgeql (100%) rename starters/features/gel/{gel => }/queries/insertOrUpdateEmail.edgeql (100%) rename starters/features/gel/{gel => }/queries/insertOrUpdateUser.edgeql (100%) diff --git a/starters/features/gel/dbschema/default.gel b/starters/features/gel/dbschema/default.gel new file mode 100644 index 00000000000..e4bedd9e379 --- /dev/null +++ b/starters/features/gel/dbschema/default.gel @@ -0,0 +1,29 @@ +module default { + abstract type Timestamped { + last_updated: datetime { + rewrite insert, update using (datetime_of_statement()); + }; + } + + type User extending Timestamped{ + errmessage := 'A user with that name already exists!'; + required name: str { + constraint exclusive; + }; + description: str; + has_profile: bool; + multi emails: Email; + + index on (.name); + + } + + type Email { + errmessage := 'an email with that address already exists!'; + required address: str { + constraint exclusive; + }; + provider: str; + required user: User; + } +} diff --git a/starters/features/gel/dbschema/extensions.gel b/starters/features/gel/dbschema/extensions.gel new file mode 100644 index 00000000000..c566b414fd4 --- /dev/null +++ b/starters/features/gel/dbschema/extensions.gel @@ -0,0 +1,33 @@ +# This file contains Gel extensions used by the project. +# Uncomment the `using extension ...` below to enable them. + + +# Gel Auth is a batteries-included authentication solution +# for your app built into the Gel server. +# +# See: https://docs.geldata.com/reference/auth +# +#using extension auth; + + +# Gel AI is a set of tools designed to enable you to ship +# AI-enabled apps with practically no effort. +# +# See: https://docs.geldata.com/reference/ai +# +#using extension ai; + + +# The `ext::postgis` extension exposes the functionality of the +# PostGIS library. It is a vast library dedicated to handling +# geographic and various geometric data. The scope of the Gel +# extension is to mainly adapt the types and functions used in +# this library with minimal changes. +# +# See: https://docs.geldata.com/reference/stdlib/postgis +# +# `ext::postgis` is not installed by default, use the command +# `gel extension` to manage its installation, then uncomment +# the line below to enable it. +# +#using extension postgis; diff --git a/starters/features/gel/dbschema/futures.gel b/starters/features/gel/dbschema/futures.gel new file mode 100644 index 00000000000..20f2ff302b4 --- /dev/null +++ b/starters/features/gel/dbschema/futures.gel @@ -0,0 +1,4 @@ +# Use a simpler algorithm for resolving the scope of object names. +# This behavior will become the default in Gel 8.0. +# See: https://docs.geldata.com/reference/edgeql/path_resolution#new-path-scoping +using future simple_scoping; diff --git a/starters/features/gel/dbschema/migrations/00001-m1nmosd.edgeql b/starters/features/gel/dbschema/migrations/00001-m1nmosd.edgeql new file mode 100644 index 00000000000..4da7c1fb98e --- /dev/null +++ b/starters/features/gel/dbschema/migrations/00001-m1nmosd.edgeql @@ -0,0 +1,35 @@ +CREATE MIGRATION m1nmosduidfn2cl6attui644sivfoenkklq3y6m2b6vacma2pwoeva + ONTO initial +{ + CREATE FUTURE simple_scoping; + CREATE TYPE default::Email { + CREATE REQUIRED PROPERTY address: std::str { + CREATE CONSTRAINT std::exclusive; + }; + CREATE PROPERTY errmessage := ('an email with that address already exists!'); + CREATE PROPERTY provider: std::str; + }; + CREATE ABSTRACT TYPE default::Timestamped { + CREATE PROPERTY last_updated: std::datetime { + CREATE REWRITE + INSERT + USING (std::datetime_of_statement()); + CREATE REWRITE + UPDATE + USING (std::datetime_of_statement()); + }; + }; + CREATE TYPE default::User EXTENDING default::Timestamped { + CREATE MULTI LINK emails: default::Email; + CREATE REQUIRED PROPERTY name: std::str { + CREATE CONSTRAINT std::exclusive; + }; + CREATE INDEX ON (.name); + CREATE PROPERTY description: std::str; + CREATE PROPERTY errmessage := ('A user with that name already exists!'); + CREATE PROPERTY has_profile: std::bool; + }; + ALTER TYPE default::Email { + CREATE REQUIRED LINK user: default::User; + }; +}; diff --git a/starters/features/gel/gel/schema/default.gel b/starters/features/gel/gel/schema/default.gel deleted file mode 100644 index 17dca7eeeda..00000000000 --- a/starters/features/gel/gel/schema/default.gel +++ /dev/null @@ -1,29 +0,0 @@ -// This is where the database schema goes -// Read more here: https://docs.geldata.com/reference/datamodel - - abstract type Timestamped { - last_updated: datetime { - rewrite insert, update using (datetime_of_statement()); - }; - } - -type User extends Timestamped { - errmessage := 'A user with that name already exists!' - required name: str { - constraint exclusive; - }; - description: str; - has_profile: bool; - multi emails: .