@auto-engineer/server-generator-apollo-emmett 1.110.4 → 1.110.5
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/.turbo/turbo-test.log +5 -5
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +41 -0
- package/dist/src/codegen/templates/command/decide.specs.ts +12 -8
- package/dist/src/codegen/templates/command/decide.specs.ts.ejs +6 -1
- package/dist/src/codegen/templates/command/decide.ts.ejs +3 -2
- package/dist/src/codegen/templates/command/evolve.specs.ts +5 -0
- package/dist/src/codegen/templates/command/evolve.ts.ejs +5 -0
- package/dist/src/codegen/templates/query/projection.specs.specs.ts +228 -5
- package/dist/src/codegen/templates/query/projection.specs.ts +24 -3
- package/dist/src/codegen/templates/query/projection.specs.ts.ejs +15 -5
- package/dist/src/codegen/templates/query/projection.ts.ejs +9 -3
- package/dist/src/codegen/templates/query/query.resolver.specs.ts +4 -4
- package/dist/src/codegen/templates/query/query.resolver.ts.ejs +1 -1
- package/dist/src/codegen/templates/react/react.specs.ts +7 -0
- package/dist/src/codegen/templates/react/react.ts.ejs +7 -0
- package/dist/src/codegen/templates/react/register.specs.ts +6 -0
- package/dist/src/codegen/templates/react/register.ts.ejs +6 -0
- package/ketchup-plan.md +5 -0
- package/package.json +4 -4
- package/src/codegen/templates/command/decide.specs.ts +12 -8
- package/src/codegen/templates/command/decide.specs.ts.ejs +6 -1
- package/src/codegen/templates/command/decide.ts.ejs +3 -2
- package/src/codegen/templates/command/evolve.specs.ts +5 -0
- package/src/codegen/templates/command/evolve.ts.ejs +5 -0
- package/src/codegen/templates/query/projection.specs.specs.ts +228 -5
- package/src/codegen/templates/query/projection.specs.ts +24 -3
- package/src/codegen/templates/query/projection.specs.ts.ejs +15 -5
- package/src/codegen/templates/query/projection.ts.ejs +9 -3
- package/src/codegen/templates/query/query.resolver.specs.ts +4 -4
- package/src/codegen/templates/query/query.resolver.ts.ejs +1 -1
- package/src/codegen/templates/react/react.specs.ts +7 -0
- package/src/codegen/templates/react/react.ts.ejs +7 -0
- package/src/codegen/templates/react/register.specs.ts +6 -0
- package/src/codegen/templates/react/register.ts.ejs +6 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/server-generator-apollo-emmett@1.110.
|
|
2
|
+
> @auto-engineer/server-generator-apollo-emmett@1.110.5 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/.turbo/turbo-test.log
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/server-generator-apollo-emmett@1.110.
|
|
2
|
+
> @auto-engineer/server-generator-apollo-emmett@1.110.4 test /home/runner/work/auto-engineer/auto-engineer/packages/server-generator-apollo-emmett
|
|
3
3
|
> vitest run --reporter=dot
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/auto-engineer/auto-engineer/packages/server-generator-apollo-emmett[39m
|
|
7
7
|
|
|
8
|
-
[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[2m[90m-[39m[22m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m
|
|
8
|
+
[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[2m[90m-[39m[22m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m[33m[39m[32m·[39m
|
|
9
9
|
|
|
10
10
|
[2m Test Files [22m [1m[32m34 passed[39m[22m[2m | [22m[33m1 skipped[39m[90m (35)[39m
|
|
11
|
-
[2m Tests [22m [1m[
|
|
12
|
-
[2m Start at [22m 19:
|
|
13
|
-
[2m Duration [22m
|
|
11
|
+
[2m Tests [22m [1m[32m248 passed[39m[22m[2m | [22m[33m1 skipped[39m[90m (249)[39m
|
|
12
|
+
[2m Start at [22m 19:20:24
|
|
13
|
+
[2m Duration [22m 37.15s[2m (transform 6.96s, setup 0ms, collect 76.28s, tests 18.25s, environment 21ms, prepare 5.95s)[22m
|
|
14
14
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/server-generator-apollo-emmett@1.110.
|
|
2
|
+
> @auto-engineer/server-generator-apollo-emmett@1.110.4 type-check /home/runner/work/auto-engineer/auto-engineer/packages/server-generator-apollo-emmett
|
|
3
3
|
> tsc --noEmit --project tsconfig.json
|
|
4
4
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @auto-engineer/server-generator-apollo-emmett
|
|
2
2
|
|
|
3
|
+
## 1.110.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`0e1e74c`](https://github.com/BeOnAuto/auto-engineer/commit/0e1e74ce67838d17108d50173d7f435d38307fca) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add test for query arg exclusion with differing values
|
|
8
|
+
|
|
9
|
+
- [`31f4711`](https://github.com/BeOnAuto/auto-engineer/commit/31f47112be977b55d13bfcf24f3c38f5511d8307) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add ketchup plan for projection spec query arg fix
|
|
10
|
+
|
|
11
|
+
- [`24756e3`](https://github.com/BeOnAuto/auto-engineer/commit/24756e3c626032108e0a7d4fb5e9fa4792853f53) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **global**: increase express.json body size limit to 10mb
|
|
12
|
+
- **server-implementer**: exclude spec files from AI context in implement-slice
|
|
13
|
+
- **server-generator-apollo-emmett**: enrich missing event data in react specs template
|
|
14
|
+
|
|
15
|
+
- [`bf35e68`](https://github.com/BeOnAuto/auto-engineer/commit/bf35e68a2e76d6943c97c5036b899b087bc68a32) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add CONSTRAINTS block to evolve.ts template
|
|
16
|
+
|
|
17
|
+
- [`437d8cc`](https://github.com/BeOnAuto/auto-engineer/commit/437d8ccd999f8a6dd606f1b3767c9c3af7d11edf) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **global**: version packages
|
|
18
|
+
- **pipeline**: remove redundant client checks from pipeline events
|
|
19
|
+
|
|
20
|
+
- [`9e2ccac`](https://github.com/BeOnAuto/auto-engineer/commit/9e2ccacccff33c9693829178af4eab28cf709e9f) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: exclude query arg fields from projection spec expected state
|
|
21
|
+
|
|
22
|
+
- [`d5d7a36`](https://github.com/BeOnAuto/auto-engineer/commit/d5d7a368505d6450909589c43bf8033a11e55e5a) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add CONSTRAINTS block to react.ts template
|
|
23
|
+
|
|
24
|
+
- [`8be0b53`](https://github.com/BeOnAuto/auto-engineer/commit/8be0b53f9e6f51aeb4759e461e8511de3c601885) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **global**: add ketchup plan for post-implementation fixes round 2
|
|
25
|
+
|
|
26
|
+
- [`b2614ef`](https://github.com/BeOnAuto/auto-engineer/commit/b2614ef82c97b4766fdc606737ae6d5ab481c2e5) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **global**: mark all round 2 fix bursts as done in ketchup plan
|
|
27
|
+
|
|
28
|
+
- [`142abac`](https://github.com/BeOnAuto/auto-engineer/commit/142abacab3ea4e0357372850ff8bdf0b55cd8f7a) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add CONSTRAINTS block to projection.ts and fix cast guidance
|
|
29
|
+
|
|
30
|
+
- [`9684c1f`](https://github.com/BeOnAuto/auto-engineer/commit/9684c1f1e45791b7bc6542229ef48ca76b8eef80) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - Fixed missing dependencies in React client generation to ensure proper optimization support
|
|
31
|
+
|
|
32
|
+
- [`aa189ea`](https://github.com/BeOnAuto/auto-engineer/commit/aa189eaa1d6309126c2554b717ddd51cc11b16b7) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: broaden cast prohibition and add field constraint in decide.ts
|
|
33
|
+
|
|
34
|
+
- [`4646433`](https://github.com/BeOnAuto/auto-engineer/commit/4646433ec25262d042001e5fd127a9b24003dfea) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: filter command .when() data to schema fields in decide.specs
|
|
35
|
+
|
|
36
|
+
- [`b64ef2e`](https://github.com/BeOnAuto/auto-engineer/commit/b64ef2e679462a8389b27e7fd0b59d2db516d10f) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: use NOTE instead of TODO for non-matching query args
|
|
37
|
+
|
|
38
|
+
- [`3b0afad`](https://github.com/BeOnAuto/auto-engineer/commit/3b0afad3754c7a89bfb5c83fab8138ca97eb7b21) Thanks [@rami-hatoum](https://github.com/rami-hatoum)! - - **server-generator-apollo-emmett**: add CONSTRAINTS block to register.ts template
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [[`0e1e74c`](https://github.com/BeOnAuto/auto-engineer/commit/0e1e74ce67838d17108d50173d7f435d38307fca), [`31f4711`](https://github.com/BeOnAuto/auto-engineer/commit/31f47112be977b55d13bfcf24f3c38f5511d8307), [`24756e3`](https://github.com/BeOnAuto/auto-engineer/commit/24756e3c626032108e0a7d4fb5e9fa4792853f53), [`bf35e68`](https://github.com/BeOnAuto/auto-engineer/commit/bf35e68a2e76d6943c97c5036b899b087bc68a32), [`437d8cc`](https://github.com/BeOnAuto/auto-engineer/commit/437d8ccd999f8a6dd606f1b3767c9c3af7d11edf), [`9e2ccac`](https://github.com/BeOnAuto/auto-engineer/commit/9e2ccacccff33c9693829178af4eab28cf709e9f), [`d5d7a36`](https://github.com/BeOnAuto/auto-engineer/commit/d5d7a368505d6450909589c43bf8033a11e55e5a), [`8be0b53`](https://github.com/BeOnAuto/auto-engineer/commit/8be0b53f9e6f51aeb4759e461e8511de3c601885), [`b2614ef`](https://github.com/BeOnAuto/auto-engineer/commit/b2614ef82c97b4766fdc606737ae6d5ab481c2e5), [`142abac`](https://github.com/BeOnAuto/auto-engineer/commit/142abacab3ea4e0357372850ff8bdf0b55cd8f7a), [`9684c1f`](https://github.com/BeOnAuto/auto-engineer/commit/9684c1f1e45791b7bc6542229ef48ca76b8eef80), [`aa189ea`](https://github.com/BeOnAuto/auto-engineer/commit/aa189eaa1d6309126c2554b717ddd51cc11b16b7), [`4646433`](https://github.com/BeOnAuto/auto-engineer/commit/4646433ec25262d042001e5fd127a9b24003dfea), [`b64ef2e`](https://github.com/BeOnAuto/auto-engineer/commit/b64ef2e679462a8389b27e7fd0b59d2db516d10f), [`3b0afad`](https://github.com/BeOnAuto/auto-engineer/commit/3b0afad3754c7a89bfb5c83fab8138ca97eb7b21)]:
|
|
41
|
+
- @auto-engineer/message-bus@1.110.5
|
|
42
|
+
- @auto-engineer/narrative@1.110.5
|
|
43
|
+
|
|
3
44
|
## 1.110.4
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
|
@@ -97,13 +97,14 @@ describe('decide.ts.ejs', () => {
|
|
|
97
97
|
* You should:
|
|
98
98
|
* - Validate the command input fields
|
|
99
99
|
* - Inspect the current domain \`_state\` to determine if the command is allowed
|
|
100
|
-
* -
|
|
101
|
-
*
|
|
100
|
+
* - NEVER use \`as SomeType\` type assertions — not \`as any\`, not \`as EventType\`, no casts at all. Use typed variable declarations.
|
|
101
|
+
* - If State is a discriminated union, narrow with the discriminant: \`if (_state.status !== 'active') throw new IllegalStateError('...');\`
|
|
102
102
|
* After narrowing, access variant fields directly — TypeScript infers the correct type.
|
|
103
103
|
* - If invalid, throw one of the following domain errors: \`IllegalStateError\`
|
|
104
104
|
* ⚠️ Error constructors: IllegalStateError takes a string message
|
|
105
105
|
* - If valid, return one or more events with the correct structure
|
|
106
106
|
*
|
|
107
|
+
* - Only destructure/reference command.data fields that exist in the command type (imported from ./commands). Do NOT access fields not declared in the type, even if example data includes them.
|
|
107
108
|
* ⚠️ Only read from inputs — never mutate them. \`evolve.ts\` handles state updates.
|
|
108
109
|
|
|
109
110
|
* Business rules:
|
|
@@ -235,13 +236,14 @@ describe('decide.ts.ejs', () => {
|
|
|
235
236
|
* You should:
|
|
236
237
|
* - Validate the command input fields
|
|
237
238
|
* - Inspect the current domain \`_state\` to determine if the command is allowed
|
|
238
|
-
* -
|
|
239
|
-
*
|
|
239
|
+
* - NEVER use \`as SomeType\` type assertions — not \`as any\`, not \`as EventType\`, no casts at all. Use typed variable declarations.
|
|
240
|
+
* - If State is a discriminated union, narrow with the discriminant: \`if (_state.status !== 'active') throw new IllegalStateError('...');\`
|
|
240
241
|
* After narrowing, access variant fields directly — TypeScript infers the correct type.
|
|
241
242
|
* - If invalid, throw one of the following domain errors: \`IllegalStateError\`
|
|
242
243
|
* ⚠️ Error constructors: IllegalStateError takes a string message
|
|
243
244
|
* - If valid, return one or more events with the correct structure
|
|
244
245
|
*
|
|
246
|
+
* - Only destructure/reference command.data fields that exist in the command type (imported from ./commands). Do NOT access fields not declared in the type, even if example data includes them.
|
|
245
247
|
* ⚠️ Only read from inputs — never mutate them. \`evolve.ts\` handles state updates.
|
|
246
248
|
|
|
247
249
|
* Business rules:
|
|
@@ -399,13 +401,14 @@ describe('decide.ts.ejs', () => {
|
|
|
399
401
|
* You should:
|
|
400
402
|
* - Validate the command input fields
|
|
401
403
|
* - Inspect the current domain \`_state\` to determine if the command is allowed
|
|
402
|
-
* -
|
|
403
|
-
*
|
|
404
|
+
* - NEVER use \`as SomeType\` type assertions — not \`as any\`, not \`as EventType\`, no casts at all. Use typed variable declarations.
|
|
405
|
+
* - If State is a discriminated union, narrow with the discriminant: \`if (_state.status !== 'active') throw new IllegalStateError('...');\`
|
|
404
406
|
* After narrowing, access variant fields directly — TypeScript infers the correct type.
|
|
405
407
|
* - If invalid, throw one of the following domain errors: \`IllegalStateError\`, \`ValidationError\`
|
|
406
408
|
* ⚠️ Error constructors: IllegalStateError takes a string message, ValidationError takes a string message
|
|
407
409
|
* - If valid, return one or more events with the correct structure
|
|
408
410
|
*
|
|
411
|
+
* - Only destructure/reference command.data fields that exist in the command type (imported from ./commands). Do NOT access fields not declared in the type, even if example data includes them.
|
|
409
412
|
* ⚠️ Only read from inputs — never mutate them. \`evolve.ts\` handles state updates.
|
|
410
413
|
|
|
411
414
|
* Business rules:
|
|
@@ -601,14 +604,15 @@ describe('decide.ts.ejs', () => {
|
|
|
601
604
|
* You should:
|
|
602
605
|
* - Validate the command input fields
|
|
603
606
|
* - Inspect the current domain \`_state\` to determine if the command is allowed
|
|
604
|
-
* -
|
|
605
|
-
*
|
|
607
|
+
* - NEVER use \`as SomeType\` type assertions — not \`as any\`, not \`as EventType\`, no casts at all. Use typed variable declarations.
|
|
608
|
+
* - If State is a discriminated union, narrow with the discriminant: \`if (_state.status !== 'active') throw new IllegalStateError('...');\`
|
|
606
609
|
* After narrowing, access variant fields directly — TypeScript infers the correct type.
|
|
607
610
|
* - Use \`products\` (integration result) to enrich or filter the output
|
|
608
611
|
* - If invalid, throw one of the following domain errors: \`IllegalStateError\`
|
|
609
612
|
* ⚠️ Error constructors: IllegalStateError takes a string message
|
|
610
613
|
* - If valid, return one or more events with the correct structure
|
|
611
614
|
*
|
|
615
|
+
* - Only destructure/reference command.data fields that exist in the command type (imported from ./commands). Do NOT access fields not declared in the type, even if example data includes them.
|
|
612
616
|
* ⚠️ Only read from inputs — never mutate them. \`evolve.ts\` handles state updates.
|
|
613
617
|
*
|
|
614
618
|
* Integration result shape (Products):
|
|
@@ -145,8 +145,13 @@ describe('<%= ruleDescription %>', () => {
|
|
|
145
145
|
])
|
|
146
146
|
.when({
|
|
147
147
|
type: '<%= example.commandRef %>',
|
|
148
|
-
data: <%- formatDataObject(example.exampleData, schema) %>,
|
|
149
148
|
<% const commandFieldNames = new Set(schema?.fields?.map(f => f.name) || []);
|
|
149
|
+
const filteredCmdData = Object.fromEntries(
|
|
150
|
+
Object.entries(example.exampleData || {}).filter(([key]) => commandFieldNames.has(key))
|
|
151
|
+
);
|
|
152
|
+
-%>
|
|
153
|
+
data: <%- formatDataObject(filteredCmdData, schema) %>,
|
|
154
|
+
<%
|
|
150
155
|
const { date: derivedDate, fields: derivedDateFieldNames } = findDerivedDateInfo(eventResults, commandFieldNames, gwt.given);
|
|
151
156
|
const keepFieldNames = buildKeepFieldNames(eventResults, commandFieldNames, derivedDateFieldNames, gwt.given);
|
|
152
157
|
-%>
|
|
@@ -61,8 +61,8 @@ case '<%= command %>': {
|
|
|
61
61
|
* You should:
|
|
62
62
|
* - Validate the command input fields
|
|
63
63
|
* - Inspect the current domain `_state` to determine if the command is allowed
|
|
64
|
-
* -
|
|
65
|
-
*
|
|
64
|
+
* - NEVER use `as SomeType` type assertions — not `as any`, not `as EventType`, no casts at all. Use typed variable declarations.
|
|
65
|
+
* - If State is a discriminated union, narrow with the discriminant: `if (_state.status !== 'active') throw new IllegalStateError('...');`
|
|
66
66
|
* After narrowing, access variant fields directly — TypeScript infers the correct type.
|
|
67
67
|
<% if (integrationReturnType) { -%>
|
|
68
68
|
* - Use `<%= camelCase(integrationReturnType) %>` (integration result) to enrich or filter the output
|
|
@@ -71,6 +71,7 @@ case '<%= command %>': {
|
|
|
71
71
|
* ⚠️ Error constructors: IllegalStateError takes a string message<% if (usedErrors.includes('ValidationError')) { %>, ValidationError takes a string message<% } %><% if (usedErrors.includes('NotFoundError')) { %>, NotFoundError takes { id, type, message? }<% } %>
|
|
72
72
|
* - If valid, return one or more events with the correct structure
|
|
73
73
|
*
|
|
74
|
+
* - Only destructure/reference command.data fields that exist in the command type (imported from ./commands). Do NOT access fields not declared in the type, even if example data includes them.
|
|
74
75
|
* ⚠️ Only read from inputs — never mutate them. `evolve.ts` handles state updates.
|
|
75
76
|
<% if (integrationReturnFields.length > 0) { -%>
|
|
76
77
|
*
|
|
@@ -102,6 +102,11 @@ describe('evolve.ts.ejs', () => {
|
|
|
102
102
|
* [ ] Every return (except \`return state;\`) matches a variant from state.ts
|
|
103
103
|
* [ ] Every return includes the discriminant field
|
|
104
104
|
* [ ] No spread operators in return statements
|
|
105
|
+
*
|
|
106
|
+
* CONSTRAINTS:
|
|
107
|
+
* - NEVER use \`as SomeType\` type assertions. Return properly typed object literals.
|
|
108
|
+
* - Only reference event.data fields that exist on the event type (check imports above).
|
|
109
|
+
* - Only return fields that exist in the State type (check state.ts). Do NOT invent new fields.
|
|
105
110
|
*/
|
|
106
111
|
|
|
107
112
|
export const evolve = (state: State, event: ListingCreated): State => {
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
* [ ] Every return (except `return state;`) matches a variant from state.ts
|
|
23
23
|
* [ ] Every return includes the discriminant field
|
|
24
24
|
* [ ] No spread operators in return statements
|
|
25
|
+
*
|
|
26
|
+
* CONSTRAINTS:
|
|
27
|
+
* - NEVER use `as SomeType` type assertions. Return properly typed object literals.
|
|
28
|
+
* - Only reference event.data fields that exist on the event type (check imports above).
|
|
29
|
+
* - Only return fields that exist in the State type (check state.ts). Do NOT invent new fields.
|
|
25
30
|
*/
|
|
26
31
|
|
|
27
32
|
export const evolve = (
|
|
@@ -1202,8 +1202,7 @@ describe('projection.specs.ts.ejs', () => {
|
|
|
1202
1202
|
.collection<WorkoutHistory>('WorkoutHistoryProjection')
|
|
1203
1203
|
.findOne((doc) => doc.memberId === 'mem_001');
|
|
1204
1204
|
|
|
1205
|
-
const expected
|
|
1206
|
-
memberId: 'mem_001',
|
|
1205
|
+
const expected = {
|
|
1207
1206
|
totalCalories: 250,
|
|
1208
1207
|
};
|
|
1209
1208
|
|
|
@@ -1214,6 +1213,224 @@ describe('projection.specs.ts.ejs', () => {
|
|
|
1214
1213
|
`);
|
|
1215
1214
|
});
|
|
1216
1215
|
|
|
1216
|
+
it('should exclude query arg fields that differ from projection-computed values', async () => {
|
|
1217
|
+
const spec: SpecsSchema = {
|
|
1218
|
+
variant: 'specs',
|
|
1219
|
+
narratives: [
|
|
1220
|
+
{
|
|
1221
|
+
name: 'fart-flow',
|
|
1222
|
+
slices: [
|
|
1223
|
+
{
|
|
1224
|
+
type: 'command',
|
|
1225
|
+
name: 'log-fart',
|
|
1226
|
+
stream: 'farts-${userId}',
|
|
1227
|
+
client: { specs: [] },
|
|
1228
|
+
server: {
|
|
1229
|
+
description: '',
|
|
1230
|
+
specs: [
|
|
1231
|
+
{
|
|
1232
|
+
type: 'gherkin',
|
|
1233
|
+
feature: 'Log fart command',
|
|
1234
|
+
rules: [
|
|
1235
|
+
{
|
|
1236
|
+
name: 'Should record farts',
|
|
1237
|
+
examples: [
|
|
1238
|
+
{
|
|
1239
|
+
name: 'User logs fart',
|
|
1240
|
+
steps: [
|
|
1241
|
+
{
|
|
1242
|
+
keyword: 'When',
|
|
1243
|
+
text: 'LogFart',
|
|
1244
|
+
docString: { userId: 'usr_123', intensity: 7 },
|
|
1245
|
+
},
|
|
1246
|
+
{
|
|
1247
|
+
keyword: 'Then',
|
|
1248
|
+
text: 'FartLogged',
|
|
1249
|
+
docString: { userId: 'usr_123', fartId: 'fart_456', intensity: 7 },
|
|
1250
|
+
},
|
|
1251
|
+
],
|
|
1252
|
+
},
|
|
1253
|
+
],
|
|
1254
|
+
},
|
|
1255
|
+
],
|
|
1256
|
+
},
|
|
1257
|
+
],
|
|
1258
|
+
},
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
type: 'query',
|
|
1262
|
+
name: 'view-fart-history',
|
|
1263
|
+
stream: 'farts',
|
|
1264
|
+
request:
|
|
1265
|
+
'query GetFartHistory($userId: ID!, $minIntensity: Int) { fartHistory(userId: $userId, minIntensity: $minIntensity) { farts { fartId intensity } } }',
|
|
1266
|
+
client: { specs: [] },
|
|
1267
|
+
server: {
|
|
1268
|
+
description: '',
|
|
1269
|
+
data: {
|
|
1270
|
+
items: [
|
|
1271
|
+
{
|
|
1272
|
+
target: { type: 'State', name: 'FartHistory' },
|
|
1273
|
+
origin: { type: 'projection', name: 'FartHistoryProjection', idField: 'userId' },
|
|
1274
|
+
},
|
|
1275
|
+
],
|
|
1276
|
+
},
|
|
1277
|
+
specs: [
|
|
1278
|
+
{
|
|
1279
|
+
type: 'gherkin',
|
|
1280
|
+
feature: 'View fart history query',
|
|
1281
|
+
rules: [
|
|
1282
|
+
{
|
|
1283
|
+
name: 'Fart history projection',
|
|
1284
|
+
examples: [
|
|
1285
|
+
{
|
|
1286
|
+
name: 'Shows farts after logging',
|
|
1287
|
+
steps: [
|
|
1288
|
+
{
|
|
1289
|
+
keyword: 'Given',
|
|
1290
|
+
text: 'FartLogged',
|
|
1291
|
+
docString: { userId: 'usr_123', fartId: 'fart_456', intensity: 7 },
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
keyword: 'Given',
|
|
1295
|
+
text: 'FartLogged',
|
|
1296
|
+
docString: { userId: 'usr_123', fartId: 'fart_789', intensity: 9 },
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
keyword: 'When',
|
|
1300
|
+
text: 'GetFartHistory',
|
|
1301
|
+
docString: { userId: 'usr_123', minIntensity: 6 },
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
keyword: 'Then',
|
|
1305
|
+
text: 'FartHistory',
|
|
1306
|
+
docString: {
|
|
1307
|
+
userId: 'usr_123',
|
|
1308
|
+
farts: [
|
|
1309
|
+
{ fartId: 'fart_456', intensity: 7 },
|
|
1310
|
+
{ fartId: 'fart_789', intensity: 9 },
|
|
1311
|
+
],
|
|
1312
|
+
minIntensity: 6,
|
|
1313
|
+
},
|
|
1314
|
+
},
|
|
1315
|
+
],
|
|
1316
|
+
},
|
|
1317
|
+
],
|
|
1318
|
+
},
|
|
1319
|
+
],
|
|
1320
|
+
},
|
|
1321
|
+
],
|
|
1322
|
+
},
|
|
1323
|
+
},
|
|
1324
|
+
],
|
|
1325
|
+
},
|
|
1326
|
+
],
|
|
1327
|
+
messages: [
|
|
1328
|
+
{
|
|
1329
|
+
type: 'command',
|
|
1330
|
+
name: 'LogFart',
|
|
1331
|
+
fields: [
|
|
1332
|
+
{ name: 'userId', type: 'string', required: true },
|
|
1333
|
+
{ name: 'intensity', type: 'number', required: true },
|
|
1334
|
+
],
|
|
1335
|
+
},
|
|
1336
|
+
{
|
|
1337
|
+
type: 'event',
|
|
1338
|
+
name: 'FartLogged',
|
|
1339
|
+
source: 'internal',
|
|
1340
|
+
fields: [
|
|
1341
|
+
{ name: 'userId', type: 'string', required: true },
|
|
1342
|
+
{ name: 'fartId', type: 'string', required: true },
|
|
1343
|
+
{ name: 'intensity', type: 'number', required: true },
|
|
1344
|
+
],
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
type: 'query',
|
|
1348
|
+
name: 'GetFartHistory',
|
|
1349
|
+
fields: [
|
|
1350
|
+
{ name: 'userId', type: 'string', required: true },
|
|
1351
|
+
{ name: 'minIntensity', type: 'number', required: true },
|
|
1352
|
+
],
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
type: 'state',
|
|
1356
|
+
name: 'FartHistory',
|
|
1357
|
+
fields: [
|
|
1358
|
+
{ name: 'userId', type: 'string', required: true },
|
|
1359
|
+
{ name: 'farts', type: 'Array<{ fartId: string; intensity: number }>', required: true },
|
|
1360
|
+
{ name: 'minIntensity', type: 'number', required: true },
|
|
1361
|
+
],
|
|
1362
|
+
},
|
|
1363
|
+
],
|
|
1364
|
+
} as SpecsSchema;
|
|
1365
|
+
|
|
1366
|
+
const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
|
|
1367
|
+
const specFile = plans.find((p) => p.outputPath.endsWith('view-fart-history/projection.specs.ts'));
|
|
1368
|
+
|
|
1369
|
+
expect(specFile?.contents).toMatchInlineSnapshot(`
|
|
1370
|
+
"import { describe, it, beforeEach, expect } from 'vitest';
|
|
1371
|
+
import { InMemoryProjectionSpec } from '@event-driven-io/emmett';
|
|
1372
|
+
import { projection } from './projection';
|
|
1373
|
+
import type { FartLogged } from '../log-fart/events';
|
|
1374
|
+
import { FartHistory } from './state';
|
|
1375
|
+
|
|
1376
|
+
type ProjectionEvent = FartLogged;
|
|
1377
|
+
|
|
1378
|
+
describe('Fart history projection', () => {
|
|
1379
|
+
let given: InMemoryProjectionSpec<ProjectionEvent>;
|
|
1380
|
+
|
|
1381
|
+
beforeEach(() => {
|
|
1382
|
+
given = InMemoryProjectionSpec.for({ projection });
|
|
1383
|
+
});
|
|
1384
|
+
|
|
1385
|
+
it('Shows farts after logging', () =>
|
|
1386
|
+
given([
|
|
1387
|
+
{
|
|
1388
|
+
type: 'FartLogged',
|
|
1389
|
+
data: {
|
|
1390
|
+
userId: 'usr_123',
|
|
1391
|
+
fartId: 'fart_456',
|
|
1392
|
+
intensity: 7,
|
|
1393
|
+
},
|
|
1394
|
+
metadata: {
|
|
1395
|
+
streamName: 'farts',
|
|
1396
|
+
streamPosition: 1n,
|
|
1397
|
+
globalPosition: 1n,
|
|
1398
|
+
},
|
|
1399
|
+
},
|
|
1400
|
+
{
|
|
1401
|
+
type: 'FartLogged',
|
|
1402
|
+
data: {
|
|
1403
|
+
userId: 'usr_123',
|
|
1404
|
+
fartId: 'fart_789',
|
|
1405
|
+
intensity: 9,
|
|
1406
|
+
},
|
|
1407
|
+
metadata: {
|
|
1408
|
+
streamName: 'farts',
|
|
1409
|
+
streamPosition: 1n,
|
|
1410
|
+
globalPosition: 1n,
|
|
1411
|
+
},
|
|
1412
|
+
},
|
|
1413
|
+
])
|
|
1414
|
+
.when([])
|
|
1415
|
+
.then(async (state) => {
|
|
1416
|
+
const document = await state.database
|
|
1417
|
+
.collection<FartHistory>('FartHistoryProjection')
|
|
1418
|
+
.findOne((doc) => doc.userId === 'usr_123');
|
|
1419
|
+
|
|
1420
|
+
const expected = {
|
|
1421
|
+
farts: [
|
|
1422
|
+
{ fartId: 'fart_456', intensity: 7 },
|
|
1423
|
+
{ fartId: 'fart_789', intensity: 9 },
|
|
1424
|
+
],
|
|
1425
|
+
};
|
|
1426
|
+
|
|
1427
|
+
expect(document).toMatchObject(expected);
|
|
1428
|
+
}));
|
|
1429
|
+
});
|
|
1430
|
+
"
|
|
1431
|
+
`);
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1217
1434
|
it('should serialize inline objects and arrays with Date sub-fields correctly', async () => {
|
|
1218
1435
|
const spec: SpecsSchema = {
|
|
1219
1436
|
variant: 'specs',
|
|
@@ -1572,6 +1789,11 @@ describe('projection.specs.ts.ejs', () => {
|
|
|
1572
1789
|
* NEVER hardcode constant values — every output field must trace to an input.
|
|
1573
1790
|
* Preserve all import paths above — they are generated from the model.
|
|
1574
1791
|
* ⚠️ \`document\` may be null (first event for this entity). Guard before accessing properties.
|
|
1792
|
+
*
|
|
1793
|
+
* CONSTRAINTS:
|
|
1794
|
+
* - NEVER use \`as SomeType\` type assertions. Declare typed variables instead: \`const x: Type = value;\`
|
|
1795
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
1796
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
1575
1797
|
*
|
|
1576
1798
|
* Implement how this event updates the projection.
|
|
1577
1799
|
*
|
|
@@ -1584,11 +1806,12 @@ describe('projection.specs.ts.ejs', () => {
|
|
|
1584
1806
|
* internalField: SomeType;
|
|
1585
1807
|
* }
|
|
1586
1808
|
*
|
|
1587
|
-
* 2.
|
|
1809
|
+
* 2. Assign document to extended type:
|
|
1588
1810
|
* const current: InternalWorkoutHistory = document ?? { ...defaults };
|
|
1589
1811
|
*
|
|
1590
|
-
* 3.
|
|
1591
|
-
*
|
|
1812
|
+
* 3. Return via typed variable (preserves internal state for next event):
|
|
1813
|
+
* const result: InternalWorkoutHistory = { ...allFields, internalField };
|
|
1814
|
+
* return result;
|
|
1592
1815
|
*
|
|
1593
1816
|
* This keeps internal state separate from the public GraphQL schema.
|
|
1594
1817
|
|
|
@@ -244,6 +244,11 @@ describe('projection.ts.ejs', () => {
|
|
|
244
244
|
* NEVER hardcode constant values — every output field must trace to an input.
|
|
245
245
|
* Preserve all import paths above — they are generated from the model.
|
|
246
246
|
* ⚠️ \`document\` may be null (first event for this entity). Guard before accessing properties.
|
|
247
|
+
*
|
|
248
|
+
* CONSTRAINTS:
|
|
249
|
+
* - NEVER use \`as SomeType\` type assertions. Declare typed variables instead: \`const x: Type = value;\`
|
|
250
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
251
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
247
252
|
*
|
|
248
253
|
* Implement how this event updates the projection.
|
|
249
254
|
*
|
|
@@ -256,11 +261,12 @@ describe('projection.ts.ejs', () => {
|
|
|
256
261
|
* internalField: SomeType;
|
|
257
262
|
* }
|
|
258
263
|
*
|
|
259
|
-
* 2.
|
|
264
|
+
* 2. Assign document to extended type:
|
|
260
265
|
* const current: InternalAvailableListings = document ?? { ...defaults };
|
|
261
266
|
*
|
|
262
|
-
* 3.
|
|
263
|
-
*
|
|
267
|
+
* 3. Return via typed variable (preserves internal state for next event):
|
|
268
|
+
* const result: InternalAvailableListings = { ...allFields, internalField };
|
|
269
|
+
* return result;
|
|
264
270
|
*
|
|
265
271
|
* This keeps internal state separate from the public GraphQL schema.
|
|
266
272
|
|
|
@@ -284,6 +290,11 @@ describe('projection.ts.ejs', () => {
|
|
|
284
290
|
* NEVER hardcode constant values — every output field must trace to an input.
|
|
285
291
|
* Preserve all import paths above — they are generated from the model.
|
|
286
292
|
* ⚠️ \`document\` may be null (first event for this entity). Guard before accessing properties.
|
|
293
|
+
*
|
|
294
|
+
* CONSTRAINTS:
|
|
295
|
+
* - NEVER use \`as SomeType\` type assertions. Declare typed variables instead: \`const x: Type = value;\`
|
|
296
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
297
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
287
298
|
*
|
|
288
299
|
* This event might indicate removal of a AvailableListings.
|
|
289
300
|
*
|
|
@@ -588,6 +599,11 @@ describe('projection.ts.ejs', () => {
|
|
|
588
599
|
* NEVER hardcode constant values — every output field must trace to an input.
|
|
589
600
|
* Preserve all import paths above — they are generated from the model.
|
|
590
601
|
* ⚠️ \`document\` may be null (first event for this entity). Guard before accessing properties.
|
|
602
|
+
*
|
|
603
|
+
* CONSTRAINTS:
|
|
604
|
+
* - NEVER use \`as SomeType\` type assertions. Declare typed variables instead: \`const x: Type = value;\`
|
|
605
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
606
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
591
607
|
*
|
|
592
608
|
* **SINGLETON AGGREGATION PATTERN**
|
|
593
609
|
*
|
|
@@ -810,6 +826,11 @@ describe('projection.ts.ejs', () => {
|
|
|
810
826
|
* NEVER hardcode constant values — every output field must trace to an input.
|
|
811
827
|
* Preserve all import paths above — they are generated from the model.
|
|
812
828
|
* ⚠️ \`document\` may be null (first event for this entity). Guard before accessing properties.
|
|
829
|
+
*
|
|
830
|
+
* CONSTRAINTS:
|
|
831
|
+
* - NEVER use \`as SomeType\` type assertions. Declare typed variables instead: \`const x: Type = value;\`
|
|
832
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
833
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
813
834
|
*
|
|
814
835
|
* **COMPOSITE KEY PROJECTION**
|
|
815
836
|
*
|
|
@@ -277,13 +277,23 @@ if (isCompositeKey) {
|
|
|
277
277
|
}
|
|
278
278
|
%>
|
|
279
279
|
|
|
280
|
-
|
|
281
|
-
|
|
280
|
+
<%
|
|
281
|
+
const stateKeys = Object.keys(expectedState.exampleData || {});
|
|
282
|
+
const queryArgs = isQueryActionTest
|
|
283
|
+
? (testCase.when?.args
|
|
284
|
+
|| (Array.isArray(testCase.when) && testCase.when[0]?.exampleData)
|
|
285
|
+
|| {})
|
|
286
|
+
: {};
|
|
287
|
+
const queryArgKeys = new Set(Object.keys(queryArgs));
|
|
288
|
+
const assertionKeys = stateKeys.filter(k => !queryArgKeys.has(k));
|
|
282
289
|
const stateMessage = messages.find(m => m.name === targetName);
|
|
283
|
-
|
|
284
|
-
|
|
290
|
+
const isPartial = assertionKeys.length < stateKeys.length;
|
|
291
|
+
-%>
|
|
292
|
+
const expected<%= isPartial ? '' : `: ${TargetType}` %> = {
|
|
293
|
+
<% for (let i = 0; i < assertionKeys.length; i++) {
|
|
294
|
+
const key = assertionKeys[i];
|
|
285
295
|
const value = expectedState.exampleData[key];
|
|
286
|
-
const isLast = i ===
|
|
296
|
+
const isLast = i === assertionKeys.length - 1;
|
|
287
297
|
const field = stateMessage?.fields?.find(f => f.name === key);
|
|
288
298
|
const tsType = field?.tsType || field?.type || 'string';
|
|
289
299
|
const formattedValue = formatSpecValue(value, tsType);
|
|
@@ -132,6 +132,11 @@ case '<%= event.type %>': {
|
|
|
132
132
|
* Preserve all import paths above — they are generated from the model.
|
|
133
133
|
* ⚠️ `document` may be null (first event for this entity). Guard before accessing properties.
|
|
134
134
|
*
|
|
135
|
+
* CONSTRAINTS:
|
|
136
|
+
* - NEVER use `as SomeType` type assertions. Declare typed variables instead: `const x: Type = value;`
|
|
137
|
+
* - Only reference event.data fields listed in the "Event fields:" line below.
|
|
138
|
+
* - Do NOT modify anything outside this case block: imports, type parameters, canHandle, collectionName, and getDocumentId are auto-generated.
|
|
139
|
+
*
|
|
135
140
|
<% if (isSingleton) { -%>
|
|
136
141
|
* **SINGLETON AGGREGATION PATTERN**
|
|
137
142
|
*
|
|
@@ -188,11 +193,12 @@ case '<%= event.type %>': {
|
|
|
188
193
|
* internalField: SomeType;
|
|
189
194
|
* }
|
|
190
195
|
*
|
|
191
|
-
* 2.
|
|
196
|
+
* 2. Assign document to extended type:
|
|
192
197
|
* const current: Internal<%= pascalCase(targetName || 'State') %> = document ?? { ...defaults };
|
|
193
198
|
*
|
|
194
|
-
* 3.
|
|
195
|
-
*
|
|
199
|
+
* 3. Return via typed variable (preserves internal state for next event):
|
|
200
|
+
* const result: Internal<%= pascalCase(targetName || 'State') %> = { ...allFields, internalField };
|
|
201
|
+
* return result;
|
|
196
202
|
*
|
|
197
203
|
* This keeps internal state separate from the public GraphQL schema.
|
|
198
204
|
<% } -%>
|