Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,18 @@ export default class UsersController {
users,
lazyProp: Inertia.lazy(() => {
return { lazy: 'too lazy' };
})
}),
});
}
}
```

The data will be loaded on demand by the explicit Inertia visit with option

```typescript
{ only: ['lazyProp']}
{
only: ['lazyProp'];
}
```

## Root template data
Expand Down Expand Up @@ -210,6 +214,40 @@ Route.inertia('about', 'About');
Route.inertia('about', 'About', { metadata: '...' });
```

## TypeScript Helpers

### InertiaPage

Manually typing your front-end components can be tedious and error-prone. This is where the `InertiaPage` type comes in handy.

If you have a controller similar to the following example:

```typescript
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { InertiaPage } from '@ioc:EidelLev/Inertia';

export default class FooController {
public async index({ inertia }: HttpContextContract) {
return inertia.render('Foo', {
bar: 'FooBar',
});
}
}

// Export this type to use in your front-end components
export type FooIndexProps = InertiaPage<FooController['index']>;
```

You can then use the `FooIndexProps` type in your front-end component and get type safety for your props that will update automatically if you change the controller method response params.

```typescript
import type FooIndexProps from 'App/Controllers/FooController';

const FooPage = ({ bar }: FooIndexProps) => {
return <div>{bar}</div>;
};
```

## Redirects

### External redirects
Expand Down
14 changes: 11 additions & 3 deletions adonis-typings/inertia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@ declare module '@ioc:EidelLev/Inertia' {
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { ResponseContract } from '@ioc:Adonis/Core/Response';

export type ResponseProps = Record<string, unknown>;
export type RenderResponse = Promise<Record<string, unknown> | string | ResponseContract>;
type AdonisControllerMethod = (ctx: HttpContextContract, ...args: any) => any;
export type ResponseProps = Record<string, any>;
type RenderedResponseProps<T extends ResponseProps> = {
component: string;
version: VersionValue;
props: T;
url: string;
}
export type RenderResponse<T extends ResponseProps> = Promise<RenderedResponseProps<T> | string | ResponseContract>;
export type InertiaPage<T extends AdonisControllerMethod> = Exclude<Awaited<ReturnType<T>>, string | ResponseContract>['props'];

/**
* Shared data types
Expand Down Expand Up @@ -31,7 +39,7 @@ declare module '@ioc:EidelLev/Inertia' {
* @param {string} component Page component
* @param {ResponseProps} responseProps Props
*/
render(component: string, responseProps?: ResponseProps, pageOnlyProps?: ResponseProps): RenderResponse;
render<T extends ResponseProps>(component: string, responseProps?: T, pageOnlyProps?: ResponseProps): RenderResponse<T>;

/**
* Redirect back with the correct HTTP status code
Expand Down
10 changes: 5 additions & 5 deletions src/Inertia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@ export class Inertia implements InertiaContract {
return new LazyProp(callback);
}

public async render(
public async render<T extends ResponseProps>(
component: string,
responseProps: ResponseProps = {},
responseProps?: T,
pageOnlyProps: ResponseProps = {},
): RenderResponse {
): RenderResponse<T> {
const { view: inertiaView, ssr = { enabled: false } } = this.config;
const { request, response, view, session } = this.ctx;
const isInertia = request.inertia();
const partialData = this.resolvePartialData(request.header(HEADERS.INERTIA_PARTIAL_DATA));
const partialDataComponentHeader = request.header(HEADERS.INERTIA_PARTIAL_DATA_COMPONENT);
const requestAssetVersion = request.header(HEADERS.INERTIA_VERSION);
const props: ResponseProps = await this.resolveProps(
{ ...Inertia.sharedData, ...responseProps },
const props: T = await this.resolveProps(
{ ...Inertia.sharedData, ...Object(responseProps) },
partialData,
component,
partialDataComponentHeader,
Expand Down