Skip to content

Commit

Permalink
fix: broken special props used in sharedData config file
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien-R44 committed Dec 18, 2024
1 parent 3c0a396 commit bd7d337
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
30 changes: 19 additions & 11 deletions src/inertia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ export class Inertia {
return newProps
}

/**
* Resolve a single prop
*/
async #resolveProp(key: string, value: any) {
if (
value instanceof OptionalProp ||
value instanceof MergeProp ||
value instanceof DeferProp ||
value instanceof AlwaysProp
) {
return [key, await value.callback()]
}

return [key, value]
}

/**
* Resolve a single prop by calling the callback or resolving the promise
*/
Expand All @@ -143,19 +159,11 @@ export class Inertia {
await Promise.all(
Object.entries(props).map(async ([key, value]) => {
if (typeof value === 'function') {
return [key, await value(this.ctx)]
}

if (
value instanceof OptionalProp ||
value instanceof MergeProp ||
value instanceof DeferProp ||
value instanceof AlwaysProp
) {
return [key, await value.callback()]
const result = await value(this.ctx)
return this.#resolveProp(key, result)
}

return [key, value]
return this.#resolveProp(key, value)
})
)
)
Expand Down
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ type InferProps<T> = {

type ReturnsTypesSharedData<T extends SharedData> = {} extends T
? {}
: { [K in keyof T]: T[K] extends (...args: any[]) => MaybePromise<infer U> ? U : T[K] }
: InferProps<{
[K in keyof T]: T[K] extends (...args: any[]) => MaybePromise<infer U> ? U : T[K]
}>

/**
* Infer shared data types from the config provider
Expand Down
2 changes: 1 addition & 1 deletion stubs/config.stub
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const inertiaConfig = defineConfig({
* Data that should be shared with all rendered pages
*/
sharedData: {
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
errors: (ctx) => ctx.inertia.always(() => ctx.session?.flashMessages.get('errors')),
},

/**
Expand Down
4 changes: 3 additions & 1 deletion tests/define_config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ test.group('Define Config', () => {
foo: 'string' as const,
bar: (ctx) => ctx.request.url(),
bar2: () => (Math.random() ? 'string' : 1),
bar4: (ctx) => ctx.inertia.always(() => 'foo'),
},
})

type Props = InferSharedProps<typeof config>
expectTypeOf<Props>().toEqualTypeOf<{
expectTypeOf<Props>().toMatchTypeOf<{
foo: 'string'
bar: string
bar2: 'string' | 1
bar4: string
}>()
})

Expand Down
13 changes: 13 additions & 0 deletions tests/inertia.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ test.group('Inertia', () => {
assert.deepEqual(result.props, { user: 'jul', message: 'hello' })
})

test('shared data are unwrapped when they use always', async ({ assert }) => {
setupViewMacroMock()

const inertia = await new InertiaFactory()
.merge({ config: { sharedData: { foo: () => inertia.always(() => 'bar') } } })
.withXInertiaHeader()
.create()

const result: any = await inertia.render('foo')

assert.deepEqual(result.props, { foo: 'bar' })
})

test('correct server response when mergeable props is used', async ({ assert }) => {
const inertia = await new InertiaFactory().withXInertiaHeader().create()

Expand Down

0 comments on commit bd7d337

Please sign in to comment.