Skip to content

Commit 0b53ab2

Browse files
committed
fix: restrict in-page emits to events
1 parent 6be6f9c commit 0b53ab2

3 files changed

Lines changed: 35 additions & 18 deletions

File tree

‎packages/devframe/src/in-page-channel/types.test-d.ts‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ describe('In-page script channel', () => {
148148
describe('Function calling', () => {
149149
it('types fire-and-forget calls to panel functions', () => {
150150
expectTypeOf(channel.emit('notify', 'ready')).toEqualTypeOf<void>()
151+
expectTypeOf(channel.callEvent('notify', 'ready')).toEqualTypeOf<void>()
151152

152153
// @ts-expect-error In-page script functions cannot be called on panels.
153154
channel.emit('echo', 'ready')
@@ -159,6 +160,19 @@ describe('In-page script channel', () => {
159160
channel.emit('notify', 'ready', 'extra')
160161
})
161162

163+
it('rejects fire-and-forget calls to panel queries', () => {
164+
const mixedChannel = createPageScriptChannel<MixedPanelProtocol>({
165+
name: 'devframes:mixed-panel',
166+
functions: {},
167+
})
168+
169+
mixedChannel.emit('notify', 'ready')
170+
// @ts-expect-error Queries cannot be emitted as events.
171+
mixedChannel.emit('confirm', 'continue?')
172+
// @ts-expect-error The deprecated alias has the same event-only contract.
173+
mixedChannel.callEvent('confirm', 'continue?')
174+
})
175+
162176
it('types calls to connected panels', () => {
163177
const panel = channel.panels[0]!
164178

@@ -330,16 +344,19 @@ describe('Panel channel', () => {
330344
})
331345

332346
it('types fire-and-forget calls to in-page script functions', () => {
333-
expectTypeOf(channel.emit('echo', 'hello')).toEqualTypeOf<void>()
334-
expectTypeOf(channel.emit('sum', 1, 2)).toEqualTypeOf<void>()
335347
expectTypeOf(channel.emit('save', 'draft')).toEqualTypeOf<void>()
348+
expectTypeOf(channel.callEvent('save', 'draft')).toEqualTypeOf<void>()
336349

337350
// @ts-expect-error Panel functions cannot be emitted to the in-page script.
338351
channel.emit('notify', 'hello')
339-
// @ts-expect-error `echo` requires a string.
340-
channel.emit('echo', false)
341-
// @ts-expect-error `sum` requires two arguments.
342-
channel.emit('sum', 1)
352+
// @ts-expect-error Queries cannot be emitted as events.
353+
channel.emit('echo', 'hello')
354+
// @ts-expect-error Queries cannot be emitted as events.
355+
channel.emit('sum', 1, 2)
356+
// @ts-expect-error `save` requires a string.
357+
channel.emit('save', false)
358+
// @ts-expect-error The deprecated alias has the same event-only contract.
359+
channel.callEvent('echo', 'hello')
343360
})
344361

345362
it('types channel state', () => {

‎packages/devframe/src/in-page-channel/types.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,14 @@ export interface PageScriptChannel<P extends InPageChannelProtocol> {
346346
readonly panels: readonly PanelPeer<P>[]
347347
readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>
348348
/** Fan an event out to every connected panel. */
349-
emit: <K extends keyof PanelFunctions<P> & string>(
349+
emit: <K extends keyof PanelFunctionsEvents<P> & string>(
350350
name: K,
351-
...args: FnArgs<PanelFunctions<P>[K]>
351+
...args: FnArgs<PanelFunctionsEvents<P>[K]>
352352
) => void
353353
/** @deprecated Use `emit()` instead. */
354-
callEvent: <K extends keyof PanelFunctions<P> & string>(
354+
callEvent: <K extends keyof PanelFunctionsEvents<P> & string>(
355355
name: K,
356-
...args: FnArgs<PanelFunctions<P>[K]>
356+
...args: FnArgs<PanelFunctionsEvents<P>[K]>
357357
) => void
358358
/** Subscribe to an event emitted by a panel. Returns an unsubscribe function. */
359359
on: <K extends keyof PageScriptFunctionsEvents<P> & string>(
@@ -403,14 +403,14 @@ export interface PanelChannel<P extends InPageChannelProtocol> {
403403
* Emit an event to the page script. While `connecting` the event is buffered
404404
* (up to `eventBufferLimit`) and flushed on connect.
405405
*/
406-
emit: <K extends keyof PageScriptFunctions<P> & string>(
406+
emit: <K extends keyof PageScriptFunctionsEvents<P> & string>(
407407
name: K,
408-
...args: FnArgs<PageScriptFunctions<P>[K]>
408+
...args: FnArgs<PageScriptFunctionsEvents<P>[K]>
409409
) => void
410410
/** @deprecated Use `emit()` instead. */
411-
callEvent: <K extends keyof PageScriptFunctions<P> & string>(
411+
callEvent: <K extends keyof PageScriptFunctionsEvents<P> & string>(
412412
name: K,
413-
...args: FnArgs<PageScriptFunctions<P>[K]>
413+
...args: FnArgs<PageScriptFunctionsEvents<P>[K]>
414414
) => void
415415
/** Subscribe to an event emitted by the page script. Returns an unsubscribe function. */
416416
on: <K extends keyof PanelFunctionsEvents<P> & string>(

‎tests/__snapshots__/tsnapi/devframe/in-page-channel.snapshot.d.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export interface PageScriptChannel<P extends InPageChannelProtocol> {
2525
readonly instanceId: string;
2626
readonly panels: readonly PanelPeer<P>[];
2727
readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>;
28-
emit: <K extends keyof PanelFunctions<P> & string>(_: K, ..._: FnArgs<PanelFunctions<P>[K]>) => void;
29-
callEvent: <K extends keyof PanelFunctions<P> & string>(_: K, ..._: FnArgs<PanelFunctions<P>[K]>) => void;
28+
emit: <K extends keyof PanelFunctionsEvents<P> & string>(_: K, ..._: FnArgs<PanelFunctionsEvents<P>[K]>) => void;
29+
callEvent: <K extends keyof PanelFunctionsEvents<P> & string>(_: K, ..._: FnArgs<PanelFunctionsEvents<P>[K]>) => void;
3030
on: <K extends keyof PageScriptFunctionsEvents<P> & string>(_: K, _: (..._: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void) => () => void;
3131
readonly sharedState: InPageSharedStateHost<P>;
3232
addPanelPort: (_: MessagePort) => PanelPeer<P>;
@@ -41,8 +41,8 @@ export interface PanelChannel<P extends InPageChannelProtocol> {
4141
readonly events: Pick<EventEmitter<PanelChannelEvents>, 'on' | 'once'>;
4242
whenConnected: (_?: number) => Promise<void>;
4343
call: <K extends keyof PageScriptFunctions<P> & string>(_: K, ..._: FnArgs<PageScriptFunctions<P>[K]>) => Promise<FnReturn<PageScriptFunctions<P>[K]>>;
44-
emit: <K extends keyof PageScriptFunctions<P> & string>(_: K, ..._: FnArgs<PageScriptFunctions<P>[K]>) => void;
45-
callEvent: <K extends keyof PageScriptFunctions<P> & string>(_: K, ..._: FnArgs<PageScriptFunctions<P>[K]>) => void;
44+
emit: <K extends keyof PageScriptFunctionsEvents<P> & string>(_: K, ..._: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void;
45+
callEvent: <K extends keyof PageScriptFunctionsEvents<P> & string>(_: K, ..._: FnArgs<PageScriptFunctionsEvents<P>[K]>) => void;
4646
on: <K extends keyof PanelFunctionsEvents<P> & string>(_: K, _: (..._: FnArgs<PanelFunctionsEvents<P>[K]>) => void) => () => void;
4747
readonly sharedState: InPageSharedStateHost<P>;
4848
close: () => void;

0 commit comments

Comments
 (0)