test: ssr
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
name: E2E composable + SSR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v4
|
||||
- feat/*
|
||||
- fix/*
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build and test
|
||||
|
||||
env:
|
||||
dir: ./packages/test-e2e-ssr
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2.0.1
|
||||
with:
|
||||
version: 8.6.2
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
|
||||
|
||||
- name: Cache pnpm modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
~/.cache/Cypress
|
||||
key: pnpm-v1-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-v1-${{ runner.os }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: E2E tests
|
||||
working-directory: ${{env.dir}}
|
||||
run: pnpm run test:e2e
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
path: ${{env.dir}}/tests/e2e/screenshots
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-videos
|
||||
path: ${{env.dir}}/tests/e2e/videos
|
||||
@@ -22,19 +22,19 @@
|
||||
"graphql-tag": "^2.12.6",
|
||||
"test-server": "workspace:*",
|
||||
"vue": "^3.3.4",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"vue-router": "^4.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.4.2",
|
||||
"vue-tsc": "^1.8.3",
|
||||
"typescript": "^5.0.2",
|
||||
"cypress-vite": "^1.4.1",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"axios": "^1.4.0",
|
||||
"cypress": "^12.17.0",
|
||||
"cypress-vite": "^1.4.1",
|
||||
"postcss": "^8.4.25",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"postcss": "^8.4.25",
|
||||
"autoprefixer": "^10.4.14"
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.2",
|
||||
"vue-tsc": "^1.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env",
|
||||
"vite/client",
|
||||
"cypress"
|
||||
],
|
||||
"paths": {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
@@ -0,0 +1,5 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
@@ -0,0 +1,27 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
/tests/e2e/videos/
|
||||
/tests/e2e/screenshots/
|
||||
/tests/e2e/downloads/
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -0,0 +1,24 @@
|
||||
# test-e2e-global-composable-vue3
|
||||
|
||||
## Project setup
|
||||
```
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
pnpm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### Run your end-to-end tests
|
||||
```
|
||||
pnpm run test:e2e
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
@@ -0,0 +1,31 @@
|
||||
import { defineConfig } from 'cypress'
|
||||
import vitePreprocessor from 'cypress-vite'
|
||||
import axios from 'axios'
|
||||
|
||||
export default defineConfig({
|
||||
fixturesFolder: 'tests/e2e/fixtures',
|
||||
screenshotsFolder: 'tests/e2e/screenshots',
|
||||
videosFolder: 'tests/e2e/videos',
|
||||
downloadsFolder: 'tests/e2e/downloads',
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:8080',
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents (on) {
|
||||
on('task', {
|
||||
async 'db:reset' () {
|
||||
await axios.get('http://localhost:4042/_reset')
|
||||
return true
|
||||
},
|
||||
|
||||
async 'db:seed' () {
|
||||
await axios.get('http://localhost:4042/_seed')
|
||||
return true
|
||||
},
|
||||
})
|
||||
on('file:preprocessor', vitePreprocessor())
|
||||
},
|
||||
specPattern: 'tests/e2e/specs/**/*.cy.{js,jsx,ts,tsx}',
|
||||
supportFile: 'tests/e2e/support/index.ts',
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>My app</title>
|
||||
<script>window._INITIAL_STATE_ = <!--state--></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-render--></div>
|
||||
<script type="module" src="/src/entry-client.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "test-e2e-ssr",
|
||||
"version": "4.0.0-alpha.16",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "node ./server.mjs",
|
||||
"test": "pnpm run test:e2e",
|
||||
"test:e2e": "start-server-and-test api 'http-get://localhost:4042/graphql?query=%7B__typename%7D' test:e2e:run",
|
||||
"test:e2e:run": "start-server-and-test dev http://localhost:8080 test:e2e:cy",
|
||||
"test:e2e:cy": "cypress run --headless",
|
||||
"test:e2e:dev": "cypress open",
|
||||
"api": "test-server --simulate-latency 50",
|
||||
"api:dev": "test-server --simulate-latency 500"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.16",
|
||||
"@vue/apollo-composable": "workspace:*",
|
||||
"@vue/apollo-util": "workspace:*",
|
||||
"devalue": "^4.3.2",
|
||||
"express": "^4.18.2",
|
||||
"graphql": "^16.7.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"test-server": "workspace:*",
|
||||
"vue": "^3.3.4",
|
||||
"vue-router": "^4.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.6.0",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"axios": "^1.4.0",
|
||||
"cypress": "^12.17.0",
|
||||
"cypress-vite": "^1.4.1",
|
||||
"postcss": "^8.4.25",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.2",
|
||||
"vue-tsc": "^1.8.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import express from 'express'
|
||||
import fs from 'node:fs'
|
||||
import { createServer } from 'vite'
|
||||
import { uneval } from 'devalue'
|
||||
|
||||
const server = express()
|
||||
|
||||
const viteServer = await createServer({
|
||||
server: {
|
||||
middlewareMode: true,
|
||||
},
|
||||
appType: 'custom',
|
||||
})
|
||||
server.use(viteServer.middlewares)
|
||||
|
||||
server.get('*', async (req, res) => {
|
||||
try {
|
||||
const url = req.originalUrl
|
||||
console.log(url)
|
||||
|
||||
let template = fs.readFileSync('./index.html', 'utf8')
|
||||
|
||||
const { render } = await viteServer.ssrLoadModule('/src/entry-server.ts')
|
||||
const { html, context } = await render(url)
|
||||
|
||||
console.log(context)
|
||||
|
||||
template = template
|
||||
.replace('<!--state-->', uneval(context.state))
|
||||
.replace('<!--app-render-->', html)
|
||||
|
||||
res.send(template)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
res.send(e.stack)
|
||||
}
|
||||
})
|
||||
|
||||
server.use(express.static('.'))
|
||||
|
||||
server.listen(8080, () => {
|
||||
console.log('Server is running on http://localhost:8080')
|
||||
})
|
||||
@@ -0,0 +1,35 @@
|
||||
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client/core'
|
||||
import { onError } from '@apollo/client/link/error'
|
||||
import { logErrorMessages } from '@vue/apollo-util'
|
||||
import { isServer } from './env.js'
|
||||
|
||||
export function createApollo () {
|
||||
const cache = new InMemoryCache()
|
||||
|
||||
const restoreCache = !isServer && !!window._INITIAL_STATE_?.apollo
|
||||
if (restoreCache) {
|
||||
cache.restore(window._INITIAL_STATE_.apollo)
|
||||
}
|
||||
|
||||
// HTTP connection to the API
|
||||
const httpLink = createHttpLink({
|
||||
// You should use an absolute URL here
|
||||
uri: 'http://localhost:4042/graphql',
|
||||
})
|
||||
|
||||
// Handle errors
|
||||
const errorLink = onError(error => {
|
||||
logErrorMessages(error)
|
||||
})
|
||||
|
||||
const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
link: errorLink.concat(httpLink),
|
||||
ssrForceFetchDelay: restoreCache ? 100 : undefined,
|
||||
ssrMode: isServer,
|
||||
})
|
||||
|
||||
return {
|
||||
apolloClient,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createApp } from 'vue'
|
||||
import { DefaultApolloClient } from '@vue/apollo-composable'
|
||||
import { createApollo } from './apollo'
|
||||
import App from './components/App.vue'
|
||||
import { createMyRouter } from './router'
|
||||
import '@/assets/styles/tailwind.css'
|
||||
|
||||
export function createMyApp () {
|
||||
const app = createApp(App)
|
||||
|
||||
const { apolloClient } = createApollo()
|
||||
app.provide(DefaultApolloClient, apolloClient)
|
||||
|
||||
const { router } = createMyRouter()
|
||||
app.use(router)
|
||||
|
||||
return {
|
||||
app,
|
||||
router,
|
||||
apolloClient,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@tailwind base;
|
||||
|
||||
@tailwind components;
|
||||
|
||||
@tailwind utilities;
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<GlobalLoading />
|
||||
<div class="flex h-screen items-stretch bg-gray-100">
|
||||
<ChannelList class="w-1/4 border-r border-gray-200" />
|
||||
<router-view class="flex-1 overflow-auto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import ChannelList from './ChannelList.vue'
|
||||
import GlobalLoading from './GlobalLoading.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
|
||||
components: {
|
||||
ChannelList,
|
||||
GlobalLoading,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts" setup>
|
||||
import gql from 'graphql-tag'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { computed } from 'vue'
|
||||
import ClientOnly from './ClientOnly.vue'
|
||||
|
||||
interface Channel {
|
||||
id: string
|
||||
label: string
|
||||
}
|
||||
|
||||
const { result, loading } = useQuery<{
|
||||
channels: Channel[]
|
||||
}>(gql`
|
||||
query channels {
|
||||
channels {
|
||||
id
|
||||
label
|
||||
}
|
||||
}
|
||||
`)
|
||||
const channels = computed(() => result.value?.channels ?? [])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="loading"
|
||||
class="p-12 text-gray-500"
|
||||
>
|
||||
Loading channels...
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col bg-white"
|
||||
>
|
||||
<router-link
|
||||
v-for="channel of channels"
|
||||
:key="channel.id"
|
||||
v-slot="{ href, navigate, isActive }"
|
||||
:to="{
|
||||
name: 'channel',
|
||||
params: {
|
||||
id: channel.id,
|
||||
},
|
||||
}"
|
||||
custom
|
||||
>
|
||||
<a
|
||||
:href="href"
|
||||
class="channel-link px-4 py-2 hover:bg-green-100 text-green-700"
|
||||
:class="{
|
||||
'bg-green-200 hover:bg-green-300 text-green-900': isActive,
|
||||
}"
|
||||
@click="navigate"
|
||||
>
|
||||
# {{ channel.label }}
|
||||
</a>
|
||||
</router-link>
|
||||
|
||||
<div class="mt-auto p-2 text-gray-500">
|
||||
<ClientOnly>
|
||||
Client loaded ✅
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,108 @@
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import { defineComponent, onMounted, ref, watch, computed } from 'vue'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import MessageItem from './MessageItem.vue'
|
||||
import MessageForm from './MessageForm.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MessageItem,
|
||||
MessageForm,
|
||||
},
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup (props) {
|
||||
const { result, loading, refetch } = useQuery(gql`
|
||||
query channel ($id: ID!) {
|
||||
channel (id: $id) {
|
||||
id
|
||||
label
|
||||
messages {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
`, () => ({
|
||||
id: props.id,
|
||||
}), {
|
||||
notifyOnNetworkStatusChange: true,
|
||||
})
|
||||
const channel = computed(() => result.value?.channel)
|
||||
|
||||
const messagesEl = ref()
|
||||
|
||||
function scrollToBottom () {
|
||||
if (!messagesEl.value) return
|
||||
messagesEl.value.scrollTop = messagesEl.value.scrollHeight
|
||||
}
|
||||
|
||||
watch(() => channel.value?.messages, () => {
|
||||
scrollToBottom()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
scrollToBottom()
|
||||
})
|
||||
|
||||
return {
|
||||
loading,
|
||||
refetch,
|
||||
channel,
|
||||
messagesEl,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
v-if="loading"
|
||||
class="loading-channel fixed top-0 left-0 w-full flex"
|
||||
>
|
||||
<div class="px-4 py-2 rounded-b mx-auto bg-white border-b border-l border-r border-gray-200">
|
||||
Loading channel...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="channel"
|
||||
class="flex flex-col h-full"
|
||||
>
|
||||
<div class="flex-none p-6 border-b border-gray-200 bg-white">
|
||||
Currently viewing # {{ channel.label }}
|
||||
|
||||
<a
|
||||
class="text-green-500 cursor-pointer"
|
||||
data-test-id="refetch"
|
||||
@click="refetch()"
|
||||
>Refetch</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref="messagesEl"
|
||||
class="flex-1 overflow-y-auto"
|
||||
>
|
||||
<MessageItem
|
||||
v-for="message of channel.messages"
|
||||
:key="message.id"
|
||||
:message="message"
|
||||
class="m-2"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MessageForm
|
||||
:channel-id="channel.id"
|
||||
class="flex-none m-2 mt-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const displayed = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
displayed.value = true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<slot v-if="displayed" />
|
||||
</template>
|
||||
@@ -0,0 +1,16 @@
|
||||
<script lang="ts" setup>
|
||||
import { useGlobalQueryLoading } from '@vue/apollo-composable'
|
||||
|
||||
const loading = useGlobalQueryLoading()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="fixed bg-white p-4 rounded-br top-0 right-0"
|
||||
data-test-id="global-loading"
|
||||
>
|
||||
<div v-if="loading">
|
||||
Global loading...
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,68 @@
|
||||
<script lang="ts">
|
||||
import gql from 'graphql-tag'
|
||||
import { useLazyQuery } from '@vue/apollo-composable'
|
||||
import { defineComponent, computed, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const { result, loading, load, refetch } = useLazyQuery(gql`
|
||||
query list {
|
||||
list
|
||||
}
|
||||
`)
|
||||
const list = computed(() => result.value?.list ?? [])
|
||||
|
||||
const refetched = ref(false)
|
||||
|
||||
function r () {
|
||||
refetched.value = true
|
||||
refetch()
|
||||
}
|
||||
|
||||
function loadOrRefetch () {
|
||||
load() || r()
|
||||
}
|
||||
|
||||
return {
|
||||
loadOrRefetch,
|
||||
loading,
|
||||
list,
|
||||
refetched,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="m-6">
|
||||
<div>
|
||||
<button
|
||||
class="bg-green-200 rounded-lg p-4"
|
||||
@click="loadOrRefetch()"
|
||||
>
|
||||
Load list
|
||||
</button>
|
||||
|
||||
<span data-test-id="refetched">
|
||||
Refetched: {{ refetched }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="loading"
|
||||
class="loading"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<ul class="my-4">
|
||||
<li
|
||||
v-for="(item, index) of list"
|
||||
:key="index"
|
||||
class="list-disc ml-6"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
import gql from 'graphql-tag'
|
||||
import { useLazyQuery } from '@vue/apollo-composable'
|
||||
import { defineComponent, computed, reactive } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const { result, loading, load } = useLazyQuery(gql`
|
||||
query channel ($id: ID!) {
|
||||
channel (id: $id) {
|
||||
id
|
||||
label
|
||||
messages {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`, {
|
||||
id: 'general',
|
||||
})
|
||||
const channel = computed(() => result.value?.channel)
|
||||
|
||||
load(undefined, {
|
||||
id: 'general',
|
||||
})
|
||||
|
||||
return {
|
||||
loading,
|
||||
channel,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="m-6">
|
||||
<div
|
||||
v-if="loading"
|
||||
class="loading"
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div v-if="channel">
|
||||
<div>Loaded channel: {{ channel.label }}</div>
|
||||
<div>Messages: {{ channel.messages.length }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,76 @@
|
||||
<script lang="ts">
|
||||
import gql from 'graphql-tag'
|
||||
import { useMutation } from '@vue/apollo-composable'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
channelId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup (props) {
|
||||
const text = ref('')
|
||||
|
||||
const { mutate } = useMutation(gql`
|
||||
mutation sendMessage ($input: AddMessageInput!) {
|
||||
message: addMessage (input: $input) {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
`, {
|
||||
update: (cache, { data: { message } }) => {
|
||||
cache.modify({
|
||||
id: cache.identify({
|
||||
__typename: 'Channel',
|
||||
id: props.channelId,
|
||||
}),
|
||||
fields: {
|
||||
messages: (existingMessages = []) => [
|
||||
...existingMessages,
|
||||
message,
|
||||
],
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
async function sendMessage () {
|
||||
await mutate({
|
||||
input: {
|
||||
channelId: props.channelId,
|
||||
text: text.value,
|
||||
},
|
||||
}, {
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
message: {
|
||||
id: Date.now().toString(),
|
||||
text: text.value,
|
||||
},
|
||||
},
|
||||
})
|
||||
text.value = ''
|
||||
}
|
||||
|
||||
return {
|
||||
text,
|
||||
sendMessage,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border border-gray-200 rounded-lg bg-white">
|
||||
<input
|
||||
v-model="text"
|
||||
placeholder="Type a message..."
|
||||
class="w-full px-4 py-2 bg-transparent"
|
||||
@keyup.enter="sendMessage()"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="message inline-block bg-green-100 border border-green-200 rounded-2xl px-4 py-2">
|
||||
{{ message.text }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center">
|
||||
Welcome
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface Context {
|
||||
state: {
|
||||
apollo?: any
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_INITIAL_STATE_: Context['state']
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { createMyApp } from './app.js'
|
||||
|
||||
const { app, router } = createMyApp()
|
||||
|
||||
router.isReady().then(() => {
|
||||
app.mount('#app')
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'isomorphic-fetch'
|
||||
import { renderToString } from 'vue/server-renderer'
|
||||
import { createMyApp } from './app.js'
|
||||
import { Context } from '@apollo/client'
|
||||
|
||||
export async function render (url: string) {
|
||||
const {
|
||||
app,
|
||||
router,
|
||||
apolloClient,
|
||||
} = await createMyApp()
|
||||
|
||||
await router.push(url)
|
||||
await router.isReady()
|
||||
|
||||
const context: Context = {
|
||||
state: {},
|
||||
}
|
||||
|
||||
const html = await renderToString(app, context)
|
||||
|
||||
context.state.apollo = apolloClient.extract()
|
||||
|
||||
return {
|
||||
html,
|
||||
context,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const isServer = typeof window === 'undefined'
|
||||
@@ -0,0 +1,33 @@
|
||||
import { createRouter, createWebHistory, createMemoryHistory } from 'vue-router'
|
||||
import { isServer } from './env.js'
|
||||
|
||||
export function createMyRouter () {
|
||||
const router = createRouter({
|
||||
history: isServer ? createMemoryHistory() : createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('./components/Welcome.vue'),
|
||||
},
|
||||
{
|
||||
path: '/channel/:id',
|
||||
name: 'channel',
|
||||
component: () => import('./components/ChannelView.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/lazy-query',
|
||||
component: () => import('./components/LazyQuery.vue'),
|
||||
},
|
||||
{
|
||||
path: '/lazy-query-immediately',
|
||||
component: () => import('./components/LazyQueryImmediately.vue'),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
return {
|
||||
router,
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent
|
||||
export default component
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'cypress',
|
||||
],
|
||||
env: {
|
||||
mocha: true,
|
||||
'cypress/globals': true,
|
||||
},
|
||||
rules: {
|
||||
strict: 'off',
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
describe('Vue 3 + Apollo Composable', () => {
|
||||
beforeEach(() => {
|
||||
cy.task('db:seed')
|
||||
})
|
||||
|
||||
it('loads channels', () => {
|
||||
cy.intercept('http://localhost:4042/graphql', (req) => {
|
||||
throw new Error('Should not be called')
|
||||
})
|
||||
cy.visit('/')
|
||||
cy.contains('#app', 'Client loaded')
|
||||
cy.get('#app').should('not.contain', 'Loading channels...')
|
||||
cy.get('.channel-link').should('have.lengthOf', 2)
|
||||
cy.contains('.channel-link', '# General')
|
||||
cy.contains('.channel-link', '# Random')
|
||||
})
|
||||
|
||||
it('load one channel', () => {
|
||||
let shouldCallGraphQL = false
|
||||
cy.intercept('http://localhost:4042/graphql', (req) => {
|
||||
if (!shouldCallGraphQL) {
|
||||
throw new Error('Should not be called')
|
||||
}
|
||||
})
|
||||
cy.visit('/channel/general')
|
||||
cy.contains('#app', 'Client loaded')
|
||||
cy.contains('#app', 'Currently viewing # General')
|
||||
cy.get('.message').should('have.lengthOf', 2)
|
||||
cy.contains('.message', 'Meow?')
|
||||
cy.contains('.message', 'Meow!')
|
||||
shouldCallGraphQL = true
|
||||
cy.get('.channel-link').eq(1).click()
|
||||
cy.get('[data-test-id="global-loading"]').should('contain', 'Global loading...')
|
||||
cy.contains('#app', 'Currently viewing # Random')
|
||||
cy.get('.message').should('have.lengthOf', 1)
|
||||
cy.contains('.message', 'Hello world!')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"vite/client",
|
||||
"cypress",
|
||||
"node"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { resolve } from 'path'
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, './src'),
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -27,4 +27,26 @@ export function resetDatabase (): void {
|
||||
]
|
||||
}
|
||||
|
||||
export function seedDatabase (): void {
|
||||
channels[0].messages = [
|
||||
{
|
||||
id: '1',
|
||||
channel: channels[0],
|
||||
text: 'Meow?',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
channel: channels[0],
|
||||
text: 'Meow!',
|
||||
},
|
||||
]
|
||||
channels[1].messages = [
|
||||
{
|
||||
id: '3',
|
||||
channel: channels[1],
|
||||
text: 'Hello world!',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
resetDatabase()
|
||||
|
||||
@@ -7,7 +7,7 @@ import { expressMiddleware } from '@apollo/server/express4'
|
||||
import { WebSocketServer } from 'ws'
|
||||
import { useServer } from 'graphql-ws/lib/use/ws'
|
||||
import { schema } from './schema.js'
|
||||
import { resetDatabase } from './data.js'
|
||||
import { resetDatabase, seedDatabase } from './data.js'
|
||||
import { simulateLatency } from './util.js'
|
||||
|
||||
const app = express()
|
||||
@@ -23,6 +23,11 @@ app.get('/_reset', (req, res) => {
|
||||
res.status(200).end()
|
||||
})
|
||||
|
||||
app.get('/_seed', (req, res) => {
|
||||
seedDatabase()
|
||||
res.status(200).end()
|
||||
})
|
||||
|
||||
const server = new ApolloServer({
|
||||
schema,
|
||||
plugins: [
|
||||
|
||||
Generated
+153
-41
@@ -177,9 +177,6 @@ importers:
|
||||
'@apollo/client':
|
||||
specifier: ^3.7.16
|
||||
version: 3.7.16(graphql@16.7.1)
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(vite@4.4.2)(vue@3.3.4)
|
||||
'@vue/apollo-composable':
|
||||
specifier: workspace:*
|
||||
version: link:../vue-apollo-composable
|
||||
@@ -202,6 +199,9 @@ importers:
|
||||
specifier: ^4.2.4
|
||||
version: 4.2.4(vue@3.3.4)
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(vite@4.4.2)(vue@3.3.4)
|
||||
autoprefixer:
|
||||
specifier: ^10.4.14
|
||||
version: 10.4.14(postcss@8.4.25)
|
||||
@@ -228,7 +228,80 @@ importers:
|
||||
version: 5.0.2
|
||||
vite:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2
|
||||
version: 4.4.2(@types/node@20.6.0)
|
||||
vue-tsc:
|
||||
specifier: ^1.8.3
|
||||
version: 1.8.3(typescript@5.0.2)
|
||||
|
||||
packages/test-e2e-ssr:
|
||||
dependencies:
|
||||
'@apollo/client':
|
||||
specifier: ^3.7.16
|
||||
version: 3.7.16(graphql@16.7.1)
|
||||
'@vue/apollo-composable':
|
||||
specifier: workspace:*
|
||||
version: link:../vue-apollo-composable
|
||||
'@vue/apollo-util':
|
||||
specifier: workspace:*
|
||||
version: link:../vue-apollo-util
|
||||
devalue:
|
||||
specifier: ^4.3.2
|
||||
version: 4.3.2
|
||||
express:
|
||||
specifier: ^4.18.2
|
||||
version: 4.18.2
|
||||
graphql:
|
||||
specifier: ^16.7.1
|
||||
version: 16.7.1
|
||||
graphql-tag:
|
||||
specifier: ^2.12.6
|
||||
version: 2.12.6(graphql@16.7.1)
|
||||
isomorphic-fetch:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
test-server:
|
||||
specifier: workspace:*
|
||||
version: link:../test-server
|
||||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4
|
||||
vue-router:
|
||||
specifier: ^4.2.4
|
||||
version: 4.2.4(vue@3.3.4)
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^20.6.0
|
||||
version: 20.6.0
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(vite@4.4.2)(vue@3.3.4)
|
||||
autoprefixer:
|
||||
specifier: ^10.4.14
|
||||
version: 10.4.14(postcss@8.4.25)
|
||||
axios:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
cypress:
|
||||
specifier: ^12.17.0
|
||||
version: 12.17.0
|
||||
cypress-vite:
|
||||
specifier: ^1.4.1
|
||||
version: 1.4.1(vite@4.4.2)
|
||||
postcss:
|
||||
specifier: ^8.4.25
|
||||
version: 8.4.25
|
||||
start-server-and-test:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
tailwindcss:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
typescript:
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
vite:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2(@types/node@20.6.0)
|
||||
vue-tsc:
|
||||
specifier: ^1.8.3
|
||||
version: 1.8.3(typescript@5.0.2)
|
||||
@@ -1280,7 +1353,7 @@ packages:
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.1
|
||||
resolve: 1.22.2
|
||||
semver: 6.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -1296,7 +1369,7 @@ packages:
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.1
|
||||
resolve: 1.22.2
|
||||
semver: 6.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -3431,6 +3504,7 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.18.11:
|
||||
@@ -3439,6 +3513,7 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-x64@0.18.11:
|
||||
@@ -3447,6 +3522,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-arm64@0.18.11:
|
||||
@@ -3455,6 +3531,7 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-x64@0.18.11:
|
||||
@@ -3463,6 +3540,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-arm64@0.18.11:
|
||||
@@ -3471,6 +3549,7 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-x64@0.18.11:
|
||||
@@ -3479,6 +3558,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm64@0.18.11:
|
||||
@@ -3487,6 +3567,7 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm@0.18.11:
|
||||
@@ -3495,6 +3576,7 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ia32@0.18.11:
|
||||
@@ -3503,6 +3585,7 @@ packages:
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.14.54:
|
||||
@@ -3520,6 +3603,7 @@ packages:
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-mips64el@0.18.11:
|
||||
@@ -3528,6 +3612,7 @@ packages:
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ppc64@0.18.11:
|
||||
@@ -3536,6 +3621,7 @@ packages:
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-riscv64@0.18.11:
|
||||
@@ -3544,6 +3630,7 @@ packages:
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-s390x@0.18.11:
|
||||
@@ -3552,6 +3639,7 @@ packages:
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-x64@0.18.11:
|
||||
@@ -3560,6 +3648,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/netbsd-x64@0.18.11:
|
||||
@@ -3568,6 +3657,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-x64@0.18.11:
|
||||
@@ -3576,6 +3666,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/sunos-x64@0.18.11:
|
||||
@@ -3584,6 +3675,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-arm64@0.18.11:
|
||||
@@ -3592,6 +3684,7 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-ia32@0.18.11:
|
||||
@@ -3600,6 +3693,7 @@ packages:
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-x64@0.18.11:
|
||||
@@ -3608,6 +3702,7 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@eslint/eslintrc@0.4.3:
|
||||
@@ -4135,7 +4230,7 @@ packages:
|
||||
/@types/accepts@1.3.5:
|
||||
resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/babel__core@7.20.0:
|
||||
@@ -4171,32 +4266,32 @@ packages:
|
||||
resolution: {integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==}
|
||||
dependencies:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/body-parser@1.19.2:
|
||||
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
|
||||
dependencies:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
|
||||
/@types/bonjour@3.5.10:
|
||||
resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/connect-history-api-fallback@1.3.5:
|
||||
resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==}
|
||||
dependencies:
|
||||
'@types/express-serve-static-core': 4.17.33
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/connect@3.4.35:
|
||||
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
|
||||
/@types/content-disposition@0.5.5:
|
||||
resolution: {integrity: sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==}
|
||||
@@ -4208,7 +4303,7 @@ packages:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/express': 4.17.17
|
||||
'@types/keygrip': 1.0.2
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/cors@2.8.10:
|
||||
@@ -4218,7 +4313,7 @@ packages:
|
||||
/@types/cors@2.8.13:
|
||||
resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/eslint-scope@3.7.4:
|
||||
@@ -4246,7 +4341,7 @@ packages:
|
||||
/@types/express-serve-static-core@4.17.33:
|
||||
resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
'@types/qs': 6.9.7
|
||||
'@types/range-parser': 1.2.4
|
||||
|
||||
@@ -4261,7 +4356,7 @@ packages:
|
||||
/@types/fs-capacitor@2.0.0:
|
||||
resolution: {integrity: sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/graphql@14.5.0:
|
||||
@@ -4286,7 +4381,7 @@ packages:
|
||||
/@types/http-proxy@1.17.9:
|
||||
resolution: {integrity: sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/istanbul-lib-coverage@2.0.4:
|
||||
@@ -4321,7 +4416,7 @@ packages:
|
||||
/@types/keyv@3.1.4:
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/koa-compose@3.2.5:
|
||||
@@ -4340,7 +4435,7 @@ packages:
|
||||
'@types/http-errors': 2.0.1
|
||||
'@types/keygrip': 1.0.2
|
||||
'@types/koa-compose': 3.2.5
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/long@4.0.2:
|
||||
@@ -4357,7 +4452,7 @@ packages:
|
||||
/@types/node-fetch@2.6.4:
|
||||
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
form-data: 3.0.1
|
||||
dev: false
|
||||
|
||||
@@ -4369,8 +4464,8 @@ packages:
|
||||
resolution: {integrity: sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==}
|
||||
dev: true
|
||||
|
||||
/@types/node@18.14.0:
|
||||
resolution: {integrity: sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==}
|
||||
/@types/node@20.6.0:
|
||||
resolution: {integrity: sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==}
|
||||
|
||||
/@types/normalize-package-data@2.4.1:
|
||||
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
|
||||
@@ -4389,13 +4484,13 @@ packages:
|
||||
/@types/resolve@0.0.8:
|
||||
resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/responselike@1.0.0:
|
||||
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/retry@0.12.0:
|
||||
@@ -4416,7 +4511,7 @@ packages:
|
||||
resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==}
|
||||
dependencies:
|
||||
'@types/mime': 3.0.1
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
|
||||
/@types/shortid@0.0.29:
|
||||
resolution: {integrity: sha512-9BCYD9btg2CY4kPcpMQ+vCR8U6V8f/KvixYD5ZbxoWlkhddNF5IeZMVL3p+QFUkg+Hb+kPAG9Jgk4bnnF1v/Fw==}
|
||||
@@ -4433,7 +4528,7 @@ packages:
|
||||
/@types/sockjs@0.3.33:
|
||||
resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/stack-utils@1.0.1:
|
||||
@@ -4447,13 +4542,13 @@ packages:
|
||||
/@types/ws@7.4.7:
|
||||
resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: false
|
||||
|
||||
/@types/ws@8.5.5:
|
||||
resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
|
||||
/@types/yargs-parser@21.0.0:
|
||||
@@ -4470,7 +4565,7 @@ packages:
|
||||
resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
@@ -4605,9 +4700,9 @@ packages:
|
||||
vite: ^4.0.0
|
||||
vue: '*'
|
||||
dependencies:
|
||||
vite: 4.4.2
|
||||
vite: 4.4.2(@types/node@20.6.0)
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
dev: true
|
||||
|
||||
/@volar/language-core@1.7.10:
|
||||
resolution: {integrity: sha512-18Gmth5M0UI3hDDqhZngjMnb6WCslcfglkOdepRIhGxRYe7xR7DRRzciisYDMZsvOQxDYme+uaohg0dKUxLV2Q==}
|
||||
@@ -4693,7 +4788,7 @@ packages:
|
||||
babel-plugin-dynamic-import-node: 2.3.3
|
||||
core-js: 3.28.0
|
||||
core-js-compat: 3.28.0
|
||||
semver: 7.3.8
|
||||
semver: 7.5.4
|
||||
vue: 3.2.47
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -5012,7 +5107,7 @@ packages:
|
||||
open: 8.4.2
|
||||
ora: 5.4.1
|
||||
read-pkg: 5.2.0
|
||||
semver: 7.3.8
|
||||
semver: 7.5.4
|
||||
strip-ansi: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -7801,7 +7896,7 @@ packages:
|
||||
dependencies:
|
||||
chokidar: 3.5.3
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
vite: 4.4.2
|
||||
vite: 4.4.2(@types/node@20.6.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -8105,6 +8200,10 @@ packages:
|
||||
resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
|
||||
dev: true
|
||||
|
||||
/devalue@4.3.2:
|
||||
resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==}
|
||||
dev: false
|
||||
|
||||
/dicer@0.3.0:
|
||||
resolution: {integrity: sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==}
|
||||
engines: {node: '>=4.5.0'}
|
||||
@@ -8657,6 +8756,7 @@ packages:
|
||||
'@esbuild/win32-arm64': 0.18.11
|
||||
'@esbuild/win32-ia32': 0.18.11
|
||||
'@esbuild/win32-x64': 0.18.11
|
||||
dev: true
|
||||
|
||||
/esbuild@0.8.57:
|
||||
resolution: {integrity: sha512-j02SFrUwFTRUqiY0Kjplwjm1psuzO1d6AjaXKuOR9hrY0HuPsT6sV42B6myW34h1q4CRy+Y3g4RU/cGJeI/nNA==}
|
||||
@@ -9557,6 +9657,7 @@ packages:
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/function-bind@1.1.1:
|
||||
@@ -10799,6 +10900,15 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/isomorphic-fetch@3.0.0:
|
||||
resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==}
|
||||
dependencies:
|
||||
node-fetch: 2.6.9
|
||||
whatwg-fetch: 3.6.2
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/isstream@0.1.2:
|
||||
resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
|
||||
dev: true
|
||||
@@ -11265,7 +11375,7 @@ packages:
|
||||
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
dev: true
|
||||
@@ -11847,7 +11957,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/media-typer@0.3.0:
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
/memfs@3.4.13:
|
||||
@@ -11879,7 +11989,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/merge-descriptors@1.0.1:
|
||||
resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
|
||||
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
|
||||
|
||||
/merge-source-map@1.1.0:
|
||||
resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==}
|
||||
@@ -12222,7 +12332,7 @@ packages:
|
||||
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
||||
dependencies:
|
||||
hosted-git-info: 2.8.9
|
||||
resolve: 1.22.1
|
||||
resolve: 1.22.2
|
||||
semver: 5.7.1
|
||||
validate-npm-package-license: 3.0.4
|
||||
dev: true
|
||||
@@ -14154,7 +14264,7 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/estree': 1.0.0
|
||||
'@types/node': 18.14.0
|
||||
'@types/node': 20.6.0
|
||||
acorn: 7.4.1
|
||||
dev: true
|
||||
|
||||
@@ -14172,6 +14282,7 @@ packages:
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/rsvp@4.8.5:
|
||||
resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==}
|
||||
@@ -15700,7 +15811,7 @@ packages:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vite@4.4.2:
|
||||
/vite@4.4.2(@types/node@20.6.0):
|
||||
resolution: {integrity: sha512-zUcsJN+UvdSyHhYa277UHhiJ3iq4hUBwHavOpsNUGsTgjBeoBlK8eDt+iT09pBq0h9/knhG/SPrZiM7cGmg7NA==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
@@ -15728,11 +15839,13 @@ packages:
|
||||
terser:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/node': 20.6.0
|
||||
esbuild: 0.18.11
|
||||
postcss: 8.4.25
|
||||
rollup: 3.26.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vitepress@0.22.4:
|
||||
resolution: {integrity: sha512-oZUnLO/SpYdThaBKefDeOiVlr0Rie4Ppx3FzMnMyLtJnI5GlBMNjqYqMy/4+umm/iC+ZDJfI+IlDKxv5fZnYzA==}
|
||||
@@ -16239,7 +16352,6 @@ packages:
|
||||
|
||||
/whatwg-fetch@3.6.2:
|
||||
resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==}
|
||||
dev: true
|
||||
|
||||
/whatwg-mimetype@2.3.0:
|
||||
resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==}
|
||||
|
||||
Reference in New Issue
Block a user