Skip to content

Commit aad227d

Browse files
committed
fix: passthrough output if it's a reference
1 parent d337fea commit aad227d

File tree

5 files changed

+170
-17
lines changed

5 files changed

+170
-17
lines changed

.changeset/five-oranges-protect.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"middy-store": patch
3+
---
4+
5+
fix: passthrough output if it's a reference

packages/core/src/store.ts

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { MiddlewareObj } from "@middy/core";
22
import {
33
calculateByteSize,
4+
createReference,
45
formatPath,
56
generatePayloadPaths,
67
generateReferencePaths,
@@ -68,12 +69,16 @@ export const Sizes = {
6869
LAMBDA_ASYNC: 256 * 1024 * 1024, // 256KB,
6970
};
7071

72+
// TODO add metadata object which will be passed to the store and load methods
73+
7174
export type StoreArgs<TPayload> = {
75+
// TODO add output to StoreArgs OR metadata?
7276
payload: TPayload;
7377
byteSize: number;
7478
};
7579

7680
export type LoadArgs<TReference> = {
81+
// TODO add input to LoadArgs OR metadata?
7782
reference: TReference;
7883
};
7984

@@ -105,9 +110,13 @@ export interface LoadingOptions<TInput> {
105110
passThrough?: boolean;
106111

107112
// selector?: Selector<TInput>; // TODO
113+
114+
// TODO metadata here?
108115
}
109116

110117
export interface StoringOptions<TInput, TOutput> {
118+
// TODO metadata here?
119+
111120
/**
112121
* Skip storing the payload in the Store, even if the output exceeds the maximum size.
113122
*/
@@ -190,7 +199,9 @@ export const middyStore = <TInput = unknown, TOutput = unknown>(
190199
const { stores, loadingOptions, storingOptions } = opts;
191200
const logger = opts.logger ?? DUMMY_LOGGER;
192201

193-
return {
202+
// let request: Request<TInput, TOutput> | undefined;
203+
204+
const middleware: MiddlewareObj<TInput, TOutput> = {
194205
before: async (request) => {
195206
// setting read to false will skip the store
196207
if (loadingOptions?.skip) {
@@ -339,9 +350,9 @@ export const middyStore = <TInput = unknown, TOutput = unknown>(
339350
logger(`Found store "${store.name}" to save payload`);
340351

341352
// store the payload in the store
342-
const reference: MiddyStore<unknown> = {
343-
[MIDDY_STORE]: await store.store(storeArgs),
344-
};
353+
const reference: MiddyStore<unknown> = createReference(
354+
await store.store(storeArgs),
355+
);
345356

346357
logger(`Saved payload in store "${store.name}"`);
347358

@@ -361,4 +372,10 @@ export const middyStore = <TInput = unknown, TOutput = unknown>(
361372
}
362373
},
363374
};
375+
376+
// const earlyReturn = (output: TOutput) => {
377+
// middleware.after!({});
378+
// };
379+
380+
return middleware;
364381
};

packages/core/src/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ export function* generatePayloadPaths({
171171
throw new Error(`Path not found at ${path}`);
172172
}
173173

174+
// if the payload is a reference, we skip it
175+
if (hasReference(payload)) {
176+
return;
177+
}
178+
174179
if (isMultiPayload && Array.isArray(payload)) {
175180
for (let index = 0; index < payload.length; index++) {
176181
// if the item is a reference, we skip it
@@ -197,6 +202,12 @@ export const getReference = <TReference = unknown>(
197202
return hasReference<TReference>(input) ? input[MIDDY_STORE] : undefined;
198203
};
199204

205+
export const createReference = <TReference = unknown>(
206+
reference: TReference,
207+
): MiddyStore<TReference> => {
208+
return { [MIDDY_STORE]: reference };
209+
};
210+
200211
type GenerateReferencePathsArgs = {
201212
input: unknown;
202213
path: string;

packages/core/test/store.unit.test.ts

+124-13
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
type StoreInterface,
1010
middyStore,
1111
} from "../src/store.js";
12-
import { calculateByteSize } from "../src/utils.js";
12+
import { calculateByteSize, createReference } from "../src/utils.js";
1313

1414
const context = {} as Context;
1515

@@ -520,12 +520,123 @@ describe("store", () => {
520520

521521
await expect(
522522
handler(structuredClone([payload, payload]), context),
523-
).resolves.toEqual({ [MIDDY_STORE]: reference });
523+
).resolves.toEqual(createReference(reference));
524524
expect(mockStore.canStore).toHaveBeenCalled();
525525
expect(mockStore.store).toHaveBeenCalled();
526526
});
527527
});
528528

529+
test("should passthrough output if it's a reference", async () => {
530+
const reference = { store: "mock" };
531+
532+
{
533+
const payload = createReference(reference);
534+
const handler = useStore({
535+
stores: [mockStore],
536+
loadingOptions: { skip: true },
537+
storingOptions: {
538+
minSize: Sizes.ZERO,
539+
},
540+
});
541+
542+
await expect(handler(payload, context)).resolves.toEqual(payload);
543+
expect(mockStore.canStore).not.toHaveBeenCalled();
544+
expect(mockStore.store).not.toHaveBeenCalled();
545+
}
546+
547+
{
548+
const payload = { a: createReference(reference) };
549+
const handler = useStore({
550+
stores: [mockStore],
551+
loadingOptions: { skip: true },
552+
storingOptions: {
553+
minSize: Sizes.ZERO,
554+
selector: "a",
555+
},
556+
});
557+
558+
await expect(handler(payload, context)).resolves.toEqual(payload);
559+
expect(mockStore.canStore).not.toHaveBeenCalled();
560+
expect(mockStore.store).not.toHaveBeenCalled();
561+
}
562+
563+
{
564+
const payload = { a: { b: createReference(reference) } };
565+
const handler = useStore({
566+
stores: [mockStore],
567+
loadingOptions: { skip: true },
568+
storingOptions: {
569+
minSize: Sizes.ZERO,
570+
selector: "a.b",
571+
},
572+
});
573+
574+
await expect(handler(payload, context)).resolves.toEqual(payload);
575+
expect(mockStore.canStore).not.toHaveBeenCalled();
576+
expect(mockStore.store).not.toHaveBeenCalled();
577+
}
578+
579+
{
580+
const payload = {
581+
a: {
582+
b: { c: createReference(reference) },
583+
},
584+
};
585+
const handler = useStore({
586+
stores: [mockStore],
587+
loadingOptions: { skip: true },
588+
storingOptions: {
589+
minSize: Sizes.ZERO,
590+
selector: "a.b.c",
591+
},
592+
});
593+
594+
await expect(handler(payload, context)).resolves.toEqual(payload);
595+
expect(mockStore.canStore).not.toHaveBeenCalled();
596+
expect(mockStore.store).not.toHaveBeenCalled();
597+
}
598+
599+
{
600+
const payload = {
601+
a: {
602+
b: { c: [createReference(reference), createReference(reference)] },
603+
},
604+
};
605+
const handler = useStore({
606+
stores: [mockStore],
607+
loadingOptions: { skip: true },
608+
storingOptions: {
609+
minSize: Sizes.ZERO,
610+
selector: "a.b.c[0]",
611+
},
612+
});
613+
614+
await expect(handler(payload, context)).resolves.toEqual(payload);
615+
expect(mockStore.canStore).not.toHaveBeenCalled();
616+
expect(mockStore.store).not.toHaveBeenCalled();
617+
}
618+
619+
{
620+
const payload = {
621+
a: {
622+
b: { c: [createReference(reference), createReference(reference)] },
623+
},
624+
};
625+
const handler = useStore({
626+
stores: [mockStore],
627+
loadingOptions: { skip: true },
628+
storingOptions: {
629+
minSize: Sizes.ZERO,
630+
selector: "a.b.c[*]",
631+
},
632+
});
633+
634+
await expect(handler(payload, context)).resolves.toEqual(payload);
635+
expect(mockStore.canStore).not.toHaveBeenCalled();
636+
expect(mockStore.store).not.toHaveBeenCalled();
637+
}
638+
});
639+
529640
test("should passthrough output if stores are empty", async () => {
530641
const payload = {
531642
foo: "bar",
@@ -694,7 +805,7 @@ describe("store", () => {
694805

695806
await expect(
696807
handler(structuredClone(payload), context),
697-
).resolves.toEqual({ [MIDDY_STORE]: reference });
808+
).resolves.toEqual(createReference(reference));
698809
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
699810
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
700811
}
@@ -710,7 +821,7 @@ describe("store", () => {
710821

711822
await expect(
712823
handler(structuredClone(payload), context),
713-
).resolves.toEqual({ [MIDDY_STORE]: reference });
824+
).resolves.toEqual(createReference(reference));
714825
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
715826
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
716827
}
@@ -727,7 +838,7 @@ describe("store", () => {
727838

728839
await expect(
729840
handler(structuredClone(payload), context),
730-
).resolves.toEqual({ [MIDDY_STORE]: reference });
841+
).resolves.toEqual(createReference(reference));
731842
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
732843
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
733844
}
@@ -744,7 +855,7 @@ describe("store", () => {
744855

745856
await expect(
746857
handler(structuredClone(payload), context),
747-
).resolves.toEqual({ [MIDDY_STORE]: reference });
858+
).resolves.toEqual(createReference(reference));
748859
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
749860
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
750861
}
@@ -771,7 +882,7 @@ describe("store", () => {
771882

772883
await expect(
773884
handler(structuredClone(payload), context),
774-
).resolves.toEqual({ [MIDDY_STORE]: reference });
885+
).resolves.toEqual(createReference(reference));
775886
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
776887
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
777888
}
@@ -787,7 +898,7 @@ describe("store", () => {
787898

788899
await expect(
789900
handler(structuredClone(payload), context),
790-
).resolves.toEqual({ [MIDDY_STORE]: reference });
901+
).resolves.toEqual(createReference(reference));
791902
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
792903
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
793904
}
@@ -803,7 +914,7 @@ describe("store", () => {
803914

804915
await expect(
805916
handler(structuredClone(payload), context),
806-
).resolves.toEqual({ a: { [MIDDY_STORE]: reference } });
917+
).resolves.toEqual({ a: createReference(reference) });
807918
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
808919
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
809920
}
@@ -819,7 +930,7 @@ describe("store", () => {
819930

820931
await expect(
821932
handler(structuredClone(payload), context),
822-
).resolves.toEqual({ a: { b: { [MIDDY_STORE]: reference } } });
933+
).resolves.toEqual({ a: { b: createReference(reference) } });
823934
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
824935
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
825936
}
@@ -835,7 +946,7 @@ describe("store", () => {
835946

836947
await expect(
837948
handler(structuredClone(payload), context),
838-
).resolves.toEqual({ a: { b: { c: { [MIDDY_STORE]: reference } } } });
949+
).resolves.toEqual({ a: { b: { c: createReference(reference) } } });
839950
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
840951
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
841952
}
@@ -852,7 +963,7 @@ describe("store", () => {
852963
await expect(
853964
handler(structuredClone(payload), context),
854965
).resolves.toEqual({
855-
a: { b: { c: [{ [MIDDY_STORE]: reference }, { foo: "bar" }] } },
966+
a: { b: { c: [createReference(reference), { foo: "bar" }] } },
856967
});
857968
expect(mockStore.canStore).toHaveBeenCalledWith({ payload, byteSize });
858969
expect(mockStore.store).toHaveBeenCalledWith({ payload, byteSize });
@@ -872,7 +983,7 @@ describe("store", () => {
872983
).resolves.toEqual({
873984
a: {
874985
b: {
875-
c: [{ [MIDDY_STORE]: reference }, { [MIDDY_STORE]: reference }],
986+
c: [createReference(reference), createReference(reference)],
876987
},
877988
},
878989
});

packages/core/test/utils.unit.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { randomStringInBytes } from "../src/internal.js";
33
import { MIDDY_STORE, Sizes } from "../src/store.js";
44
import {
55
calculateByteSize,
6+
createReference,
67
hasReference,
78
isObject,
89
resolvableFn,
@@ -164,3 +165,11 @@ describe("getReference", () => {
164165
},
165166
);
166167
});
168+
169+
describe("createReference", () => {
170+
test("should create a reference", async () => {
171+
const reference = "foo";
172+
const result = createReference(reference);
173+
expect(result).toEqual({ [MIDDY_STORE]: reference });
174+
});
175+
});

0 commit comments

Comments
 (0)