Skip to content
Merged
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
24 changes: 22 additions & 2 deletions packages/runtime/src/action-execution-calldata-not-found.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@

import { describe, it, expect } from 'vitest';
import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol';
// [#4550, from #4434] The REAL engine's delete-dispatch predicate. A fake whose
// `delete` is looser than the implementation it stands in for turns a green
// suite into no suite at all; importing the producer's decision (rather than
// mirroring it) is what makes that impossible. `@objectstack/objectql` is
// already a `dependencies` entry of `@objectstack/runtime`, so no manifest
// change is needed to reach it.
import { assertEngineDeleteDispatch } from '@objectstack/objectql';
import { ApiEndpointSchema } from '@objectstack/spec/api';
import type { ApiEndpoint } from '@objectstack/spec/api';

Expand Down Expand Up @@ -81,7 +88,14 @@ function fallbackHarness(store = rows()) {
return store.get(id);
},
delete: async (_o: string, opts: any) => {
const id = String(opts?.where?.id);
// [#4550, from #4434] Open on the producer's own dispatch predicate,
// so this double cannot accept a call the real `ObjectQL.delete`
// refuses. It also earns its keep here: the assertion is what proves
// `callData`'s fallback issues a SCALAR by-id delete — the shape a
// running engine executes — rather than a predicate-shaped one that
// would 500 in production while this suite stayed green.
const dispatch = assertEngineDeleteDispatch(opts);
const id = String((dispatch as { kind: 'by-id'; id: string | number | bigint }).id);
deleted.push(id);
return store.delete(id);
},
Expand Down Expand Up @@ -109,7 +123,13 @@ function protocolHarness(store = rows()) {
store.set(id, { ...store.get(id), ...data });
return store.get(id);
},
delete: async (_o: string, opts: any) => store.delete(String(opts?.where?.id)),
// [#4550] Same pinning as the fallback harness above — this engine sits
// under the REAL protocol implementation, so its `delete` is reached by
// `deleteData`'s own by-id call and must be held to the same contract.
delete: async (_o: string, opts: any) => {
const dispatch = assertEngineDeleteDispatch(opts);
return store.delete(String((dispatch as { kind: 'by-id'; id: string | number | bigint }).id));
},
};
const services: Record<string, any> = {
metadata: { getObject: async () => ({ name: 'task', fields: {} }) },
Expand Down
Loading