@quilted/create 0.1.78 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/build/cjs/app.cjs +8 -10
- package/build/esm/app.mjs +8 -10
- package/build/esnext/app.esnext +8 -10
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/shared.d.ts +1 -1
- package/build/typescript/shared.d.ts.map +1 -1
- package/package.json +1 -1
- package/source/app.ts +16 -18
- package/source/shared.ts +0 -2
- package/templates/app-basic/App.tsx +37 -13
- package/templates/app-basic/browser.tsx +2 -2
- package/templates/app-basic/features/start/Start/Start.tsx +5 -0
- package/templates/app-basic/features/start.ts +5 -0
- package/templates/app-basic/foundation/frame/Frame.module.css +14 -0
- package/templates/app-basic/foundation/frame/Frame.tsx +7 -0
- package/templates/app-basic/foundation/frame.ts +1 -0
- package/templates/app-basic/foundation/{Head → html}/Head.test.tsx +4 -4
- package/templates/app-basic/foundation/html.ts +1 -0
- package/templates/{app-trpc/foundation/Http/Http.test.tsx → app-basic/foundation/http/Headers.test.tsx} +8 -8
- package/templates/app-basic/foundation/{Http/Http.tsx → http/Headers.tsx} +3 -3
- package/templates/app-basic/foundation/http.ts +1 -0
- package/templates/app-basic/server.tsx +18 -15
- package/templates/app-basic/shared/context.ts +1 -6
- package/templates/app-basic/tests/render/render.tsx +12 -12
- package/templates/app-basic/tests/render/types.ts +3 -5
- package/templates/app-basic/tests/render.ts +2 -2
- package/templates/app-basic/tsconfig.json +1 -1
- package/templates/app-empty/App.tsx +1 -1
- package/templates/app-empty/browser.tsx +1 -1
- package/templates/app-empty/server.tsx +18 -14
- package/templates/app-empty/tsconfig.json +1 -1
- package/templates/app-graphql/App.tsx +36 -26
- package/templates/app-graphql/browser.tsx +2 -2
- package/templates/app-graphql/features/{Start → start/Start}/Start.test.tsx +3 -7
- package/templates/app-graphql/features/start/Start/Start.tsx +14 -0
- package/templates/app-graphql/features/start.ts +5 -0
- package/templates/app-graphql/foundation/frame/Frame.module.css +14 -0
- package/templates/app-graphql/foundation/frame/Frame.tsx +7 -0
- package/templates/app-graphql/foundation/frame.ts +1 -0
- package/templates/{app-trpc/foundation/Head → app-graphql/foundation/html}/Head.test.tsx +4 -4
- package/templates/app-graphql/foundation/html.ts +1 -0
- package/templates/{app-basic/foundation/Http/Http.test.tsx → app-graphql/foundation/http/Headers.test.tsx} +8 -8
- package/templates/app-graphql/foundation/{Http/Http.tsx → http/Headers.tsx} +3 -3
- package/templates/app-graphql/foundation/http.ts +1 -0
- package/templates/app-graphql/graphql/schema.graphql +4 -2
- package/templates/app-graphql/server/graphql.ts +9 -4
- package/templates/app-graphql/server.tsx +36 -33
- package/templates/app-graphql/shared/context.ts +1 -6
- package/templates/app-graphql/tests/graphql.ts +3 -4
- package/templates/app-graphql/tests/render/render.tsx +16 -15
- package/templates/app-graphql/tests/render/types.ts +9 -10
- package/templates/app-graphql/tests/render.ts +2 -3
- package/templates/app-graphql/tsconfig.json +1 -1
- package/templates/app-trpc/App.tsx +39 -33
- package/templates/app-trpc/browser.tsx +2 -2
- package/templates/app-trpc/features/{Start → start/Start}/Start.test.tsx +2 -2
- package/templates/app-trpc/features/start/Start/Start.tsx +9 -0
- package/templates/app-trpc/features/start.ts +5 -0
- package/templates/app-trpc/foundation/frame/Frame.module.css +14 -0
- package/templates/app-trpc/foundation/frame/Frame.tsx +7 -0
- package/templates/app-trpc/foundation/frame.ts +1 -0
- package/templates/{app-graphql/foundation/Head → app-trpc/foundation/html}/Head.test.tsx +4 -4
- package/templates/app-trpc/foundation/html.ts +1 -0
- package/templates/{app-graphql/foundation/Http/Http.test.tsx → app-trpc/foundation/http/Headers.test.tsx} +8 -8
- package/templates/app-trpc/foundation/{Http/Http.tsx → http/Headers.tsx} +3 -3
- package/templates/app-trpc/foundation/http.ts +1 -0
- package/templates/app-trpc/server.tsx +20 -13
- package/templates/app-trpc/shared/context.ts +1 -6
- package/templates/app-trpc/tests/render/render.tsx +17 -16
- package/templates/app-trpc/tsconfig.json +1 -1
- package/templates/service-basic/service.ts +2 -2
- package/templates/app-basic/features/Start/Start.tsx +0 -12
- package/templates/app-basic/features/Start.tsx +0 -3
- package/templates/app-basic/foundation/Head.tsx +0 -1
- package/templates/app-basic/foundation/Http.tsx +0 -1
- package/templates/app-basic/foundation/Metrics/Metrics.tsx +0 -23
- package/templates/app-basic/foundation/Metrics.tsx +0 -1
- package/templates/app-graphql/features/Start/Start.tsx +0 -20
- package/templates/app-graphql/features/Start.tsx +0 -3
- package/templates/app-graphql/foundation/Head.tsx +0 -1
- package/templates/app-graphql/foundation/Http.tsx +0 -1
- package/templates/app-graphql/foundation/Metrics/Metrics.tsx +0 -23
- package/templates/app-graphql/foundation/Metrics.tsx +0 -1
- package/templates/app-single-file/App.tsx +0 -199
- package/templates/app-single-file/package.json +0 -35
- package/templates/app-single-file/quilt.project.ts +0 -5
- package/templates/app-single-file/tsconfig.json +0 -9
- package/templates/app-trpc/features/Start/Start.tsx +0 -16
- package/templates/app-trpc/features/Start.tsx +0 -3
- package/templates/app-trpc/foundation/Head.tsx +0 -1
- package/templates/app-trpc/foundation/Http.tsx +0 -1
- package/templates/app-trpc/foundation/Metrics/Metrics.tsx +0 -23
- package/templates/app-trpc/foundation/Metrics.tsx +0 -1
- /package/templates/app-basic/features/{Start → start/Start}/Start.module.css +0 -0
- /package/templates/app-basic/features/{Start → start/Start}/Start.test.tsx +0 -0
- /package/templates/app-basic/foundation/{Head → html}/Head.tsx +0 -0
- /package/templates/app-graphql/features/{Start → start/Start}/Start.module.css +0 -0
- /package/templates/app-graphql/features/{Start → start/Start}/StartQuery.graphql +0 -0
- /package/templates/app-graphql/foundation/{Head → html}/Head.tsx +0 -0
- /package/templates/app-trpc/features/{Start → start/Start}/Start.module.css +0 -0
- /package/templates/app-trpc/foundation/{Head → html}/Head.tsx +0 -0
|
@@ -1,50 +1,53 @@
|
|
|
1
|
-
import '@quilted/quilt/
|
|
1
|
+
import '@quilted/quilt/globals';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {createServerRender} from '@quilted/quilt/server';
|
|
3
|
+
import {RequestRouter, JSONResponse} from '@quilted/quilt/request-router';
|
|
5
4
|
import {type GraphQLFetch} from '@quilted/quilt/graphql';
|
|
6
|
-
import {
|
|
5
|
+
import {BrowserAssets} from '@quilted/quilt/magic/assets';
|
|
7
6
|
|
|
8
|
-
const router =
|
|
7
|
+
const router = new RequestRouter();
|
|
8
|
+
const assets = new BrowserAssets();
|
|
9
9
|
|
|
10
10
|
// GraphQL API, called from the client
|
|
11
11
|
router.post('/api/graphql', async (request) => {
|
|
12
|
-
const [{
|
|
13
|
-
await Promise.all([import('./server/graphql.ts')
|
|
12
|
+
const [{query, operationName, variables}, {performGraphQLOperation}] =
|
|
13
|
+
await Promise.all([request.json(), import('./server/graphql.ts')]);
|
|
14
14
|
|
|
15
15
|
const result = await performGraphQLOperation(query, {
|
|
16
16
|
variables,
|
|
17
17
|
operationName,
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
return
|
|
20
|
+
return new JSONResponse(result);
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// For all GET requests, render our React application.
|
|
24
|
-
router.get(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
);
|
|
24
|
+
router.get(async (request) => {
|
|
25
|
+
const [{App}, {performGraphQLOperation}, {renderToResponse}] =
|
|
26
|
+
await Promise.all([
|
|
27
|
+
import('./App.tsx'),
|
|
28
|
+
import('./server/graphql.ts'),
|
|
29
|
+
import('@quilted/quilt/server'),
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
// GraphQL API, called during server rendering
|
|
33
|
+
const fetchGraphQL: GraphQLFetch = async (operation, options) => {
|
|
34
|
+
const result = await performGraphQLOperation<any>(
|
|
35
|
+
(operation as any).source,
|
|
36
|
+
{
|
|
37
|
+
variables: options?.variables as any,
|
|
38
|
+
operationName: (operation as any).name,
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const response = await renderToResponse(<App fetchGraphQL={fetchGraphQL} />, {
|
|
46
|
+
request,
|
|
47
|
+
assets,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return response;
|
|
51
|
+
});
|
|
49
52
|
|
|
50
53
|
export default router;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createOptionalContext,
|
|
3
3
|
createUseContextHook,
|
|
4
|
-
|
|
5
|
-
} from '@quilted/quilt';
|
|
4
|
+
} from '@quilted/quilt/react/tools';
|
|
6
5
|
|
|
7
6
|
export interface AppContext {}
|
|
8
7
|
|
|
9
8
|
export const AppContextReact = createOptionalContext<AppContext>();
|
|
10
9
|
export const useAppContext = createUseContextHook(AppContextReact);
|
|
11
|
-
|
|
12
|
-
export function createUseAppContextHook<T>(hook: (context: AppContext) => T) {
|
|
13
|
-
return createUseOptionalValueHook<T>(() => hook(useAppContext()));
|
|
14
|
-
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
GraphQLTesting,
|
|
3
|
+
GraphQLController,
|
|
3
4
|
createGraphQLSchema,
|
|
4
5
|
createGraphQLFiller,
|
|
5
|
-
createGraphQLController,
|
|
6
|
-
type GraphQLController,
|
|
7
6
|
} from '@quilted/quilt/graphql/testing';
|
|
8
7
|
|
|
9
8
|
import schemaSource from '../graphql/schema.ts';
|
|
@@ -11,4 +10,4 @@ import schemaSource from '../graphql/schema.ts';
|
|
|
11
10
|
export const schema = createGraphQLSchema(schemaSource);
|
|
12
11
|
export const fillGraphQL = createGraphQLFiller(schema);
|
|
13
12
|
|
|
14
|
-
export {
|
|
13
|
+
export {GraphQLController, GraphQLTesting};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@quilted/quilt/testing';
|
|
1
|
+
import {createRender} from '@quilted/quilt/react/testing';
|
|
2
|
+
import {TestRouting, TestRouter} from '@quilted/quilt/navigate/testing';
|
|
3
|
+
import {Localization} from '@quilted/quilt/localize';
|
|
4
|
+
|
|
6
5
|
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
|
|
7
6
|
|
|
8
7
|
import {AppContextReact} from '~/shared/context.ts';
|
|
9
8
|
|
|
10
|
-
import {
|
|
9
|
+
import {GraphQLTesting, GraphQLController} from '../graphql.ts';
|
|
11
10
|
|
|
12
11
|
import {RenderOptions, RenderContext, RenderActions} from './types.ts';
|
|
13
12
|
|
|
@@ -24,23 +23,25 @@ export const renderApp = createRender<
|
|
|
24
23
|
// Create context that can be used by the `render` function, and referenced by test
|
|
25
24
|
// authors on the `root.context` property. Context is used to share data between your
|
|
26
25
|
// React tree and your test code, and is ideal for mocking out global context providers.
|
|
27
|
-
context({router =
|
|
26
|
+
context({router = new TestRouter(), graphql = new GraphQLController()}) {
|
|
28
27
|
return {router, graphql, queryClient: new QueryClient()};
|
|
29
28
|
},
|
|
30
29
|
// Render all of our app-wide context providers around each component under test.
|
|
31
|
-
render(element, context, {locale}) {
|
|
30
|
+
render(element, context, {locale = 'en'}) {
|
|
32
31
|
const {router, graphql, queryClient} = context;
|
|
33
32
|
|
|
34
33
|
return (
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
34
|
+
<Localization locale={locale}>
|
|
35
|
+
<TestRouting router={router}>
|
|
36
|
+
<GraphQLTesting controller={graphql}>
|
|
38
37
|
<QueryClientProvider client={queryClient}>
|
|
39
|
-
{
|
|
38
|
+
<AppContextReact.Provider value={context}>
|
|
39
|
+
{element}
|
|
40
|
+
</AppContextReact.Provider>
|
|
40
41
|
</QueryClientProvider>
|
|
41
|
-
</
|
|
42
|
-
</
|
|
43
|
-
</
|
|
42
|
+
</GraphQLTesting>
|
|
43
|
+
</TestRouting>
|
|
44
|
+
</Localization>
|
|
44
45
|
);
|
|
45
46
|
},
|
|
46
47
|
async afterRender(wrapper) {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {TestRouter} from '@quilted/quilt/navigate/testing';
|
|
2
2
|
import type {QueryClient} from '@tanstack/react-query';
|
|
3
3
|
|
|
4
4
|
import type {AppContext} from '~/shared/context.ts';
|
|
5
5
|
|
|
6
6
|
import type {GraphQLController} from '../graphql.ts';
|
|
7
7
|
|
|
8
|
-
type Router = ReturnType<typeof createTestRouter>;
|
|
9
|
-
|
|
10
8
|
export interface RenderOptions {
|
|
11
9
|
/**
|
|
12
10
|
* A custom router to use for this component test. You can use a
|
|
@@ -14,7 +12,7 @@ export interface RenderOptions {
|
|
|
14
12
|
* its navigation method to check that components navigate as
|
|
15
13
|
* you expect.
|
|
16
14
|
*/
|
|
17
|
-
readonly router?:
|
|
15
|
+
readonly router?: TestRouter;
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
18
|
* An object that controls the responses to GraphQL queries and mutations
|
|
@@ -23,15 +21,16 @@ export interface RenderOptions {
|
|
|
23
21
|
* by this module.
|
|
24
22
|
*
|
|
25
23
|
* ```tsx
|
|
26
|
-
* import {
|
|
24
|
+
* import {renderApp} from '~/tests/render.ts';
|
|
25
|
+
* import {fillGraphQL, GraphQLController} from '~/tests/graphql.ts';
|
|
27
26
|
*
|
|
28
27
|
* import {MyComponent} from './MyComponent.tsx';
|
|
29
28
|
* import myComponentQuery from './MyComponentQuery.graphql';
|
|
30
29
|
*
|
|
31
|
-
* const myComponent = await
|
|
32
|
-
* graphql:
|
|
33
|
-
* fillGraphQL(myComponentQuery, {
|
|
34
|
-
* ),
|
|
30
|
+
* const myComponent = await renderApp(<MyComponent />, {
|
|
31
|
+
* graphql: new GraphQLController([
|
|
32
|
+
* fillGraphQL(myComponentQuery, {me: {name: 'Winston'}}),
|
|
33
|
+
* ]),
|
|
35
34
|
* });
|
|
36
35
|
* ```
|
|
37
36
|
*/
|
|
@@ -47,7 +46,7 @@ export interface RenderContext extends AppContext {
|
|
|
47
46
|
/**
|
|
48
47
|
* The router used for this component test.
|
|
49
48
|
*/
|
|
50
|
-
readonly router:
|
|
49
|
+
readonly router: TestRouter;
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* The GraphQL controller used for this component test.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import '@quilted/quilt/
|
|
1
|
+
import '@quilted/quilt/react/testing';
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export {TestRouter} from '@quilted/quilt/navigate/testing';
|
|
4
4
|
|
|
5
5
|
export * from './render/types.ts';
|
|
6
6
|
export {renderApp} from './render/render.tsx';
|
|
7
|
-
export {fillGraphQL, createGraphQLController} from './graphql.ts';
|
|
@@ -1,38 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '@quilted/quilt';
|
|
1
|
+
import {useMemo} from 'react';
|
|
2
|
+
|
|
3
|
+
import {HTML} from '@quilted/quilt/html';
|
|
4
|
+
import {Routing, useRoutes, useInitialUrl} from '@quilted/quilt/navigate';
|
|
5
|
+
import {Localization, useLocaleFromEnvironment} from '@quilted/quilt/localize';
|
|
6
|
+
import {type PropsWithChildren} from '@quilted/quilt/react/tools';
|
|
7
7
|
|
|
8
8
|
import {httpBatchLink} from '@trpc/client';
|
|
9
9
|
import {QueryClient} from '@tanstack/react-query';
|
|
10
10
|
import {ReactQueryContext} from '@quilted/react-query';
|
|
11
11
|
|
|
12
|
+
import {Head} from './foundation/html.ts';
|
|
13
|
+
import {Headers} from './foundation/http.ts';
|
|
14
|
+
import {Frame} from './foundation/frame.ts';
|
|
15
|
+
|
|
16
|
+
import {Start} from './features/start.ts';
|
|
17
|
+
|
|
18
|
+
import {trpc} from './shared/trpc.ts';
|
|
12
19
|
import {
|
|
13
20
|
AppContextReact,
|
|
14
21
|
type AppContext as AppContextType,
|
|
15
|
-
} from '
|
|
16
|
-
import {trpc} from '~/shared/trpc.ts';
|
|
22
|
+
} from './shared/context.ts';
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
import {Head} from './foundation/Head.tsx';
|
|
20
|
-
import {Metrics} from './foundation/Metrics.tsx';
|
|
21
|
-
|
|
22
|
-
import {Start} from './features/Start.tsx';
|
|
23
|
-
import {useMemo} from 'react';
|
|
24
|
-
|
|
25
|
-
export interface Props extends AppContextType {}
|
|
24
|
+
export interface AppProps extends AppContextType {}
|
|
26
25
|
|
|
27
26
|
// The root component for your application. You will typically render any
|
|
28
27
|
// app-wide context in this component.
|
|
29
|
-
export
|
|
28
|
+
export function App(props: AppProps) {
|
|
29
|
+
const locale = useLocaleFromEnvironment() ?? 'en';
|
|
30
|
+
|
|
30
31
|
return (
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
<HTML>
|
|
33
|
+
<Localization locale={locale}>
|
|
34
|
+
<Routing>
|
|
35
|
+
<AppContext {...props}>
|
|
36
|
+
<Headers />
|
|
37
|
+
<Head />
|
|
38
|
+
<Frame>
|
|
39
|
+
<Routes />
|
|
40
|
+
</Frame>
|
|
41
|
+
</AppContext>
|
|
42
|
+
</Routing>
|
|
43
|
+
</Localization>
|
|
44
|
+
</HTML>
|
|
36
45
|
);
|
|
37
46
|
}
|
|
38
47
|
|
|
@@ -45,10 +54,7 @@ function Routes() {
|
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
// This component renders any app-wide context.
|
|
48
|
-
function AppContext({
|
|
49
|
-
children,
|
|
50
|
-
...appContext
|
|
51
|
-
}: PropsWithChildren<AppContextType>) {
|
|
57
|
+
function AppContext({children, ...context}: PropsWithChildren<AppProps>) {
|
|
52
58
|
const initialUrl = useInitialUrl();
|
|
53
59
|
|
|
54
60
|
const {queryClient, trpcClient} = useMemo(() => {
|
|
@@ -65,12 +71,12 @@ function AppContext({
|
|
|
65
71
|
}, [initialUrl]);
|
|
66
72
|
|
|
67
73
|
return (
|
|
68
|
-
<
|
|
69
|
-
<
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
</
|
|
73
|
-
</
|
|
74
|
-
</
|
|
74
|
+
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
75
|
+
<ReactQueryContext client={queryClient}>
|
|
76
|
+
<AppContextReact.Provider value={context}>
|
|
77
|
+
{children}
|
|
78
|
+
</AppContextReact.Provider>
|
|
79
|
+
</ReactQueryContext>
|
|
80
|
+
</trpc.Provider>
|
|
75
81
|
);
|
|
76
82
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import '@quilted/quilt/
|
|
1
|
+
import '@quilted/quilt/globals';
|
|
2
2
|
import {hydrateRoot} from 'react-dom/client';
|
|
3
3
|
import {httpBatchLink} from '@trpc/client';
|
|
4
4
|
|
|
5
5
|
import {trpc} from '~/shared/trpc.ts';
|
|
6
6
|
|
|
7
|
-
import App from './App.tsx';
|
|
7
|
+
import {App} from './App.tsx';
|
|
8
8
|
|
|
9
9
|
const element = document.querySelector('#app')!;
|
|
10
10
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {describe, it, expect} from '@quilted/quilt/testing';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {renderApp} from '~/tests/render.ts';
|
|
4
4
|
|
|
5
5
|
import Start from './Start.tsx';
|
|
6
6
|
|
|
7
7
|
describe('<Start />', () => {
|
|
8
8
|
it('includes a welcome message', async () => {
|
|
9
|
-
const start = await
|
|
9
|
+
const start = await renderApp(<Start />);
|
|
10
10
|
expect(start).toContainReactText('Hello world!');
|
|
11
11
|
});
|
|
12
12
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {Frame} from './frame/Frame.tsx';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {Viewport, SearchRobots} from '@quilted/quilt/html';
|
|
2
1
|
import {describe, it, expect} from '@quilted/quilt/testing';
|
|
2
|
+
import {Viewport, SearchRobots} from '@quilted/quilt/html';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {renderApp} from '~/tests/render.ts';
|
|
5
5
|
|
|
6
6
|
import {Head} from './Head.tsx';
|
|
7
7
|
|
|
8
8
|
describe('<Head />', () => {
|
|
9
9
|
it('includes a responsive viewport tag', async () => {
|
|
10
|
-
const head = await
|
|
10
|
+
const head = await renderApp(<Head />);
|
|
11
11
|
|
|
12
12
|
expect(head).toContainReactComponent(Viewport, {
|
|
13
13
|
cover: true,
|
|
@@ -15,7 +15,7 @@ describe('<Head />', () => {
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('prevents search robots from indexing the application', async () => {
|
|
18
|
-
const head = await
|
|
18
|
+
const head = await renderApp(<Head />);
|
|
19
19
|
|
|
20
20
|
expect(head).toContainReactComponent(SearchRobots, {
|
|
21
21
|
index: false,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {Head} from './html/Head.tsx';
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {CacheControl, ContentSecurityPolicy} from '@quilted/quilt/http';
|
|
2
1
|
import {describe, it, expect} from '@quilted/quilt/testing';
|
|
2
|
+
import {CacheControl, ContentSecurityPolicy} from '@quilted/quilt/http';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {renderApp} from '~/tests/render.ts';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {Headers} from './Headers.tsx';
|
|
7
7
|
|
|
8
|
-
describe('<
|
|
8
|
+
describe('<Headers />', () => {
|
|
9
9
|
it('does not cache the response', async () => {
|
|
10
|
-
const
|
|
10
|
+
const headers = await renderApp(<Headers />);
|
|
11
11
|
|
|
12
|
-
expect(
|
|
12
|
+
expect(headers).toContainReactComponent(CacheControl, {
|
|
13
13
|
cache: false,
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('adds a content security policy with a strict default policy', async () => {
|
|
18
|
-
const
|
|
18
|
+
const headers = await renderApp(<Headers />);
|
|
19
19
|
|
|
20
|
-
expect(
|
|
20
|
+
expect(headers).toContainReactComponent(ContentSecurityPolicy, {
|
|
21
21
|
defaultSources: ["'self'"],
|
|
22
22
|
});
|
|
23
23
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Env from '@quilted/quilt/env';
|
|
2
|
-
import {
|
|
2
|
+
import {useInitialUrl} from '@quilted/quilt/navigate';
|
|
3
3
|
import {
|
|
4
4
|
CacheControl,
|
|
5
5
|
ResponseHeader,
|
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
// wherever in your application you can read that state.
|
|
15
15
|
//
|
|
16
16
|
// @see https://github.com/lemonmade/quilt/blob/main/documentation/features/http.md
|
|
17
|
-
export function
|
|
18
|
-
const isHttps =
|
|
17
|
+
export function Headers() {
|
|
18
|
+
const isHttps = useInitialUrl().protocol === 'https:';
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {Headers} from './http/Headers.tsx';
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import '@quilted/quilt/
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import '@quilted/quilt/globals';
|
|
2
|
+
import {RequestRouter} from '@quilted/quilt/request-router';
|
|
3
|
+
import {BrowserAssets} from '@quilted/quilt/magic/assets';
|
|
4
|
+
|
|
4
5
|
import {createDirectClient} from '@quilted/trpc/server';
|
|
5
6
|
import {fetchRequestHandler} from '@trpc/server/adapters/fetch';
|
|
6
7
|
|
|
7
8
|
import {appRouter} from './trpc.ts';
|
|
8
9
|
|
|
9
|
-
const router =
|
|
10
|
+
const router = new RequestRouter();
|
|
11
|
+
const assets = new BrowserAssets();
|
|
10
12
|
|
|
11
13
|
router.any(
|
|
12
14
|
'api',
|
|
@@ -22,16 +24,21 @@ router.any(
|
|
|
22
24
|
);
|
|
23
25
|
|
|
24
26
|
// For all GET requests, render our React application.
|
|
25
|
-
router.get(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
router.get(async (request) => {
|
|
28
|
+
const [{App}, {renderToResponse}] = await Promise.all([
|
|
29
|
+
import('./App.tsx'),
|
|
30
|
+
import('@quilted/quilt/server'),
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const response = await renderToResponse(
|
|
34
|
+
<App trpc={createDirectClient(appRouter)} />,
|
|
31
35
|
{
|
|
32
|
-
|
|
36
|
+
request,
|
|
37
|
+
assets,
|
|
33
38
|
},
|
|
34
|
-
)
|
|
35
|
-
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return response;
|
|
42
|
+
});
|
|
36
43
|
|
|
37
44
|
export default router;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createOptionalContext,
|
|
3
3
|
createUseContextHook,
|
|
4
|
-
|
|
5
|
-
} from '@quilted/quilt';
|
|
4
|
+
} from '@quilted/quilt/react/tools';
|
|
6
5
|
|
|
7
6
|
export interface AppContext {}
|
|
8
7
|
|
|
9
8
|
export const AppContextReact = createOptionalContext<AppContext>();
|
|
10
9
|
export const useAppContext = createUseContextHook(AppContextReact);
|
|
11
|
-
|
|
12
|
-
export function createUseAppContextHook<T>(hook: (context: AppContext) => T) {
|
|
13
|
-
return createUseOptionalValueHook<T>(() => hook(useAppContext()));
|
|
14
|
-
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@quilted/quilt/testing';
|
|
1
|
+
import {createRender} from '@quilted/quilt/react/testing';
|
|
2
|
+
import {TestRouting, TestRouter} from '@quilted/quilt/navigate/testing';
|
|
3
|
+
import {Localization} from '@quilted/quilt/localize';
|
|
4
|
+
|
|
6
5
|
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
|
|
7
6
|
|
|
8
7
|
import {trpc} from '~/shared/trpc.ts';
|
|
@@ -23,23 +22,25 @@ export const renderApp = createRender<
|
|
|
23
22
|
// Create context that can be used by the `render` function, and referenced by test
|
|
24
23
|
// authors on the `root.context` property. Context is used to share data between your
|
|
25
24
|
// React tree and your test code, and is ideal for mocking out global context providers.
|
|
26
|
-
context({router =
|
|
25
|
+
context({router = new TestRouter()}) {
|
|
27
26
|
return {router, trpc: trpc.createClient(), queryClient: new QueryClient()};
|
|
28
27
|
},
|
|
29
28
|
// Render all of our app-wide context providers around each component under test.
|
|
30
|
-
render(element, context, {locale}) {
|
|
29
|
+
render(element, context, {locale = 'en'}) {
|
|
31
30
|
const {router, trpc: trpcClient, queryClient} = context;
|
|
32
31
|
|
|
33
32
|
return (
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
<Localization locale={locale}>
|
|
34
|
+
<TestRouting router={router}>
|
|
35
|
+
<AppContextReact.Provider value={context}>
|
|
36
|
+
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
37
|
+
<QueryClientProvider client={queryClient}>
|
|
38
|
+
{element}
|
|
39
|
+
</QueryClientProvider>
|
|
40
|
+
</trpc.Provider>
|
|
41
|
+
</AppContextReact.Provider>
|
|
42
|
+
</TestRouting>
|
|
43
|
+
</Localization>
|
|
43
44
|
);
|
|
44
45
|
},
|
|
45
46
|
async afterRender() {
|