fix: restore the credential-rejected branch and admit SRC absence by key
Review follow-ups that are logic rather than documentation: - rpc.schema.ts had lost the credential-rejected branch while api-proxy.ts still returns that code, so a legitimate business error failed the client's response parse. Restore the branch and assert it. - rpc-schemas.spec.ts had lost the workspace list, archiveSession and insertSessionBefore cases along with the command schemas; those routes still ship, so restore their coverage. - An omitted SRC field is now recognized by an absent key instead of an undefined value, which makes the allowance assertExactArguments already granted reachable; an explicitly undefined field stays invalid input. A weak descriptor's undefined result rides the wire as an absent value, matching the envelope removal. - The chooser unmounts an already-created backend when the surface entry fails to load, and no longer reverses the captured id array in place.
This commit is contained in:
@@ -176,6 +176,10 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
if (request.signal?.aborted === true) throw new RemoteInvocationCancelled(endpoint, error)
|
||||
throw error
|
||||
}
|
||||
// A weak descriptor declares no return type, so nothing returned is a void
|
||||
// result and rides the wire as an absent value field. A strict descriptor
|
||||
// keeps its schema: there, undefined has to be a declared result.
|
||||
if (result === undefined && descriptor.result.mode !== 'strict') return result
|
||||
return decode(descriptor.result, result, 'result-invalid', endpoint, 'result')
|
||||
}
|
||||
|
||||
@@ -405,6 +409,11 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
args: Readonly<Record<string, unknown>>,
|
||||
endpoint: string,
|
||||
): Promise<unknown> {
|
||||
// An absent field reached assertExactArguments' allowance, so this parameter
|
||||
// takes undefined; a present-but-undefined field is not JSON-safe input and
|
||||
// still fails decode. Lookup ids are never omissible, so absence here only
|
||||
// ever belongs to a json parameter.
|
||||
if (!Object.hasOwn(args, parameter.wire)) return undefined
|
||||
const value = decode(parameter.codec, args[parameter.wire], 'input-invalid', endpoint, parameter.wire)
|
||||
if (parameter.source === 'json') return value
|
||||
const key = parameter.lookup
|
||||
|
||||
@@ -788,6 +788,19 @@ describe('TypertGatewayService', () => {
|
||||
}), 'input-invalid')
|
||||
})
|
||||
|
||||
it('admits an omitted SRC field and hands the Host method undefined', async () => {
|
||||
const { ctx, service } = await setup()
|
||||
// A weak descriptor reads parameter names from the JavaScript signature and
|
||||
// cannot see which are optional, so an absent field is admitted; the case
|
||||
// above keeps an explicitly undefined field rejected.
|
||||
await expect(ctx.typertGateway.invoke({
|
||||
namespace: 'goals',
|
||||
method: 'passthrough',
|
||||
args: {},
|
||||
})).resolves.toBeUndefined()
|
||||
expect(service.calls).toContain('passthrough')
|
||||
})
|
||||
|
||||
it('rejects cyclic SRC input and non-JSON SRC results', async () => {
|
||||
const { ctx, service } = await setup()
|
||||
const cyclic: { self?: unknown } = {}
|
||||
|
||||
Reference in New Issue
Block a user