@auto-engineer/server-generator-apollo-emmett 0.11.13 → 0.11.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +8 -0
- package/dist/src/codegen/templates/query/projection.specs.specs.ts +368 -0
- package/dist/src/codegen/templates/query/projection.specs.ts +404 -0
- package/dist/src/codegen/templates/query/projection.ts.ejs +64 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/codegen/templates/query/projection.specs.specs.ts +368 -0
- package/src/codegen/templates/query/projection.specs.ts +404 -0
- package/src/codegen/templates/query/projection.ts.ejs +64 -11
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/server-generator-apollo-emmett@0.11.
|
|
2
|
+
> @auto-engineer/server-generator-apollo-emmett@0.11.14 build /home/runner/work/auto-engineer/auto-engineer/packages/server-generator-apollo-emmett
|
|
3
3
|
> tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp src/server.ts dist/src && cp -r src/utils dist/src && cp -r src/domain dist/src
|
|
4
4
|
|
|
5
5
|
Fixed ESM imports in dist/
|
package/CHANGELOG.md
CHANGED
|
@@ -620,4 +620,372 @@ describe('projection.specs.ts.ejs', () => {
|
|
|
620
620
|
// canHandle must include BOTH events
|
|
621
621
|
expect(projectionFile?.contents).toContain("canHandle: ['QuestionnaireLinkSent', 'QuestionAnswered']");
|
|
622
622
|
});
|
|
623
|
+
|
|
624
|
+
it('should generate a valid test spec for singleton projection', async () => {
|
|
625
|
+
const spec: SpecsSchema = {
|
|
626
|
+
variant: 'specs',
|
|
627
|
+
narratives: [
|
|
628
|
+
{
|
|
629
|
+
name: 'todo-flow',
|
|
630
|
+
slices: [
|
|
631
|
+
{
|
|
632
|
+
type: 'command',
|
|
633
|
+
name: 'manage-todo',
|
|
634
|
+
stream: 'todo-${todoId}',
|
|
635
|
+
client: { description: '' },
|
|
636
|
+
server: {
|
|
637
|
+
description: '',
|
|
638
|
+
specs: {
|
|
639
|
+
name: 'Manage todo command',
|
|
640
|
+
rules: [
|
|
641
|
+
{
|
|
642
|
+
description: 'Should handle todo operations',
|
|
643
|
+
examples: [
|
|
644
|
+
{
|
|
645
|
+
description: 'User adds todo',
|
|
646
|
+
when: {
|
|
647
|
+
commandRef: 'AddTodo',
|
|
648
|
+
exampleData: {
|
|
649
|
+
todoId: 'todo_123',
|
|
650
|
+
title: 'Buy milk',
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
then: [
|
|
654
|
+
{
|
|
655
|
+
eventRef: 'TodoAdded',
|
|
656
|
+
exampleData: {
|
|
657
|
+
todoId: 'todo_123',
|
|
658
|
+
title: 'Buy milk',
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
],
|
|
662
|
+
},
|
|
663
|
+
],
|
|
664
|
+
},
|
|
665
|
+
],
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
type: 'query',
|
|
671
|
+
name: 'view-summary',
|
|
672
|
+
stream: 'todos',
|
|
673
|
+
client: { description: '' },
|
|
674
|
+
server: {
|
|
675
|
+
description: '',
|
|
676
|
+
data: [
|
|
677
|
+
{
|
|
678
|
+
target: {
|
|
679
|
+
type: 'State',
|
|
680
|
+
name: 'TodoSummary',
|
|
681
|
+
},
|
|
682
|
+
origin: {
|
|
683
|
+
type: 'projection',
|
|
684
|
+
name: 'TodoSummaryProjection',
|
|
685
|
+
singleton: true,
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
],
|
|
689
|
+
specs: {
|
|
690
|
+
name: 'View summary query',
|
|
691
|
+
rules: [
|
|
692
|
+
{
|
|
693
|
+
description: 'Should aggregate todo counts',
|
|
694
|
+
examples: [
|
|
695
|
+
{
|
|
696
|
+
description: 'Todo added updates count',
|
|
697
|
+
when: [
|
|
698
|
+
{
|
|
699
|
+
eventRef: 'TodoAdded',
|
|
700
|
+
exampleData: {
|
|
701
|
+
todoId: 'todo_123',
|
|
702
|
+
title: 'Buy milk',
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
],
|
|
706
|
+
then: [
|
|
707
|
+
{
|
|
708
|
+
stateRef: 'TodoSummary',
|
|
709
|
+
exampleData: {
|
|
710
|
+
totalCount: 1,
|
|
711
|
+
},
|
|
712
|
+
},
|
|
713
|
+
],
|
|
714
|
+
},
|
|
715
|
+
],
|
|
716
|
+
},
|
|
717
|
+
],
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
],
|
|
722
|
+
},
|
|
723
|
+
],
|
|
724
|
+
messages: [
|
|
725
|
+
{
|
|
726
|
+
type: 'command',
|
|
727
|
+
name: 'AddTodo',
|
|
728
|
+
fields: [
|
|
729
|
+
{ name: 'todoId', type: 'string', required: true },
|
|
730
|
+
{ name: 'title', type: 'string', required: true },
|
|
731
|
+
],
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
type: 'event',
|
|
735
|
+
name: 'TodoAdded',
|
|
736
|
+
source: 'internal',
|
|
737
|
+
fields: [
|
|
738
|
+
{ name: 'todoId', type: 'string', required: true },
|
|
739
|
+
{ name: 'title', type: 'string', required: true },
|
|
740
|
+
],
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
type: 'state',
|
|
744
|
+
name: 'TodoSummary',
|
|
745
|
+
fields: [{ name: 'totalCount', type: 'number', required: true }],
|
|
746
|
+
},
|
|
747
|
+
],
|
|
748
|
+
} as SpecsSchema;
|
|
749
|
+
|
|
750
|
+
const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
|
|
751
|
+
const specFile = plans.find((p) => p.outputPath.endsWith('view-summary/projection.specs.ts'));
|
|
752
|
+
|
|
753
|
+
expect(specFile?.contents).toMatchInlineSnapshot(`
|
|
754
|
+
"import { describe, it, beforeEach, expect } from 'vitest';
|
|
755
|
+
import { InMemoryProjectionSpec } from '@event-driven-io/emmett';
|
|
756
|
+
import { projection } from './projection';
|
|
757
|
+
import type { TodoAdded } from '../manage-todo/events';
|
|
758
|
+
import { TodoSummary } from './state';
|
|
759
|
+
|
|
760
|
+
type ProjectionEvent = TodoAdded;
|
|
761
|
+
|
|
762
|
+
describe('Should aggregate todo counts', () => {
|
|
763
|
+
let given: InMemoryProjectionSpec<ProjectionEvent>;
|
|
764
|
+
|
|
765
|
+
beforeEach(() => {
|
|
766
|
+
given = InMemoryProjectionSpec.for({ projection });
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
it('Todo added updates count', () =>
|
|
770
|
+
given([])
|
|
771
|
+
.when([
|
|
772
|
+
{
|
|
773
|
+
type: 'TodoAdded',
|
|
774
|
+
data: {
|
|
775
|
+
todoId: 'todo_123',
|
|
776
|
+
title: 'Buy milk',
|
|
777
|
+
},
|
|
778
|
+
metadata: {
|
|
779
|
+
streamName: 'todos',
|
|
780
|
+
streamPosition: 1n,
|
|
781
|
+
globalPosition: 1n,
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
])
|
|
785
|
+
.then(async (state) => {
|
|
786
|
+
const document = await state.database
|
|
787
|
+
.collection<TodoSummary>('TodoSummaryProjection')
|
|
788
|
+
.findOne((doc) => doc.id === 'test-id');
|
|
789
|
+
|
|
790
|
+
const expected: TodoSummary = {
|
|
791
|
+
totalCount: 1,
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
expect(document).toMatchObject(expected);
|
|
795
|
+
}));
|
|
796
|
+
});
|
|
797
|
+
"
|
|
798
|
+
`);
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
it('should generate a valid test spec for composite key projection', async () => {
|
|
802
|
+
const spec: SpecsSchema = {
|
|
803
|
+
variant: 'specs',
|
|
804
|
+
narratives: [
|
|
805
|
+
{
|
|
806
|
+
name: 'user-project-flow',
|
|
807
|
+
slices: [
|
|
808
|
+
{
|
|
809
|
+
type: 'command',
|
|
810
|
+
name: 'manage-user-project',
|
|
811
|
+
stream: 'user-project-${userId}-${projectId}',
|
|
812
|
+
client: { description: '' },
|
|
813
|
+
server: {
|
|
814
|
+
description: '',
|
|
815
|
+
specs: {
|
|
816
|
+
name: 'Manage user project command',
|
|
817
|
+
rules: [
|
|
818
|
+
{
|
|
819
|
+
description: 'Should handle user project operations',
|
|
820
|
+
examples: [
|
|
821
|
+
{
|
|
822
|
+
description: 'User joins project',
|
|
823
|
+
when: {
|
|
824
|
+
commandRef: 'JoinProject',
|
|
825
|
+
exampleData: {
|
|
826
|
+
userId: 'user_123',
|
|
827
|
+
projectId: 'proj_456',
|
|
828
|
+
role: 'developer',
|
|
829
|
+
},
|
|
830
|
+
},
|
|
831
|
+
then: [
|
|
832
|
+
{
|
|
833
|
+
eventRef: 'UserJoinedProject',
|
|
834
|
+
exampleData: {
|
|
835
|
+
userId: 'user_123',
|
|
836
|
+
projectId: 'proj_456',
|
|
837
|
+
role: 'developer',
|
|
838
|
+
},
|
|
839
|
+
},
|
|
840
|
+
],
|
|
841
|
+
},
|
|
842
|
+
],
|
|
843
|
+
},
|
|
844
|
+
],
|
|
845
|
+
},
|
|
846
|
+
},
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
type: 'query',
|
|
850
|
+
name: 'view-user-projects',
|
|
851
|
+
stream: 'user-projects',
|
|
852
|
+
client: { description: '' },
|
|
853
|
+
server: {
|
|
854
|
+
description: '',
|
|
855
|
+
data: [
|
|
856
|
+
{
|
|
857
|
+
target: {
|
|
858
|
+
type: 'State',
|
|
859
|
+
name: 'UserProject',
|
|
860
|
+
},
|
|
861
|
+
origin: {
|
|
862
|
+
type: 'projection',
|
|
863
|
+
name: 'UserProjectsProjection',
|
|
864
|
+
idField: ['userId', 'projectId'],
|
|
865
|
+
},
|
|
866
|
+
},
|
|
867
|
+
],
|
|
868
|
+
specs: {
|
|
869
|
+
name: 'View user projects query',
|
|
870
|
+
rules: [
|
|
871
|
+
{
|
|
872
|
+
description: 'Should track user project memberships',
|
|
873
|
+
examples: [
|
|
874
|
+
{
|
|
875
|
+
description: 'User joins project',
|
|
876
|
+
when: [
|
|
877
|
+
{
|
|
878
|
+
eventRef: 'UserJoinedProject',
|
|
879
|
+
exampleData: {
|
|
880
|
+
userId: 'user_123',
|
|
881
|
+
projectId: 'proj_456',
|
|
882
|
+
role: 'developer',
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
],
|
|
886
|
+
then: [
|
|
887
|
+
{
|
|
888
|
+
stateRef: 'UserProject',
|
|
889
|
+
exampleData: {
|
|
890
|
+
userId: 'user_123',
|
|
891
|
+
projectId: 'proj_456',
|
|
892
|
+
role: 'developer',
|
|
893
|
+
},
|
|
894
|
+
},
|
|
895
|
+
],
|
|
896
|
+
},
|
|
897
|
+
],
|
|
898
|
+
},
|
|
899
|
+
],
|
|
900
|
+
},
|
|
901
|
+
},
|
|
902
|
+
},
|
|
903
|
+
],
|
|
904
|
+
},
|
|
905
|
+
],
|
|
906
|
+
messages: [
|
|
907
|
+
{
|
|
908
|
+
type: 'command',
|
|
909
|
+
name: 'JoinProject',
|
|
910
|
+
fields: [
|
|
911
|
+
{ name: 'userId', type: 'string', required: true },
|
|
912
|
+
{ name: 'projectId', type: 'string', required: true },
|
|
913
|
+
{ name: 'role', type: 'string', required: true },
|
|
914
|
+
],
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
type: 'event',
|
|
918
|
+
name: 'UserJoinedProject',
|
|
919
|
+
source: 'internal',
|
|
920
|
+
fields: [
|
|
921
|
+
{ name: 'userId', type: 'string', required: true },
|
|
922
|
+
{ name: 'projectId', type: 'string', required: true },
|
|
923
|
+
{ name: 'role', type: 'string', required: true },
|
|
924
|
+
],
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
type: 'state',
|
|
928
|
+
name: 'UserProject',
|
|
929
|
+
fields: [
|
|
930
|
+
{ name: 'userId', type: 'string', required: true },
|
|
931
|
+
{ name: 'projectId', type: 'string', required: true },
|
|
932
|
+
{ name: 'role', type: 'string', required: true },
|
|
933
|
+
],
|
|
934
|
+
},
|
|
935
|
+
],
|
|
936
|
+
} as SpecsSchema;
|
|
937
|
+
|
|
938
|
+
const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
|
|
939
|
+
const specFile = plans.find((p) => p.outputPath.endsWith('view-user-projects/projection.specs.ts'));
|
|
940
|
+
|
|
941
|
+
expect(specFile?.contents).toMatchInlineSnapshot(`
|
|
942
|
+
"import { describe, it, beforeEach, expect } from 'vitest';
|
|
943
|
+
import { InMemoryProjectionSpec } from '@event-driven-io/emmett';
|
|
944
|
+
import { projection } from './projection';
|
|
945
|
+
import type { UserJoinedProject } from '../manage-user-project/events';
|
|
946
|
+
import { UserProject } from './state';
|
|
947
|
+
|
|
948
|
+
type ProjectionEvent = UserJoinedProject;
|
|
949
|
+
|
|
950
|
+
describe('Should track user project memberships', () => {
|
|
951
|
+
let given: InMemoryProjectionSpec<ProjectionEvent>;
|
|
952
|
+
|
|
953
|
+
beforeEach(() => {
|
|
954
|
+
given = InMemoryProjectionSpec.for({ projection });
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
it('User joins project', () =>
|
|
958
|
+
given([])
|
|
959
|
+
.when([
|
|
960
|
+
{
|
|
961
|
+
type: 'UserJoinedProject',
|
|
962
|
+
data: {
|
|
963
|
+
userId: 'user_123',
|
|
964
|
+
projectId: 'proj_456',
|
|
965
|
+
role: 'developer',
|
|
966
|
+
},
|
|
967
|
+
metadata: {
|
|
968
|
+
streamName: 'user-projects',
|
|
969
|
+
streamPosition: 1n,
|
|
970
|
+
globalPosition: 1n,
|
|
971
|
+
},
|
|
972
|
+
},
|
|
973
|
+
])
|
|
974
|
+
.then(async (state) => {
|
|
975
|
+
const document = await state.database
|
|
976
|
+
.collection<UserProject>('UserProjectsProjection')
|
|
977
|
+
.findOne((doc) => doc.id === 'test-id');
|
|
978
|
+
|
|
979
|
+
const expected: UserProject = {
|
|
980
|
+
userId: 'user_123',
|
|
981
|
+
projectId: 'proj_456',
|
|
982
|
+
role: 'developer',
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
expect(document).toMatchObject(expected);
|
|
986
|
+
}));
|
|
987
|
+
});
|
|
988
|
+
"
|
|
989
|
+
`);
|
|
990
|
+
});
|
|
623
991
|
});
|