From adf90d3c3406c79c9b07060c764bf41289bf2a38 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Thu, 14 Sep 2023 20:17:48 -0700 Subject: [PATCH] Cloudflare adapter (#1155) --- .changeset/empty-eels-destroy-more.md | 5 + .changeset/empty-eels-destroy.md | 7 + .husky/pre-commit | 2 +- e2e/react/houdini.config.js | 4 +- e2e/react/package.json | 17 +- e2e/react/schema.graphql | 23 + e2e/react/src/+client.js | 2 +- e2e/react/src/routes/+layout.gql | 3 - e2e/react/src/routes/+layout.tsx | 22 +- e2e/react/src/routes/+page.gql | 5 + e2e/react/src/routes/+page.tsx | 4 +- e2e/react/src/routes/links/+page.gql | 5 + e2e/react/src/routes/links/+page.tsx | 5 + e2e/react/src/routes/users/[id]/+page.gql | 6 - e2e/react/src/routes/users/[id]/+page.tsx | 23 - e2e/react/vite.config.ts | 3 +- package.json | 9 +- .../houdini-adapter-cloudflare/package.json | 64 + .../houdini-adapter-cloudflare/src/index.ts | 18 + .../houdini-adapter-cloudflare/src/worker.tsx | 84 ++ packages/houdini-react/package.json | 11 +- .../src/plugin/codegen/entries.test.ts | 78 +- .../src/plugin/codegen/entries.ts | 47 +- .../houdini-react/src/plugin/codegen/index.ts | 5 +- .../src/plugin/codegen/manifest.ts | 353 +----- .../src/plugin/codegen/render.test.ts | 38 +- .../src/plugin/codegen/render.ts | 30 +- .../src/plugin/codegen/router.test.ts | 75 +- .../src/plugin/codegen/router.ts | 12 +- .../src/plugin/codegen/typeRoot.test.ts | 3 +- .../src/plugin/codegen/typeRoot.ts | 3 +- packages/houdini-react/src/plugin/index.ts | 13 +- packages/houdini-react/src/plugin/vite.tsx | 145 ++- packages/houdini-react/src/runtime/index.tsx | 17 +- .../src/runtime/routing/components/Router.tsx | 60 +- .../src/runtime/routing/lib/cache.ts | 10 +- .../src/{ => runtime}/server/compat.ts | 0 .../src/{ => runtime}/server/index.ts | 2 +- .../src/{ => runtime}/server/session.ts | 0 packages/houdini/package.json | 1 + packages/houdini/src/lib/config.ts | 6 +- packages/houdini/src/lib/index.ts | 1 + .../src/lib/router}/conventions.ts | 13 +- packages/houdini/src/lib/router/index.ts | 8 + .../src/lib/router}/manifest.test.ts | 100 +- packages/houdini/src/lib/router/manifest.ts | 362 ++++++ packages/houdini/src/lib/router/types.ts | 10 + packages/houdini/src/lib/types.ts | 31 +- packages/houdini/src/vite/houdini.ts | 106 +- pnpm-lock.yaml | 1103 +++++++++++++++-- .../routes/api/client-plugins/Authoring.svx | 2 +- tsconfig.json | 2 +- 52 files changed, 2204 insertions(+), 754 deletions(-) create mode 100644 .changeset/empty-eels-destroy-more.md create mode 100644 .changeset/empty-eels-destroy.md create mode 100644 e2e/react/schema.graphql delete mode 100644 e2e/react/src/routes/+layout.gql create mode 100644 e2e/react/src/routes/+page.gql create mode 100644 e2e/react/src/routes/links/+page.gql create mode 100644 e2e/react/src/routes/links/+page.tsx delete mode 100644 e2e/react/src/routes/users/[id]/+page.gql delete mode 100644 e2e/react/src/routes/users/[id]/+page.tsx create mode 100644 packages/houdini-adapter-cloudflare/package.json create mode 100644 packages/houdini-adapter-cloudflare/src/index.ts create mode 100644 packages/houdini-adapter-cloudflare/src/worker.tsx rename packages/houdini-react/src/{ => runtime}/server/compat.ts (100%) rename packages/houdini-react/src/{ => runtime}/server/index.ts (96%) rename packages/houdini-react/src/{ => runtime}/server/session.ts (100%) rename packages/{houdini-react/src/plugin => houdini/src/lib/router}/conventions.ts (91%) create mode 100644 packages/houdini/src/lib/router/index.ts rename packages/{houdini-react/src/plugin/codegen => houdini/src/lib/router}/manifest.test.ts (88%) create mode 100644 packages/houdini/src/lib/router/manifest.ts create mode 100644 packages/houdini/src/lib/router/types.ts diff --git a/.changeset/empty-eels-destroy-more.md b/.changeset/empty-eels-destroy-more.md new file mode 100644 index 0000000000..a36fe23b1d --- /dev/null +++ b/.changeset/empty-eels-destroy-more.md @@ -0,0 +1,5 @@ +--- +'houdini': patch +--- + +Add adapter infrastructure when building for production diff --git a/.changeset/empty-eels-destroy.md b/.changeset/empty-eels-destroy.md new file mode 100644 index 0000000000..80829dead7 --- /dev/null +++ b/.changeset/empty-eels-destroy.md @@ -0,0 +1,7 @@ +--- +'houdini-adapter-cloudflare': patch +'houdini-react': patch +'houdini': patch +--- + +Add cloudflare adapter diff --git a/.husky/pre-commit b/.husky/pre-commit index 0cf7e455b4..d22d41f52c 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npx pretty-quick@latest --staged +npx lint-staged@latest diff --git a/e2e/react/houdini.config.js b/e2e/react/houdini.config.js index 0bfb150b14..d543794ae9 100644 --- a/e2e/react/houdini.config.js +++ b/e2e/react/houdini.config.js @@ -2,7 +2,9 @@ /// /** @type {import('houdini').ConfigFile} */ const config = { - schemaPath: '../_api/*.graphql', + watchSchema: { + url: 'https://houdinigraphql.com/graphql', + }, defaultPartial: true, scalars: { DateTime: { diff --git a/e2e/react/package.json b/e2e/react/package.json index 9c8a019e3f..cddb55a084 100644 --- a/e2e/react/package.json +++ b/e2e/react/package.json @@ -9,17 +9,20 @@ "build:web": "pnpm build: && pnpm web", "build:test": "pnpm build: && pnpm test", "build:build": "pnpm build: && pnpm build", - "web": "vite ", - "api": "cross-env TZ=utc e2e-api", - "dev": "concurrently \"pnpm run web\" \"pnpm run api\" -n \"web,api\" -c \"green,magenta\"", + "dev": "vite", "build": "tsc && vite build", "preview": "vite preview" }, "dependencies": { + "@cloudflare/kv-asset-handler": "^0.3.0", + "@cloudflare/workers-types": "^4.20230904.0", + "cookie": "^0.5.0", "houdini": "workspace:^", + "houdini-adapter-cloudflare": "workspace:^", "houdini-react": "workspace:^", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "itty-router": "^4.0.23", + "react": "^18.3.0-canary-d6dcad6a8-20230914", + "react-dom": "^18.3.0-canary-d6dcad6a8-20230914", "react-streaming": "^0.3.10" }, "devDependencies": { @@ -29,7 +32,9 @@ "concurrently": "7.1.0", "cross-env": "^7.0.3", "e2e-api": "workspace:^", + "hono": "^3.6.0", "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.1.0", + "wrangler": "^3.7.0" } } diff --git a/e2e/react/schema.graphql b/e2e/react/schema.graphql new file mode 100644 index 0000000000..bca9a8e88a --- /dev/null +++ b/e2e/react/schema.graphql @@ -0,0 +1,23 @@ +type Link { + name: String + url: String +} + +type Mutation { + hello(name: String!): String! +} + +type Query { + giveMeAnError: String + links(delai: Int): [Link!]! + sponsors: [Sponsor!]! + welcome: String! +} + +type Sponsor { + avatarUrl: String! + login: String! + name: String! + tiersTitle: String! + websiteUrl: String +} diff --git a/e2e/react/src/+client.js b/e2e/react/src/+client.js index d144a7e115..5a788fbda7 100644 --- a/e2e/react/src/+client.js +++ b/e2e/react/src/+client.js @@ -2,5 +2,5 @@ import { HoudiniClient } from '$houdini' // Export the Houdini client export default new HoudiniClient({ - url: 'http://localhost:4000/graphql', + url: 'https://houdinigraphql.com/graphql', }) diff --git a/e2e/react/src/routes/+layout.gql b/e2e/react/src/routes/+layout.gql deleted file mode 100644 index c9f7e21506..0000000000 --- a/e2e/react/src/routes/+layout.gql +++ /dev/null @@ -1,3 +0,0 @@ -query HelloRouter { - message: hello -} diff --git a/e2e/react/src/routes/+layout.tsx b/e2e/react/src/routes/+layout.tsx index ff6eaf199e..cc66a01155 100644 --- a/e2e/react/src/routes/+layout.tsx +++ b/e2e/react/src/routes/+layout.tsx @@ -1,23 +1,13 @@ import type { LayoutProps } from './$types' -export default function ({ HelloRouter, children }: LayoutProps) { +export default function ({ children }: LayoutProps) { return (
- message: {HelloRouter.message} - + Layout! +
+ Sponsors + Links +
{children}
) diff --git a/e2e/react/src/routes/+page.gql b/e2e/react/src/routes/+page.gql new file mode 100644 index 0000000000..957a410d70 --- /dev/null +++ b/e2e/react/src/routes/+page.gql @@ -0,0 +1,5 @@ +query SponsorList { + sponsors { + name + } +} diff --git a/e2e/react/src/routes/+page.tsx b/e2e/react/src/routes/+page.tsx index 9834bf2301..1ea24975be 100644 --- a/e2e/react/src/routes/+page.tsx +++ b/e2e/react/src/routes/+page.tsx @@ -1,5 +1,5 @@ import type { PageProps } from './$types' -export default function ({ HelloRouter }: PageProps) { - return
{HelloRouter.message}!
+export default function ({ SponsorList }: PageProps) { + return
{JSON.stringify(SponsorList)}
} diff --git a/e2e/react/src/routes/links/+page.gql b/e2e/react/src/routes/links/+page.gql new file mode 100644 index 0000000000..bcc97328db --- /dev/null +++ b/e2e/react/src/routes/links/+page.gql @@ -0,0 +1,5 @@ +query LinkList { + links { + url + } +} diff --git a/e2e/react/src/routes/links/+page.tsx b/e2e/react/src/routes/links/+page.tsx new file mode 100644 index 0000000000..27e92d7152 --- /dev/null +++ b/e2e/react/src/routes/links/+page.tsx @@ -0,0 +1,5 @@ +import type { PageProps } from './$types' + +export default function ({ LinkList }: PageProps) { + return
{JSON.stringify(LinkList)}
+} diff --git a/e2e/react/src/routes/users/[id]/+page.gql b/e2e/react/src/routes/users/[id]/+page.gql deleted file mode 100644 index 5d567d5583..0000000000 --- a/e2e/react/src/routes/users/[id]/+page.gql +++ /dev/null @@ -1,6 +0,0 @@ -query UserInfo($id: ID!) { - user(id: $id, snapshot: "hello", delay: 250) @loading { - id - name - } -} diff --git a/e2e/react/src/routes/users/[id]/+page.tsx b/e2e/react/src/routes/users/[id]/+page.tsx deleted file mode 100644 index 7298b3ecfc..0000000000 --- a/e2e/react/src/routes/users/[id]/+page.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { isPending } from '$houdini' -import React from 'react' - -import type { PageProps } from './$types' - -export default function ({ UserInfo }: PageProps) { - const { user } = UserInfo - - // if we are loading the user render the loading state - if (isPending(user)) { - return 'loading user...' - } - - const [count, setCount] = React.useState(0) - - // render the user information - return ( -
-

{user.name}

- -
- ) -} diff --git a/e2e/react/vite.config.ts b/e2e/react/vite.config.ts index ea18f3b489..1102503b2e 100644 --- a/e2e/react/vite.config.ts +++ b/e2e/react/vite.config.ts @@ -1,8 +1,9 @@ import react from '@vitejs/plugin-react' +import adapter from 'houdini-adapter-cloudflare' import houdini from 'houdini/vite' import { defineConfig } from 'vite' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [houdini(), react({ fastRefresh: false })], + plugins: [houdini({ adapter }), react({ fastRefresh: false })], }) diff --git a/package.json b/package.json index 4a0790c37d..72b21fc720 100755 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@vitest/ui": "^0.28.3", "eslint-plugin-unused-imports": "^2.0.0", "graphql": "^15.8.0", + "lint-staged": "^12.3.4", "prettier": "^2.8.3", "turbo": "^1.8.8", "typescript": "^4.9", @@ -49,5 +50,11 @@ "memfs": "^3.4.7", "recast": "^0.23.1" }, - "packageManager": "pnpm@8.6.7" + "packageManager": "pnpm@8.6.7", + "lint-staged": { + "*.ts": "prettier -w", + "*.tsx": "prettier -w", + "*.js": "prettier -w", + "*.json": "prettier -w" + } } diff --git a/packages/houdini-adapter-cloudflare/package.json b/packages/houdini-adapter-cloudflare/package.json new file mode 100644 index 0000000000..ff02174c8d --- /dev/null +++ b/packages/houdini-adapter-cloudflare/package.json @@ -0,0 +1,64 @@ +{ + "name": "houdini-adapter-cloudflare", + "version": "1.2.9", + "description": "The adapter for deploying your Houdini application to Cloudflare Pages", + "keywords": [ + "houdini", + "adpter", + "cloudflare", + "workers" + ], + "homepage": "https://github.com/HoudiniGraphql/houdini", + "funding": "https://github.com/sponsors/HoudiniGraphql", + "repository": { + "type": "git", + "url": "https://github.com/HoudiniGraphql/houdini.git" + }, + "license": "MIT", + "type": "module", + "devDependencies": { + "@cloudflare/workers-types": "^4.20230904.0", + "@types/cookie": "^0.5.2", + "scripts": "workspace:^", + "tsup": "^7.2.0", + "vitest": "^0.28.3" + }, + "scripts": { + "build": "tsup src/index.ts src/worker.tsx --format esm,cjs --external ../\\$houdini --external __STATIC_CONTENT_MANIFEST --minify --dts --clean --out-dir build", + "build:": "cd ../../ && ((run build && cd -) || (cd - && exit 1))", + "build:build": "pnpm build: && pnpm build" + }, + "dependencies": { + "@cloudflare/kv-asset-handler": "^0.3.0", + "@types/react": "^18.2.21", + "@types/react-dom": "^18.0.10", + "cookie": "^0.5.0", + "houdini": "workspace:^", + "itty-router": "^4.0.23", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-streaming": "^0.3.14" + }, + "files": [ + "build" + ], + "exports": { + "./package.json": "./package.json", + ".": { + "import": "./build/index.js", + "require": "./build/index.cjs" + }, + "./app": { + "import": "./build/app.js", + "require": "./build/app.cjs" + } + }, + "types": "./build/index.d.ts", + "typesVersions": { + "*": { + "app": [ + "build/app.d.ts" + ] + } + } +} diff --git a/packages/houdini-adapter-cloudflare/src/index.ts b/packages/houdini-adapter-cloudflare/src/index.ts new file mode 100644 index 0000000000..8c78ca25ef --- /dev/null +++ b/packages/houdini-adapter-cloudflare/src/index.ts @@ -0,0 +1,18 @@ +import { type Adapter, fs, path } from 'houdini' +import { fileURLToPath } from 'node:url' + +const adapter: Adapter = async ({ config, conventions, publicBase, outDir, sourceDir }) => { + // the first thing we have to do is copy the source directory over + await fs.recursiveCopy(sourceDir, outDir) + + // read the contents of the worker file + const workerContents = await fs.readFile(sourcePath('./worker.js')) + + await fs.writeFile(path.join(outDir, '_worker.js'), workerContents!) +} + +export default adapter + +function sourcePath(path: string) { + return fileURLToPath(new URL(path, import.meta.url).href) +} diff --git a/packages/houdini-adapter-cloudflare/src/worker.tsx b/packages/houdini-adapter-cloudflare/src/worker.tsx new file mode 100644 index 0000000000..04ed563247 --- /dev/null +++ b/packages/houdini-adapter-cloudflare/src/worker.tsx @@ -0,0 +1,84 @@ +import { ExportedHandler } from '@cloudflare/workers-types' +import { parse } from 'cookie' +import type { QueryArtifact } from 'houdini' +import { renderToStream } from 'react-streaming/server' + +// The following imports local assets from the generated runtime +// This is not the desired API. just the easiest way to get this working +// and validate the rendering strategy +// +// +// @ts-expect-error +import { router_cache } from '../$houdini' +// @ts-expect-error +import manifest from '../$houdini/plugins/houdini-react/runtime/manifest' +// @ts-expect-error +import { find_match } from '../$houdini/plugins/houdini-react/runtime/routing/lib/match' +// @ts-expect-error +import App from '../$houdini/plugins/houdini-react/units/render/App' +// @ts-expect-error +import { Cache } from '../$houdini/runtime/cache/cache.js' + +const handlers: ExportedHandler = { + async fetch(req, env: any, ctx) { + // if we aren't loading an asset, push the request through our router + const url = new URL(req.url).pathname + + // we are handling an asset + if (url.startsWith('/assets/') || url === '/favicon.ico') { + return await env.ASSETS.fetch(req) + } + + // otherwise we just need to render the application + return await render_app(req) + }, +} + +async function render_app(request: Parameters['fetch']>[0]) { + // pull out the desired url + const url = new URL(request.url).pathname + + // load the session cookie + const cookie = parse(request.headers.get('Cookie') || '')['houdini-session'] + const session = cookie ? JSON.parse(cookie) : null + + // find the matching url + const [match] = find_match(manifest, url, true) + if (!match) { + throw new Error('no match') + } + + // instanitate a cache we can use + const cache = new Cache({ disabled: false }) + + const { readable, injectToStream } = await renderToStream( + , + { + userAgent: 'Vite', + } + ) + + // add the initial scripts to the page + injectToStream(` + + + + + `) + + // and deliver our Response while that’s running. + return new Response(readable) +} + +export default handlers diff --git a/packages/houdini-react/package.json b/packages/houdini-react/package.json index e6fdd1594e..e57d4e8917 100644 --- a/packages/houdini-react/package.json +++ b/packages/houdini-react/package.json @@ -55,19 +55,10 @@ "types": "./build/plugin/index.d.ts", "import": "./build/plugin-esm/index.js", "require": "./build/plugin-cjs/index.js" - }, - "./server": { - "types": "./build/server/index.d.ts", - "import": "./build/server-esm/index.js", - "require": "./build/server-cjs/index.js" } }, "typesVersions": { - "*": { - "server": [ - "build/server/index.d.ts" - ] - } + "*": {} }, "main": "./build/plugin-cjs/index.js", "types": "./build/plugin/index.d.ts" diff --git a/packages/houdini-react/src/plugin/codegen/entries.test.ts b/packages/houdini-react/src/plugin/codegen/entries.test.ts index 43d6fbde73..fa8330b2e9 100644 --- a/packages/houdini-react/src/plugin/codegen/entries.test.ts +++ b/packages/houdini-react/src/plugin/codegen/entries.test.ts @@ -1,15 +1,8 @@ -import { fs, parseJS } from 'houdini' +import { fs, parseJS, routerConventions, load_manifest } from 'houdini' import { test, expect } from 'vitest' import { test_config } from '../config' -import { - page_entry_path, - page_unit_path, - layout_unit_path, - fallback_unit_path, -} from '../conventions' import { generate_entries } from './entries' -import { load_manifest } from './manifest' test('composes layouts and pages', async function () { const config = await test_config() @@ -37,15 +30,17 @@ test('composes layouts and pages', async function () { await generate_entries({ config, manifest }) const page_entry = await parseJS( - (await fs.readFile(page_entry_path(config, Object.keys(manifest.pages)[0]))) ?? '', + (await fs.readFile( + routerConventions.page_entry_path(config, Object.keys(manifest.pages)[0]) + )) ?? '', { plugins: ['jsx'] } ) expect(page_entry).toMatchInlineSnapshot(` - import Layout__0 from "../layouts/_0.jsx"; - import Layout__0subRoute from "../layouts/_0subRoute.jsx"; - import Page__0subRoute_0nested from "../pages/_0subRoute_0nested.jsx"; - import PageFallback__0subRoute_0nested from "../fallbacks/page/_0subRoute_0nested.jsx"; - import LayoutFallback__0subRoute_0nested from "../../fallbacks/layout"; + import Layout__ from "../layouts/_.jsx"; + import Layout__subRoute from "../layouts/_subRoute.jsx"; + import Page__subRoute_nested from "../pages/_subRoute_nested.jsx"; + import PageFallback__subRoute_nested from "../fallbacks/page/_subRoute_nested.jsx"; + import LayoutFallback__subRoute_nested from "../../fallbacks/layout"; export default ( { @@ -53,28 +48,30 @@ test('composes layouts and pages', async function () { } ) => { return ( - ( - - - - - - - - ) + ( + + + + + + + + ) ); }; `) const page_unit = await parseJS( - (await fs.readFile(page_unit_path(config, Object.keys(manifest.pages)[0]))) ?? '', + (await fs.readFile( + routerConventions.page_unit_path(config, Object.keys(manifest.pages)[0]) + )) ?? '', { plugins: ['jsx'], } ) expect(page_unit).toMatchInlineSnapshot(` import { useQueryResult } from "$houdini/plugins/houdini-react/runtime/routing/components/Router"; - import Component__0subRoute_0nested from "../../../../../src/routes/subRoute/nested/+page"; + import Component__subRoute_nested from "../../../../../src/routes/subRoute/nested/+page"; export default ( { @@ -84,22 +81,24 @@ test('composes layouts and pages', async function () { const [FinalQuery$data, FinalQuery$handle] = useQueryResult("FinalQuery"); return ( - ( + ( {children} - ) + ) ); }; `) const root_layout_unit = await parseJS( - (await fs.readFile(layout_unit_path(config, Object.keys(manifest.layouts)[0]))) ?? '', + (await fs.readFile( + routerConventions.layout_unit_path(config, Object.keys(manifest.layouts)[0]) + )) ?? '', { plugins: ['jsx'], } ) expect(root_layout_unit).toMatchInlineSnapshot(` import { useQueryResult } from "$houdini/plugins/houdini-react/runtime/routing/components/Router"; - import Component__0 from "../../../../../src/routes/+layout"; + import Component__ from "../../../../../src/routes/+layout"; export default ( { @@ -107,22 +106,24 @@ test('composes layouts and pages', async function () { } ) => { return ( - ( + ( {children} - ) + ) ); }; `) const deep_layout_unit = await parseJS( - (await fs.readFile(layout_unit_path(config, Object.keys(manifest.layouts)[1]))) ?? '', + (await fs.readFile( + routerConventions.layout_unit_path(config, Object.keys(manifest.layouts)[1]) + )) ?? '', { plugins: ['jsx'], } ) expect(deep_layout_unit).toMatchInlineSnapshot(` import { useQueryResult } from "$houdini/plugins/houdini-react/runtime/routing/components/Router"; - import Component__0subRoute from "../../../../../src/routes/subRoute/+layout"; + import Component__subRoute from "../../../../../src/routes/subRoute/+layout"; export default ( { @@ -133,21 +134,22 @@ test('composes layouts and pages', async function () { const [SubQuery$data, SubQuery$handle] = useQueryResult("SubQuery"); return ( - ( {children} - ) + ) ); }; `) // make sure we generated the fallback units const page_fallback = await parseJS( - (await fs.readFile(fallback_unit_path(config, 'page', Object.keys(manifest.pages)[0]))) ?? - '', + (await fs.readFile( + routerConventions.fallback_unit_path(config, 'page', Object.keys(manifest.pages)[0]) + )) ?? '', { plugins: ['jsx'], } @@ -202,7 +204,7 @@ test('composes layouts and pages', async function () { `) const layout_fallback = await parseJS( (await fs.readFile( - fallback_unit_path(config, 'layout', Object.keys(manifest.layouts)[0]) + routerConventions.fallback_unit_path(config, 'layout', Object.keys(manifest.layouts)[0]) )) ?? '', { plugins: ['jsx'], diff --git a/packages/houdini-react/src/plugin/codegen/entries.ts b/packages/houdini-react/src/plugin/codegen/entries.ts index bad9aae6f5..cbd2f4718d 100644 --- a/packages/houdini-react/src/plugin/codegen/entries.ts +++ b/packages/houdini-react/src/plugin/codegen/entries.ts @@ -1,13 +1,14 @@ -import { type Config, fs, parseJS, printJS, path } from 'houdini' - import { - page_entry_path, - page_unit_path, - layout_unit_path, - is_layout, - fallback_unit_path, -} from '../conventions' -import type { ProjectManifest, PageManifest, QueryManifest } from './manifest' + type Config, + fs, + parseJS, + printJS, + path, + routerConventions, + type ProjectManifest, + type PageManifest, + type QueryManifest, +} from 'houdini' export async function generate_entries({ config, @@ -37,12 +38,12 @@ type PageBundleInput = { /** Generates the component that passes query data to the actual component on the filesystem */ async function generate_routing_units(args: PageBundleInput) { // look up the page manifest - const layout = is_layout(args.page.path) + const layout = routerConventions.is_layout(args.page.path) const page = layout ? args.project.layouts[args.id] : args.project.pages[args.id] const unit_path = layout - ? layout_unit_path(args.config, args.id) - : page_unit_path(args.config, args.id) + ? routerConventions.layout_unit_path(args.config, args.id) + : routerConventions.page_unit_path(args.config, args.id) // the first thing we need to do is make sure that the page has a bundle directory await fs.mkdirp(path.dirname(unit_path)) @@ -95,7 +96,7 @@ async function generate_routing_units(args: PageBundleInput) { } async function generate_page_entries(args: PageBundleInput) { - const component_path = page_entry_path(args.config, args.id) + const component_path = routerConventions.page_entry_path(args.config, args.id) // the first thing we need to do is make sure that the page has a bundle directory await fs.mkdirp(path.dirname(component_path)) @@ -108,7 +109,7 @@ async function generate_page_entries(args: PageBundleInput) { for (const layout_id of args.page.layouts) { // generate the relative filepath from the component file // to the layout - const layout_path = layout_unit_path(args.config, layout_id) + const layout_path = routerConventions.layout_unit_path(args.config, layout_id) const relative_path = path.relative(path.dirname(component_path), layout_path) // generate the local name for the layout component @@ -121,7 +122,7 @@ async function generate_page_entries(args: PageBundleInput) { // generate the relative filepath from the component file // to the page - const page_path = page_unit_path(args.config, args.page.id) + const page_path = routerConventions.page_unit_path(args.config, args.page.id) // generate the local import for the page component const relative_path = path.relative(path.dirname(component_path), page_path) @@ -133,7 +134,11 @@ async function generate_page_entries(args: PageBundleInput) { let content = `<${Component} />` // if the layout has a loading state then wrap it in a fallback if (args.project.page_queries[args.page.id]?.loading) { - const fallback_path = fallback_unit_path(args.config, 'page', args.page.id) + const fallback_path = routerConventions.fallback_unit_path( + args.config, + 'page', + args.page.id + ) source.push( `import ${PageFallback} from "${path.relative( path.dirname(page_path), @@ -160,7 +165,11 @@ async function generate_page_entries(args: PageBundleInput) { // if the layout has a loading state then wrap it in a fallback if (args.project.layout_queries[layout]?.loading) { const LayoutFallback = 'LayoutFallback_' + args.page.id - const fallback_path = fallback_unit_path(args.config, 'layout', args.page.id) + const fallback_path = routerConventions.fallback_unit_path( + args.config, + 'layout', + args.page.id + ) source.push( `import ${LayoutFallback} from "${path.relative( page_path, @@ -210,7 +219,7 @@ async function generate_fallbacks({ for (const [id, page] of Object.entries(project.layouts).concat( Object.entries(project.pages) )) { - const layout = is_layout(page.path) + const layout = routerConventions.is_layout(page.path) const which = layout ? 'layout' : 'page' // in order to generate the fallback, we need to know which queries are @@ -229,7 +238,7 @@ async function generate_fallbacks({ { required_queries: [] as string[], loading_queries: [] as string[] } ) - const fallback_path = fallback_unit_path(config, which, id) + const fallback_path = routerConventions.fallback_unit_path(config, which, id) const page_path = path.join( config.pluginDirectory('houdini-router'), '..', diff --git a/packages/houdini-react/src/plugin/codegen/index.ts b/packages/houdini-react/src/plugin/codegen/index.ts index 030570e9c2..0df81e15cc 100644 --- a/packages/houdini-react/src/plugin/codegen/index.ts +++ b/packages/houdini-react/src/plugin/codegen/index.ts @@ -1,7 +1,7 @@ -import type { GenerateHookInput } from 'houdini' +import type { GenerateHookInput, ProjectManifest } from 'houdini' import { generate_entries } from './entries' -import type { ProjectManifest } from './manifest' +import { write_manifest } from './manifest' import { generate_renders } from './render' import { generate_type_root } from './typeRoot' @@ -23,5 +23,6 @@ export default async function routerCodegen({ generate_entries({ config, manifest }), generate_renders(config), generate_type_root({ config, manifest }), + write_manifest({ config, manifest }), ]) } diff --git a/packages/houdini-react/src/plugin/codegen/manifest.ts b/packages/houdini-react/src/plugin/codegen/manifest.ts index 82368031a0..03d4dc9fab 100644 --- a/packages/houdini-react/src/plugin/codegen/manifest.ts +++ b/packages/houdini-react/src/plugin/codegen/manifest.ts @@ -1,342 +1,17 @@ -import * as t from '@babel/types' -import * as graphql from 'graphql' -import { path, fs, parseJS } from 'houdini' -import type { Config } from 'houdini' - -import { - read_layoutQuery, - read_layoutView, - read_pageView, - read_pageQuery, - normalize_path, -} from '../conventions' - -/** - * Walk down the routes directory and build a normalized description of the project's - * filesystem. - */ -export async function load_manifest(args: { config: Config }) { - // we'll start at the route directory and start building it up - return await walk_routes({ - config: args.config, - url: '/', - filepath: args.config.routesDir, - project: { - pages: {}, - layouts: {}, - page_queries: {}, - layout_queries: {}, - }, - queries: [], - layouts: [], - }) -} - -async function walk_routes(args: { - filepath: string - config: Config - url: string - project: ProjectManifest - queries: string[] - layouts: string[] -}): Promise { - const directory_contents = await fs.readdir(args.filepath, { - withFileTypes: true, - }) - - // before we can go down, we need to look at the files in the directory - // to see what queries were added to the context. this means we have to - // first collect the layout query and view, and then check for a page query - // to validate the page view - let newLayouts = args.layouts - let newLayoutQueries = args.queries - - // track the manifests we create along the way - let layout: PageManifest | null = null - let layoutQuery: QueryManifest | null = null - let pageQuery: QueryManifest | null = null - - // read file contents - const [ - [layoutQueryPath, layoutQueryContents], - [layoutViewPath, layoutViewContents], - [pageQueryPath, pageQueryContents], - [pageViewPath, pageViewContents], - ] = await Promise.all([ - read_layoutQuery(args.filepath), - read_layoutView(args.filepath), - read_pageQuery(args.filepath), - read_pageView(args.filepath), - ]) - - // TODO: allow plugins to transform this content before we analyze it for information - - // we have a layout query, so we need to add it to the context - if (layoutQueryContents) { - layoutQuery = await add_query({ - path: layoutQueryPath!, - config: args.config, - url: args.url, - project: args.project, - type: 'layout', - contents: layoutQueryContents, - }) - newLayoutQueries = [...args.queries, layoutQuery.name] - } - - // we have a layout query, so we need to add it to the context - if (layoutViewContents) { - layout = await add_view({ - url: args.url, - path: layoutViewPath!, - project: args.project, - type: 'layout', - contents: layoutViewContents, - layouts: args.layouts, - queries: newLayoutQueries, - config: args.config, - }) - newLayouts = [...args.layouts, normalize_path(layout.url)] - } - - // if we have a page query, add it - if (pageQueryContents) { - pageQuery = await add_query({ - path: pageQueryPath!, - config: args.config, - url: args.url, - project: args.project, - type: 'page', - contents: pageQueryContents, - }) - } - - // if we have a page query, add it - if (pageViewContents) { - await add_view({ - path: pageViewPath!, - url: args.url.substring(0, args.url.length - 1) || '/', - project: args.project, - type: 'page', - contents: pageViewContents, - layouts: newLayouts, - queries: pageQuery ? [...newLayoutQueries, pageQuery.name] : newLayoutQueries, - config: args.config, - }) - } - - // now we can walk down the directories - await Promise.all( - directory_contents.map((dir) => { - if (!dir.isDirectory()) { - return - } - - return walk_routes({ - ...args, - filepath: path.join(args.filepath, dir.name), - url: `${args.url}${dir.name}/`, - queries: newLayoutQueries, - layouts: newLayouts, - }) - }) - ) - - return args.project -} - -async function add_view(args: { - path: string - url: string - project: ProjectManifest - type: 'page' | 'layout' - contents: string - layouts: string[] - queries: string[] - config: Config -}) { - const target = args.type === 'page' ? args.project.pages : args.project.layouts - const queries = await extractQueries(args.contents) - // look for any queries that we are asking for that aren't available - const missing_queries = queries.filter((query) => !args.queries.includes(query)) - if (missing_queries.length > 0) { - throw { - message: 'Missing Queries', - description: JSON.stringify(missing_queries), - } - } - - const id = normalize_path(args.url) - - target[id] = { - id, - queries, - url: args.url, - layouts: args.layouts, - path: path.relative(args.config.projectRoot, args.path), - query_options: args.queries, - } - - return target[id] -} - -async function add_query(args: { - path: string +// a serialized version of the manifest is used during the build process to configure +import { type Config, type ProjectManifest, fs, routerConventions } from 'houdini' + +// vite to see every entry point +export async function write_manifest({ + config, + manifest, +}: { config: Config - url: string - project: ProjectManifest - type: 'page' | 'layout' - contents: string -}) { - // we need to parse the query to get the name - const parsed = graphql.parse(args.contents) - // look for the query definition - const query = parsed.definitions.find( - (def): def is graphql.OperationDefinitionNode => - def.kind === 'OperationDefinition' && def.operation === 'query' + manifest: ProjectManifest +}): Promise { + // all we need to do is stringify and write the manifest to the correct location + await fs.writeFile( + routerConventions.serialized_manifest_path(config), + JSON.stringify(manifest, null, 4) ) - if (!query?.name) { - throw new Error('No query found') - } - - let loading = false - await graphql.visit(parsed, { - Directive(node) { - if (node.name.value === args.config.loadingDirective) { - loading = true - } - }, - }) - - const target = args.type === 'page' ? args.project.page_queries : args.project.layout_queries - target[normalize_path(args.url)] = { - path: path.relative(args.config.routesDir, args.path), - name: query.name.value, - url: args.url, - loading, - } - - return target[normalize_path(args.url)] -} - -export async function extractQueries(source: string): Promise { - const ast = parseJS(source, { plugins: ['jsx'] }) - - let defaultExportNode: t.Node | null = null - let defaultExportIdentifier: string | null = null - - // walk through the function body and find the default export - for (const node of ast.body) { - if (t.isExportDefaultDeclaration(node)) { - if ( - t.isFunctionDeclaration(node.declaration) || - t.isArrowFunctionExpression(node.declaration) || - t.isFunctionExpression(node.declaration) - ) { - defaultExportNode = node.declaration - break - - // if the export is an identifier we'll have to go back through - // and find the declaration - } else if (t.isIdentifier(node.declaration)) { - defaultExportIdentifier = node.declaration.name - } - } - } - - // if the default export was an identifier then go back through and find the correct one - if (defaultExportIdentifier) { - for (const node of ast.body) { - if (t.isVariableDeclaration(node)) { - for (const declaration of node.declarations) { - if ( - t.isVariableDeclarator(declaration) && - t.isIdentifier(declaration.id) && - declaration.id.name === defaultExportIdentifier - ) { - if ( - t.isArrowFunctionExpression(declaration.init) || - t.isFunctionExpression(declaration.init) - ) { - defaultExportNode = declaration.init - break - } else if ( - t.isTSAsExpression(declaration.init) && - (t.isArrowFunctionExpression(declaration.init.expression) || - t.isFunctionExpression(declaration.init.expression)) - ) { - defaultExportNode = declaration.init.expression - break - } - } - } - } - } - } - if (!defaultExportNode) { - throw new Error('No default export found.') - } - - let props: string[] = [] - const componentFunction = defaultExportNode as - | t.FunctionDeclaration - | t.ArrowFunctionExpression - | t.FunctionExpression - | undefined - - if (componentFunction && componentFunction.params.length > 0) { - const firstParam = componentFunction.params[0] - - if (t.isObjectPattern(firstParam)) { - for (const property of firstParam.properties) { - if (t.isObjectProperty(property) && t.isIdentifier(property.key)) { - props.push(property.key.name) - } - } - } else { - throw new Error('Props should be specified as an object pattern.') - } - } else { - return [] - } - - return props.filter((p) => p !== 'children') -} - -// The manifest is a tree of routes that the router will use to render -// the correct component tree for a given url -export type ProjectManifest = { - /** All of the pages in the project */ - pages: Record - /** All of the layouts in the project */ - layouts: Record - /** All of the page queries in the project */ - page_queries: Record - /** All of the layout queries in the project */ - layout_queries: Record -} - -export type PageManifest = { - id: string - /** the name of every query that the page depends on */ - queries: string[] - /** the list of queries that this page could potentially ask for */ - query_options: string[] - /** the full url pattern of the page */ - url: string - /** the ids of layouts that wrap this page */ - layouts: string[] - /** The filepath of the unit */ - path: string -} - -export type QueryManifest = { - /** the name of the query */ - name: string - /** the url tied with the query */ - url: string - /** wether the query uses the loading directive (ie, wants a fallback) */ - loading: boolean - /** The filepath of the unit */ - path: string } diff --git a/packages/houdini-react/src/plugin/codegen/render.test.ts b/packages/houdini-react/src/plugin/codegen/render.test.ts index a63ed40c4a..908b65a677 100644 --- a/packages/houdini-react/src/plugin/codegen/render.test.ts +++ b/packages/houdini-react/src/plugin/codegen/render.test.ts @@ -1,8 +1,7 @@ -import { fs, parseJS } from 'houdini' +import { fs, parseJS, routerConventions } from 'houdini' import { test, expect } from 'vitest' import { test_config } from '../config' -import { render_server_path, render_client_path } from '../conventions' import { generate_renders } from './render' test('generates render functions', async function () { @@ -10,14 +9,20 @@ test('generates render functions', async function () { await generate_renders(config) - const render_client = await parseJS((await fs.readFile(render_client_path(config))) ?? '', { - plugins: ['jsx'], - }) + const render_client = await parseJS( + (await fs.readFile(routerConventions.render_client_path(config))) ?? '', + { + plugins: ['jsx'], + } + ) expect(render_client).toMatchInlineSnapshot('') - const render_server = await parseJS((await fs.readFile(render_server_path(config))) ?? '', { - plugins: ['jsx'], - }) + const render_server = await parseJS( + (await fs.readFile(routerConventions.render_server_path(config))) ?? '', + { + plugins: ['jsx'], + } + ) expect(render_server).toMatchInlineSnapshot(` import React from "react"; import { renderToStream } from "react-streaming/server"; @@ -31,16 +36,19 @@ test('generates render functions', async function () { loaded_queries, loaded_artifacts, session, + assetPrefix, ...config } ) { - return renderToStream(, config); + return renderToStream(React.createElement(App, { + initialURL: url, + cache, + ...router_cache(), + loaded_queries, + session, + loaded_artifacts, + assetPrefix + }), config); } `) }) diff --git a/packages/houdini-react/src/plugin/codegen/render.ts b/packages/houdini-react/src/plugin/codegen/render.ts index d1080dcb0f..c2a328734e 100644 --- a/packages/houdini-react/src/plugin/codegen/render.ts +++ b/packages/houdini-react/src/plugin/codegen/render.ts @@ -1,10 +1,8 @@ -import { type Config, fs, path } from 'houdini' - -import { render_client_path, render_server_path, render_app_path } from '../conventions' +import { type Config, fs, path, routerConventions } from 'houdini' export async function generate_renders(config: Config) { // make sure the necessary directories exist - await fs.mkdirp(path.dirname(render_client_path(config))) + await fs.mkdirp(path.dirname(routerConventions.render_client_path(config))) // everything is in fixed locations so just generate what we need where we need it const app_index = ` @@ -22,23 +20,23 @@ import { renderToStream } from 'react-streaming/server' import App from './App' import { router_cache } from '$houdini' -export function render_to_stream({url, cache, loaded_queries, loaded_artifacts, session, ...config}) { +export function render_to_stream({url, cache, loaded_queries, loaded_artifacts, session, assetPrefix, ...config}) { return renderToStream( - - , config + React.createElement(App, { + initialURL: url, + cache, + ...router_cache(), + loaded_queries, + session, + loaded_artifacts, + assetPrefix, + }), config ) } ` await Promise.all([ - fs.writeFile(render_server_path(config), render_server), - fs.writeFile(render_app_path(config), app_index), + fs.writeFile(routerConventions.render_server_path(config), render_server), + fs.writeFile(routerConventions.render_app_path(config), app_index), ]) } diff --git a/packages/houdini-react/src/plugin/codegen/router.test.ts b/packages/houdini-react/src/plugin/codegen/router.test.ts index 51ab039ea1..6053f1df4f 100644 --- a/packages/houdini-react/src/plugin/codegen/router.test.ts +++ b/packages/houdini-react/src/plugin/codegen/router.test.ts @@ -1,8 +1,7 @@ -import { fs } from 'houdini' +import { fs, load_manifest } from 'houdini' import { test, expect } from 'vitest' import { test_config } from '../config' -import { load_manifest } from './manifest' import { format_router_manifest } from './router' const importStatement = (where: string, as: string) => `import ${as} from '${where}'` @@ -44,8 +43,8 @@ test('happy path', async function () { .toMatchInlineSnapshot(` "export default { pages: { - \\"_0\\": { - id: \\"_0\\", + \\"_\\": { + id: \\"_\\", pattern: /^\\\\/$/, params: [], @@ -57,11 +56,11 @@ test('happy path', async function () { } }, - component: () => import(\\"../units/entries/_0\\") + component: () => import(\\"../units/entries/_\\") }, - \\"_0_2id_1\\": { - id: \\"_0_2id_1\\", + \\"__id_\\": { + id: \\"__id_\\", pattern: /^\\\\/([^/]+?)\\\\/?$/, params: [{\\"name\\":\\"id\\",\\"optional\\":false,\\"rest\\":false,\\"chained\\":false}], @@ -77,11 +76,11 @@ test('happy path', async function () { } }, - component: () => import(\\"../units/entries/_0_2id_1\\") + component: () => import(\\"../units/entries/__id_\\") }, - \\"_0another\\": { - id: \\"_0another\\", + \\"_another\\": { + id: \\"_another\\", pattern: /^\\\\/another\\\\/?$/, params: [], @@ -101,11 +100,11 @@ test('happy path', async function () { } }, - component: () => import(\\"../units/entries/_0another\\") + component: () => import(\\"../units/entries/_another\\") }, - \\"_0_2id_1_0nested\\": { - id: \\"_0_2id_1_0nested\\", + \\"__id__nested\\": { + id: \\"__id__nested\\", pattern: /^\\\\/([^/]+?)\\\\/nested\\\\/?$/, params: [{\\"name\\":\\"id\\",\\"optional\\":false,\\"rest\\":false,\\"chained\\":false}], @@ -121,23 +120,23 @@ test('happy path', async function () { } }, - component: () => import(\\"../units/entries/_0_2id_1_0nested\\") + component: () => import(\\"../units/entries/__id__nested\\") }, }, layouts: { - \\"_0\\": { - id: \\"_0\\", + \\"_\\": { + id: \\"_\\", queries: [], }, - \\"_0_2id_1\\": { - id: \\"_0_2id_1\\", + \\"__id_\\": { + id: \\"__id_\\", queries: [\\"RootQuery\\"], }, - \\"_0another\\": { - id: \\"_0another\\", + \\"_another\\": { + id: \\"_another\\", queries: [\\"RootQuery\\"], } @@ -181,8 +180,8 @@ test('loading state at root', async function () { .toMatchInlineSnapshot(` "export default { pages: { - \\"_0\\": { - id: \\"_0\\", + \\"_\\": { + id: \\"_\\", pattern: /^\\\\/$/, params: [], @@ -194,11 +193,11 @@ test('loading state at root', async function () { } }, - component: () => import(\\"../units/entries/_0\\") + component: () => import(\\"../units/entries/_\\") }, - \\"_0_2id_1\\": { - id: \\"_0_2id_1\\", + \\"__id_\\": { + id: \\"__id_\\", pattern: /^\\\\/([^/]+?)\\\\/?$/, params: [{\\"name\\":\\"id\\",\\"optional\\":false,\\"rest\\":false,\\"chained\\":false}], @@ -214,11 +213,11 @@ test('loading state at root', async function () { } }, - component: () => import(\\"../units/entries/_0_2id_1\\") + component: () => import(\\"../units/entries/__id_\\") }, - \\"_0another\\": { - id: \\"_0another\\", + \\"_another\\": { + id: \\"_another\\", pattern: /^\\\\/another\\\\/?$/, params: [], @@ -238,11 +237,11 @@ test('loading state at root', async function () { } }, - component: () => import(\\"../units/entries/_0another\\") + component: () => import(\\"../units/entries/_another\\") }, - \\"_0_2id_1_0nested\\": { - id: \\"_0_2id_1_0nested\\", + \\"__id__nested\\": { + id: \\"__id__nested\\", pattern: /^\\\\/([^/]+?)\\\\/nested\\\\/?$/, params: [{\\"name\\":\\"id\\",\\"optional\\":false,\\"rest\\":false,\\"chained\\":false}], @@ -258,23 +257,23 @@ test('loading state at root', async function () { } }, - component: () => import(\\"../units/entries/_0_2id_1_0nested\\") + component: () => import(\\"../units/entries/__id__nested\\") }, }, layouts: { - \\"_0\\": { - id: \\"_0\\", + \\"_\\": { + id: \\"_\\", queries: [], }, - \\"_0_2id_1\\": { - id: \\"_0_2id_1\\", + \\"__id_\\": { + id: \\"__id_\\", queries: [\\"RootQuery\\"], }, - \\"_0another\\": { - id: \\"_0another\\", + \\"_another\\": { + id: \\"_another\\", queries: [\\"RootQuery\\"], } diff --git a/packages/houdini-react/src/plugin/codegen/router.ts b/packages/houdini-react/src/plugin/codegen/router.ts index 1c5a05737c..c10a1eda6b 100644 --- a/packages/houdini-react/src/plugin/codegen/router.ts +++ b/packages/houdini-react/src/plugin/codegen/router.ts @@ -1,9 +1,13 @@ -import { type Config, path } from 'houdini' +import { + path, + routerConventions, + type Config, + type ProjectManifest, + type QueryManifest, +} from 'houdini' import { parse_page_pattern } from '../../runtime/routing/lib/match' -import { page_entry_path } from '../conventions' import { dedent } from '../dedent' -import type { ProjectManifest, QueryManifest } from './manifest' export function format_router_manifest({ config, @@ -32,7 +36,7 @@ ${Object.entries(manifest.pages) // parse the url pattern const pattern_parsed = parse_page_pattern(page.url) - let component_path = path.join(page_entry_path(config, page.id, '..')) + let component_path = path.join(routerConventions.page_entry_path(config, page.id, '..')) const path_parsed = path.parse(component_path) component_path = path.join(path_parsed.dir, path_parsed.name) diff --git a/packages/houdini-react/src/plugin/codegen/typeRoot.test.ts b/packages/houdini-react/src/plugin/codegen/typeRoot.test.ts index 5bea963633..83a3113470 100644 --- a/packages/houdini-react/src/plugin/codegen/typeRoot.test.ts +++ b/packages/houdini-react/src/plugin/codegen/typeRoot.test.ts @@ -1,8 +1,7 @@ -import { fs } from 'houdini' +import { fs, load_manifest } from 'houdini' import { test, expect } from 'vitest' import { test_config } from '../config' -import { load_manifest } from './manifest' import { generate_type_root } from './typeRoot' test('generates type files for pages', async function () { diff --git a/packages/houdini-react/src/plugin/codegen/typeRoot.ts b/packages/houdini-react/src/plugin/codegen/typeRoot.ts index 98ff1b230b..49f5166c45 100644 --- a/packages/houdini-react/src/plugin/codegen/typeRoot.ts +++ b/packages/houdini-react/src/plugin/codegen/typeRoot.ts @@ -1,7 +1,6 @@ -import { type Config, path, fs } from 'houdini' +import { path, fs, type Config, type PageManifest, type ProjectManifest } from 'houdini' import { dedent } from '../dedent' -import type { PageManifest, ProjectManifest } from './manifest' export async function generate_type_root({ config, diff --git a/packages/houdini-react/src/plugin/index.ts b/packages/houdini-react/src/plugin/index.ts index 7c587c933d..d0aeb5cd31 100644 --- a/packages/houdini-react/src/plugin/index.ts +++ b/packages/houdini-react/src/plugin/index.ts @@ -6,18 +6,19 @@ import { ArtifactKind, plugin, fragmentKey, + load_manifest, + type ProjectManifest, } from 'houdini' import path from 'node:path' import { loadEnv } from 'vite' import generate from './codegen' -import { load_manifest, type ProjectManifest } from './codegen/manifest' import { format_router_manifest } from './codegen/router' import { extractDocuments } from './extract' import { transformFile } from './transform' import vite_plugin from './vite' -let manifest: ProjectManifest +export let manifest: ProjectManifest export const hooks: Plugin = async () => ({ order: 'core', @@ -28,7 +29,9 @@ export const hooks: Plugin = async () => ({ // always make sure our definition of the manifest is up to date before // we generate anything async beforeGenerate({ config }) { - manifest = await load_manifest({ config }) + if (!manifest) { + manifest = await load_manifest({ config }) + } }, // include the runtime @@ -288,3 +291,7 @@ type HoudiniReactAuthStrategy = sessionKeys: string[] url: string } + +export function setManifest(newManifest: ProjectManifest): void { + manifest = newManifest +} diff --git a/packages/houdini-react/src/plugin/vite.tsx b/packages/houdini-react/src/plugin/vite.tsx index 389d8b476f..4d88ad4cad 100644 --- a/packages/houdini-react/src/plugin/vite.tsx +++ b/packages/houdini-react/src/plugin/vite.tsx @@ -1,32 +1,58 @@ -import { PluginHooks, Config, Cache, path, QueryArtifact, fs } from 'houdini' +import { + PluginHooks, + Config, + Cache, + path, + QueryArtifact, + fs, + type ProjectManifest, + load_manifest, + routerConventions, +} from 'houdini' import type { renderToStream as streamingRender } from 'react-streaming/server' +import { InputOption } from 'rollup' import type { Connect, ViteDevServer } from 'vite' -import { RouterManifest } from '../runtime' -import { find_match } from '../runtime/routing/lib/match' -import { configure_server } from '../server' -import { dev_server } from '../server/compat' -import { get_session } from '../server/session' -import { plugin_config } from './config' -import { render_server_path } from './conventions' - +import { setManifest } from '.' // in order to coordinate the client and server, the client's pending request cache // needs to start with a value for every query that we are sending on the server. // While values resolve, chunks are sent, etc, the pending cache will be resolved // and components will be allowed to render if their data cache is sufficiently full - // We need to generate all sorts of files to make this work and in development, we want // to rely heavily on Vite's dev server for loading things so that we can make sure we always // integrate well with hmr. We're going to use virtual modules in place of the statically // generated files. - // Here is a potentially incomplete list of things that are mocked / need to be generated: -// @@houdini/page/[query_names.join(',')] - An entry for every page that starts the pending cache with the correct values -// @@houdini/artifact/[name] - An entry for loading an artifact and notifying the artifact cache +// virtual:houdini/pages/[query_names.join(',')] - An entry for every page that starts the pending cache with the correct values +// virtual:houdini/artifacts/[name] - An entry for loading an artifact and notifying the artifact cache +import { RouterManifest } from '../runtime' +import { find_match } from '../runtime/routing/lib/match' +import { configure_server } from '../runtime/server' +import { dev_server } from '../runtime/server/compat' +import { get_session } from '../runtime/server/session' +import { plugin_config } from './config' + +let manifest: ProjectManifest export default { // we want to set up some vite aliases by default - config(config) { + async config(config, env) { + manifest = await load_manifest({ config, includeArtifacts: env.mode === 'production' }) + setManifest(manifest) + + // build up the list of entries that we need vite to bundle + const entries: InputOption = {} + + // every page in the manifest is a new entry point for vite + for (const [id, page] of Object.entries(manifest.pages)) { + entries[`pages/${id}`] = `virtual:houdini/pages/${page.id}@${page.queries}.jsx` + } + + // every artifact asset needs to be bundled individually + for (const artifact of manifest.artifacts) { + entries[`artifacts/${artifact}`] = `virtual:houdini/artifacts/${artifact}.js` + } + return { resolve: { alias: { @@ -36,22 +62,31 @@ export default { '~/*': path.join(config.projectRoot, 'src', '*'), }, }, + build: { + outDir: config.compiledAssetsDir, + rollupOptions: { + input: entries, + output: { + entryFileNames: 'assets/[name].js', + }, + }, + }, } }, resolveId(id) { // we only care about the virtual modules that generate - if (!id.includes('@@houdini')) { + if (!id.includes('virtual:houdini')) { return } // let them all through as is but strip anything that comes before the marker - return id.substring(id.indexOf('@@houdini')) + return id.substring(id.indexOf('virtual:houdini')) }, async load(id, { config }) { // we only care about the virtual modules that generate - if (!id.startsWith('@@houdini')) { + if (!id.startsWith('virtual:houdini')) { return } @@ -63,7 +98,7 @@ export default { arg = parsedPath.name // if we are rendering the virtual page - if (which === 'page') { + if (which === 'pages') { const [id, query_names] = arg.split('@') const queries = query_names.split(',') @@ -75,17 +110,44 @@ export default { import client from '$houdini/plugins/houdini-react/runtime/client' import Component from '$houdini/plugins/houdini-react/units/entries/${id}.jsx' + // if there is pending data (or artifacts) then we should prime the caches + let initialData = {} + let initialArtifacts = {} - // attach things to the global scope to synchronize streaming - window.__houdini__nav_caches__ = router_cache({ - pending_queries: ${JSON.stringify(queries)}, - components: { - '${id}': Component + if (!window.__houdini__cache__) { + window.__houdini__cache__ = new Cache() + window.__houdini__hydration__layer__ = window.__houdini__cache__._internal_unstable.storage.createLayer(true) + window.__houdini__client__ = client + } + + // the artifacts are the source of the zip (without them, we can't prime either cache) + for (const [artifactName, artifact] of Object.entries(window.__houdini__pending_artifacts__ ?? {})) { + // save the value in the initial artifact cache + initialArtifacts[artifactName] = artifact + + // if we also have data for the artifact, save it in the initial data cache + if (window.__houdini__pending_data__?.[artifactName]) { + // create the store we'll put in the cache + const observer = client.observe({ artifact, cache: window.__houdini__cache__, initialValue: window.__houdini__pending_data__[artifactName] }) + + // save it in the cache + initialData[artifactName] = observer } - }) - window.__houdini__cache__ = new Cache() - window.__houdini__hydration__layer__ = window.__houdini__cache__._internal_unstable.storage.createLayer(true) - window.__houdini__client__ = client + + } + + // attach things to the global scope to synchronize streaming + if (!window.__houdini__nav_caches__) { + window.__houdini__nav_caches__ = router_cache({ + pending_queries: ${JSON.stringify(queries)}, + initialData, + initialArtifacts, + components: { + '${id}': Component + } + }) + } + // hydrate the cache with the information from the initial payload @@ -99,7 +161,7 @@ export default { ` } - if (which === 'artifact') { + if (which === 'artifacts') { // the arg is the name of the artifact const artifact = (await fs.readFile( path.join(config.artifactDirectory, arg + '.js') @@ -109,7 +171,7 @@ export default { artifact + ` if (window.__houdini__nav_caches__ && window.__houdini__nav_caches__.artifact_cache && !window.__houdini__nav_caches__.artifact_cache.has("${arg}")) { - window.__houdini__nav_caches__.artifact_cache.set(${arg}, artifact) + window.__houdini__nav_caches__.artifact_cache.set(${JSON.stringify(arg)}, artifact) } ` ) @@ -185,6 +247,7 @@ const render_stream = cache, session, userAgent: 'Vite', + assetPrefix: '/virtual:houdini', }) // our pending cache needs to start with signals that we can alert @@ -195,25 +258,28 @@ const render_stream = // start streaming the response to the user pipe?.(response) + // the entry point for the page will start the pending cache with the correct values + const entry = `/virtual:houdini/pages/${match.id}@${pending_query_names}.jsx` + // add the initial scripts to the page injectToStream(` - + - + - - - `) + + + `) } async function load_render(server: ViteDevServer & { houdiniConfig: Config }) { - // load the function to rener the response from the generated output + // load the function to redner the response from the generated output // this is a hack to avoid a dependency issue with pnpm (i think) return (await server.ssrLoadModule( - render_server_path(server.houdiniConfig) + '?t=' + new Date().getTime() + routerConventions.render_server_path(server.houdiniConfig) + '?t=' + new Date().getTime() )) as { render_to_stream: ( args: { @@ -222,6 +288,7 @@ async function load_render(server: ViteDevServer & { houdiniConfig: Config }) { cache: Cache url: string session: App.Session + assetPrefix: '/virtual:houdini' } & Parameters[1] ) => ReturnType } diff --git a/packages/houdini-react/src/runtime/index.tsx b/packages/houdini-react/src/runtime/index.tsx index 36b34d49c4..fa59a87455 100644 --- a/packages/houdini-react/src/runtime/index.tsx +++ b/packages/houdini-react/src/runtime/index.tsx @@ -15,7 +15,7 @@ export * from './routing' export function Router({ cache, - intialURL, + initialURL, artifact_cache, component_cache, data_cache, @@ -24,12 +24,14 @@ export function Router({ loaded_queries, loaded_artifacts, session, + assetPrefix, }: { - intialURL: string + initialURL: string cache: Cache loaded_queries?: Record loaded_artifacts?: Record session?: App.Session + assetPrefix: string } & RouterCache) { return ( ) @@ -64,15 +67,19 @@ export function router_cache({ pending_queries = [], artifacts = {}, components = {}, + initialData = {}, + initialArtifacts = {}, }: { pending_queries?: string[] artifacts?: Record components?: Record React.ReactElement> + initialData?: Record> + initialArtifacts?: Record } = {}): RouterCache { const result: RouterCache = { - artifact_cache: suspense_cache(), + artifact_cache: suspense_cache(initialArtifacts), component_cache: suspense_cache(), - data_cache: suspense_cache(), + data_cache: suspense_cache(initialData), pending_cache: suspense_cache(), last_variables: suspense_cache(), } diff --git a/packages/houdini-react/src/runtime/routing/components/Router.tsx b/packages/houdini-react/src/runtime/routing/components/Router.tsx index 32e0119251..ce535c3310 100644 --- a/packages/houdini-react/src/runtime/routing/components/Router.tsx +++ b/packages/houdini-react/src/runtime/routing/components/Router.tsx @@ -4,7 +4,7 @@ import { deepEquals } from '$houdini/runtime/lib/deepEquals' import { LRUCache } from '$houdini/runtime/lib/lru' import { GraphQLObject, GraphQLVariables } from '$houdini/runtime/lib/types' import { QueryArtifact } from '$houdini/runtime/lib/types' -import React, { SyntheticEvent } from 'react' +import React from 'react' import { useStream } from 'react-streaming' import { useDocumentStore } from '../../hooks/useDocumentStore' @@ -25,18 +25,20 @@ import type { RouterManifest, RouterPageManifest } from '../lib/types' // they can grab what they need if its ready and suspend if not. export function Router({ manifest, - intialURL, + initialURL, loaded_queries, loaded_artifacts, + assetPrefix, }: { manifest: RouterManifest - intialURL?: string + initialURL?: string loaded_queries?: Record loaded_artifacts?: Record + assetPrefix: string }) { // the current route is just a string in state. const [current, setCurrent] = React.useState(() => { - return intialURL || window.location.pathname + return initialURL || window.location.pathname }) // find the matching page for the current route @@ -48,8 +50,7 @@ export function Router({ // load the page assets (source, artifacts, data). this will suspend if the component is not available yet // this hook embeds pending requests in context so that the component can suspend if necessary14 - usePageData({ page, variables, loaded_queries, loaded_artifacts }) - + usePageData({ page, variables, loaded_queries, loaded_artifacts, assetPrefix }) // if we get this far, it's safe to load the component const { component_cache } = useRouterContext() const PageComponent = component_cache.get(page.id)! @@ -60,13 +61,16 @@ export function Router({ // whenever the route changes, we need to make sure the browser's stack is up to date React.useEffect(() => { - if (window.location.pathname !== current) { + if (globalThis.window && window.location.pathname !== current) { window.history.pushState({}, '', current) } }, [current]) // when we first mount we should start listening to the back button React.useEffect(() => { + if (!globalThis.window) { + return + } const onChange = (evt: PopStateEvent) => { setCurrent(window.location.pathname) } @@ -80,7 +84,6 @@ export function Router({ useAnchorIntercept({ goto: setCurrent }) // TODO: cleanup navigation caches - // render the component embedded in the necessary context so it can orchestrate // its needs return ( @@ -101,11 +104,13 @@ function usePageData({ variables, loaded_queries, loaded_artifacts, + assetPrefix, }: { page: RouterPageManifest variables: GraphQLVariables loaded_queries?: Record loaded_artifacts?: Record + assetPrefix: string }) { // grab context values const { @@ -169,17 +174,38 @@ function usePageData({ `) @@ -245,7 +271,7 @@ function usePageData({ // add a script to load the artifact stream?.injectToStream(` - + `) // now that we have the artifact, we can load the query too @@ -357,7 +383,7 @@ type RouterContext = { // Pages need a way to wait for data data_cache: SuspenseCache> - // A way to track pending requests for an artifact + // A way to dedupe requests for a query pending_cache: PendingCache // A way to track the last known good variables @@ -472,5 +498,5 @@ function useAnchorIntercept({ goto }: { goto: (url: string) => void }) { return () => { document.removeEventListener('click', onClick!) } - }, [goto]) + }, []) } diff --git a/packages/houdini-react/src/runtime/routing/lib/cache.ts b/packages/houdini-react/src/runtime/routing/lib/cache.ts index d9d7c794f9..349fc6b3e1 100644 --- a/packages/houdini-react/src/runtime/routing/lib/cache.ts +++ b/packages/houdini-react/src/runtime/routing/lib/cache.ts @@ -3,8 +3,14 @@ // is thrown that resolves when a value is passed to set() import { LRUCache } from '$houdini/runtime/lib/lru' -export function suspense_cache(): SuspenseCache { - return new SuspenseCache() +export function suspense_cache(initialData?: Record): SuspenseCache { + const cache = new SuspenseCache() + + for (const [key, value] of Object.entries(initialData ?? {})) { + cache.set(key, value) + } + + return cache } export class SuspenseCache<_Data> extends LRUCache<_Data> { diff --git a/packages/houdini-react/src/server/compat.ts b/packages/houdini-react/src/runtime/server/compat.ts similarity index 100% rename from packages/houdini-react/src/server/compat.ts rename to packages/houdini-react/src/runtime/server/compat.ts diff --git a/packages/houdini-react/src/server/index.ts b/packages/houdini-react/src/runtime/server/index.ts similarity index 96% rename from packages/houdini-react/src/server/index.ts rename to packages/houdini-react/src/runtime/server/index.ts index 3344556218..7fdbaa1994 100644 --- a/packages/houdini-react/src/server/index.ts +++ b/packages/houdini-react/src/runtime/server/index.ts @@ -1,7 +1,7 @@ // This function defines the primary entrypoint for requests import type { Config } from 'houdini' -import { plugin_config as get_plugin_config } from '../plugin/config' +import { plugin_config as get_plugin_config } from '../../plugin/config' import { set_session } from './session' export function configure_server({ server, config }: { server: Server; config: Config }) { diff --git a/packages/houdini-react/src/server/session.ts b/packages/houdini-react/src/runtime/server/session.ts similarity index 100% rename from packages/houdini-react/src/server/session.ts rename to packages/houdini-react/src/runtime/server/session.ts diff --git a/packages/houdini/package.json b/packages/houdini/package.json index 44b70a2486..3b9abdd822 100644 --- a/packages/houdini/package.json +++ b/packages/houdini/package.json @@ -20,6 +20,7 @@ "typedefs": "scripts typedefs" }, "devDependencies": { + "@babel/types": "^7.21.5", "@trivago/prettier-plugin-sort-imports": "^4.0.0", "@types/glob": "^8.0.0", "@types/minimatch": "^5.1.2", diff --git a/packages/houdini/src/lib/config.ts b/packages/houdini/src/lib/config.ts index 5cc62a7b42..b3bbf33cfd 100644 --- a/packages/houdini/src/lib/config.ts +++ b/packages/houdini/src/lib/config.ts @@ -329,6 +329,10 @@ export class Config { return path.join(this.definitionsDirectory, 'schema.graphql') } + get routerBuildDirectory() { + return path.join(this.projectRoot, 'dist') + } + get definitionsDocumentsPath() { return path.join(this.definitionsDirectory, 'documents.gql') } @@ -448,7 +452,7 @@ export class Config { } get compiledAssetsDir() { - return path.join(this.rootDir, '.build') + return path.join(this.rootDir, 'build') } compiledAssetPath(filepath: string) { diff --git a/packages/houdini/src/lib/index.ts b/packages/houdini/src/lib/index.ts index cd96237c27..fcea449a4c 100644 --- a/packages/houdini/src/lib/index.ts +++ b/packages/houdini/src/lib/index.ts @@ -18,5 +18,6 @@ export type { EmbeddedGraphqlDocument } from './walk' export * as fs from './fs' export * as path from './path' +export * from './router' export { Cache } from '../runtime/cache/cache' diff --git a/packages/houdini-react/src/plugin/conventions.ts b/packages/houdini/src/lib/router/conventions.ts similarity index 91% rename from packages/houdini-react/src/plugin/conventions.ts rename to packages/houdini/src/lib/router/conventions.ts index 66d65d0ad5..888b7ddc7c 100644 --- a/packages/houdini-react/src/plugin/conventions.ts +++ b/packages/houdini/src/lib/router/conventions.ts @@ -1,4 +1,4 @@ -import { path, fs, type Config } from 'houdini' +import { path, fs, type Config } from '../' /** The location of the project's router */ export function router_path(config: Config) { @@ -15,7 +15,7 @@ export function render_client_path(config: Config, base?: string) { } export function render_server_path(config: Config, base?: string) { - return path.join(units_dir(config, base), 'render', 'server.jsx') + return path.join(units_dir(config, base), 'render', 'server.js') } export function render_app_path(config: Config, base?: string) { @@ -86,7 +86,7 @@ export function is_layout(path: string) { } /** Transforms paths to ids */ -export function normalize_path(path: string) { +export function page_id(path: string) { if (path.endsWith('/') && path.length > 1) { path = path.substring(0, path.length - 1) } @@ -97,11 +97,12 @@ export function normalize_path(path: string) { for (const char of path) { const match = special_chars.indexOf(char) if (match !== -1) { - copy += mask + match.toString() + copy += mask } else { copy += char } } + return copy } @@ -128,3 +129,7 @@ function units_dir(config: Config, base: string = base_dir(config)) { function base_dir(config: Config) { return config.pluginDirectory('houdini-react') } + +export function serialized_manifest_path(config: Config, base: string = base_dir(config)): string { + return path.join(base, 'manifest.json') +} diff --git a/packages/houdini/src/lib/router/index.ts b/packages/houdini/src/lib/router/index.ts new file mode 100644 index 0000000000..a8738a5a69 --- /dev/null +++ b/packages/houdini/src/lib/router/index.ts @@ -0,0 +1,8 @@ +/** + * This directory contains all of the utilities that are designed to + * be used by plugins that generate router code. + */ + +export * as routerConventions from './conventions' +export * from './manifest' +export * from './types' diff --git a/packages/houdini-react/src/plugin/codegen/manifest.test.ts b/packages/houdini/src/lib/router/manifest.test.ts similarity index 88% rename from packages/houdini-react/src/plugin/codegen/manifest.test.ts rename to packages/houdini/src/lib/router/manifest.test.ts index ff5b90bd17..08b8712a3f 100644 --- a/packages/houdini-react/src/plugin/codegen/manifest.test.ts +++ b/packages/houdini/src/lib/router/manifest.test.ts @@ -1,12 +1,11 @@ -import { fs } from 'houdini' -import { clearMock } from 'houdini/test' import { test, expect, describe } from 'vitest' -import { test_config } from '../config' +import { fs } from '..' +import { testConfig, clearMock } from '../../test' import { load_manifest, extractQueries } from './manifest' test('empty routes dir generates empty manifest', async function () { - const config = await test_config() + const config = testConfig() // create the mock filesystem await fs.mock({}) @@ -20,13 +19,14 @@ test('empty routes dir generates empty manifest', async function () { "pages": {}, "layouts": {}, "page_queries": {}, - "layout_queries": {} + "layout_queries": {}, + "artifacts": [] } `) }) test('route groups', async function () { - const config = await test_config() + const config = testConfig() // create the mock filesystem await fs.mock({ @@ -50,15 +50,15 @@ test('route groups', async function () { ).toMatchInlineSnapshot(` { "pages": { - "_0_3subRoute_4_0nested": { - "id": "_0_3subRoute_4_0nested", + "__subRoute__nested": { + "id": "__subRoute__nested", "queries": [ "FinalQuery" ], "url": "/(subRoute)/nested", "layouts": [ - "_0", - "_0_3subRoute_4" + "_", + "__subRoute_" ], "path": "src/routes/(subRoute)/nested/+page.tsx", "query_options": [ @@ -68,22 +68,22 @@ test('route groups', async function () { } }, "layouts": { - "_0": { - "id": "_0", + "_": { + "id": "_", "queries": [], "url": "/", "layouts": [], "path": "src/routes/+layout.tsx", "query_options": [] }, - "_0_3subRoute_4": { - "id": "_0_3subRoute_4", + "__subRoute_": { + "id": "__subRoute_", "queries": [ "RootQuery" ], "url": "/(subRoute)/", "layouts": [ - "_0" + "_" ], "path": "src/routes/(subRoute)/+layout.tsx", "query_options": [ @@ -92,7 +92,7 @@ test('route groups', async function () { } }, "page_queries": { - "_0_3subRoute_4_0nested": { + "__subRoute__nested": { "path": "(subRoute)/nested/+page.gql", "name": "FinalQuery", "url": "/(subRoute)/nested/", @@ -100,19 +100,20 @@ test('route groups', async function () { } }, "layout_queries": { - "_0_3subRoute_4": { + "__subRoute_": { "path": "(subRoute)/+layout.gql", "name": "RootQuery", "url": "/(subRoute)/", "loading": false } - } + }, + "artifacts": [] } `) }) test('nested route structure happy path', async function () { - const config = await test_config() + const config = testConfig() // create the mock filesystem await fs.mock({ @@ -145,30 +146,30 @@ test('nested route structure happy path', async function () { ).resolves.toMatchInlineSnapshot(` { "pages": { - "_0": { - "id": "_0", + "_": { + "id": "_", "queries": [ "RootQuery" ], "url": "/", "layouts": [ - "_0" + "_" ], "path": "src/routes/+page.tsx", "query_options": [ "RootQuery" ] }, - "_0subRoute": { - "id": "_0subRoute", + "_subRoute": { + "id": "_subRoute", "queries": [ "SubQuery", "RootQuery" ], "url": "/subRoute", "layouts": [ - "_0", - "_0subRoute" + "_", + "_subRoute" ], "path": "src/routes/subRoute/+page.jsx", "query_options": [ @@ -176,16 +177,16 @@ test('nested route structure happy path', async function () { "SubQuery" ] }, - "_0another": { - "id": "_0another", + "_another": { + "id": "_another", "queries": [ "MyQuery", "MyLayoutQuery" ], "url": "/another", "layouts": [ - "_0", - "_0another" + "_", + "_another" ], "path": "src/routes/another/+page.tsx", "query_options": [ @@ -194,15 +195,15 @@ test('nested route structure happy path', async function () { "MyQuery" ] }, - "_0subRoute_0nested": { - "id": "_0subRoute_0nested", + "_subRoute_nested": { + "id": "_subRoute_nested", "queries": [ "FinalQuery" ], "url": "/subRoute/nested", "layouts": [ - "_0", - "_0subRoute" + "_", + "_subRoute" ], "path": "src/routes/subRoute/nested/+page.tsx", "query_options": [ @@ -213,8 +214,8 @@ test('nested route structure happy path', async function () { } }, "layouts": { - "_0": { - "id": "_0", + "_": { + "id": "_", "queries": [], "url": "/", "layouts": [], @@ -223,14 +224,14 @@ test('nested route structure happy path', async function () { "RootQuery" ] }, - "_0another": { - "id": "_0another", + "_another": { + "id": "_another", "queries": [ "RootQuery" ], "url": "/another/", "layouts": [ - "_0" + "_" ], "path": "src/routes/another/+layout.tsx", "query_options": [ @@ -238,14 +239,14 @@ test('nested route structure happy path', async function () { "MyLayoutQuery" ] }, - "_0subRoute": { - "id": "_0subRoute", + "_subRoute": { + "id": "_subRoute", "queries": [ "RootQuery" ], "url": "/subRoute/", "layouts": [ - "_0" + "_" ], "path": "src/routes/subRoute/+layout.tsx", "query_options": [ @@ -255,13 +256,13 @@ test('nested route structure happy path', async function () { } }, "page_queries": { - "_0another": { + "_another": { "path": "another/+page.gql", "name": "MyQuery", "url": "/another/", "loading": false }, - "_0subRoute_0nested": { + "_subRoute_nested": { "path": "subRoute/nested/+page.gql", "name": "FinalQuery", "url": "/subRoute/nested/", @@ -269,31 +270,32 @@ test('nested route structure happy path', async function () { } }, "layout_queries": { - "_0": { + "_": { "path": "+layout.gql", "name": "RootQuery", "url": "/", "loading": true }, - "_0another": { + "_another": { "path": "another/+layout.gql", "name": "MyLayoutQuery", "url": "/another/", "loading": false }, - "_0subRoute": { + "_subRoute": { "path": "subRoute/+layout.gql", "name": "SubQuery", "url": "/subRoute/", "loading": false } - } + }, + "artifacts": [] } `) }) describe('validate filesystem', async () => { - const config = await test_config() + const config = testConfig() const testCases: { name: string diff --git a/packages/houdini/src/lib/router/manifest.ts b/packages/houdini/src/lib/router/manifest.ts new file mode 100644 index 0000000000..d97eab5997 --- /dev/null +++ b/packages/houdini/src/lib/router/manifest.ts @@ -0,0 +1,362 @@ +import * as t from '@babel/types' +import * as graphql from 'graphql' + +import { path, fs, parseJS, type Config } from '../' +import { + read_layoutQuery, + read_layoutView, + read_pageView, + read_pageQuery, + page_id, +} from './conventions' + +/** + * Walk down the routes directory and build a normalized description of the project's + * filesystem. + */ +export async function load_manifest(args: { + config: Config + includeArtifacts?: boolean +}): Promise { + // we'll start at the route directory and start building it up + const manifest = await walk_routes({ + config: args.config, + url: '/', + filepath: args.config.routesDir, + project: { + pages: {}, + layouts: {}, + page_queries: {}, + layout_queries: {}, + artifacts: [], + }, + queries: [], + layouts: [], + }) + + if (args.includeArtifacts) { + // look at the artifact directory for every artifact + for (const artifactPath of await fs.readdir(args.config.artifactDirectory)) { + // only consider the js files + if (!artifactPath.endsWith('.js') || artifactPath === 'index.js') { + continue + } + + // push the artifact path without the extension + manifest.artifacts.push(artifactPath.substring(0, artifactPath.length - 3)) + } + } + + return manifest +} + +async function walk_routes(args: { + filepath: string + config: Config + url: string + project: ProjectManifest + queries: string[] + layouts: string[] +}): Promise { + const directory_contents = await fs.readdir(args.filepath, { + withFileTypes: true, + }) + + // before we can go down, we need to look at the files in the directory + // to see what queries were added to the context. this means we have to + // first collect the layout query and view, and then check for a page query + // to validate the page view + let newLayouts = args.layouts + let newLayoutQueries = args.queries + + // track the manifests we create along the way + let layout: PageManifest | null = null + let layoutQuery: QueryManifest | null = null + let pageQuery: QueryManifest | null = null + + // read file contents + const [ + [layoutQueryPath, layoutQueryContents], + [layoutViewPath, layoutViewContents], + [pageQueryPath, pageQueryContents], + [pageViewPath, pageViewContents], + ] = await Promise.all([ + read_layoutQuery(args.filepath), + read_layoutView(args.filepath), + read_pageQuery(args.filepath), + read_pageView(args.filepath), + ]) + + // TODO: allow plugins to transform this content before we analyze it for information + + // we have a layout query, so we need to add it to the context + if (layoutQueryContents) { + layoutQuery = await add_query({ + path: layoutQueryPath!, + config: args.config, + url: args.url, + project: args.project, + type: 'layout', + contents: layoutQueryContents, + }) + newLayoutQueries = [...args.queries, layoutQuery.name] + } + + // we have a layout query, so we need to add it to the context + if (layoutViewContents) { + layout = await add_view({ + url: args.url, + path: layoutViewPath!, + project: args.project, + type: 'layout', + contents: layoutViewContents, + layouts: args.layouts, + queries: newLayoutQueries, + config: args.config, + }) + newLayouts = [...args.layouts, page_id(layout.url)] + } + + // if we have a page query, add it + if (pageQueryContents) { + pageQuery = await add_query({ + path: pageQueryPath!, + config: args.config, + url: args.url, + project: args.project, + type: 'page', + contents: pageQueryContents, + }) + } + + // if we have a page query, add it + if (pageViewContents) { + await add_view({ + path: pageViewPath!, + url: args.url.substring(0, args.url.length - 1) || '/', + project: args.project, + type: 'page', + contents: pageViewContents, + layouts: newLayouts, + queries: pageQuery ? [...newLayoutQueries, pageQuery.name] : newLayoutQueries, + config: args.config, + }) + } + + // now we can walk down the directories + await Promise.all( + directory_contents.map((dir) => { + if (!dir.isDirectory()) { + return + } + + return walk_routes({ + ...args, + filepath: path.join(args.filepath, dir.name), + url: `${args.url}${dir.name}/`, + queries: newLayoutQueries, + layouts: newLayouts, + }) + }) + ) + + return args.project +} + +async function add_view(args: { + path: string + url: string + project: ProjectManifest + type: 'page' | 'layout' + contents: string + layouts: string[] + queries: string[] + config: Config +}) { + const target = args.type === 'page' ? args.project.pages : args.project.layouts + const queries = await extractQueries(args.contents) + // look for any queries that we are asking for that aren't available + const missing_queries = queries.filter((query) => !args.queries.includes(query)) + if (missing_queries.length > 0) { + throw { + message: 'Missing Queries', + description: JSON.stringify(missing_queries), + } + } + + const id = page_id(args.url) + + target[id] = { + id, + queries, + url: args.url, + layouts: args.layouts, + path: path.relative(args.config.projectRoot, args.path), + query_options: args.queries, + } + + return target[id] +} + +async function add_query(args: { + path: string + config: Config + url: string + project: ProjectManifest + type: 'page' | 'layout' + contents: string +}) { + // we need to parse the query to get the name + const parsed = graphql.parse(args.contents) + // look for the query definition + const query = parsed.definitions.find( + (def): def is graphql.OperationDefinitionNode => + def.kind === 'OperationDefinition' && def.operation === 'query' + ) + if (!query?.name) { + throw new Error('No query found') + } + + let loading = false + await graphql.visit(parsed, { + Directive(node) { + if (node.name.value === args.config.loadingDirective) { + loading = true + } + }, + }) + + const target = args.type === 'page' ? args.project.page_queries : args.project.layout_queries + target[page_id(args.url)] = { + path: path.relative(args.config.routesDir, args.path), + name: query.name.value, + url: args.url, + loading, + } + + return target[page_id(args.url)] +} + +export async function extractQueries(source: string): Promise { + const ast = parseJS(source, { plugins: ['jsx'] }) + + let defaultExportNode: t.Node | null = null + let defaultExportIdentifier: string | null = null + + // walk through the function body and find the default export + for (const node of ast.body) { + if (t.isExportDefaultDeclaration(node)) { + if ( + t.isFunctionDeclaration(node.declaration) || + t.isArrowFunctionExpression(node.declaration) || + t.isFunctionExpression(node.declaration) + ) { + defaultExportNode = node.declaration + break + + // if the export is an identifier we'll have to go back through + // and find the declaration + } else if (t.isIdentifier(node.declaration)) { + defaultExportIdentifier = node.declaration.name + } + } + } + + // if the default export was an identifier then go back through and find the correct one + if (defaultExportIdentifier) { + for (const node of ast.body) { + if (t.isVariableDeclaration(node)) { + for (const declaration of node.declarations) { + if ( + t.isVariableDeclarator(declaration) && + t.isIdentifier(declaration.id) && + declaration.id.name === defaultExportIdentifier + ) { + if ( + t.isArrowFunctionExpression(declaration.init) || + t.isFunctionExpression(declaration.init) + ) { + defaultExportNode = declaration.init + break + } else if ( + t.isTSAsExpression(declaration.init) && + (t.isArrowFunctionExpression(declaration.init.expression) || + t.isFunctionExpression(declaration.init.expression)) + ) { + defaultExportNode = declaration.init.expression + break + } + } + } + } + } + } + if (!defaultExportNode) { + throw new Error('No default export found.') + } + + let props: string[] = [] + const componentFunction = defaultExportNode as + | t.FunctionDeclaration + | t.ArrowFunctionExpression + | t.FunctionExpression + | undefined + + if (componentFunction && componentFunction.params.length > 0) { + const firstParam = componentFunction.params[0] + + if (t.isObjectPattern(firstParam)) { + for (const property of firstParam.properties) { + if (t.isObjectProperty(property) && t.isIdentifier(property.key)) { + props.push(property.key.name) + } + } + } else { + throw new Error('Props should be specified as an object pattern.') + } + } else { + return [] + } + + return props.filter((p) => p !== 'children') +} + +// The manifest is a tree of routes that the router will use to render +// the correct component tree for a given url +export type ProjectManifest = { + /** All of the pages in the project */ + pages: Record + /** All of the layouts in the project */ + layouts: Record + /** All of the page queries in the project */ + page_queries: Record + /** All of the layout queries in the project */ + layout_queries: Record + /** All of the artifacts in the project */ + artifacts: string[] +} + +export type PageManifest = { + id: string + /** the name of every query that the page depends on */ + queries: string[] + /** the list of queries that this page could potentially ask for */ + query_options: string[] + /** the full url pattern of the page */ + url: string + /** the ids of layouts that wrap this page */ + layouts: string[] + /** The filepath of the unit */ + path: string +} + +export type QueryManifest = { + /** the name of the query */ + name: string + /** the url tied with the query */ + url: string + /** wether the query uses the loading directive (ie, wants a fallback) */ + loading: boolean + /** The filepath of the unit */ + path: string +} diff --git a/packages/houdini/src/lib/router/types.ts b/packages/houdini/src/lib/router/types.ts new file mode 100644 index 0000000000..1539c88e43 --- /dev/null +++ b/packages/houdini/src/lib/router/types.ts @@ -0,0 +1,10 @@ +import type { routerConventions } from '.' +import type { Config } from '../config' + +export type Adapter = (args: { + config: Config + conventions: typeof routerConventions + sourceDir: string + publicBase: string + outDir: string +}) => void | Promise diff --git a/packages/houdini/src/lib/types.ts b/packages/houdini/src/lib/types.ts index 921409774d..68bbb5ea72 100644 --- a/packages/houdini/src/lib/types.ts +++ b/packages/houdini/src/lib/types.ts @@ -2,13 +2,17 @@ import type graphql from 'graphql' import type * as recast from 'recast' import type { CustomPluginOptions, + InputOptions, LoadResult, + MinimalPluginContext, + NormalizedInputOptions, + NullValue, ObjectHook, PluginContext, ResolveIdResult, SourceMapInput, } from 'rollup' -import type { UserConfig, ViteDevServer } from 'vite' +import type { ConfigEnv, ResolvedConfig, UserConfig, ViteDevServer } from 'vite' import type { ConfigFile } from '../runtime/lib/config' import type { @@ -19,6 +23,7 @@ import type { } from '../runtime/lib/types' import type { TransformPage } from '../vite/houdini' import type { Config } from './config' +import type { Adapter } from './router' type Program = recast.types.namedTypes.Program @@ -275,7 +280,27 @@ export type PluginHooks = { | { code: string; map?: SourceMapInput | string } vite?: { - config?: (config: Config) => UserConfig + config?: (config: Config, env: ConfigEnv) => UserConfig | Promise + + buildStart?: ( + this: PluginContext, + options: NormalizedInputOptions & { houdiniConfig: Config } + ) => void + + buildEnd?: ( + this: PluginContext, + error?: Error, + houdiniConfig?: Config + ) => void | Promise + + closeBundle?: (this: PluginContext) => void | Promise + + configResolved?: ObjectHook<(this: void, config: ResolvedConfig) => void | Promise> + + options?: ( + this: MinimalPluginContext, + options: InputOptions & { houdiniConfig: Config } + ) => InputOptions | NullValue // these type definitions are copy and pasted from the vite ones // with config added to the appropriate options object @@ -333,7 +358,7 @@ export type GenerateHookInput = { pluginRoot: string } -export type PluginConfig = { configPath?: string } & Partial +export type PluginConfig = { configPath?: string; adapter?: Adapter } & Partial export * from '../runtime/lib/types' export * from '../runtime/lib/config' diff --git a/packages/houdini/src/vite/houdini.ts b/packages/houdini/src/vite/houdini.ts index 8cc07224b6..573018198a 100644 --- a/packages/houdini/src/vite/houdini.ts +++ b/packages/houdini/src/vite/houdini.ts @@ -1,11 +1,12 @@ import type { SourceMapInput } from 'rollup' -import type { Plugin as VitePlugin, UserConfig } from 'vite' +import type { Plugin as VitePlugin, UserConfig, ResolvedConfig } from 'vite' import generate from '../codegen' import type { Config, PluginConfig } from '../lib' -import { path, getConfig, formatErrors, deepMerge } from '../lib' +import { path, getConfig, formatErrors, fs, deepMerge, routerConventions } from '../lib' let config: Config +let viteConfig: ResolvedConfig export default function Plugin(opts: PluginConfig = {}): VitePlugin { return { @@ -16,15 +17,15 @@ export default function Plugin(opts: PluginConfig = {}): VitePlugin { enforce: 'pre', // add watch-and-run to their vite config - async config(viteConfig) { + async config(userConfig, ...rest) { config = await getConfig(opts) let result: UserConfig = { server: { - ...viteConfig.server, + ...userConfig.server, fs: { - ...viteConfig.server?.fs, - allow: ['.'].concat(viteConfig.server?.fs?.allow || []), + ...userConfig.server?.fs, + allow: ['.'].concat(userConfig.server?.fs?.allow || []), }, }, } @@ -34,19 +35,108 @@ export default function Plugin(opts: PluginConfig = {}): VitePlugin { if (typeof plugin.vite?.config !== 'function') { continue } - result = deepMerge('', result, plugin.vite!.config.call(this, config)) + result = deepMerge( + '', + result, + await plugin.vite!.config.call(this, config, ...rest) + ) } return result }, + async buildEnd(args) { + for (const plugin of config.plugins) { + if (typeof plugin.vite?.buildEnd !== 'function') { + continue + } + + await plugin.vite!.buildEnd.call(this, args, config) + } + }, + + async configResolved(conf) { + viteConfig = conf + for (const plugin of config.plugins) { + if (typeof plugin.vite?.configResolved !== 'function') { + continue + } + + await plugin.vite!.configResolved.call(this, conf) + } + }, + + // called when all of the bundles have been generated (ie, when vite is done) + // we use this to generate the final assets needed for a production build of the server. + // this is only called when bundling (ie, not in dev mode) + async closeBundle() { + for (const plugin of config.plugins) { + if (typeof plugin.vite?.closeBundle !== 'function') { + continue + } + + await plugin.vite!.closeBundle.call(this) + } + + // if we dont' have an adapter, we don't need to do anything + if (!opts.adapter) { + return + } + + // tell the user what we're doing + console.log('🎩 Generating Deployment Assets...') + + // before we can invoke the adpater we need to ensure the build directory is present + await fs.rmdir(config.routerBuildDirectory) + await fs.mkdirp(config.routerBuildDirectory) + + // invoke the adapter + await opts.adapter({ + config, + conventions: routerConventions, + sourceDir: viteConfig.build.outDir, + publicBase: viteConfig.base, + outDir: config.routerBuildDirectory, + }) + }, + // when the build starts, we need to make sure to generate - async buildStart() { + async buildStart(args) { try { await generate(config) } catch (e) { formatErrors(e) } + + for (const plugin of config.plugins) { + if (typeof plugin.vite?.buildStart !== 'function') { + continue + } + + // @ts-expect-error + plugin.vite!.buildStart.call(this, { + ...args, + houdiniConfig: config, + }) + } + }, + + options(options) { + for (const plugin of config.plugins) { + if (typeof plugin.vite?.options !== 'function') { + continue + } + + // @ts-expect-error + options = plugin.vite!.options.call(this, { + ...options, + houdiniConfig: config, + }) + } + + return Object.fromEntries( + Object.entries(options).filter(([key]) => key !== 'houdiniConfig') + ) }, configureServer(server) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b5017649d..cee7a0a042 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,9 @@ importers: graphql: specifier: ^15.8.0 version: 15.8.0 + lint-staged: + specifier: ^12.3.4 + version: 12.5.0 prettier: specifier: ^2.8.3 version: 2.8.3 @@ -178,21 +181,36 @@ importers: e2e/react: dependencies: + '@cloudflare/kv-asset-handler': + specifier: ^0.3.0 + version: 0.3.0 + '@cloudflare/workers-types': + specifier: ^4.20230904.0 + version: 4.20230904.0 + cookie: + specifier: ^0.5.0 + version: 0.5.0 houdini: specifier: workspace:^ version: link:../../packages/houdini + houdini-adapter-cloudflare: + specifier: workspace:^ + version: link:../../packages/houdini-adapter-cloudflare houdini-react: specifier: workspace:^ version: link:../../packages/houdini-react + itty-router: + specifier: ^4.0.23 + version: 4.0.23 react: - specifier: ^18.2.0 - version: 18.2.0 + specifier: ^18.3.0-canary-d6dcad6a8-20230914 + version: 18.3.0-canary-d7a98a5e9-20230517 react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + specifier: ^18.3.0-canary-d6dcad6a8-20230914 + version: 18.3.0-canary-d6dcad6a8-20230914(react@18.3.0-canary-d7a98a5e9-20230517) react-streaming: specifier: ^0.3.10 - version: 0.3.10(react-dom@18.2.0)(react@18.2.0) + version: 0.3.10(react-dom@18.3.0-canary-d6dcad6a8-20230914)(react@18.3.0-canary-d7a98a5e9-20230517) devDependencies: '@types/react': specifier: ^18.0.27 @@ -212,12 +230,18 @@ importers: e2e-api: specifier: workspace:^ version: link:../_api + hono: + specifier: ^3.6.0 + version: 3.6.0 typescript: specifier: ^4.9.3 version: 4.9.4 vite: specifier: ^4.1.0 version: 4.1.4(@types/node@18.11.15) + wrangler: + specifier: ^3.7.0 + version: 3.7.0 e2e/svelte: devDependencies: @@ -379,6 +403,9 @@ importers: specifier: ^1.1.0 version: 1.1.0 devDependencies: + '@babel/types': + specifier: ^7.21.5 + version: 7.21.5 '@trivago/prettier-plugin-sort-imports': specifier: ^4.0.0 version: 4.0.0(@vue/compiler-sfc@3.2.47)(prettier@2.8.3) @@ -413,6 +440,52 @@ importers: specifier: ^0.28.3 version: 0.28.3(@vitest/ui@0.28.3) + packages/houdini-adapter-cloudflare: + dependencies: + '@cloudflare/kv-asset-handler': + specifier: ^0.3.0 + version: 0.3.0 + '@types/react': + specifier: ^18.2.21 + version: 18.2.21 + '@types/react-dom': + specifier: ^18.0.10 + version: 18.0.11 + cookie: + specifier: ^0.5.0 + version: 0.5.0 + houdini: + specifier: workspace:^ + version: link:../houdini + itty-router: + specifier: ^4.0.23 + version: 4.0.23 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + react-streaming: + specifier: ^0.3.14 + version: 0.3.14(react-dom@18.2.0)(react@18.2.0) + devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20230904.0 + version: 4.20230904.0 + '@types/cookie': + specifier: ^0.5.2 + version: 0.5.2 + scripts: + specifier: workspace:^ + version: link:../_scripts + tsup: + specifier: ^7.2.0 + version: 7.2.0(typescript@4.9.4) + vitest: + specifier: ^0.28.3 + version: 0.28.3(@vitest/ui@0.28.3) + packages/houdini-plugin-svelte-global-stores: dependencies: '@sveltejs/kit': @@ -885,6 +958,7 @@ packages: /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} + dev: false /@babel/helper-string-parser@7.21.5: resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} @@ -929,7 +1003,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.21.5 /@babel/parser@7.21.8: resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==} @@ -1162,15 +1236,6 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babel/types@7.20.7: - resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.21.5 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: false - /@babel/types@7.21.4: resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==} engines: {node: '>=6.9.0'} @@ -1178,6 +1243,7 @@ packages: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + dev: false /@babel/types@7.21.5: resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==} @@ -1195,6 +1261,10 @@ packages: resolution: {integrity: sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==} dev: true + /@brillout/import@0.2.3: + resolution: {integrity: sha512-1T8WlD75eeFSMrptGy8jiLHmfHgMmSjWvLOIUvHmSVZt+6k0eQqYUoK4KbmE4T9pVLIfxvZSOm2D68VEqKRHRw==} + dev: false + /@brillout/json-serializer@0.5.3: resolution: {integrity: sha512-IxlOMD5gOM0WfFGdeR98jHKiC82Ad1tUnSjvLS5jnRkfMEKBI+YzHA32Umw8W3Ccp5N4fNEX229BW6RaRpxRWQ==} dev: false @@ -1419,6 +1489,66 @@ packages: bundledDependencies: - is-unicode-supported + /@cloudflare/kv-asset-handler@0.2.0: + resolution: {integrity: sha512-MVbXLbTcAotOPUj0pAMhVtJ+3/kFkwJqc5qNOleOZTv6QkZZABDMS21dSrSlVswEHwrpWC03e4fWytjqKvuE2A==} + dependencies: + mime: 3.0.0 + dev: true + + /@cloudflare/kv-asset-handler@0.3.0: + resolution: {integrity: sha512-9CB/MKf/wdvbfkUdfrj+OkEwZ5b7rws0eogJ4293h+7b6KX5toPwym+VQKmILafNB9YiehqY0DlNrDcDhdWHSQ==} + dependencies: + mime: 3.0.0 + dev: false + + /@cloudflare/workerd-darwin-64@1.20230904.0: + resolution: {integrity: sha512-/GDlmxAFbDtrQwP4zOXFbqOfaPvkDxdsCoEa+KEBcAl5uR98+7WW5/b8naBHX+t26uS7p4bLlImM8J5F1ienRQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-darwin-arm64@1.20230904.0: + resolution: {integrity: sha512-x8WXNc2xnDqr5y1iirnNdyx8GZY3rL5xiF7ebK3mKQeB+jFjkhO71yuPTkDCzUWtOvw1Wfd4jbwy4wxacMX4mQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-linux-64@1.20230904.0: + resolution: {integrity: sha512-V58xyMS3oDpKO8Dpdh0r0BXm99OzoGgvWe9ufttVraj/1NTMGELwb6i9ySb8k3F1J9m/sO26+TV7pQc/bGC1VQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-linux-arm64@1.20230904.0: + resolution: {integrity: sha512-VrDaW+pjb5IAKEnNWtEaFiG377kXKmk5Fu0Era4W+jKzPON2BW/qRb/4LNHXQ4yxg/2HLm7RiUTn7JZtt1qO6A==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-windows-64@1.20230904.0: + resolution: {integrity: sha512-/R/dE8uy+8J2YeXfDhI8/Bg7YUirdbbjH5/l/Vv00ZRE0lC3nPLcYeyBXSwXIQ6/Xht3gN+lksLQgKd0ZWRd+Q==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workers-types@4.20230904.0: + resolution: {integrity: sha512-IX4oJCe14ctblSPZBlW64BVZ9nYLUo6sD2I5gu3hX0ywByYWm1OuoKm9Xb/Zpbj8Ph18Z7Ryii6u2/ocnncXdA==} + /@envelop/core@3.0.6: resolution: {integrity: sha512-06t1xCPXq6QFN7W1JUEf68aCwYN0OUDNAIoJe7bAqhaoa2vn7NCcuX1VHkJ/OWpmElUgCsRO6RiBbIru1in0Ig==} dependencies: @@ -1429,7 +1559,7 @@ packages: /@envelop/types@3.0.2: resolution: {integrity: sha512-pOFea9ha0EkURWxJ/35axoH9fDGP5S2cUu/5Mmo9pb8zUf+TaEot8vB670XXihFEn/92759BMjLJNWBKmNhyng==} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@envelop/validation-cache@5.1.3(@envelop/core@3.0.6)(graphql@15.8.0): @@ -1442,9 +1572,27 @@ packages: graphql: 15.8.0 hash-it: 6.0.0 lru-cache: 6.0.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false + /@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19): + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + dev: true + + /@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19): + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + dev: true + /@esbuild/android-arm64@0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -1453,6 +1601,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm64@0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64@0.18.17: resolution: {integrity: sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==} engines: {node: '>=12'} @@ -1478,6 +1635,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm@0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.18.17: resolution: {integrity: sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==} engines: {node: '>=12'} @@ -1494,6 +1660,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-x64@0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.18.17: resolution: {integrity: sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==} engines: {node: '>=12'} @@ -1510,6 +1685,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-arm64@0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.18.17: resolution: {integrity: sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==} engines: {node: '>=12'} @@ -1526,6 +1710,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-x64@0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.18.17: resolution: {integrity: sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==} engines: {node: '>=12'} @@ -1542,6 +1735,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-arm64@0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.18.17: resolution: {integrity: sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==} engines: {node: '>=12'} @@ -1558,6 +1760,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-x64@0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.18.17: resolution: {integrity: sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==} engines: {node: '>=12'} @@ -1574,6 +1785,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm64@0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.18.17: resolution: {integrity: sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==} engines: {node: '>=12'} @@ -1590,6 +1810,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm@0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.18.17: resolution: {integrity: sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==} engines: {node: '>=12'} @@ -1606,6 +1835,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ia32@0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.18.17: resolution: {integrity: sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==} engines: {node: '>=12'} @@ -1631,6 +1869,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64@0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.18.17: resolution: {integrity: sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==} engines: {node: '>=12'} @@ -1647,6 +1894,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-mips64el@0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.18.17: resolution: {integrity: sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==} engines: {node: '>=12'} @@ -1663,6 +1919,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ppc64@0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.18.17: resolution: {integrity: sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==} engines: {node: '>=12'} @@ -1679,6 +1944,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-riscv64@0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.18.17: resolution: {integrity: sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==} engines: {node: '>=12'} @@ -1695,6 +1969,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-s390x@0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.18.17: resolution: {integrity: sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==} engines: {node: '>=12'} @@ -1711,6 +1994,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-x64@0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.18.17: resolution: {integrity: sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==} engines: {node: '>=12'} @@ -1727,6 +2019,15 @@ packages: requiresBuild: true optional: true + /@esbuild/netbsd-x64@0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.18.17: resolution: {integrity: sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==} engines: {node: '>=12'} @@ -1743,6 +2044,15 @@ packages: requiresBuild: true optional: true + /@esbuild/openbsd-x64@0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.18.17: resolution: {integrity: sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==} engines: {node: '>=12'} @@ -1759,6 +2069,15 @@ packages: requiresBuild: true optional: true + /@esbuild/sunos-x64@0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.18.17: resolution: {integrity: sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==} engines: {node: '>=12'} @@ -1775,6 +2094,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-arm64@0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.18.17: resolution: {integrity: sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==} engines: {node: '>=12'} @@ -1791,6 +2119,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-ia32@0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.18.17: resolution: {integrity: sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==} engines: {node: '>=12'} @@ -1807,6 +2144,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-x64@0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.18.17: resolution: {integrity: sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==} engines: {node: '>=12'} @@ -1848,7 +2194,7 @@ packages: debug: 4.3.4(supports-color@9.3.1) espree: 9.4.1 globals: 13.19.0 - ignore: 5.2.1 + ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -1865,7 +2211,7 @@ packages: debug: 4.3.4(supports-color@9.3.1) espree: 9.4.1 globals: 13.20.0 - ignore: 5.2.1 + ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -1916,7 +2262,7 @@ packages: dependencies: '@graphql-tools/utils': 9.1.3(graphql@15.8.0) graphql: 15.8.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-tools/merge@8.4.2(graphql@15.8.0): @@ -1926,7 +2272,7 @@ packages: dependencies: '@graphql-tools/utils': 9.2.1(graphql@15.8.0) graphql: 15.8.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-tools/schema@9.0.12(graphql@15.8.0): @@ -1959,7 +2305,7 @@ packages: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: graphql: 15.8.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-tools/utils@9.2.1(graphql@15.8.0): @@ -1969,7 +2315,7 @@ packages: dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@15.8.0) graphql: 15.8.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-typed-document-node/core@3.2.0(graphql@15.8.0): @@ -1983,7 +2329,7 @@ packages: /@graphql-yoga/logger@0.0.1: resolution: {integrity: sha512-6npFz7eZz33mXgSm1waBLMjUNG0D5hTc/p5Hcs1mojkT3KsLpCOFokzTEKboNsBhKevYcaVa/xeA7WBj4UYMLg==} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-yoga/plugin-persisted-operations@1.9.1(@graphql-tools/utils@9.2.1)(graphql-yoga@3.9.1)(graphql@15.8.0): @@ -2004,14 +2350,14 @@ packages: '@graphql-yoga/typed-event-target': 1.0.0 '@repeaterjs/repeater': 3.0.4 '@whatwg-node/events': 0.0.2 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@graphql-yoga/typed-event-target@1.0.0: resolution: {integrity: sha512-Mqni6AEvl3VbpMtKw+TIjc9qS9a8hKhiAjFtqX488yq5oJtj9TkNlFTIacAVS3vnPiswNsmDiQqvwUOcJgi1DA==} dependencies: '@repeaterjs/repeater': 3.0.4 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@humanwhocodes/config-array@0.11.8: @@ -2122,7 +2468,7 @@ packages: resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} dependencies: '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.18 dev: true /@jridgewell/sourcemap-codec@1.4.14: @@ -2150,7 +2496,7 @@ packages: react: 16.14.0 react-dom: 16.14.0 dependencies: - '@types/react': 18.0.37 + '@types/react': 18.2.21 react: 16.14.0 react-dom: 16.14.0(react@16.14.0) dev: true @@ -2330,14 +2676,14 @@ packages: dependencies: asn1js: 3.0.5 pvtsutils: 1.3.2 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@peculiar/json-schema@1.1.12: resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} engines: {node: '>=8.0.0'} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@peculiar/webcrypto@1.4.1: @@ -2347,7 +2693,7 @@ packages: '@peculiar/asn1-schema': 2.3.3 '@peculiar/json-schema': 1.1.12 pvtsutils: 1.3.2 - tslib: 2.5.0 + tslib: 2.6.2 webcrypto-core: 1.7.5 dev: false @@ -2360,7 +2706,7 @@ packages: open: 8.4.0 picocolors: 1.0.0 tiny-glob: 0.2.9 - tslib: 2.5.0 + tslib: 2.6.2 dev: true /@playwright/test@1.30.0: @@ -2424,7 +2770,7 @@ packages: vite: ^4.0.0 dependencies: '@sveltejs/vite-plugin-svelte': 2.0.2(svelte@3.56.0)(vite@4.4.8) - '@types/cookie': 0.5.1 + '@types/cookie': 0.5.2 cookie: 0.5.0 devalue: 4.3.0 esm-env: 1.0.0 @@ -2452,7 +2798,7 @@ packages: vite: ^4.0.0 dependencies: '@sveltejs/vite-plugin-svelte': 2.0.2(svelte@3.57.0)(vite@4.1.1) - '@types/cookie': 0.5.1 + '@types/cookie': 0.5.2 cookie: 0.5.0 devalue: 4.3.0 esm-env: 1.0.0 @@ -2479,7 +2825,7 @@ packages: vite: ^4.0.0 dependencies: '@sveltejs/vite-plugin-svelte': 2.0.2(svelte@3.57.0)(vite@4.1.4) - '@types/cookie': 0.5.1 + '@types/cookie': 0.5.2 cookie: 0.5.0 devalue: 4.3.0 esm-env: 1.0.0 @@ -2554,7 +2900,7 @@ packages: /@swc/helpers@0.4.14: resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: true /@theguild/eslint-config@0.8.0(eslint@8.39.0)(typescript@4.9.4): @@ -2664,8 +3010,8 @@ packages: '@types/keygrip': 1.0.2 dev: true - /@types/cookie@0.5.1: - resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} + /@types/cookie@0.5.2: + resolution: {integrity: sha512-DBpRoJGKJZn7RY92dPrgoMew8xCWc2P71beqsjyhEI/Ds9mOyVmBwtekyfhpwFIVt1WrxTonFifiOZ62V8CnNA==} /@types/cookies@0.7.7: resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} @@ -2844,8 +3190,7 @@ packages: /@types/react-dom@18.0.11: resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==} dependencies: - '@types/react': 18.0.37 - dev: true + '@types/react': 18.2.21 /@types/react@18.0.33: resolution: {integrity: sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==} @@ -2863,6 +3208,13 @@ packages: csstype: 3.1.1 dev: true + /@types/react@18.2.21: + resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.1 + /@types/sass@1.43.1: resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} dependencies: @@ -3382,14 +3734,14 @@ packages: busboy: 1.6.0 fast-querystring: 1.1.1 fast-url-parser: 1.1.3 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@whatwg-node/server@0.7.7: resolution: {integrity: sha512-aHURgNDFm/48WVV3vhTMfnEKCYwYgdaRdRhZsQZx4UVFjGGkGay7Ys0+AYu9QT/jpoImv2oONkstoTMUprDofg==} dependencies: '@whatwg-node/fetch': 0.8.8 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /accepts@1.3.8: @@ -3408,14 +3760,6 @@ packages: acorn: 8.10.0 dev: true - /acorn-jsx@5.3.2(acorn@8.8.1): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.8.1 - dev: true - /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} @@ -3500,6 +3844,10 @@ packages: engines: {node: '>=12'} dev: true + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -3577,6 +3925,12 @@ packages: engines: {node: '>=0.10.0'} dev: true + /as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + dependencies: + printable-characters: 1.0.42 + dev: true + /asn1js@3.0.5: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} @@ -3671,6 +4025,10 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + /better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -3678,11 +4036,37 @@ packages: is-windows: 1.0.2 dev: true + /better-sqlite3@8.6.0: + resolution: {integrity: sha512-jwAudeiTMTSyby+/SfbHDebShbmC2MCH8mU2+DXi0WJfv13ypEJm47cd3kljmy/H130CazEvkf2Li//ewcMJ1g==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.1 + dev: true + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + dev: true + /body-parser@1.20.1: resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -3754,6 +4138,13 @@ packages: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -3764,6 +4155,16 @@ packages: dependencies: semver: 7.5.4 + /bundle-require@4.0.1(esbuild@0.18.17): + resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.18.17 + load-tsconfig: 0.2.5 + dev: true + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -3826,6 +4227,15 @@ packages: /caniuse-lite@1.0.30001441: resolution: {integrity: sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==} + /capnp-ts@0.7.0: + resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + dependencies: + debug: 4.3.4(supports-color@9.3.1) + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + dev: true + /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: true @@ -3909,6 +4319,10 @@ packages: fsevents: 2.3.2 dev: true + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + /ci-info@3.7.0: resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} engines: {node: '>=8'} @@ -4011,6 +4425,11 @@ packages: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + /commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -4493,6 +4912,10 @@ packages: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true + /data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + dev: true + /data-uri-to-buffer@4.0.0: resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} engines: {node: '>= 12'} @@ -4572,6 +4995,13 @@ packages: engines: {node: '>=14.16'} dev: false + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: true + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} @@ -4579,6 +5009,11 @@ packages: type-detect: 4.0.8 dev: true + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -4629,6 +5064,11 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + dev: true + /devalue@4.3.0: resolution: {integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA==} @@ -4732,6 +5172,12 @@ packages: engines: {node: '>= 0.8'} dev: false + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + /enhanced-resolve@5.12.0: resolution: {integrity: sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==} engines: {node: '>=10.13.0'} @@ -5068,6 +5514,36 @@ packages: '@esbuild/win32-ia32': 0.16.17 '@esbuild/win32-x64': 0.16.17 + /esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + /esbuild@0.18.17: resolution: {integrity: sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==} engines: {node: '>=12'} @@ -5192,7 +5668,7 @@ packages: remark-parse: 10.0.1 remark-stringify: 10.0.2 synckit: 0.8.4 - tslib: 2.5.0 + tslib: 2.6.2 unified: 10.1.2 unist-util-visit: 4.1.1 uvu: 0.5.6 @@ -5336,7 +5812,7 @@ packages: remark-mdx: 2.2.1 remark-parse: 10.0.1 remark-stringify: 10.0.2 - tslib: 2.5.0 + tslib: 2.6.2 unified: 10.1.2 vfile: 5.3.6 transitivePeerDependencies: @@ -5723,8 +6199,8 @@ packages: resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.8.1 - acorn-jsx: 5.3.2(acorn@8.8.1) + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.3.0 dev: true @@ -5783,6 +6259,10 @@ packages: '@types/unist': 2.0.6 dev: true + /estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + dev: true + /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -5829,6 +6309,16 @@ packages: strip-final-newline: 3.0.0 dev: false + /exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + dev: true + + /expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: true + /expect@29.4.1: resolution: {integrity: sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5985,6 +6475,10 @@ packages: flat-cache: 3.0.4 dev: true + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -6088,6 +6582,10 @@ packages: engines: {node: '>= 0.6'} dev: false + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -6186,6 +6684,13 @@ packages: engines: {node: '>=8.0.0'} dev: false + /get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + dev: true + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -6202,6 +6707,10 @@ packages: resolution: {integrity: sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==} dev: true + /github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + dev: true + /github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} dev: false @@ -6220,6 +6729,21 @@ packages: is-glob: 4.0.3 dev: true + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -6421,6 +6945,11 @@ packages: resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} dev: true + /hono@3.6.0: + resolution: {integrity: sha512-snkW8naO1WCrQvpAGE/du30Ek0h71gSM3g4RzzdPIB2LQnl12BEwZYH3s2Kssd6kXGORqHmpoyMBMLWtc9nzKQ==} + engines: {node: '>=16.0.0'} + dev: true + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -6429,6 +6958,10 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: true + /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -6483,6 +7016,10 @@ packages: safer-buffer: 2.1.2 dev: true + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + /ignore@5.2.1: resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==} engines: {node: '>= 4'} @@ -6522,6 +7059,10 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + /internal-slot@1.0.4: resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} engines: {node: '>= 0.4'} @@ -6835,6 +7376,10 @@ packages: istanbul-lib-report: 3.0.0 dev: true + /itty-router@4.0.23: + resolution: {integrity: sha512-tP1NI8PVK43vWlBnIPqj47ni5FDSczFviA4wgBznscndo8lEvBA+pO3DD1rNbIQPcZhprr775iUTunyGvQMcBw==} + dev: false + /javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} dev: true @@ -6912,7 +7457,7 @@ packages: '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.20.7) '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.20.7) '@babel/traverse': 7.20.10 - '@babel/types': 7.20.7 + '@babel/types': 7.21.5 '@jest/expect-utils': 29.4.1 '@jest/transform': 29.4.1 '@jest/types': 29.4.1 @@ -6957,6 +7502,11 @@ packages: supports-color: 8.1.1 dev: false + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + /js-sdsl@4.2.0: resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} dev: true @@ -7155,6 +7705,11 @@ packages: wrap-ansi: 7.0.0 dev: true + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -7191,6 +7746,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + /lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true @@ -7810,10 +8369,40 @@ packages: engines: {node: '>=12'} dev: false + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: true + /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + /miniflare@3.20230904.0: + resolution: {integrity: sha512-+OWQqEk8hV7vZaPCoj5dk1lZr4YUy56OiyNZ45/3ITYf+ZxgQOBPWhQhpw1jCahkRKGPa9Aykz01sc+GhPZYDA==} + engines: {node: '>=16.13'} + dependencies: + acorn: 8.10.0 + acorn-walk: 8.2.0 + better-sqlite3: 8.6.0 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + http-cache-semantics: 4.1.1 + kleur: 4.1.5 + source-map-support: 0.5.21 + stoppable: 1.1.0 + undici: 5.24.0 + workerd: 1.20230904.0 + ws: 8.11.0 + youch: 3.3.1 + zod: 3.22.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -7843,6 +8432,10 @@ packages: engines: {node: '>= 8.0.0'} dev: true + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -7884,11 +8477,28 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + /mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -7945,6 +8555,13 @@ packages: - babel-plugin-macros dev: true + /node-abi@3.47.0: + resolution: {integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -7971,6 +8588,11 @@ packages: formdata-polyfill: 4.0.10 dev: false + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: true + /node-html-parser@5.4.2: resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==} dependencies: @@ -8303,6 +8925,10 @@ packages: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: false + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -8345,7 +8971,6 @@ packages: /pirates@4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} - dev: false /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} @@ -8372,6 +8997,22 @@ packages: engines: {node: '>=4'} dev: true + /postcss-load-config@4.0.1: + resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.0.5 + yaml: 2.2.1 + dev: true + /postcss@8.4.14: resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} engines: {node: ^10 || ^12 || >=14} @@ -8389,14 +9030,6 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 - /postcss@8.4.27: - resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 - /postcss@8.4.28: resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==} engines: {node: ^10 || ^12 || >=14} @@ -8404,6 +9037,24 @@ packages: nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 + + /prebuild-install@7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.7 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.47.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 dev: true /preferred-pm@3.0.3: @@ -8455,6 +9106,10 @@ packages: react-is: 18.2.0 dev: false + /printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + dev: true + /prism-svelte@0.4.7: resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==} dev: false @@ -8501,6 +9156,13 @@ packages: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: false @@ -8533,7 +9195,7 @@ packages: /pvtsutils@1.3.2: resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /pvutils@1.1.3: @@ -8589,6 +9251,16 @@ packages: unpipe: 1.0.0 dev: false + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.7 + strip-json-comments: 2.0.1 + dev: true + /react-dom@16.14.0(react@16.14.0): resolution: {integrity: sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==} peerDependencies: @@ -8610,6 +9282,16 @@ packages: react: 18.2.0 scheduler: 0.23.0 + /react-dom@18.3.0-canary-d6dcad6a8-20230914(react@18.3.0-canary-d7a98a5e9-20230517): + resolution: {integrity: sha512-KzS+Jy/WXC6I9bi9PtBU0+iMPHPNvNLdyIDJqgX91AiBP9IDDMjaDbgW0QKphi1qIOesYMeJz0uZkajhlfS8lg==} + peerDependencies: + react: 18.3.0-canary-d6dcad6a8-20230914 + dependencies: + loose-envify: 1.4.0 + react: 18.3.0-canary-d7a98a5e9-20230517 + scheduler: 0.24.0-canary-d6dcad6a8-20230914 + dev: false + /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true @@ -8627,12 +9309,25 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-streaming@0.3.10(react-dom@18.2.0)(react@18.2.0): + /react-streaming@0.3.10(react-dom@18.3.0-canary-d6dcad6a8-20230914)(react@18.3.0-canary-d7a98a5e9-20230517): resolution: {integrity: sha512-Cf/aritzKGDUEBo+jpsNKlzkNBTmBM5gYM9jArPuoBqmckBikALYu7YvQbTHSG4kbpSitnoBIUH2005LAxknBQ==} peerDependencies: react: '>=18' react-dom: '>=18' dependencies: + '@brillout/json-serializer': 0.5.3 + isbot-fast: 1.2.0 + react: 18.3.0-canary-d7a98a5e9-20230517 + react-dom: 18.3.0-canary-d6dcad6a8-20230914(react@18.3.0-canary-d7a98a5e9-20230517) + dev: false + + /react-streaming@0.3.14(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nYTYNp1NjJbEDFiiN/NpuUOhDm94GszLD/aGxXRtbYO2z2GlvL3S/OHjku17+qFfP91IQTF1fcHcvjCKEd3Ong==} + peerDependencies: + react: '>=18' + react-dom: '>=18' + dependencies: + '@brillout/import': 0.2.3 '@brillout/json-serializer': 0.5.3 isbot-fast: 1.2.0 react: 18.2.0 @@ -8666,6 +9361,13 @@ packages: dependencies: loose-envify: 1.4.0 + /react@18.3.0-canary-d7a98a5e9-20230517: + resolution: {integrity: sha512-WCoMOYGg0OR7IoQ9YhubaJ4j7743LBTx4OOcaRuI4wZkshvPIOuVWrZNOarMuKRj8bm/5DKuAV/p2kd74AbQmg==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: false + /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -8707,6 +9409,15 @@ packages: util-deprecate: 1.0.2 dev: true + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -8892,6 +9603,21 @@ packages: resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==} dev: true + /rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + dev: true + + /rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + dependencies: + rollup-plugin-inject: 3.0.2 + dev: true + /rollup-plugin-typescript2@0.34.1(rollup@3.7.4)(typescript@4.9.4): resolution: {integrity: sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw==} peerDependencies: @@ -8907,6 +9633,12 @@ packages: typescript: 4.9.4 dev: false + /rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + dependencies: + estree-walker: 0.6.1 + dev: true + /rollup@3.14.0: resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} @@ -8948,7 +9680,7 @@ packages: /rxjs@7.6.0: resolution: {integrity: sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: true /sade@1.8.1: @@ -8963,7 +9695,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} @@ -9006,6 +9737,19 @@ packages: dependencies: loose-envify: 1.4.0 + /scheduler@0.24.0-canary-d6dcad6a8-20230914: + resolution: {integrity: sha512-tC/9jHWGULTtIk39bb16jrDYyqwz0BHlQlNa3kZYyyFx8JsxioqzT/WoaInIrbkwRaY/zjYzm8IUzE3zH2wKqg==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /selfsigned@2.1.1: + resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} + engines: {node: '>=10'} + dependencies: + node-forge: 1.3.1 + dev: true + /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true @@ -9109,6 +9853,18 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: true + + /simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: true + /sirv@2.0.2: resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} engines: {node: '>= 10'} @@ -9198,6 +9954,18 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + /sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead @@ -9254,6 +10022,13 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true + /stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + dev: true + /statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -9263,6 +10038,11 @@ packages: resolution: {integrity: sha512-3H20QlwQsSm2OvAxWIYhs+j01MzzqwMwGiiO1NQaJYZgJZFPuAbf95/DiKRBSTYIJ2FeGUc+B/6mPGcWP9dO3Q==} dev: true + /stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + dev: true + /stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} dependencies: @@ -9378,6 +10158,11 @@ packages: dependencies: min-indent: 1.0.1 + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -9411,6 +10196,20 @@ packages: resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==} dev: true + /sucrase@3.34.0: + resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + commander: 4.1.1 + glob: 7.1.6 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.5 + ts-interface-checker: 0.1.13 + dev: true + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -9629,7 +10428,7 @@ packages: engines: {node: ^14.18.0 || >=16.0.0} dependencies: '@pkgr/utils': 2.3.1 - tslib: 2.5.0 + tslib: 2.6.2 dev: true /tapable@2.2.1: @@ -9637,6 +10436,26 @@ packages: engines: {node: '>=6'} dev: true + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -9648,7 +10467,7 @@ packages: hasBin: true dependencies: '@jridgewell/source-map': 0.3.2 - acorn: 8.8.1 + acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -9665,6 +10484,19 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true @@ -9723,6 +10555,12 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.0 + dev: true + /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -9741,6 +10579,10 @@ packages: engines: {node: '>=6.10'} dev: true + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + /tsconfig-paths@3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -9762,13 +10604,48 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: false /tsscmp@1.0.6: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} dev: false + /tsup@7.2.0(typescript@4.9.4): + resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==} + engines: {node: '>=16.14'} + hasBin: true + peerDependencies: + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.1.0' + peerDependenciesMeta: + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 4.0.1(esbuild@0.18.17) + cac: 6.7.14 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@9.3.1) + esbuild: 0.18.17 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + postcss-load-config: 4.0.1 + resolve-from: 5.0.0 + rollup: 3.27.1 + source-map: 0.8.0-beta.0 + sucrase: 3.34.0 + tree-kill: 1.2.2 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /tsutils@3.21.0(typescript@4.9.4): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -9793,6 +10670,12 @@ packages: yargs: 17.6.2 dev: true + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /turbo-darwin-64@1.8.8: resolution: {integrity: sha512-18cSeIm7aeEvIxGyq7PVoFyEnPpWDM/0CpZvXKHpQ6qMTkfNt517qVqUTAwsIYqNS8xazcKAqkNbvU1V49n65Q==} cpu: [x64] @@ -9927,6 +10810,13 @@ packages: dependencies: busboy: 1.6.0 + /undici@5.24.0: + resolution: {integrity: sha512-OKlckxBjFl0oXxcj9FU6oB8fDAaiRUq+D8jrFWGmOfI/gIyjk/IeS75LMzgYKUaeHzLUcYvf9bbJGSrUwTfwwQ==} + engines: {node: '>=14.0'} + dependencies: + busboy: 1.6.0 + dev: true + /unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} dependencies: @@ -10267,7 +11157,7 @@ packages: dependencies: '@types/node': 18.11.15 esbuild: 0.18.17 - postcss: 8.4.27 + postcss: 8.4.28 rollup: 3.27.1 optionalDependencies: fsevents: 2.3.2 @@ -10388,13 +11278,17 @@ packages: '@peculiar/json-schema': 1.1.12 asn1js: 3.0.5 pvtsutils: 1.3.2 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -10402,6 +11296,14 @@ packages: webidl-conversions: 3.0.1 dev: true + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -10463,6 +11365,44 @@ packages: engines: {node: '>=0.10.0'} dev: true + /workerd@1.20230904.0: + resolution: {integrity: sha512-t9znszH0rQGK4mJGvF9L3nN0qKEaObAGx0JkywFtAwH8OkSn+YfQbHNZE+YsJ4qa1hOz1DCNEk08UDFRBaYq4g==} + engines: {node: '>=16'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20230904.0 + '@cloudflare/workerd-darwin-arm64': 1.20230904.0 + '@cloudflare/workerd-linux-64': 1.20230904.0 + '@cloudflare/workerd-linux-arm64': 1.20230904.0 + '@cloudflare/workerd-windows-64': 1.20230904.0 + dev: true + + /wrangler@3.7.0: + resolution: {integrity: sha512-7823G5U7WwDIkqaZrxSh/BQ/pxA4WIX3R9GwYfh+MYJj+k5s56KGQ+K/NmY/JbgZsxVEHDjhoYzqDqJebQMZeg==} + engines: {node: '>=16.13.0'} + hasBin: true + dependencies: + '@cloudflare/kv-asset-handler': 0.2.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.5.3 + esbuild: 0.17.19 + miniflare: 3.20230904.0 + nanoid: 3.3.6 + path-to-regexp: 6.2.1 + selfsigned: 2.1.1 + source-map: 0.7.4 + xxhash-wasm: 1.0.2 + optionalDependencies: + fsevents: 2.3.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -10517,7 +11457,10 @@ packages: optional: true utf-8-validate: optional: true - dev: false + + /xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + dev: true /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} @@ -10635,10 +11578,22 @@ packages: engines: {node: '>=12.20'} dev: true + /youch@3.3.1: + resolution: {integrity: sha512-Rg9ioi+AkKyje2Hk4qILSVvayaFW98KTsOJ4aIkjDf97LZX5WJVIHZmFLnM4ThcVofHo/fbbwtYajfBPHFOVtg==} + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 + dev: true + /zencrypt@0.0.7: resolution: {integrity: sha512-UGqj7MySefAgoD8E17cJEsTNhYmjeYnT2Pp++2eC4Vgmc4S1fliFxSn6uAcLqkuPJ7YhD0Un/CW2ZYxrOlpJxw==} dev: true + /zod@3.22.2: + resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} + dev: true + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: true diff --git a/site/src/routes/api/client-plugins/Authoring.svx b/site/src/routes/api/client-plugins/Authoring.svx index 0d8e315063..2135a5ec79 100644 --- a/site/src/routes/api/client-plugins/Authoring.svx +++ b/site/src/routes/api/client-plugins/Authoring.svx @@ -80,7 +80,7 @@ const retry: ClientPlugin = () => { ``` This time we have to use `resolve` instead of `next`. At a high level, `resolve` sends the -send the information back to the server (instead of to the server using `next`). While this does sound kind of +send the information back to the user (instead of to the server using `next`). While this does sound kind of complicated, having this distinction allows us to replay the request if we run into an error relatively easily: ```typescript:title=src/client.ts&typescriptToggle=true diff --git a/tsconfig.json b/tsconfig.json index 0819996037..b6cb288650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,6 @@ "$houdini": ["../houdini/src"], "$houdini/*": ["../houdini/src/*"] }, - "jsx": "react" + "jsx": "react-jsx" } }