monorise 0.1.0 → 1.1.0-dev.0
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/dist/base/index.d.ts +90 -5
- package/dist/base/index.js.map +1 -1
- package/dist/cli/cli.js +6 -0
- package/dist/cli/cli.js.map +1 -1
- package/dist/core/chunk-QV4Q5377.js +76 -0
- package/dist/core/chunk-QV4Q5377.js.map +1 -0
- package/dist/core/index.d.ts +187 -19
- package/dist/core/index.js +1583 -85
- package/dist/core/index.js.map +1 -1
- package/dist/core/service.config-ZJEZ6EKA.js +13 -0
- package/dist/core/service.config-ZJEZ6EKA.js.map +1 -0
- package/dist/proxy/index.d.ts +35 -0
- package/dist/proxy/index.js +75 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/react/actions/websocket.action.d.ts +71 -0
- package/dist/react/actions/websocket.action.d.ts.map +1 -0
- package/dist/react/chunk-4D22OCZG.js +65 -0
- package/dist/react/chunk-4D22OCZG.js.map +1 -0
- package/dist/react/chunk-4N3P4ONH.js +588 -0
- package/dist/react/chunk-4N3P4ONH.js.map +1 -0
- package/dist/react/chunk-4Y4KWGJD.js +182 -0
- package/dist/react/chunk-4Y4KWGJD.js.map +1 -0
- package/dist/react/chunk-757E5UYA.js +893 -0
- package/dist/react/chunk-757E5UYA.js.map +1 -0
- package/dist/react/chunk-A5TI2FW3.js +13 -0
- package/dist/react/chunk-A5TI2FW3.js.map +1 -0
- package/dist/react/chunk-B3XDGUFO.js +489 -0
- package/dist/react/chunk-B3XDGUFO.js.map +1 -0
- package/dist/react/chunk-BPBCUO2Z.js +248 -0
- package/dist/react/chunk-BPBCUO2Z.js.map +1 -0
- package/dist/react/chunk-CQBOIXWK.js +142 -0
- package/dist/react/chunk-CQBOIXWK.js.map +1 -0
- package/dist/react/chunk-DRH2BB7I.js +383 -0
- package/dist/react/chunk-DRH2BB7I.js.map +1 -0
- package/dist/react/chunk-EQ3PKQ2S.js +402 -0
- package/dist/react/chunk-EQ3PKQ2S.js.map +1 -0
- package/dist/react/chunk-H64MMAL7.js +245 -0
- package/dist/react/chunk-H64MMAL7.js.map +1 -0
- package/dist/react/chunk-KJX5LOMN.js +43 -0
- package/dist/react/chunk-KJX5LOMN.js.map +1 -0
- package/dist/react/chunk-MO35V2Y7.js +172 -0
- package/dist/react/chunk-MO35V2Y7.js.map +1 -0
- package/dist/react/chunk-UC3E72G7.js +73 -0
- package/dist/react/chunk-UC3E72G7.js.map +1 -0
- package/dist/react/chunk-UHMKB3OR.js +5568 -0
- package/dist/react/chunk-UHMKB3OR.js.map +1 -0
- package/dist/react/chunk-UQPQBWEQ.js +54 -0
- package/dist/react/chunk-UQPQBWEQ.js.map +1 -0
- package/dist/react/chunk-XCDCVRJR.js +43 -0
- package/dist/react/chunk-XCDCVRJR.js.map +1 -0
- package/dist/react/chunk-XOYAZDIH.js +47 -0
- package/dist/react/chunk-XOYAZDIH.js.map +1 -0
- package/dist/react/chunk-YNFQEPO5.js +29 -0
- package/dist/react/chunk-YNFQEPO5.js.map +1 -0
- package/dist/react/dist-es-35AO47NO.js +90 -0
- package/dist/react/dist-es-35AO47NO.js.map +1 -0
- package/dist/react/dist-es-5GDBXNKQ.js +333 -0
- package/dist/react/dist-es-5GDBXNKQ.js.map +1 -0
- package/dist/react/dist-es-B3JDGWY6.js +71 -0
- package/dist/react/dist-es-B3JDGWY6.js.map +1 -0
- package/dist/react/dist-es-IWIE5JLA.js +169 -0
- package/dist/react/dist-es-IWIE5JLA.js.map +1 -0
- package/dist/react/dist-es-NRIS3TYJ.js +494 -0
- package/dist/react/dist-es-NRIS3TYJ.js.map +1 -0
- package/dist/react/dist-es-VCXAEYYN.js +22 -0
- package/dist/react/dist-es-VCXAEYYN.js.map +1 -0
- package/dist/react/dist-es-VU33JFTZ.js +379 -0
- package/dist/react/dist-es-VU33JFTZ.js.map +1 -0
- package/dist/react/event-streams-OSOTOTTP.js +277 -0
- package/dist/react/event-streams-OSOTOTTP.js.map +1 -0
- package/dist/react/index.d.ts +53 -4
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +10948 -190
- package/dist/react/index.js.map +1 -1
- package/dist/react/loadSso-ME7MKAM3.js +556 -0
- package/dist/react/loadSso-ME7MKAM3.js.map +1 -0
- package/dist/react/service.config-ZJEZ6EKA-FC2TR3GH.js +14 -0
- package/dist/react/service.config-ZJEZ6EKA-FC2TR3GH.js.map +1 -0
- package/dist/react/services/core.service.d.ts +11 -1
- package/dist/react/services/core.service.d.ts.map +1 -1
- package/dist/react/signin-LOXYIE5I.js +653 -0
- package/dist/react/signin-LOXYIE5I.js.map +1 -0
- package/dist/react/sso-oidc-X63KRRLO.js +786 -0
- package/dist/react/sso-oidc-X63KRRLO.js.map +1 -0
- package/dist/react/sts-OXBEY7HY.js +3948 -0
- package/dist/react/sts-OXBEY7HY.js.map +1 -0
- package/dist/react/websocket/WebSocketManager.d.ts +68 -0
- package/dist/react/websocket/WebSocketManager.d.ts.map +1 -0
- package/dist/react/websocket/index.d.ts +3 -0
- package/dist/react/websocket/index.d.ts.map +1 -0
- package/dist/react/websocket/optimistic.d.ts +51 -0
- package/dist/react/websocket/optimistic.d.ts.map +1 -0
- package/dist/react/websocket-QHA7SQXG.js +10 -0
- package/dist/react/websocket-QHA7SQXG.js.map +1 -0
- package/dist/sst/.sst/platform/src/components/aws/alb.d.ts +280 -0
- package/dist/sst/.sst/platform/src/components/aws/alb.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/aws/apigateway-websocket-route.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigateway-websocket-route.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigateway-websocket.d.ts +13 -2
- package/dist/sst/.sst/platform/src/components/aws/apigateway-websocket.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv1-authorizer.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv1-lambda-route.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv1-lambda-route.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv1.d.ts +93 -83
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv2-authorizer.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv2-lambda-route.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv2-lambda-route.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv2.d.ts +8 -2
- package/dist/sst/.sst/platform/src/components/aws/apigatewayv2.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/app-sync-data-source.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/app-sync-data-source.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/app-sync.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/app-sync.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/aurora.d.ts +18 -0
- package/dist/sst/.sst/platform/src/components/aws/aurora.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/auth-v1.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/auth-v1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/auth.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bucket-lambda-subscriber.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bucket-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bucket-notification.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bucket.d.ts +13 -8
- package/dist/sst/.sst/platform/src/components/aws/bucket.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bus-lambda-subscriber.d.ts +3 -2
- package/dist/sst/.sst/platform/src/components/aws/bus-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/bus.d.ts +34 -3
- package/dist/sst/.sst/platform/src/components/aws/bus.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/cdn.d.ts +11 -0
- package/dist/sst/.sst/platform/src/components/aws/cdn.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/cluster.d.ts +59 -1
- package/dist/sst/.sst/platform/src/components/aws/cluster.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/cognito-identity-pool.d.ts +5 -0
- package/dist/sst/.sst/platform/src/components/aws/cognito-identity-pool.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/cognito-user-pool.d.ts +100 -0
- package/dist/sst/.sst/platform/src/components/aws/cognito-user-pool.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/cron-v2.d.ts +325 -0
- package/dist/sst/.sst/platform/src/components/aws/cron-v2.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/aws/cron.d.ts +15 -6
- package/dist/sst/.sst/platform/src/components/aws/cron.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/dsql.d.ts +369 -0
- package/dist/sst/.sst/platform/src/components/aws/dsql.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/aws/dynamo-lambda-subscriber.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/dynamo-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/dynamo.d.ts +63 -3
- package/dist/sst/.sst/platform/src/components/aws/dynamo.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/email.d.ts +5 -0
- package/dist/sst/.sst/platform/src/components/aws/email.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/fargate.d.ts +95 -4
- package/dist/sst/.sst/platform/src/components/aws/fargate.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/function.d.ts +121 -21
- package/dist/sst/.sst/platform/src/components/aws/function.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/arn.d.ts +11 -0
- package/dist/sst/.sst/platform/src/components/aws/helpers/arn.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/container-builder.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/function-builder.d.ts +7 -3
- package/dist/sst/.sst/platform/src/components/aws/helpers/function-builder.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/load-balancer.d.ts +9 -0
- package/dist/sst/.sst/platform/src/components/aws/helpers/load-balancer.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/aws/helpers/provider.d.ts +2 -2
- package/dist/sst/.sst/platform/src/components/aws/helpers/provider.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/site-builder.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/site-builder.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/subscriber.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/helpers/subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/https-redirect.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/index.d.ts +4 -0
- package/dist/sst/.sst/platform/src/components/aws/index.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/kinesis-stream-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/kinesis-stream.d.ts +8 -3
- package/dist/sst/.sst/platform/src/components/aws/kinesis-stream.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/linkable.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/linkable.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/mysql.d.ts +34 -5
- package/dist/sst/.sst/platform/src/components/aws/mysql.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/nextjs.d.ts +39 -5
- package/dist/sst/.sst/platform/src/components/aws/nextjs.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/nuxt.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/open-search.d.ts +12 -1
- package/dist/sst/.sst/platform/src/components/aws/open-search.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/opencontrol.d.ts +7 -3
- package/dist/sst/.sst/platform/src/components/aws/opencontrol.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/permission.d.ts +5 -0
- package/dist/sst/.sst/platform/src/components/aws/permission.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/postgres-v1.d.ts +13 -2
- package/dist/sst/.sst/platform/src/components/aws/postgres-v1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/postgres.d.ts +34 -5
- package/dist/sst/.sst/platform/src/components/aws/postgres.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/queue-lambda-subscriber.d.ts +6 -1
- package/dist/sst/.sst/platform/src/components/aws/queue-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/queue.d.ts +10 -1
- package/dist/sst/.sst/platform/src/components/aws/queue.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/realtime-lambda-subscriber.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/realtime-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/realtime.d.ts +6 -1
- package/dist/sst/.sst/platform/src/components/aws/realtime.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/redis-v1.d.ts +10 -0
- package/dist/sst/.sst/platform/src/components/aws/redis-v1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/redis.d.ts +14 -0
- package/dist/sst/.sst/platform/src/components/aws/redis.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/router.d.ts +482 -2
- package/dist/sst/.sst/platform/src/components/aws/router.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/service-v1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/service.d.ts +125 -0
- package/dist/sst/.sst/platform/src/components/aws/service.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/sns-topic-lambda-subscriber.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/sns-topic-lambda-subscriber.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/sns-topic.d.ts +6 -1
- package/dist/sst/.sst/platform/src/components/aws/sns-topic.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/ssr-site.d.ts +7 -7
- package/dist/sst/.sst/platform/src/components/aws/ssr-site.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/static-site.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/step-functions/state.d.ts +1 -1
- package/dist/sst/.sst/platform/src/components/aws/step-functions/state.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/step-functions/task.d.ts +10 -2
- package/dist/sst/.sst/platform/src/components/aws/step-functions/task.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/step-functions.d.ts +5 -0
- package/dist/sst/.sst/platform/src/components/aws/step-functions.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/tan-stack-start.d.ts +20 -6
- package/dist/sst/.sst/platform/src/components/aws/tan-stack-start.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/task.d.ts +35 -15
- package/dist/sst/.sst/platform/src/components/aws/task.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/vector.d.ts +5 -0
- package/dist/sst/.sst/platform/src/components/aws/vector.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/vpc.d.ts +51 -4
- package/dist/sst/.sst/platform/src/components/aws/vpc.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/aws/workflow.d.ts +331 -0
- package/dist/sst/.sst/platform/src/components/aws/workflow.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/ai.d.ts +82 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/ai.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/binding.d.ts +15 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/binding.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/bucket.d.ts +4 -2
- package/dist/sst/.sst/platform/src/components/cloudflare/bucket.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/cron.d.ts +29 -5
- package/dist/sst/.sst/platform/src/components/cloudflare/cron.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/d1.d.ts +37 -2
- package/dist/sst/.sst/platform/src/components/cloudflare/d1.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/index.d.ts +1 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/index.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/kv.d.ts +36 -2
- package/dist/sst/.sst/platform/src/components/cloudflare/kv.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/providers/worker-placement.d.ts +27 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/providers/worker-placement.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/providers/zone-lookup.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/queue-worker-subscriber.d.ts +116 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/queue-worker-subscriber.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/cloudflare/queue.d.ts +186 -3
- package/dist/sst/.sst/platform/src/components/cloudflare/queue.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/static-site.d.ts +2 -2
- package/dist/sst/.sst/platform/src/components/cloudflare/static-site.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/cloudflare/worker.d.ts +39 -5
- package/dist/sst/.sst/platform/src/components/cloudflare/worker.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/component.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/duration.d.ts +2 -0
- package/dist/sst/.sst/platform/src/components/duration.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/esbuild.d.ts +3 -0
- package/dist/sst/.sst/platform/src/components/esbuild.d.ts.map +1 -0
- package/dist/sst/.sst/platform/src/components/link.d.ts +2 -2
- package/dist/sst/.sst/platform/src/components/link.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/linkable.d.ts +32 -2
- package/dist/sst/.sst/platform/src/components/linkable.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/rpc/rpc.d.ts.map +1 -1
- package/dist/sst/.sst/platform/src/components/vercel/dns.d.ts +2 -2
- package/dist/sst/.sst/platform/src/util/minify.d.ts +2 -0
- package/dist/sst/.sst/platform/src/util/minify.d.ts.map +1 -0
- package/dist/sst/components/monorise-core.d.ts +10 -0
- package/dist/sst/components/monorise-core.d.ts.map +1 -1
- package/dist/sst/components/q-function.d.ts +2 -3
- package/dist/sst/components/q-function.d.ts.map +1 -1
- package/dist/sst/index.js +75 -12
- package/dist/sst/index.js.map +1 -1
- package/package.json +10 -2
- package/dist/sst/.sst/platform/src/components/aws/helpers/quota.d.ts +0 -7
- package/dist/sst/.sst/platform/src/components/aws/helpers/quota.d.ts.map +0 -1
package/dist/core/index.js
CHANGED
|
@@ -1,46 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
23
|
-
};
|
|
24
|
-
var __async = (__this, __arguments, generator) => {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
var fulfilled = (value) => {
|
|
27
|
-
try {
|
|
28
|
-
step(generator.next(value));
|
|
29
|
-
} catch (e) {
|
|
30
|
-
reject(e);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
var rejected = (value) => {
|
|
34
|
-
try {
|
|
35
|
-
step(generator.throw(value));
|
|
36
|
-
} catch (e) {
|
|
37
|
-
reject(e);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
41
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
CORE_EVENT_BUS,
|
|
3
|
+
CORE_TABLE,
|
|
4
|
+
ENTITY_REPLICATION_INDEX,
|
|
5
|
+
MUTUAL_REPLICATION_INDEX,
|
|
6
|
+
__async,
|
|
7
|
+
__export,
|
|
8
|
+
__objRest,
|
|
9
|
+
__spreadProps,
|
|
10
|
+
__spreadValues
|
|
11
|
+
} from "./chunk-QV4Q5377.js";
|
|
44
12
|
|
|
45
13
|
// controllers/setupRoutes.ts
|
|
46
14
|
import { Hono } from "hono";
|
|
@@ -128,6 +96,11 @@ var setupCommonRoutes = (container) => {
|
|
|
128
96
|
container.deleteEntityController.controller
|
|
129
97
|
);
|
|
130
98
|
app.get("/tag/:entityType/:tagName", container.listTagsController.controller);
|
|
99
|
+
app.post("/transaction", container.executeTransactionController.controller);
|
|
100
|
+
app.post(
|
|
101
|
+
"/ws/ticket/:entityType/:entityId",
|
|
102
|
+
container.createTicketController.controller
|
|
103
|
+
);
|
|
131
104
|
return app;
|
|
132
105
|
};
|
|
133
106
|
|
|
@@ -163,6 +136,7 @@ var StandardErrorCode = {
|
|
|
163
136
|
ENTITY_ID_IS_UNDEFINED: "ENTITY_ID_IS_UNDEFINED",
|
|
164
137
|
ENTITY_IS_UNDEFINED: "ENTITY_IS_UNDEFINED",
|
|
165
138
|
ENTITY_NOT_FOUND: "ENTITY_NOT_FOUND",
|
|
139
|
+
INVALID_CONDITION: "INVALID_CONDITION",
|
|
166
140
|
INVALID_ENTITY_TYPE: "INVALID_ENTITY_TYPE",
|
|
167
141
|
INVALID_MUTUAL: "INVALID_MUTUAL",
|
|
168
142
|
INVALID_QUERY: "INVALID_QUERY",
|
|
@@ -175,7 +149,10 @@ var StandardErrorCode = {
|
|
|
175
149
|
REPLICATION_ERROR: "REPLICATION_ERROR",
|
|
176
150
|
RETRYABLE_MUTUAL_LOCK_CONFLICT: "RETRYABLE_MUTUAL_LOCK_CONFLICT",
|
|
177
151
|
TAG_IS_UNDEFINED: "TAG_IS_UNDEFINED",
|
|
152
|
+
TRANSACTION_EMPTY: "TRANSACTION_EMPTY",
|
|
178
153
|
TRANSACTION_FAILED: "TRANSACTION_FAILED",
|
|
154
|
+
TRANSACTION_ITEM_LIMIT_EXCEEDED: "TRANSACTION_ITEM_LIMIT_EXCEEDED",
|
|
155
|
+
TRANSACTION_UNIQUE_FIELD_UPDATE: "TRANSACTION_UNIQUE_FIELD_UPDATE",
|
|
179
156
|
UNIQUE_VALUE_EXISTS: "UNIQUE_VALUE_EXISTS"
|
|
180
157
|
};
|
|
181
158
|
|
|
@@ -762,6 +739,22 @@ var EntityRepository = class extends Repository {
|
|
|
762
739
|
} catch (err) {
|
|
763
740
|
if (err instanceof TransactionCanceledException) {
|
|
764
741
|
const [updateErr, ...uniqueFieldErr] = err.CancellationReasons || [];
|
|
742
|
+
if ((updateErr == null ? void 0 : updateErr.Code) === BatchStatementErrorCodeEnum.ConditionalCheckFailed) {
|
|
743
|
+
if (opts == null ? void 0 : opts.ConditionExpression) {
|
|
744
|
+
throw new StandardError(
|
|
745
|
+
StandardErrorCode.CONDITIONAL_CHECK_FAILED,
|
|
746
|
+
"Conditional check failed",
|
|
747
|
+
err,
|
|
748
|
+
{ entityId, toUpdate }
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
throw new StandardError(
|
|
752
|
+
StandardErrorCode.ENTITY_NOT_FOUND,
|
|
753
|
+
"Entity not found",
|
|
754
|
+
err,
|
|
755
|
+
{ entityId, toUpdate }
|
|
756
|
+
);
|
|
757
|
+
}
|
|
765
758
|
for (let i = 0; i < uniqueFieldErr.length; i++) {
|
|
766
759
|
if (i % 2 === 1 && uniqueFieldErr[i].Code === BatchStatementErrorCodeEnum.ConditionalCheckFailed) {
|
|
767
760
|
const field = updatedUniqueFields[Math.floor(i / 2)];
|
|
@@ -782,6 +775,14 @@ var EntityRepository = class extends Repository {
|
|
|
782
775
|
return updatedEntity;
|
|
783
776
|
} catch (err) {
|
|
784
777
|
if (err instanceof ConditionalCheckFailedException) {
|
|
778
|
+
if (opts == null ? void 0 : opts.ConditionExpression) {
|
|
779
|
+
throw new StandardError(
|
|
780
|
+
StandardErrorCode.CONDITIONAL_CHECK_FAILED,
|
|
781
|
+
"Conditional check failed",
|
|
782
|
+
err,
|
|
783
|
+
{ entityId, toUpdate }
|
|
784
|
+
);
|
|
785
|
+
}
|
|
785
786
|
throw new StandardError(
|
|
786
787
|
StandardErrorCode.ENTITY_NOT_FOUND,
|
|
787
788
|
"Entity not found",
|
|
@@ -796,22 +797,22 @@ var EntityRepository = class extends Repository {
|
|
|
796
797
|
}
|
|
797
798
|
});
|
|
798
799
|
}
|
|
799
|
-
adjustEntity(entityType, entityId, adjustments,
|
|
800
|
+
adjustEntity(entityType, entityId, adjustments, opts) {
|
|
800
801
|
return __async(this, null, function* () {
|
|
801
802
|
const entity = new Entity(entityType, entityId);
|
|
802
|
-
const { UpdateExpression,
|
|
803
|
+
const { UpdateExpression, ExpressionAttributeNames, ExpressionAttributeValues } = this.toAdjustUpdate(adjustments);
|
|
803
804
|
const updatedAtExpression = ", #updatedAt = :updatedAt";
|
|
804
805
|
ExpressionAttributeNames["#updatedAt"] = "updatedAt";
|
|
805
806
|
ExpressionAttributeValues[":updatedAt"] = { S: (/* @__PURE__ */ new Date()).toISOString() };
|
|
806
|
-
const resp = yield this.dynamodbClient.updateItem(
|
|
807
|
+
const resp = yield this.dynamodbClient.updateItem({
|
|
807
808
|
TableName: this.TABLE_NAME,
|
|
808
809
|
Key: entity.keys(),
|
|
809
|
-
UpdateExpression: UpdateExpression + updatedAtExpression
|
|
810
|
-
|
|
811
|
-
ExpressionAttributeNames,
|
|
812
|
-
ExpressionAttributeValues,
|
|
810
|
+
UpdateExpression: UpdateExpression + updatedAtExpression,
|
|
811
|
+
ConditionExpression: (opts == null ? void 0 : opts.ConditionExpression) || "attribute_exists(PK)",
|
|
812
|
+
ExpressionAttributeNames: __spreadValues(__spreadValues({}, ExpressionAttributeNames), opts == null ? void 0 : opts.ExpressionAttributeNames),
|
|
813
|
+
ExpressionAttributeValues: __spreadValues(__spreadValues({}, ExpressionAttributeValues), opts == null ? void 0 : opts.ExpressionAttributeValues),
|
|
813
814
|
ReturnValues: "ALL_NEW"
|
|
814
|
-
})
|
|
815
|
+
});
|
|
815
816
|
return Entity.fromItem(resp.Attributes);
|
|
816
817
|
});
|
|
817
818
|
}
|
|
@@ -1821,6 +1822,217 @@ var TagRepository = class extends Repository {
|
|
|
1821
1822
|
}
|
|
1822
1823
|
};
|
|
1823
1824
|
|
|
1825
|
+
// data/WebSocket.ts
|
|
1826
|
+
import {
|
|
1827
|
+
DeleteCommand,
|
|
1828
|
+
DynamoDBDocumentClient,
|
|
1829
|
+
PutCommand,
|
|
1830
|
+
QueryCommand
|
|
1831
|
+
} from "@aws-sdk/lib-dynamodb";
|
|
1832
|
+
var WebSocketRepository = class extends Repository {
|
|
1833
|
+
constructor(tableName, dynamodbClient) {
|
|
1834
|
+
super();
|
|
1835
|
+
this.tableName = tableName;
|
|
1836
|
+
this.dynamodbClient = dynamodbClient;
|
|
1837
|
+
this.docClient = DynamoDBDocumentClient.from(dynamodbClient);
|
|
1838
|
+
}
|
|
1839
|
+
createConnection(connectionId, metadata, expiresAt) {
|
|
1840
|
+
return __async(this, null, function* () {
|
|
1841
|
+
yield this.docClient.send(
|
|
1842
|
+
new PutCommand({
|
|
1843
|
+
TableName: this.tableName,
|
|
1844
|
+
Item: __spreadProps(__spreadValues({
|
|
1845
|
+
PK: `CONN#${connectionId}`,
|
|
1846
|
+
SK: "#METADATA#",
|
|
1847
|
+
connectionId
|
|
1848
|
+
}, metadata), {
|
|
1849
|
+
expiresAt
|
|
1850
|
+
})
|
|
1851
|
+
})
|
|
1852
|
+
);
|
|
1853
|
+
});
|
|
1854
|
+
}
|
|
1855
|
+
getConnection(connectionId) {
|
|
1856
|
+
return __async(this, null, function* () {
|
|
1857
|
+
var _a;
|
|
1858
|
+
const result = yield this.docClient.send(
|
|
1859
|
+
new QueryCommand({
|
|
1860
|
+
TableName: this.tableName,
|
|
1861
|
+
KeyConditionExpression: "PK = :pk",
|
|
1862
|
+
ExpressionAttributeValues: {
|
|
1863
|
+
":pk": `CONN#${connectionId}`
|
|
1864
|
+
}
|
|
1865
|
+
})
|
|
1866
|
+
);
|
|
1867
|
+
return (_a = result.Items) == null ? void 0 : _a[0];
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
deleteConnection(connectionId) {
|
|
1871
|
+
return __async(this, null, function* () {
|
|
1872
|
+
yield this.docClient.send(
|
|
1873
|
+
new DeleteCommand({
|
|
1874
|
+
TableName: this.tableName,
|
|
1875
|
+
Key: {
|
|
1876
|
+
PK: `CONN#${connectionId}`,
|
|
1877
|
+
SK: "#METADATA#"
|
|
1878
|
+
}
|
|
1879
|
+
})
|
|
1880
|
+
);
|
|
1881
|
+
});
|
|
1882
|
+
}
|
|
1883
|
+
createSubscription(subKey, connectionId, data) {
|
|
1884
|
+
return __async(this, null, function* () {
|
|
1885
|
+
yield this.docClient.send(
|
|
1886
|
+
new PutCommand({
|
|
1887
|
+
TableName: this.tableName,
|
|
1888
|
+
Item: __spreadValues({
|
|
1889
|
+
PK: subKey,
|
|
1890
|
+
SK: `CONN#${connectionId}`,
|
|
1891
|
+
R1PK: `CONN#${connectionId}`,
|
|
1892
|
+
R1SK: subKey,
|
|
1893
|
+
connectionId
|
|
1894
|
+
}, data)
|
|
1895
|
+
})
|
|
1896
|
+
);
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
deleteSubscription(subKey, connectionId) {
|
|
1900
|
+
return __async(this, null, function* () {
|
|
1901
|
+
yield this.docClient.send(
|
|
1902
|
+
new DeleteCommand({
|
|
1903
|
+
TableName: this.tableName,
|
|
1904
|
+
Key: {
|
|
1905
|
+
PK: subKey,
|
|
1906
|
+
SK: `CONN#${connectionId}`
|
|
1907
|
+
}
|
|
1908
|
+
})
|
|
1909
|
+
);
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
querySubscriptionsByKey(subKey) {
|
|
1913
|
+
return __async(this, null, function* () {
|
|
1914
|
+
const result = yield this.docClient.send(
|
|
1915
|
+
new QueryCommand({
|
|
1916
|
+
TableName: this.tableName,
|
|
1917
|
+
KeyConditionExpression: "PK = :pk",
|
|
1918
|
+
ExpressionAttributeValues: {
|
|
1919
|
+
":pk": subKey
|
|
1920
|
+
},
|
|
1921
|
+
ConsistentRead: true
|
|
1922
|
+
})
|
|
1923
|
+
);
|
|
1924
|
+
return result.Items || [];
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
querySubscriptionsByConnectionId(connectionId) {
|
|
1928
|
+
return __async(this, null, function* () {
|
|
1929
|
+
const { ENTITY_REPLICATION_INDEX: ENTITY_REPLICATION_INDEX2 } = yield import("./service.config-ZJEZ6EKA.js");
|
|
1930
|
+
const result = yield this.docClient.send(
|
|
1931
|
+
new QueryCommand({
|
|
1932
|
+
TableName: this.tableName,
|
|
1933
|
+
IndexName: ENTITY_REPLICATION_INDEX2,
|
|
1934
|
+
KeyConditionExpression: "R1PK = :r1pk",
|
|
1935
|
+
ExpressionAttributeValues: {
|
|
1936
|
+
":r1pk": `CONN#${connectionId}`
|
|
1937
|
+
}
|
|
1938
|
+
})
|
|
1939
|
+
);
|
|
1940
|
+
return result.Items || [];
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
createTicket(ticket, entityType, entityId, feedTypes, expiresAt) {
|
|
1944
|
+
return __async(this, null, function* () {
|
|
1945
|
+
yield this.docClient.send(
|
|
1946
|
+
new PutCommand({
|
|
1947
|
+
TableName: this.tableName,
|
|
1948
|
+
Item: {
|
|
1949
|
+
PK: `TICKET#${ticket}`,
|
|
1950
|
+
SK: "#METADATA#",
|
|
1951
|
+
entityType,
|
|
1952
|
+
entityId,
|
|
1953
|
+
feedTypes,
|
|
1954
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1955
|
+
expiresAt
|
|
1956
|
+
}
|
|
1957
|
+
})
|
|
1958
|
+
);
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
consumeTicket(ticket) {
|
|
1962
|
+
return __async(this, null, function* () {
|
|
1963
|
+
try {
|
|
1964
|
+
const result = yield this.docClient.send(
|
|
1965
|
+
new DeleteCommand({
|
|
1966
|
+
TableName: this.tableName,
|
|
1967
|
+
Key: {
|
|
1968
|
+
PK: `TICKET#${ticket}`,
|
|
1969
|
+
SK: "#METADATA#"
|
|
1970
|
+
},
|
|
1971
|
+
ConditionExpression: "attribute_exists(PK)",
|
|
1972
|
+
ReturnValues: "ALL_OLD"
|
|
1973
|
+
})
|
|
1974
|
+
);
|
|
1975
|
+
const item = result.Attributes;
|
|
1976
|
+
if (!item) return null;
|
|
1977
|
+
const expiresAt = item.expiresAt;
|
|
1978
|
+
if (expiresAt && expiresAt < Math.floor(Date.now() / 1e3)) {
|
|
1979
|
+
return null;
|
|
1980
|
+
}
|
|
1981
|
+
return {
|
|
1982
|
+
entityType: item.entityType,
|
|
1983
|
+
entityId: item.entityId,
|
|
1984
|
+
feedTypes: item.feedTypes || []
|
|
1985
|
+
};
|
|
1986
|
+
} catch (error) {
|
|
1987
|
+
if (error instanceof Error && error.name === "ConditionalCheckFailedException") {
|
|
1988
|
+
return null;
|
|
1989
|
+
}
|
|
1990
|
+
throw error;
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
queryMutualConnections(byEntityType, byEntityId) {
|
|
1995
|
+
return __async(this, null, function* () {
|
|
1996
|
+
const result = yield this.docClient.send(
|
|
1997
|
+
new QueryCommand({
|
|
1998
|
+
TableName: this.tableName,
|
|
1999
|
+
KeyConditionExpression: "PK = :pk",
|
|
2000
|
+
ExpressionAttributeValues: {
|
|
2001
|
+
":pk": `${byEntityType}#${byEntityId}`
|
|
2002
|
+
},
|
|
2003
|
+
ProjectionExpression: "SK",
|
|
2004
|
+
ConsistentRead: true
|
|
2005
|
+
})
|
|
2006
|
+
);
|
|
2007
|
+
const connections = [];
|
|
2008
|
+
for (const item of result.Items || []) {
|
|
2009
|
+
const sk = item.SK;
|
|
2010
|
+
if (!sk || sk === "#METADATA#" || sk.startsWith("#")) continue;
|
|
2011
|
+
const parts = sk.split("#");
|
|
2012
|
+
if (parts.length >= 2) {
|
|
2013
|
+
connections.push({ entityType: parts[0], entityId: parts[1] });
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
return connections;
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
queryFeedSubscriptions(entityType, entityId) {
|
|
2020
|
+
return __async(this, null, function* () {
|
|
2021
|
+
const result = yield this.docClient.send(
|
|
2022
|
+
new QueryCommand({
|
|
2023
|
+
TableName: this.tableName,
|
|
2024
|
+
KeyConditionExpression: "PK = :pk",
|
|
2025
|
+
ExpressionAttributeValues: {
|
|
2026
|
+
":pk": `SUB#FEED#${entityType}#${entityId}`
|
|
2027
|
+
},
|
|
2028
|
+
ConsistentRead: true
|
|
2029
|
+
})
|
|
2030
|
+
);
|
|
2031
|
+
return result.Items || [];
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
2035
|
+
|
|
1824
2036
|
// handles/app.ts
|
|
1825
2037
|
import { Hono as Hono2 } from "hono";
|
|
1826
2038
|
import { handle } from "hono/aws-lambda";
|
|
@@ -1860,14 +2072,6 @@ import {
|
|
|
1860
2072
|
PutEventsCommand
|
|
1861
2073
|
} from "@aws-sdk/client-eventbridge";
|
|
1862
2074
|
|
|
1863
|
-
// constants/table.ts
|
|
1864
|
-
var ENTITY_REPLICATION_INDEX = "ENTITY_REPLICATION_INDEX";
|
|
1865
|
-
var MUTUAL_REPLICATION_INDEX = "MUTUAL_REPLICATION_INDEX";
|
|
1866
|
-
|
|
1867
|
-
// configs/service.config.ts
|
|
1868
|
-
var CORE_TABLE = process.env.CORE_TABLE || "";
|
|
1869
|
-
var CORE_EVENT_BUS = process.env.CORE_EVENT_BUS || "";
|
|
1870
|
-
|
|
1871
2075
|
// types/event.ts
|
|
1872
2076
|
var SOURCE = {
|
|
1873
2077
|
CORE: "core-service",
|
|
@@ -2819,6 +3023,458 @@ var handler5 = (container) => (ev) => __async(null, null, function* () {
|
|
|
2819
3023
|
return { batchItemFailures };
|
|
2820
3024
|
});
|
|
2821
3025
|
|
|
3026
|
+
// processors/websocket-processor.ts
|
|
3027
|
+
import {
|
|
3028
|
+
ApiGatewayManagementApiClient,
|
|
3029
|
+
PostToConnectionCommand
|
|
3030
|
+
} from "@aws-sdk/client-apigatewaymanagementapi";
|
|
3031
|
+
import { unmarshall as unmarshall4 } from "@aws-sdk/util-dynamodb";
|
|
3032
|
+
import { ulid as ulid3 } from "ulid";
|
|
3033
|
+
var SUB_ENTITY_TYPE = "SUB#ENTITY#";
|
|
3034
|
+
var SUB_MUTUAL_TYPE = "SUB#MUTUAL#";
|
|
3035
|
+
var SUB_EPHEMERAL = "SUB#EPHEMERAL#";
|
|
3036
|
+
var SUB_FEED = "SUB#FEED#";
|
|
3037
|
+
var getWsEndpoint = () => process.env.WEBSOCKET_MANAGEMENT_ENDPOINT || "";
|
|
3038
|
+
var connect = (container) => (event) => __async(null, null, function* () {
|
|
3039
|
+
var _a, _b, _c, _d;
|
|
3040
|
+
const connectionId = event.requestContext.connectionId;
|
|
3041
|
+
if (!connectionId) {
|
|
3042
|
+
return { statusCode: 400, body: "Missing connection ID" };
|
|
3043
|
+
}
|
|
3044
|
+
const expiresAt = Math.floor(Date.now() / 1e3) + 2 * 60 * 60;
|
|
3045
|
+
const ticket = (_a = event.queryStringParameters) == null ? void 0 : _a.ticket;
|
|
3046
|
+
const token = ((_b = event.queryStringParameters) == null ? void 0 : _b.token) || ((_c = event.headers) == null ? void 0 : _c.authorization) || ((_d = event.headers) == null ? void 0 : _d.Authorization);
|
|
3047
|
+
if (!ticket && !token) {
|
|
3048
|
+
return { statusCode: 401, body: "Unauthorized" };
|
|
3049
|
+
}
|
|
3050
|
+
const wsRepo = container.websocketRepository;
|
|
3051
|
+
try {
|
|
3052
|
+
let entityType;
|
|
3053
|
+
let entityId;
|
|
3054
|
+
let feedTypes;
|
|
3055
|
+
if (ticket) {
|
|
3056
|
+
const ticketData = yield wsRepo.consumeTicket(ticket);
|
|
3057
|
+
if (!ticketData) {
|
|
3058
|
+
return { statusCode: 401, body: "Invalid or expired ticket" };
|
|
3059
|
+
}
|
|
3060
|
+
entityType = ticketData.entityType;
|
|
3061
|
+
entityId = ticketData.entityId;
|
|
3062
|
+
feedTypes = ticketData.feedTypes;
|
|
3063
|
+
} else {
|
|
3064
|
+
entityId = token;
|
|
3065
|
+
}
|
|
3066
|
+
yield wsRepo.createConnection(
|
|
3067
|
+
connectionId,
|
|
3068
|
+
__spreadProps(__spreadValues(__spreadValues({}, entityType && { entityType }), entityId && { entityId }), {
|
|
3069
|
+
connectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3070
|
+
}),
|
|
3071
|
+
expiresAt
|
|
3072
|
+
);
|
|
3073
|
+
if (entityType && entityId && feedTypes) {
|
|
3074
|
+
yield wsRepo.createSubscription(
|
|
3075
|
+
`${SUB_FEED}${entityType}#${entityId}`,
|
|
3076
|
+
connectionId,
|
|
3077
|
+
{
|
|
3078
|
+
subscriptionType: "feed",
|
|
3079
|
+
entityType,
|
|
3080
|
+
entityId,
|
|
3081
|
+
feedTypes,
|
|
3082
|
+
subscribedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3083
|
+
expiresAt
|
|
3084
|
+
}
|
|
3085
|
+
);
|
|
3086
|
+
}
|
|
3087
|
+
return { statusCode: 200, body: "Connected" };
|
|
3088
|
+
} catch (error) {
|
|
3089
|
+
console.error("Error in $connect:", error);
|
|
3090
|
+
return { statusCode: 500, body: "Failed to connect" };
|
|
3091
|
+
}
|
|
3092
|
+
});
|
|
3093
|
+
var disconnect = (container) => (event) => __async(null, null, function* () {
|
|
3094
|
+
const connectionId = event.requestContext.connectionId;
|
|
3095
|
+
if (!connectionId) {
|
|
3096
|
+
return { statusCode: 400, body: "Missing connection ID" };
|
|
3097
|
+
}
|
|
3098
|
+
const wsRepo = container.websocketRepository;
|
|
3099
|
+
try {
|
|
3100
|
+
const subscriptions = yield wsRepo.querySubscriptionsByConnectionId(connectionId);
|
|
3101
|
+
const deletePromises = [];
|
|
3102
|
+
for (const item of subscriptions) {
|
|
3103
|
+
if (item.PK && item.SK) {
|
|
3104
|
+
deletePromises.push(
|
|
3105
|
+
wsRepo.deleteSubscription(item.PK, item.connectionId).catch(
|
|
3106
|
+
(e) => console.warn("Failed to delete subscription on disconnect:", e)
|
|
3107
|
+
)
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
deletePromises.push(wsRepo.deleteConnection(connectionId));
|
|
3112
|
+
yield Promise.all(deletePromises);
|
|
3113
|
+
return { statusCode: 200, body: "Disconnected" };
|
|
3114
|
+
} catch (error) {
|
|
3115
|
+
console.error("Error cleaning up connection:", error);
|
|
3116
|
+
return { statusCode: 500, body: "Failed to disconnect" };
|
|
3117
|
+
}
|
|
3118
|
+
});
|
|
3119
|
+
var $default = (container) => (event) => __async(null, null, function* () {
|
|
3120
|
+
const connectionId = event.requestContext.connectionId;
|
|
3121
|
+
if (!connectionId || !event.body) {
|
|
3122
|
+
return { statusCode: 400, body: "Invalid message" };
|
|
3123
|
+
}
|
|
3124
|
+
let message;
|
|
3125
|
+
try {
|
|
3126
|
+
message = JSON.parse(event.body);
|
|
3127
|
+
} catch (e) {
|
|
3128
|
+
return { statusCode: 400, body: "Invalid JSON" };
|
|
3129
|
+
}
|
|
3130
|
+
const wsRepo = container.websocketRepository;
|
|
3131
|
+
const wsEndpoint = getWsEndpoint();
|
|
3132
|
+
const managementApi = new ApiGatewayManagementApiClient({
|
|
3133
|
+
endpoint: wsEndpoint
|
|
3134
|
+
});
|
|
3135
|
+
try {
|
|
3136
|
+
switch (message.action) {
|
|
3137
|
+
case "subscribe": {
|
|
3138
|
+
const {
|
|
3139
|
+
entityType,
|
|
3140
|
+
byEntityType,
|
|
3141
|
+
byEntityId,
|
|
3142
|
+
mutualEntityType,
|
|
3143
|
+
channel
|
|
3144
|
+
} = message.payload;
|
|
3145
|
+
if (entityType && !byEntityType) {
|
|
3146
|
+
yield wsRepo.createSubscription(
|
|
3147
|
+
`${SUB_ENTITY_TYPE}${entityType}`,
|
|
3148
|
+
connectionId,
|
|
3149
|
+
{
|
|
3150
|
+
subscriptionType: "entity-type",
|
|
3151
|
+
entityType,
|
|
3152
|
+
subscribedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3153
|
+
}
|
|
3154
|
+
);
|
|
3155
|
+
} else if (byEntityType && byEntityId && mutualEntityType) {
|
|
3156
|
+
yield wsRepo.createSubscription(
|
|
3157
|
+
`${SUB_MUTUAL_TYPE}${byEntityType}#${byEntityId}#${mutualEntityType}`,
|
|
3158
|
+
connectionId,
|
|
3159
|
+
{
|
|
3160
|
+
subscriptionType: "mutual-type",
|
|
3161
|
+
byEntityType,
|
|
3162
|
+
byEntityId,
|
|
3163
|
+
entityType: mutualEntityType,
|
|
3164
|
+
subscribedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3165
|
+
}
|
|
3166
|
+
);
|
|
3167
|
+
} else if (channel) {
|
|
3168
|
+
yield wsRepo.createSubscription(
|
|
3169
|
+
`${SUB_EPHEMERAL}${channel}`,
|
|
3170
|
+
connectionId,
|
|
3171
|
+
{
|
|
3172
|
+
subscriptionType: "ephemeral",
|
|
3173
|
+
channel,
|
|
3174
|
+
subscribedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3175
|
+
}
|
|
3176
|
+
);
|
|
3177
|
+
} else {
|
|
3178
|
+
return { statusCode: 400, body: "Invalid subscription parameters" };
|
|
3179
|
+
}
|
|
3180
|
+
const ackMessage = {
|
|
3181
|
+
type: "ack",
|
|
3182
|
+
id: message.id,
|
|
3183
|
+
payload: { action: "subscribe", success: true }
|
|
3184
|
+
};
|
|
3185
|
+
yield managementApi.send(
|
|
3186
|
+
new PostToConnectionCommand({
|
|
3187
|
+
ConnectionId: connectionId,
|
|
3188
|
+
Data: JSON.stringify(ackMessage)
|
|
3189
|
+
})
|
|
3190
|
+
);
|
|
3191
|
+
return { statusCode: 200, body: "Subscribed" };
|
|
3192
|
+
}
|
|
3193
|
+
case "unsubscribe": {
|
|
3194
|
+
const {
|
|
3195
|
+
entityType,
|
|
3196
|
+
byEntityType,
|
|
3197
|
+
byEntityId,
|
|
3198
|
+
mutualEntityType,
|
|
3199
|
+
channel
|
|
3200
|
+
} = message.payload;
|
|
3201
|
+
if (entityType && !byEntityType) {
|
|
3202
|
+
yield wsRepo.deleteSubscription(
|
|
3203
|
+
`${SUB_ENTITY_TYPE}${entityType}`,
|
|
3204
|
+
connectionId
|
|
3205
|
+
);
|
|
3206
|
+
} else if (byEntityType && byEntityId && mutualEntityType) {
|
|
3207
|
+
yield wsRepo.deleteSubscription(
|
|
3208
|
+
`${SUB_MUTUAL_TYPE}${byEntityType}#${byEntityId}#${mutualEntityType}`,
|
|
3209
|
+
connectionId
|
|
3210
|
+
);
|
|
3211
|
+
} else if (channel) {
|
|
3212
|
+
yield wsRepo.deleteSubscription(
|
|
3213
|
+
`${SUB_EPHEMERAL}${channel}`,
|
|
3214
|
+
connectionId
|
|
3215
|
+
);
|
|
3216
|
+
}
|
|
3217
|
+
const ackMessage = {
|
|
3218
|
+
type: "ack",
|
|
3219
|
+
id: message.id,
|
|
3220
|
+
payload: { action: "unsubscribe", success: true }
|
|
3221
|
+
};
|
|
3222
|
+
yield managementApi.send(
|
|
3223
|
+
new PostToConnectionCommand({
|
|
3224
|
+
ConnectionId: connectionId,
|
|
3225
|
+
Data: JSON.stringify(ackMessage)
|
|
3226
|
+
})
|
|
3227
|
+
);
|
|
3228
|
+
return { statusCode: 200, body: "Unsubscribed" };
|
|
3229
|
+
}
|
|
3230
|
+
case "ping": {
|
|
3231
|
+
const pongMessage = {
|
|
3232
|
+
type: "pong",
|
|
3233
|
+
id: message.id,
|
|
3234
|
+
payload: { timestamp: Date.now() }
|
|
3235
|
+
};
|
|
3236
|
+
yield managementApi.send(
|
|
3237
|
+
new PostToConnectionCommand({
|
|
3238
|
+
ConnectionId: connectionId,
|
|
3239
|
+
Data: JSON.stringify(pongMessage)
|
|
3240
|
+
})
|
|
3241
|
+
);
|
|
3242
|
+
return { statusCode: 200, body: "Pong" };
|
|
3243
|
+
}
|
|
3244
|
+
case "ephemeral": {
|
|
3245
|
+
const { channel, data } = message.payload;
|
|
3246
|
+
if (!channel) {
|
|
3247
|
+
return { statusCode: 400, body: "Missing channel" };
|
|
3248
|
+
}
|
|
3249
|
+
const conn = yield wsRepo.getConnection(connectionId);
|
|
3250
|
+
const senderId = conn == null ? void 0 : conn.entityId;
|
|
3251
|
+
const subKey = `${SUB_EPHEMERAL}${channel}`;
|
|
3252
|
+
const ephemeralMessage = {
|
|
3253
|
+
type: "ephemeral",
|
|
3254
|
+
id: ulid3(),
|
|
3255
|
+
payload: { channel, data, senderId }
|
|
3256
|
+
};
|
|
3257
|
+
yield broadcastToSubscribers(
|
|
3258
|
+
managementApi,
|
|
3259
|
+
wsRepo,
|
|
3260
|
+
subKey,
|
|
3261
|
+
ephemeralMessage,
|
|
3262
|
+
connectionId
|
|
3263
|
+
// Exclude sender
|
|
3264
|
+
);
|
|
3265
|
+
return { statusCode: 200, body: "Broadcasted" };
|
|
3266
|
+
}
|
|
3267
|
+
default:
|
|
3268
|
+
return { statusCode: 400, body: "Unknown action" };
|
|
3269
|
+
}
|
|
3270
|
+
} catch (error) {
|
|
3271
|
+
console.error("Error handling message:", error);
|
|
3272
|
+
try {
|
|
3273
|
+
const errorMessage = {
|
|
3274
|
+
type: "error",
|
|
3275
|
+
id: message.id,
|
|
3276
|
+
payload: { message: "Internal server error" }
|
|
3277
|
+
};
|
|
3278
|
+
yield managementApi.send(
|
|
3279
|
+
new PostToConnectionCommand({
|
|
3280
|
+
ConnectionId: connectionId,
|
|
3281
|
+
Data: JSON.stringify(errorMessage)
|
|
3282
|
+
})
|
|
3283
|
+
);
|
|
3284
|
+
} catch (e) {
|
|
3285
|
+
}
|
|
3286
|
+
return { statusCode: 500, body: "Internal server error" };
|
|
3287
|
+
}
|
|
3288
|
+
});
|
|
3289
|
+
var broadcast = (container) => (event) => __async(null, null, function* () {
|
|
3290
|
+
var _a, _b, _c, _d;
|
|
3291
|
+
const wsRepo = container.websocketRepository;
|
|
3292
|
+
const wsEndpoint = getWsEndpoint();
|
|
3293
|
+
const managementApi = new ApiGatewayManagementApiClient({
|
|
3294
|
+
endpoint: wsEndpoint
|
|
3295
|
+
});
|
|
3296
|
+
for (const record of event.Records) {
|
|
3297
|
+
const isInsert = record.eventName === "INSERT";
|
|
3298
|
+
const isModify = record.eventName === "MODIFY";
|
|
3299
|
+
const isRemove = record.eventName === "REMOVE";
|
|
3300
|
+
if (!isInsert && !isModify && !isRemove) continue;
|
|
3301
|
+
const newImage = (_a = record.dynamodb) == null ? void 0 : _a.NewImage;
|
|
3302
|
+
const oldImage = (_b = record.dynamodb) == null ? void 0 : _b.OldImage;
|
|
3303
|
+
const image = newImage || oldImage;
|
|
3304
|
+
if (!image) continue;
|
|
3305
|
+
const pk = ((_c = image.PK) == null ? void 0 : _c.S) || "";
|
|
3306
|
+
const sk = ((_d = image.SK) == null ? void 0 : _d.S) || "";
|
|
3307
|
+
const pkParts = pk.split("#");
|
|
3308
|
+
if (pkParts.length < 2) continue;
|
|
3309
|
+
const firstPart = pkParts[0];
|
|
3310
|
+
if (firstPart === firstPart.toUpperCase() || firstPart.includes(":")) {
|
|
3311
|
+
continue;
|
|
3312
|
+
}
|
|
3313
|
+
const entityType = pkParts[0];
|
|
3314
|
+
const entityId = pkParts[1];
|
|
3315
|
+
const isMutual = !sk.startsWith("#METADATA#") && sk.includes("#");
|
|
3316
|
+
try {
|
|
3317
|
+
if (isMutual) {
|
|
3318
|
+
const skParts = sk.split("#");
|
|
3319
|
+
const mutualEntityType = skParts[0];
|
|
3320
|
+
const byEntityId = entityId;
|
|
3321
|
+
const subKey = `${SUB_MUTUAL_TYPE}${entityType}#${byEntityId}#${mutualEntityType}`;
|
|
3322
|
+
const subscribers = yield wsRepo.querySubscriptionsByKey(subKey);
|
|
3323
|
+
if (subscribers.length) {
|
|
3324
|
+
let eventType;
|
|
3325
|
+
if (isInsert) eventType = "mutual.created";
|
|
3326
|
+
else if (isModify) eventType = "mutual.updated";
|
|
3327
|
+
else eventType = "mutual.deleted";
|
|
3328
|
+
const message = {
|
|
3329
|
+
type: eventType,
|
|
3330
|
+
id: ulid3(),
|
|
3331
|
+
payload: {
|
|
3332
|
+
byEntityType: entityType,
|
|
3333
|
+
byEntityId,
|
|
3334
|
+
mutualEntityType,
|
|
3335
|
+
entityId: skParts[1],
|
|
3336
|
+
data: isRemove ? void 0 : unmarshall4(image)
|
|
3337
|
+
}
|
|
3338
|
+
};
|
|
3339
|
+
yield broadcastToSubscribers(
|
|
3340
|
+
managementApi,
|
|
3341
|
+
wsRepo,
|
|
3342
|
+
subKey,
|
|
3343
|
+
message
|
|
3344
|
+
);
|
|
3345
|
+
}
|
|
3346
|
+
} else {
|
|
3347
|
+
const subKey = `${SUB_ENTITY_TYPE}${entityType}`;
|
|
3348
|
+
const subscribers = yield wsRepo.querySubscriptionsByKey(subKey);
|
|
3349
|
+
if (subscribers.length) {
|
|
3350
|
+
let eventType;
|
|
3351
|
+
if (isInsert) eventType = "entity.created";
|
|
3352
|
+
else if (isModify) eventType = "entity.updated";
|
|
3353
|
+
else eventType = "entity.deleted";
|
|
3354
|
+
const message = {
|
|
3355
|
+
type: eventType,
|
|
3356
|
+
id: ulid3(),
|
|
3357
|
+
payload: {
|
|
3358
|
+
entityType,
|
|
3359
|
+
entityId,
|
|
3360
|
+
data: isRemove ? void 0 : unmarshall4(image)
|
|
3361
|
+
}
|
|
3362
|
+
};
|
|
3363
|
+
yield broadcastToSubscribers(
|
|
3364
|
+
managementApi,
|
|
3365
|
+
wsRepo,
|
|
3366
|
+
subKey,
|
|
3367
|
+
message
|
|
3368
|
+
);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
yield broadcastToFeedSubscribers(
|
|
3372
|
+
managementApi,
|
|
3373
|
+
wsRepo,
|
|
3374
|
+
entityType,
|
|
3375
|
+
entityId,
|
|
3376
|
+
isMutual ? sk.split("#")[0] : entityType,
|
|
3377
|
+
// the changed entity type
|
|
3378
|
+
isMutual ? {
|
|
3379
|
+
type: isInsert ? "mutual.created" : isModify ? "mutual.updated" : "mutual.deleted",
|
|
3380
|
+
id: ulid3(),
|
|
3381
|
+
payload: {
|
|
3382
|
+
byEntityType: entityType,
|
|
3383
|
+
byEntityId: entityId,
|
|
3384
|
+
mutualEntityType: sk.split("#")[0],
|
|
3385
|
+
entityId: sk.split("#")[1],
|
|
3386
|
+
data: isRemove ? void 0 : unmarshall4(image)
|
|
3387
|
+
}
|
|
3388
|
+
} : {
|
|
3389
|
+
type: isInsert ? "entity.created" : isModify ? "entity.updated" : "entity.deleted",
|
|
3390
|
+
id: ulid3(),
|
|
3391
|
+
payload: {
|
|
3392
|
+
entityType,
|
|
3393
|
+
entityId,
|
|
3394
|
+
data: isRemove ? void 0 : unmarshall4(image)
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
);
|
|
3398
|
+
} catch (error) {
|
|
3399
|
+
console.error("Error broadcasting:", error);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
});
|
|
3403
|
+
function broadcastToSubscribers(managementApi, wsRepo, subKey, message, excludeConnectionId) {
|
|
3404
|
+
return __async(this, null, function* () {
|
|
3405
|
+
const subscribers = yield wsRepo.querySubscriptionsByKey(subKey);
|
|
3406
|
+
if (!subscribers.length) return;
|
|
3407
|
+
const messageData = JSON.stringify(message);
|
|
3408
|
+
const sends = subscribers.filter((subscriber) => {
|
|
3409
|
+
const id = subscriber.connectionId;
|
|
3410
|
+
return !excludeConnectionId || id !== excludeConnectionId;
|
|
3411
|
+
}).map((subscriber) => __async(null, null, function* () {
|
|
3412
|
+
var _a;
|
|
3413
|
+
try {
|
|
3414
|
+
yield managementApi.send(
|
|
3415
|
+
new PostToConnectionCommand({
|
|
3416
|
+
ConnectionId: subscriber.connectionId,
|
|
3417
|
+
Data: messageData
|
|
3418
|
+
})
|
|
3419
|
+
);
|
|
3420
|
+
} catch (error) {
|
|
3421
|
+
const isGone = (error == null ? void 0 : error.name) === "GoneException" || ((_a = error == null ? void 0 : error.$metadata) == null ? void 0 : _a.httpStatusCode) === 410;
|
|
3422
|
+
if (isGone) {
|
|
3423
|
+
yield wsRepo.deleteSubscription(subKey, subscriber.connectionId).catch(
|
|
3424
|
+
(e) => console.warn("Failed to clean up stale subscription:", e)
|
|
3425
|
+
);
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
}));
|
|
3429
|
+
yield Promise.allSettled(sends);
|
|
3430
|
+
});
|
|
3431
|
+
}
|
|
3432
|
+
function broadcastToFeedSubscribers(managementApi, wsRepo, byEntityType, byEntityId, changedEntityType, message) {
|
|
3433
|
+
return __async(this, null, function* () {
|
|
3434
|
+
var _a;
|
|
3435
|
+
const connections = yield wsRepo.queryMutualConnections(
|
|
3436
|
+
byEntityType,
|
|
3437
|
+
byEntityId
|
|
3438
|
+
);
|
|
3439
|
+
if (!connections.length) return;
|
|
3440
|
+
const connectedEntities = new Set(
|
|
3441
|
+
connections.map((c) => `${c.entityType}:${c.entityId}`)
|
|
3442
|
+
);
|
|
3443
|
+
connectedEntities.add(`${byEntityType}:${byEntityId}`);
|
|
3444
|
+
const sentConnections = /* @__PURE__ */ new Set();
|
|
3445
|
+
for (const connEntity of connectedEntities) {
|
|
3446
|
+
const [entityType, entityId] = connEntity.split(":");
|
|
3447
|
+
const feedSubs = yield wsRepo.queryFeedSubscriptions(entityType, entityId);
|
|
3448
|
+
if (!feedSubs.length) continue;
|
|
3449
|
+
for (const feedSub of feedSubs) {
|
|
3450
|
+
const feedTypes = feedSub.feedTypes;
|
|
3451
|
+
const connectionId = feedSub.connectionId;
|
|
3452
|
+
if (feedTypes && !feedTypes.includes(changedEntityType)) continue;
|
|
3453
|
+
if (sentConnections.has(connectionId)) continue;
|
|
3454
|
+
sentConnections.add(connectionId);
|
|
3455
|
+
try {
|
|
3456
|
+
yield managementApi.send(
|
|
3457
|
+
new PostToConnectionCommand({
|
|
3458
|
+
ConnectionId: connectionId,
|
|
3459
|
+
Data: JSON.stringify(message)
|
|
3460
|
+
})
|
|
3461
|
+
);
|
|
3462
|
+
} catch (error) {
|
|
3463
|
+
const isGone = (error == null ? void 0 : error.name) === "GoneException" || ((_a = error == null ? void 0 : error.$metadata) == null ? void 0 : _a.httpStatusCode) === 410;
|
|
3464
|
+
if (isGone) {
|
|
3465
|
+
yield wsRepo.deleteSubscription(
|
|
3466
|
+
`SUB#FEED#${entityType}#${entityId}`,
|
|
3467
|
+
connectionId
|
|
3468
|
+
).catch(
|
|
3469
|
+
(e) => console.warn("Failed to clean up stale feed subscription:", e)
|
|
3470
|
+
);
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
});
|
|
3476
|
+
}
|
|
3477
|
+
|
|
2822
3478
|
// services/DependencyContainer.ts
|
|
2823
3479
|
import { DynamoDB } from "@aws-sdk/client-dynamodb";
|
|
2824
3480
|
|
|
@@ -7051,11 +7707,21 @@ var UpdateEntityController = class {
|
|
|
7051
7707
|
constructor(entityService) {
|
|
7052
7708
|
this.entityService = entityService;
|
|
7053
7709
|
this.controller = createMiddleware8((c) => __async(this, null, function* () {
|
|
7054
|
-
var
|
|
7710
|
+
var _b;
|
|
7055
7711
|
const accountId = c.req.header("account-id");
|
|
7056
7712
|
const { entityType, entityId } = c.req.param();
|
|
7057
7713
|
const body = yield c.req.json();
|
|
7058
|
-
const
|
|
7714
|
+
const _a = body, { $condition: condition, $where: where } = _a, entityPayload = __objRest(_a, ["$condition", "$where"]);
|
|
7715
|
+
if (condition !== void 0) {
|
|
7716
|
+
if (typeof condition !== "string" || condition.trim().length === 0) {
|
|
7717
|
+
c.status(httpStatus8.BAD_REQUEST);
|
|
7718
|
+
return c.json({
|
|
7719
|
+
code: "API_VALIDATION_ERROR",
|
|
7720
|
+
message: "$condition must be a non-empty string"
|
|
7721
|
+
});
|
|
7722
|
+
}
|
|
7723
|
+
}
|
|
7724
|
+
const errorContext = {
|
|
7059
7725
|
accountId,
|
|
7060
7726
|
"req.params": c.req.param(),
|
|
7061
7727
|
"req.body": body
|
|
@@ -7064,14 +7730,16 @@ var UpdateEntityController = class {
|
|
|
7064
7730
|
const entity = yield this.entityService.updateEntity({
|
|
7065
7731
|
entityType,
|
|
7066
7732
|
entityId,
|
|
7067
|
-
entityPayload
|
|
7068
|
-
accountId
|
|
7733
|
+
entityPayload,
|
|
7734
|
+
accountId,
|
|
7735
|
+
condition,
|
|
7736
|
+
where
|
|
7069
7737
|
});
|
|
7070
7738
|
errorContext.entity = entity;
|
|
7071
7739
|
c.status(httpStatus8.OK);
|
|
7072
7740
|
return c.json(entity);
|
|
7073
7741
|
} catch (err) {
|
|
7074
|
-
if (((
|
|
7742
|
+
if (((_b = err.constructor) == null ? void 0 : _b.name) === "ZodError") {
|
|
7075
7743
|
c.status(httpStatus8.BAD_REQUEST);
|
|
7076
7744
|
return c.json({
|
|
7077
7745
|
code: "API_VALIDATION_ERROR",
|
|
@@ -7083,10 +7751,18 @@ var UpdateEntityController = class {
|
|
|
7083
7751
|
c.status(httpStatus8.NOT_FOUND);
|
|
7084
7752
|
return c.json(__spreadValues({}, err.toJSON()));
|
|
7085
7753
|
}
|
|
7754
|
+
if (err instanceof StandardError && err.code === StandardErrorCode.INVALID_CONDITION) {
|
|
7755
|
+
c.status(httpStatus8.BAD_REQUEST);
|
|
7756
|
+
return c.json(__spreadValues({}, err.toJSON()));
|
|
7757
|
+
}
|
|
7086
7758
|
if (err instanceof StandardError && err.code === StandardErrorCode.UNIQUE_VALUE_EXISTS) {
|
|
7087
7759
|
c.status(httpStatus8.BAD_REQUEST);
|
|
7088
7760
|
return c.json(__spreadValues({}, err.toJSON()));
|
|
7089
7761
|
}
|
|
7762
|
+
if (err instanceof StandardError && err.code === StandardErrorCode.CONDITIONAL_CHECK_FAILED) {
|
|
7763
|
+
c.status(httpStatus8.CONFLICT);
|
|
7764
|
+
return c.json(__spreadValues({}, err.toJSON()));
|
|
7765
|
+
}
|
|
7090
7766
|
console.log(
|
|
7091
7767
|
"====UPDATE_ENTITY_CONTROLLER_ERROR",
|
|
7092
7768
|
err,
|
|
@@ -7105,11 +7781,21 @@ var AdjustEntityController = class {
|
|
|
7105
7781
|
constructor(entityService) {
|
|
7106
7782
|
this.entityService = entityService;
|
|
7107
7783
|
this.controller = createMiddleware9((c) => __async(this, null, function* () {
|
|
7108
|
-
var
|
|
7784
|
+
var _b;
|
|
7109
7785
|
const accountId = c.req.header("account-id") || "";
|
|
7110
7786
|
const { entityType, entityId } = c.req.param();
|
|
7111
7787
|
const body = yield c.req.json();
|
|
7112
|
-
|
|
7788
|
+
const _a = body, { $condition: condition } = _a, adjustments = __objRest(_a, ["$condition"]);
|
|
7789
|
+
if (condition !== void 0) {
|
|
7790
|
+
if (typeof condition !== "string" || condition.trim().length === 0) {
|
|
7791
|
+
c.status(httpStatus9.BAD_REQUEST);
|
|
7792
|
+
return c.json({
|
|
7793
|
+
code: "API_VALIDATION_ERROR",
|
|
7794
|
+
message: "$condition must be a non-empty string"
|
|
7795
|
+
});
|
|
7796
|
+
}
|
|
7797
|
+
}
|
|
7798
|
+
for (const [key, value] of Object.entries(adjustments)) {
|
|
7113
7799
|
if (typeof value !== "number") {
|
|
7114
7800
|
c.status(httpStatus9.BAD_REQUEST);
|
|
7115
7801
|
return c.json({
|
|
@@ -7122,8 +7808,9 @@ var AdjustEntityController = class {
|
|
|
7122
7808
|
const entity = yield this.entityService.adjustEntity({
|
|
7123
7809
|
entityType,
|
|
7124
7810
|
entityId,
|
|
7125
|
-
adjustments
|
|
7126
|
-
accountId
|
|
7811
|
+
adjustments,
|
|
7812
|
+
accountId,
|
|
7813
|
+
condition
|
|
7127
7814
|
});
|
|
7128
7815
|
c.status(httpStatus9.OK);
|
|
7129
7816
|
return c.json(entity.toJSON());
|
|
@@ -7132,7 +7819,11 @@ var AdjustEntityController = class {
|
|
|
7132
7819
|
c.status(httpStatus9.NOT_FOUND);
|
|
7133
7820
|
return c.json(__spreadValues({}, err.toJSON()));
|
|
7134
7821
|
}
|
|
7135
|
-
if (
|
|
7822
|
+
if (err instanceof StandardError && err.code === StandardErrorCode.INVALID_CONDITION) {
|
|
7823
|
+
c.status(httpStatus9.BAD_REQUEST);
|
|
7824
|
+
return c.json(__spreadValues({}, err.toJSON()));
|
|
7825
|
+
}
|
|
7826
|
+
if ((err == null ? void 0 : err.name) === "ConditionalCheckFailedException" || ((_b = err == null ? void 0 : err.__type) == null ? void 0 : _b.includes("ConditionalCheckFailed"))) {
|
|
7136
7827
|
c.status(httpStatus9.CONFLICT);
|
|
7137
7828
|
return c.json({
|
|
7138
7829
|
code: "ADJUSTMENT_CONSTRAINT_VIOLATED",
|
|
@@ -7437,6 +8128,119 @@ var UpdateMutualController = class {
|
|
|
7437
8128
|
}
|
|
7438
8129
|
};
|
|
7439
8130
|
|
|
8131
|
+
// services/entity.service.ts
|
|
8132
|
+
import { marshall as marshall6 } from "@aws-sdk/util-dynamodb";
|
|
8133
|
+
|
|
8134
|
+
// data/utils/build-condition-expression.ts
|
|
8135
|
+
import { marshall as marshall5 } from "@aws-sdk/util-dynamodb";
|
|
8136
|
+
function buildConditionExpression(where) {
|
|
8137
|
+
const conditions = ["attribute_exists(PK)"];
|
|
8138
|
+
const expressionAttributeNames = { "#data": "data" };
|
|
8139
|
+
const expressionAttributeValues = {};
|
|
8140
|
+
for (const [field, clause] of Object.entries(where)) {
|
|
8141
|
+
const namePlaceholder = `#where_${field}`;
|
|
8142
|
+
expressionAttributeNames[namePlaceholder] = field;
|
|
8143
|
+
const fieldRef = `#data.${namePlaceholder}`;
|
|
8144
|
+
if (clause === null || clause === void 0) continue;
|
|
8145
|
+
if (typeof clause !== "object") {
|
|
8146
|
+
const valPlaceholder = `:where_${field}`;
|
|
8147
|
+
expressionAttributeValues[valPlaceholder] = clause;
|
|
8148
|
+
conditions.push(`${fieldRef} = ${valPlaceholder}`);
|
|
8149
|
+
continue;
|
|
8150
|
+
}
|
|
8151
|
+
const op = clause;
|
|
8152
|
+
if ("$eq" in op) {
|
|
8153
|
+
const valPlaceholder = `:where_${field}_eq`;
|
|
8154
|
+
expressionAttributeValues[valPlaceholder] = op.$eq;
|
|
8155
|
+
conditions.push(`${fieldRef} = ${valPlaceholder}`);
|
|
8156
|
+
} else if ("$ne" in op) {
|
|
8157
|
+
const valPlaceholder = `:where_${field}_ne`;
|
|
8158
|
+
expressionAttributeValues[valPlaceholder] = op.$ne;
|
|
8159
|
+
conditions.push(`${fieldRef} <> ${valPlaceholder}`);
|
|
8160
|
+
} else if ("$gt" in op) {
|
|
8161
|
+
const valPlaceholder = `:where_${field}_gt`;
|
|
8162
|
+
expressionAttributeValues[valPlaceholder] = op.$gt;
|
|
8163
|
+
conditions.push(`${fieldRef} > ${valPlaceholder}`);
|
|
8164
|
+
} else if ("$lt" in op) {
|
|
8165
|
+
const valPlaceholder = `:where_${field}_lt`;
|
|
8166
|
+
expressionAttributeValues[valPlaceholder] = op.$lt;
|
|
8167
|
+
conditions.push(`${fieldRef} < ${valPlaceholder}`);
|
|
8168
|
+
} else if ("$gte" in op) {
|
|
8169
|
+
const valPlaceholder = `:where_${field}_gte`;
|
|
8170
|
+
expressionAttributeValues[valPlaceholder] = op.$gte;
|
|
8171
|
+
conditions.push(`${fieldRef} >= ${valPlaceholder}`);
|
|
8172
|
+
} else if ("$lte" in op) {
|
|
8173
|
+
const valPlaceholder = `:where_${field}_lte`;
|
|
8174
|
+
expressionAttributeValues[valPlaceholder] = op.$lte;
|
|
8175
|
+
conditions.push(`${fieldRef} <= ${valPlaceholder}`);
|
|
8176
|
+
} else if ("$exists" in op) {
|
|
8177
|
+
if (op.$exists) {
|
|
8178
|
+
conditions.push(`attribute_exists(${fieldRef})`);
|
|
8179
|
+
} else {
|
|
8180
|
+
conditions.push(`attribute_not_exists(${fieldRef})`);
|
|
8181
|
+
}
|
|
8182
|
+
} else if ("$beginsWith" in op) {
|
|
8183
|
+
const valPlaceholder = `:where_${field}_beginsWith`;
|
|
8184
|
+
expressionAttributeValues[valPlaceholder] = op.$beginsWith;
|
|
8185
|
+
conditions.push(`begins_with(${fieldRef}, ${valPlaceholder})`);
|
|
8186
|
+
}
|
|
8187
|
+
}
|
|
8188
|
+
return {
|
|
8189
|
+
ConditionExpression: conditions.join(" AND "),
|
|
8190
|
+
ExpressionAttributeNames: expressionAttributeNames,
|
|
8191
|
+
ExpressionAttributeValues: marshall5(expressionAttributeValues)
|
|
8192
|
+
};
|
|
8193
|
+
}
|
|
8194
|
+
|
|
8195
|
+
// services/resolve-condition.ts
|
|
8196
|
+
function resolveAdjustmentCondition(_0) {
|
|
8197
|
+
return __async(this, arguments, function* ({
|
|
8198
|
+
conditionName,
|
|
8199
|
+
conditions,
|
|
8200
|
+
adjustments,
|
|
8201
|
+
getEntityData
|
|
8202
|
+
}) {
|
|
8203
|
+
if (!Object.hasOwn(conditions, conditionName)) {
|
|
8204
|
+
throw new StandardError(
|
|
8205
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
8206
|
+
`Unknown adjustment condition: '${conditionName}'`
|
|
8207
|
+
);
|
|
8208
|
+
}
|
|
8209
|
+
const condition = conditions[conditionName];
|
|
8210
|
+
let resolved;
|
|
8211
|
+
if (typeof condition === "function") {
|
|
8212
|
+
const data = yield getEntityData();
|
|
8213
|
+
resolved = condition(data, adjustments);
|
|
8214
|
+
} else {
|
|
8215
|
+
resolved = condition;
|
|
8216
|
+
}
|
|
8217
|
+
return buildConditionExpression(resolved);
|
|
8218
|
+
});
|
|
8219
|
+
}
|
|
8220
|
+
function resolveUpdateCondition(_0) {
|
|
8221
|
+
return __async(this, arguments, function* ({
|
|
8222
|
+
conditionName,
|
|
8223
|
+
conditions,
|
|
8224
|
+
getEntityData
|
|
8225
|
+
}) {
|
|
8226
|
+
if (!Object.hasOwn(conditions, conditionName)) {
|
|
8227
|
+
throw new StandardError(
|
|
8228
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
8229
|
+
`Unknown update condition: '${conditionName}'`
|
|
8230
|
+
);
|
|
8231
|
+
}
|
|
8232
|
+
const condition = conditions[conditionName];
|
|
8233
|
+
let resolved;
|
|
8234
|
+
if (typeof condition === "function") {
|
|
8235
|
+
const data = yield getEntityData();
|
|
8236
|
+
resolved = condition(data);
|
|
8237
|
+
} else {
|
|
8238
|
+
resolved = condition;
|
|
8239
|
+
}
|
|
8240
|
+
return buildConditionExpression(resolved);
|
|
8241
|
+
});
|
|
8242
|
+
}
|
|
8243
|
+
|
|
7440
8244
|
// services/entity.service.ts
|
|
7441
8245
|
var EntityService = class {
|
|
7442
8246
|
constructor(EntityConfig, EmailAuthEnabledEntities, entityRepository, publishEvent2, entityServiceLifeCycle) {
|
|
@@ -7492,34 +8296,59 @@ var EntityService = class {
|
|
|
7492
8296
|
entityType,
|
|
7493
8297
|
entityId,
|
|
7494
8298
|
adjustments,
|
|
7495
|
-
accountId
|
|
8299
|
+
accountId,
|
|
8300
|
+
condition
|
|
7496
8301
|
}) {
|
|
7497
|
-
var _a, _b, _c
|
|
7498
|
-
const
|
|
7499
|
-
|
|
7500
|
-
|
|
8302
|
+
var _a, _b, _c;
|
|
8303
|
+
const entityConfig = this.EntityConfig[entityType];
|
|
8304
|
+
const adjustmentConditions = entityConfig == null ? void 0 : entityConfig.adjustmentConditions;
|
|
8305
|
+
const rawConstraints = entityConfig == null ? void 0 : entityConfig.adjustmentConstraints;
|
|
8306
|
+
let opts;
|
|
8307
|
+
if (adjustmentConditions) {
|
|
8308
|
+
if (!condition) {
|
|
8309
|
+
throw new StandardError(
|
|
8310
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
8311
|
+
"Entity has adjustmentConditions defined; $condition is required for adjustEntity"
|
|
8312
|
+
);
|
|
8313
|
+
}
|
|
8314
|
+
opts = yield resolveAdjustmentCondition({
|
|
8315
|
+
conditionName: condition,
|
|
8316
|
+
conditions: adjustmentConditions,
|
|
8317
|
+
adjustments,
|
|
8318
|
+
getEntityData: () => __async(this, null, function* () {
|
|
8319
|
+
var _a2;
|
|
8320
|
+
const entity2 = yield this.entityRepository.getEntity(entityType, entityId);
|
|
8321
|
+
return (_a2 = entity2 == null ? void 0 : entity2.data) != null ? _a2 : {};
|
|
8322
|
+
})
|
|
8323
|
+
});
|
|
8324
|
+
} else if (rawConstraints) {
|
|
8325
|
+
console.warn(
|
|
8326
|
+
"[monorise] adjustmentConstraints is deprecated. Use adjustmentConditions instead."
|
|
8327
|
+
);
|
|
8328
|
+
let resolvedConstraints = rawConstraints;
|
|
7501
8329
|
const hasDynamicFields = Object.values(rawConstraints).some(
|
|
7502
8330
|
(c) => c.minField || c.maxField
|
|
7503
8331
|
);
|
|
7504
8332
|
if (hasDynamicFields) {
|
|
7505
8333
|
const currentEntity = yield this.entityRepository.getEntity(entityType, entityId);
|
|
7506
|
-
const data = (
|
|
8334
|
+
const data = (_a = currentEntity == null ? void 0 : currentEntity.data) != null ? _a : {};
|
|
7507
8335
|
resolvedConstraints = {};
|
|
7508
8336
|
for (const [field, constraint] of Object.entries(rawConstraints)) {
|
|
7509
8337
|
const resolved = {};
|
|
7510
8338
|
if (constraint.min !== void 0) resolved.min = constraint.min;
|
|
7511
8339
|
if (constraint.max !== void 0) resolved.max = constraint.max;
|
|
7512
|
-
if (constraint.minField) resolved.min = (
|
|
7513
|
-
if (constraint.maxField) resolved.max = (
|
|
8340
|
+
if (constraint.minField) resolved.min = (_b = data[constraint.minField]) != null ? _b : 0;
|
|
8341
|
+
if (constraint.maxField) resolved.max = (_c = data[constraint.maxField]) != null ? _c : Number.MAX_SAFE_INTEGER;
|
|
7514
8342
|
resolvedConstraints[field] = resolved;
|
|
7515
8343
|
}
|
|
7516
8344
|
}
|
|
8345
|
+
opts = this.buildLegacyAdjustCondition(adjustments, resolvedConstraints);
|
|
7517
8346
|
}
|
|
7518
8347
|
const entity = yield this.entityRepository.adjustEntity(
|
|
7519
8348
|
entityType,
|
|
7520
8349
|
entityId,
|
|
7521
8350
|
adjustments,
|
|
7522
|
-
|
|
8351
|
+
opts
|
|
7523
8352
|
);
|
|
7524
8353
|
yield this.publishEvent({
|
|
7525
8354
|
event: EVENT.CORE.ENTITY_UPDATED,
|
|
@@ -7537,9 +8366,11 @@ var EntityService = class {
|
|
|
7537
8366
|
entityType,
|
|
7538
8367
|
entityId,
|
|
7539
8368
|
entityPayload,
|
|
7540
|
-
accountId
|
|
8369
|
+
accountId,
|
|
8370
|
+
condition,
|
|
8371
|
+
where
|
|
7541
8372
|
}) {
|
|
7542
|
-
var _a, _b;
|
|
8373
|
+
var _a, _b, _c;
|
|
7543
8374
|
const errorContext = {};
|
|
7544
8375
|
try {
|
|
7545
8376
|
const entitySchema = this.EntityConfig[entityType].baseSchema;
|
|
@@ -7553,10 +8384,35 @@ var EntityService = class {
|
|
|
7553
8384
|
const parsedEntityPayload = entitySchema.parse(entityPayload);
|
|
7554
8385
|
const parsedMutualPayload = mutualSchema == null ? void 0 : mutualSchema.parse(entityPayload);
|
|
7555
8386
|
errorContext.parsedMutualPayload = parsedMutualPayload;
|
|
8387
|
+
let opts;
|
|
8388
|
+
if (condition) {
|
|
8389
|
+
const updateConditions = (_b = this.EntityConfig[entityType]) == null ? void 0 : _b.updateConditions;
|
|
8390
|
+
if (!updateConditions) {
|
|
8391
|
+
throw new StandardError(
|
|
8392
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
8393
|
+
`Entity '${entityType}' has no updateConditions defined`
|
|
8394
|
+
);
|
|
8395
|
+
}
|
|
8396
|
+
opts = yield resolveUpdateCondition({
|
|
8397
|
+
conditionName: condition,
|
|
8398
|
+
conditions: updateConditions,
|
|
8399
|
+
getEntityData: () => __async(this, null, function* () {
|
|
8400
|
+
var _a2;
|
|
8401
|
+
const entity2 = yield this.entityRepository.getEntity(entityType, entityId);
|
|
8402
|
+
return (_a2 = entity2 == null ? void 0 : entity2.data) != null ? _a2 : {};
|
|
8403
|
+
})
|
|
8404
|
+
});
|
|
8405
|
+
} else if (where && Object.keys(where).length > 0) {
|
|
8406
|
+
console.warn(
|
|
8407
|
+
"[monorise] $where is deprecated. Use named conditions via $condition instead."
|
|
8408
|
+
);
|
|
8409
|
+
opts = buildConditionExpression(where);
|
|
8410
|
+
}
|
|
7556
8411
|
const entity = yield this.entityRepository.updateEntity(
|
|
7557
8412
|
entityType,
|
|
7558
8413
|
entityId,
|
|
7559
|
-
{ data: parsedEntityPayload }
|
|
8414
|
+
{ data: parsedEntityPayload },
|
|
8415
|
+
opts
|
|
7560
8416
|
);
|
|
7561
8417
|
errorContext.entity = entity;
|
|
7562
8418
|
if (parsedMutualPayload) {
|
|
@@ -7564,7 +8420,7 @@ var EntityService = class {
|
|
|
7564
8420
|
const byEntityId = entityId;
|
|
7565
8421
|
const publishEventPromises = [];
|
|
7566
8422
|
for (const [fieldKey, config] of Object.entries(
|
|
7567
|
-
((
|
|
8423
|
+
((_c = this.EntityConfig[entityType].mutual) == null ? void 0 : _c.mutualFields) || {}
|
|
7568
8424
|
)) {
|
|
7569
8425
|
const toMutualIds = config.toMutualIds;
|
|
7570
8426
|
const mutualPayload = parsedMutualPayload[fieldKey];
|
|
@@ -7620,10 +8476,39 @@ var EntityService = class {
|
|
|
7620
8476
|
});
|
|
7621
8477
|
});
|
|
7622
8478
|
}
|
|
8479
|
+
/** @deprecated Converts legacy adjustmentConstraints to condition expression opts. */
|
|
8480
|
+
buildLegacyAdjustCondition(adjustments, constraints) {
|
|
8481
|
+
const conditionParts = [];
|
|
8482
|
+
const names = { "#data": "data" };
|
|
8483
|
+
const values = {};
|
|
8484
|
+
for (const [field, constraint] of Object.entries(constraints)) {
|
|
8485
|
+
const delta = adjustments[field];
|
|
8486
|
+
if (delta === void 0) continue;
|
|
8487
|
+
const namePlaceholder = `#where_${field}`;
|
|
8488
|
+
names[namePlaceholder] = field;
|
|
8489
|
+
const fieldRef = `#data.${namePlaceholder}`;
|
|
8490
|
+
if (constraint.min !== void 0 && delta < 0) {
|
|
8491
|
+
const valKey = `:where_${field}_min_threshold`;
|
|
8492
|
+
conditionParts.push(`${fieldRef} >= ${valKey}`);
|
|
8493
|
+
values[valKey] = constraint.min - delta;
|
|
8494
|
+
}
|
|
8495
|
+
if (constraint.max !== void 0 && delta > 0) {
|
|
8496
|
+
const valKey = `:where_${field}_max_threshold`;
|
|
8497
|
+
conditionParts.push(`${fieldRef} <= ${valKey}`);
|
|
8498
|
+
values[valKey] = constraint.max - delta;
|
|
8499
|
+
}
|
|
8500
|
+
}
|
|
8501
|
+
if (conditionParts.length === 0) return void 0;
|
|
8502
|
+
return {
|
|
8503
|
+
ConditionExpression: conditionParts.join(" AND "),
|
|
8504
|
+
ExpressionAttributeNames: names,
|
|
8505
|
+
ExpressionAttributeValues: marshall6(values)
|
|
8506
|
+
};
|
|
8507
|
+
}
|
|
7623
8508
|
};
|
|
7624
8509
|
|
|
7625
8510
|
// services/mutual.service.ts
|
|
7626
|
-
import { ulid as
|
|
8511
|
+
import { ulid as ulid4 } from "ulid";
|
|
7627
8512
|
var MutualService = class {
|
|
7628
8513
|
constructor(entityRepository, mutualRepository, publishEvent2, ddbUtils, entityServiceLifeCycle) {
|
|
7629
8514
|
this.entityRepository = entityRepository;
|
|
@@ -7683,7 +8568,7 @@ var MutualService = class {
|
|
|
7683
8568
|
entityId,
|
|
7684
8569
|
entityData,
|
|
7685
8570
|
parsedMutualPayload,
|
|
7686
|
-
mutualId ||
|
|
8571
|
+
mutualId || ulid4(),
|
|
7687
8572
|
currentDatetime,
|
|
7688
8573
|
currentDatetime,
|
|
7689
8574
|
currentDatetime
|
|
@@ -7861,6 +8746,116 @@ var ListTagsController = class {
|
|
|
7861
8746
|
}
|
|
7862
8747
|
};
|
|
7863
8748
|
|
|
8749
|
+
// controllers/transaction/execute-transaction.controller.ts
|
|
8750
|
+
import { createMiddleware as createMiddleware17 } from "hono/factory";
|
|
8751
|
+
import httpStatus15 from "http-status";
|
|
8752
|
+
var ExecuteTransactionController = class {
|
|
8753
|
+
constructor(transactionService) {
|
|
8754
|
+
this.transactionService = transactionService;
|
|
8755
|
+
// biome-ignore lint/suspicious/noExplicitAny: Hono createMiddleware requires consistent return types
|
|
8756
|
+
this.controller = createMiddleware17((c) => __async(this, null, function* () {
|
|
8757
|
+
var _a;
|
|
8758
|
+
const accountId = c.req.header("account-id") || "";
|
|
8759
|
+
const body = yield c.req.json();
|
|
8760
|
+
if (!body.operations || !Array.isArray(body.operations)) {
|
|
8761
|
+
c.status(httpStatus15.BAD_REQUEST);
|
|
8762
|
+
return c.json({
|
|
8763
|
+
code: "API_VALIDATION_ERROR",
|
|
8764
|
+
message: 'Request body must contain an "operations" array'
|
|
8765
|
+
});
|
|
8766
|
+
}
|
|
8767
|
+
try {
|
|
8768
|
+
const result = yield this.transactionService.executeTransaction(
|
|
8769
|
+
body.operations,
|
|
8770
|
+
accountId
|
|
8771
|
+
);
|
|
8772
|
+
c.status(httpStatus15.OK);
|
|
8773
|
+
return c.json(result);
|
|
8774
|
+
} catch (err) {
|
|
8775
|
+
if (((_a = err.constructor) == null ? void 0 : _a.name) === "ZodError") {
|
|
8776
|
+
c.status(httpStatus15.BAD_REQUEST);
|
|
8777
|
+
return c.json({
|
|
8778
|
+
code: "API_VALIDATION_ERROR",
|
|
8779
|
+
message: "Validation failed",
|
|
8780
|
+
details: err.flatten()
|
|
8781
|
+
});
|
|
8782
|
+
}
|
|
8783
|
+
if (err instanceof StandardError) {
|
|
8784
|
+
const code = err.code;
|
|
8785
|
+
if (code === StandardErrorCode.TRANSACTION_EMPTY || code === StandardErrorCode.TRANSACTION_ITEM_LIMIT_EXCEEDED || code === StandardErrorCode.TRANSACTION_UNIQUE_FIELD_UPDATE || code === StandardErrorCode.INVALID_ENTITY_TYPE || code === StandardErrorCode.INVALID_CONDITION || code === StandardErrorCode.INVALID_UNIQUE_VALUE_TYPE) {
|
|
8786
|
+
c.status(httpStatus15.BAD_REQUEST);
|
|
8787
|
+
return c.json(__spreadValues({}, err.toJSON()));
|
|
8788
|
+
}
|
|
8789
|
+
if (code === StandardErrorCode.TRANSACTION_FAILED || code === StandardErrorCode.CONDITIONAL_CHECK_FAILED || code === StandardErrorCode.UNIQUE_VALUE_EXISTS) {
|
|
8790
|
+
c.status(httpStatus15.CONFLICT);
|
|
8791
|
+
return c.json(__spreadValues({}, err.toJSON()));
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
throw err;
|
|
8795
|
+
}
|
|
8796
|
+
}));
|
|
8797
|
+
}
|
|
8798
|
+
};
|
|
8799
|
+
|
|
8800
|
+
// controllers/ws/create-ticket.controller.ts
|
|
8801
|
+
import { createMiddleware as createMiddleware18 } from "hono/factory";
|
|
8802
|
+
import { ulid as ulid5 } from "ulid";
|
|
8803
|
+
var TICKET_TTL_SECONDS = 30 * 60;
|
|
8804
|
+
var CreateTicketController = class {
|
|
8805
|
+
constructor(container) {
|
|
8806
|
+
this.container = container;
|
|
8807
|
+
this.controller = createMiddleware18((c) => __async(this, null, function* () {
|
|
8808
|
+
var _a;
|
|
8809
|
+
const { entityType, entityId } = c.req.param();
|
|
8810
|
+
let feedTypes;
|
|
8811
|
+
try {
|
|
8812
|
+
const body = yield c.req.json();
|
|
8813
|
+
feedTypes = body.feedTypes;
|
|
8814
|
+
} catch (e) {
|
|
8815
|
+
}
|
|
8816
|
+
if (!feedTypes || feedTypes.length === 0) {
|
|
8817
|
+
const allConfigs = this.container.config.EntityConfig;
|
|
8818
|
+
const visited = /* @__PURE__ */ new Set();
|
|
8819
|
+
const queue = [entityType];
|
|
8820
|
+
while (queue.length > 0) {
|
|
8821
|
+
const current = queue.shift();
|
|
8822
|
+
if (!current) continue;
|
|
8823
|
+
if (visited.has(current)) continue;
|
|
8824
|
+
visited.add(current);
|
|
8825
|
+
const config = allConfigs[current];
|
|
8826
|
+
if ((_a = config == null ? void 0 : config.mutual) == null ? void 0 : _a.mutualFields) {
|
|
8827
|
+
for (const field of Object.values(
|
|
8828
|
+
config.mutual.mutualFields
|
|
8829
|
+
)) {
|
|
8830
|
+
if (!visited.has(field.entityType)) {
|
|
8831
|
+
queue.push(field.entityType);
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8834
|
+
}
|
|
8835
|
+
}
|
|
8836
|
+
visited.delete(entityType);
|
|
8837
|
+
feedTypes = Array.from(visited);
|
|
8838
|
+
}
|
|
8839
|
+
const ticket = ulid5();
|
|
8840
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
8841
|
+
const expiresAt = now + TICKET_TTL_SECONDS;
|
|
8842
|
+
yield this.container.websocketRepository.createTicket(
|
|
8843
|
+
ticket,
|
|
8844
|
+
entityType,
|
|
8845
|
+
entityId,
|
|
8846
|
+
feedTypes,
|
|
8847
|
+
expiresAt
|
|
8848
|
+
);
|
|
8849
|
+
const wsEndpoint = process.env.WEBSOCKET_URL || "";
|
|
8850
|
+
return c.json({
|
|
8851
|
+
ticket,
|
|
8852
|
+
wsUrl: wsEndpoint,
|
|
8853
|
+
expiresIn: TICKET_TTL_SECONDS
|
|
8854
|
+
});
|
|
8855
|
+
}));
|
|
8856
|
+
}
|
|
8857
|
+
};
|
|
8858
|
+
|
|
7864
8859
|
// services/entity-service-lifecycle.ts
|
|
7865
8860
|
var EntityServiceLifeCycle = class {
|
|
7866
8861
|
constructor(EntityConfig, publishEvent2, eventUtils) {
|
|
@@ -7893,6 +8888,435 @@ var EntityServiceLifeCycle = class {
|
|
|
7893
8888
|
}
|
|
7894
8889
|
};
|
|
7895
8890
|
|
|
8891
|
+
// services/transaction.service.ts
|
|
8892
|
+
import { TransactionCanceledException as TransactionCanceledException5 } from "@aws-sdk/client-dynamodb";
|
|
8893
|
+
import { ulid as ulid6 } from "ulid";
|
|
8894
|
+
var MAX_TRANSACTION_ITEMS = 100;
|
|
8895
|
+
var TransactionService = class {
|
|
8896
|
+
constructor(EntityConfig, EmailAuthEnabledEntities, entityRepository, dynamodbClient, publishEvent2, entityServiceLifeCycle, eventUtils) {
|
|
8897
|
+
this.EntityConfig = EntityConfig;
|
|
8898
|
+
this.EmailAuthEnabledEntities = EmailAuthEnabledEntities;
|
|
8899
|
+
this.entityRepository = entityRepository;
|
|
8900
|
+
this.dynamodbClient = dynamodbClient;
|
|
8901
|
+
this.publishEvent = publishEvent2;
|
|
8902
|
+
this.entityServiceLifeCycle = entityServiceLifeCycle;
|
|
8903
|
+
this.eventUtils = eventUtils;
|
|
8904
|
+
this.executeTransaction = (operations, accountId) => __async(this, null, function* () {
|
|
8905
|
+
var _a;
|
|
8906
|
+
if (!operations || operations.length === 0) {
|
|
8907
|
+
throw new StandardError(
|
|
8908
|
+
StandardErrorCode.TRANSACTION_EMPTY,
|
|
8909
|
+
"Transaction must contain at least one operation"
|
|
8910
|
+
);
|
|
8911
|
+
}
|
|
8912
|
+
const allTransactItems = [];
|
|
8913
|
+
const pendingEvents = [];
|
|
8914
|
+
const resultEntries = [];
|
|
8915
|
+
for (const op of operations) {
|
|
8916
|
+
switch (op.operation) {
|
|
8917
|
+
case "createEntity": {
|
|
8918
|
+
const { items, entity } = yield this.buildCreateItems(op);
|
|
8919
|
+
allTransactItems.push(...items);
|
|
8920
|
+
pendingEvents.push(
|
|
8921
|
+
...this.collectCreateEvents(
|
|
8922
|
+
entity,
|
|
8923
|
+
op.payload,
|
|
8924
|
+
accountId
|
|
8925
|
+
)
|
|
8926
|
+
);
|
|
8927
|
+
resultEntries.push({
|
|
8928
|
+
operation: "createEntity",
|
|
8929
|
+
entityType: op.entityType,
|
|
8930
|
+
entityId: entity.entityId,
|
|
8931
|
+
data: entity.data
|
|
8932
|
+
});
|
|
8933
|
+
break;
|
|
8934
|
+
}
|
|
8935
|
+
case "updateEntity": {
|
|
8936
|
+
const { item, updatedAt } = yield this.buildUpdateItem(op);
|
|
8937
|
+
allTransactItems.push(item);
|
|
8938
|
+
pendingEvents.push(
|
|
8939
|
+
...this.collectUpdateEvents(
|
|
8940
|
+
op,
|
|
8941
|
+
updatedAt,
|
|
8942
|
+
accountId
|
|
8943
|
+
)
|
|
8944
|
+
);
|
|
8945
|
+
resultEntries.push({
|
|
8946
|
+
operation: "updateEntity",
|
|
8947
|
+
entityType: op.entityType,
|
|
8948
|
+
entityId: op.entityId
|
|
8949
|
+
});
|
|
8950
|
+
break;
|
|
8951
|
+
}
|
|
8952
|
+
case "adjustEntity": {
|
|
8953
|
+
const { item, updatedAt } = yield this.buildAdjustItem(op);
|
|
8954
|
+
allTransactItems.push(item);
|
|
8955
|
+
pendingEvents.push({
|
|
8956
|
+
event: EVENT.CORE.ENTITY_UPDATED,
|
|
8957
|
+
payload: {
|
|
8958
|
+
entityType: op.entityType,
|
|
8959
|
+
entityId: op.entityId,
|
|
8960
|
+
updatedByAccountId: accountId,
|
|
8961
|
+
publishedAt: updatedAt
|
|
8962
|
+
}
|
|
8963
|
+
});
|
|
8964
|
+
resultEntries.push({
|
|
8965
|
+
operation: "adjustEntity",
|
|
8966
|
+
entityType: op.entityType,
|
|
8967
|
+
entityId: op.entityId
|
|
8968
|
+
});
|
|
8969
|
+
break;
|
|
8970
|
+
}
|
|
8971
|
+
case "deleteEntity": {
|
|
8972
|
+
const item = this.buildDeleteItem(op);
|
|
8973
|
+
allTransactItems.push(item);
|
|
8974
|
+
pendingEvents.push({
|
|
8975
|
+
event: EVENT.CORE.ENTITY_DELETED,
|
|
8976
|
+
payload: {
|
|
8977
|
+
entityType: op.entityType,
|
|
8978
|
+
entityId: op.entityId,
|
|
8979
|
+
deletedByAccountId: accountId
|
|
8980
|
+
}
|
|
8981
|
+
});
|
|
8982
|
+
resultEntries.push({
|
|
8983
|
+
operation: "deleteEntity",
|
|
8984
|
+
entityType: op.entityType,
|
|
8985
|
+
entityId: op.entityId
|
|
8986
|
+
});
|
|
8987
|
+
break;
|
|
8988
|
+
}
|
|
8989
|
+
default:
|
|
8990
|
+
throw new StandardError(
|
|
8991
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
8992
|
+
`Unknown operation: '${op.operation}'`
|
|
8993
|
+
);
|
|
8994
|
+
}
|
|
8995
|
+
}
|
|
8996
|
+
if (allTransactItems.length > MAX_TRANSACTION_ITEMS) {
|
|
8997
|
+
throw new StandardError(
|
|
8998
|
+
StandardErrorCode.TRANSACTION_ITEM_LIMIT_EXCEEDED,
|
|
8999
|
+
`Transaction contains ${allTransactItems.length} items, exceeds limit of ${MAX_TRANSACTION_ITEMS}`
|
|
9000
|
+
);
|
|
9001
|
+
}
|
|
9002
|
+
try {
|
|
9003
|
+
yield this.dynamodbClient.transactWriteItems({
|
|
9004
|
+
TransactItems: allTransactItems
|
|
9005
|
+
});
|
|
9006
|
+
} catch (err) {
|
|
9007
|
+
if (err instanceof TransactionCanceledException5) {
|
|
9008
|
+
throw new StandardError(
|
|
9009
|
+
StandardErrorCode.TRANSACTION_FAILED,
|
|
9010
|
+
"Transaction failed",
|
|
9011
|
+
err,
|
|
9012
|
+
{
|
|
9013
|
+
reasons: (_a = err.CancellationReasons) == null ? void 0 : _a.map((r, i) => ({
|
|
9014
|
+
index: i,
|
|
9015
|
+
code: r.Code,
|
|
9016
|
+
message: r.Message
|
|
9017
|
+
}))
|
|
9018
|
+
}
|
|
9019
|
+
);
|
|
9020
|
+
}
|
|
9021
|
+
throw err;
|
|
9022
|
+
}
|
|
9023
|
+
const readPromises = resultEntries.map((entry) => __async(this, null, function* () {
|
|
9024
|
+
if ((entry.operation === "updateEntity" || entry.operation === "adjustEntity") && !entry.data) {
|
|
9025
|
+
try {
|
|
9026
|
+
const entity = yield this.entityRepository.getEntity(
|
|
9027
|
+
entry.entityType,
|
|
9028
|
+
entry.entityId
|
|
9029
|
+
);
|
|
9030
|
+
entry.data = entity.data;
|
|
9031
|
+
} catch (e) {
|
|
9032
|
+
}
|
|
9033
|
+
}
|
|
9034
|
+
}));
|
|
9035
|
+
yield Promise.all(readPromises);
|
|
9036
|
+
yield Promise.allSettled(pendingEvents.map((ev) => this.publishEvent(ev)));
|
|
9037
|
+
return { results: resultEntries };
|
|
9038
|
+
});
|
|
9039
|
+
}
|
|
9040
|
+
buildCreateItems(op) {
|
|
9041
|
+
return __async(this, null, function* () {
|
|
9042
|
+
const config = this.EntityConfig[op.entityType];
|
|
9043
|
+
if (!config) {
|
|
9044
|
+
throw new StandardError(
|
|
9045
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9046
|
+
`Unknown entity type: '${op.entityType}'`
|
|
9047
|
+
);
|
|
9048
|
+
}
|
|
9049
|
+
const entitySchema = config.createSchema || config.baseSchema;
|
|
9050
|
+
if (!entitySchema) {
|
|
9051
|
+
throw new StandardError(
|
|
9052
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9053
|
+
`No schema defined for entity type: '${op.entityType}'`
|
|
9054
|
+
);
|
|
9055
|
+
}
|
|
9056
|
+
if (config.finalSchema) {
|
|
9057
|
+
config.finalSchema.parse(op.payload);
|
|
9058
|
+
}
|
|
9059
|
+
const parsedPayload = entitySchema.parse(
|
|
9060
|
+
op.payload
|
|
9061
|
+
);
|
|
9062
|
+
const currentDatetime = /* @__PURE__ */ new Date();
|
|
9063
|
+
const entity = new Entity(
|
|
9064
|
+
op.entityType,
|
|
9065
|
+
op.entityId || ulid6(),
|
|
9066
|
+
parsedPayload,
|
|
9067
|
+
currentDatetime,
|
|
9068
|
+
currentDatetime
|
|
9069
|
+
);
|
|
9070
|
+
const uniqueFields = config.uniqueFields || [];
|
|
9071
|
+
const uniqueFieldValues = {};
|
|
9072
|
+
for (const field of uniqueFields) {
|
|
9073
|
+
if (!(field in parsedPayload)) continue;
|
|
9074
|
+
const value = parsedPayload[field];
|
|
9075
|
+
if (typeof value !== "string") {
|
|
9076
|
+
throw new StandardError(
|
|
9077
|
+
StandardErrorCode.INVALID_UNIQUE_VALUE_TYPE,
|
|
9078
|
+
`Invalid type. ${field} is not a 'string'.`
|
|
9079
|
+
);
|
|
9080
|
+
}
|
|
9081
|
+
uniqueFieldValues[field] = value;
|
|
9082
|
+
}
|
|
9083
|
+
const items = this.entityRepository.createEntityTransactItems(entity, {
|
|
9084
|
+
uniqueFieldValues
|
|
9085
|
+
});
|
|
9086
|
+
return { items, entity };
|
|
9087
|
+
});
|
|
9088
|
+
}
|
|
9089
|
+
buildUpdateItem(op) {
|
|
9090
|
+
return __async(this, null, function* () {
|
|
9091
|
+
const config = this.EntityConfig[op.entityType];
|
|
9092
|
+
if (!config) {
|
|
9093
|
+
throw new StandardError(
|
|
9094
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9095
|
+
`Unknown entity type: '${op.entityType}'`
|
|
9096
|
+
);
|
|
9097
|
+
}
|
|
9098
|
+
const uniqueFields = config.uniqueFields || [];
|
|
9099
|
+
for (const field of uniqueFields) {
|
|
9100
|
+
if (field in op.payload) {
|
|
9101
|
+
throw new StandardError(
|
|
9102
|
+
StandardErrorCode.TRANSACTION_UNIQUE_FIELD_UPDATE,
|
|
9103
|
+
`Cannot update unique field '${field}' within a transaction. Use a standalone updateEntity call instead.`
|
|
9104
|
+
);
|
|
9105
|
+
}
|
|
9106
|
+
}
|
|
9107
|
+
const entitySchema = config.baseSchema;
|
|
9108
|
+
if (!entitySchema) {
|
|
9109
|
+
throw new StandardError(
|
|
9110
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9111
|
+
`No schema defined for entity type: '${op.entityType}'`
|
|
9112
|
+
);
|
|
9113
|
+
}
|
|
9114
|
+
const parsedPayload = entitySchema.partial().parse(op.payload);
|
|
9115
|
+
const currentDatetime = (/* @__PURE__ */ new Date()).toISOString();
|
|
9116
|
+
const toUpdateExpressions = this.entityRepository.toUpdate({
|
|
9117
|
+
updatedAt: currentDatetime,
|
|
9118
|
+
data: parsedPayload
|
|
9119
|
+
});
|
|
9120
|
+
let conditionOpts;
|
|
9121
|
+
if (op.condition) {
|
|
9122
|
+
const updateConditions = config.updateConditions;
|
|
9123
|
+
if (!updateConditions) {
|
|
9124
|
+
throw new StandardError(
|
|
9125
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
9126
|
+
`Entity '${op.entityType}' has no updateConditions defined`
|
|
9127
|
+
);
|
|
9128
|
+
}
|
|
9129
|
+
conditionOpts = yield resolveUpdateCondition({
|
|
9130
|
+
conditionName: op.condition,
|
|
9131
|
+
conditions: updateConditions,
|
|
9132
|
+
getEntityData: () => __async(this, null, function* () {
|
|
9133
|
+
var _a;
|
|
9134
|
+
const entity2 = yield this.entityRepository.getEntity(
|
|
9135
|
+
op.entityType,
|
|
9136
|
+
op.entityId
|
|
9137
|
+
);
|
|
9138
|
+
return (_a = entity2 == null ? void 0 : entity2.data) != null ? _a : {};
|
|
9139
|
+
})
|
|
9140
|
+
});
|
|
9141
|
+
}
|
|
9142
|
+
const entity = new Entity(op.entityType, op.entityId);
|
|
9143
|
+
const item = {
|
|
9144
|
+
Update: {
|
|
9145
|
+
TableName: this.entityRepository.TABLE_NAME,
|
|
9146
|
+
Key: entity.keys(),
|
|
9147
|
+
ConditionExpression: (conditionOpts == null ? void 0 : conditionOpts.ConditionExpression) || "attribute_exists(PK)",
|
|
9148
|
+
UpdateExpression: toUpdateExpressions.UpdateExpression,
|
|
9149
|
+
ExpressionAttributeNames: __spreadValues(__spreadValues({}, toUpdateExpressions.ExpressionAttributeNames), conditionOpts == null ? void 0 : conditionOpts.ExpressionAttributeNames),
|
|
9150
|
+
ExpressionAttributeValues: __spreadValues(__spreadValues({}, toUpdateExpressions.ExpressionAttributeValues), conditionOpts == null ? void 0 : conditionOpts.ExpressionAttributeValues)
|
|
9151
|
+
}
|
|
9152
|
+
};
|
|
9153
|
+
return { item, updatedAt: currentDatetime };
|
|
9154
|
+
});
|
|
9155
|
+
}
|
|
9156
|
+
buildAdjustItem(op) {
|
|
9157
|
+
return __async(this, null, function* () {
|
|
9158
|
+
const config = this.EntityConfig[op.entityType];
|
|
9159
|
+
if (!config) {
|
|
9160
|
+
throw new StandardError(
|
|
9161
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9162
|
+
`Unknown entity type: '${op.entityType}'`
|
|
9163
|
+
);
|
|
9164
|
+
}
|
|
9165
|
+
for (const [key, value] of Object.entries(op.adjustments)) {
|
|
9166
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
9167
|
+
throw new StandardError(
|
|
9168
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9169
|
+
`Adjustment field "${key}" must be a finite number`
|
|
9170
|
+
);
|
|
9171
|
+
}
|
|
9172
|
+
}
|
|
9173
|
+
const {
|
|
9174
|
+
UpdateExpression,
|
|
9175
|
+
ExpressionAttributeNames,
|
|
9176
|
+
ExpressionAttributeValues
|
|
9177
|
+
} = this.entityRepository.toAdjustUpdate(op.adjustments);
|
|
9178
|
+
const currentDatetime = (/* @__PURE__ */ new Date()).toISOString();
|
|
9179
|
+
ExpressionAttributeNames["#updatedAt"] = "updatedAt";
|
|
9180
|
+
ExpressionAttributeValues[":updatedAt"] = { S: currentDatetime };
|
|
9181
|
+
const fullUpdateExpression = `${UpdateExpression}, #updatedAt = :updatedAt`;
|
|
9182
|
+
let conditionOpts;
|
|
9183
|
+
const adjustmentConditions = config.adjustmentConditions;
|
|
9184
|
+
if (adjustmentConditions) {
|
|
9185
|
+
if (!op.condition) {
|
|
9186
|
+
throw new StandardError(
|
|
9187
|
+
StandardErrorCode.INVALID_CONDITION,
|
|
9188
|
+
`Entity '${op.entityType}' has adjustmentConditions defined; condition is required`
|
|
9189
|
+
);
|
|
9190
|
+
}
|
|
9191
|
+
conditionOpts = yield resolveAdjustmentCondition({
|
|
9192
|
+
conditionName: op.condition,
|
|
9193
|
+
conditions: adjustmentConditions,
|
|
9194
|
+
adjustments: op.adjustments,
|
|
9195
|
+
getEntityData: () => __async(this, null, function* () {
|
|
9196
|
+
var _a;
|
|
9197
|
+
const entity2 = yield this.entityRepository.getEntity(
|
|
9198
|
+
op.entityType,
|
|
9199
|
+
op.entityId
|
|
9200
|
+
);
|
|
9201
|
+
return (_a = entity2 == null ? void 0 : entity2.data) != null ? _a : {};
|
|
9202
|
+
})
|
|
9203
|
+
});
|
|
9204
|
+
}
|
|
9205
|
+
const entity = new Entity(op.entityType, op.entityId);
|
|
9206
|
+
const item = {
|
|
9207
|
+
Update: {
|
|
9208
|
+
TableName: this.entityRepository.TABLE_NAME,
|
|
9209
|
+
Key: entity.keys(),
|
|
9210
|
+
UpdateExpression: fullUpdateExpression,
|
|
9211
|
+
ConditionExpression: (conditionOpts == null ? void 0 : conditionOpts.ConditionExpression) || "attribute_exists(PK)",
|
|
9212
|
+
ExpressionAttributeNames: __spreadValues(__spreadValues({}, ExpressionAttributeNames), conditionOpts == null ? void 0 : conditionOpts.ExpressionAttributeNames),
|
|
9213
|
+
ExpressionAttributeValues: __spreadValues(__spreadValues({}, ExpressionAttributeValues), conditionOpts == null ? void 0 : conditionOpts.ExpressionAttributeValues)
|
|
9214
|
+
}
|
|
9215
|
+
};
|
|
9216
|
+
return { item, updatedAt: currentDatetime };
|
|
9217
|
+
});
|
|
9218
|
+
}
|
|
9219
|
+
buildDeleteItem(op) {
|
|
9220
|
+
const config = this.EntityConfig[op.entityType];
|
|
9221
|
+
if (!config) {
|
|
9222
|
+
throw new StandardError(
|
|
9223
|
+
StandardErrorCode.INVALID_ENTITY_TYPE,
|
|
9224
|
+
`Unknown entity type: '${op.entityType}'`
|
|
9225
|
+
);
|
|
9226
|
+
}
|
|
9227
|
+
const entity = new Entity(op.entityType, op.entityId);
|
|
9228
|
+
return {
|
|
9229
|
+
Delete: {
|
|
9230
|
+
TableName: this.entityRepository.TABLE_NAME,
|
|
9231
|
+
Key: entity.keys(),
|
|
9232
|
+
ConditionExpression: "attribute_exists(PK)"
|
|
9233
|
+
}
|
|
9234
|
+
};
|
|
9235
|
+
}
|
|
9236
|
+
collectCreateEvents(entity, payload, accountId) {
|
|
9237
|
+
var _a, _b;
|
|
9238
|
+
const events = [];
|
|
9239
|
+
const publishedAt = entity.updatedAt || (/* @__PURE__ */ new Date()).toISOString();
|
|
9240
|
+
const config = this.EntityConfig[entity.entityType];
|
|
9241
|
+
const mutualSchema = (_a = config == null ? void 0 : config.mutual) == null ? void 0 : _a.mutualSchema;
|
|
9242
|
+
if (mutualSchema) {
|
|
9243
|
+
const parsedMutualPayload = mutualSchema.parse(payload);
|
|
9244
|
+
if (parsedMutualPayload) {
|
|
9245
|
+
for (const [fieldKey, fieldConfig] of Object.entries(
|
|
9246
|
+
((_b = config.mutual) == null ? void 0 : _b.mutualFields) || {}
|
|
9247
|
+
)) {
|
|
9248
|
+
const toMutualIds = fieldConfig.toMutualIds;
|
|
9249
|
+
const mutualPayload = parsedMutualPayload[fieldKey];
|
|
9250
|
+
if (!mutualPayload) continue;
|
|
9251
|
+
events.push({
|
|
9252
|
+
event: EVENT.CORE.ENTITY_MUTUAL_TO_CREATE,
|
|
9253
|
+
payload: {
|
|
9254
|
+
byEntityType: entity.entityType,
|
|
9255
|
+
byEntityId: entity.entityId,
|
|
9256
|
+
entityType: fieldConfig.entityType,
|
|
9257
|
+
field: fieldKey,
|
|
9258
|
+
mutualIds: toMutualIds ? toMutualIds(mutualPayload) : mutualPayload,
|
|
9259
|
+
customContext: toMutualIds ? mutualPayload : {},
|
|
9260
|
+
publishedAt
|
|
9261
|
+
}
|
|
9262
|
+
});
|
|
9263
|
+
}
|
|
9264
|
+
}
|
|
9265
|
+
}
|
|
9266
|
+
events.push({
|
|
9267
|
+
event: EVENT.CORE.ENTITY_CREATED,
|
|
9268
|
+
payload: {
|
|
9269
|
+
entityType: entity.entityType,
|
|
9270
|
+
entityId: entity.entityId,
|
|
9271
|
+
data: entity.data,
|
|
9272
|
+
createdByAccountId: accountId,
|
|
9273
|
+
publishedAt
|
|
9274
|
+
}
|
|
9275
|
+
});
|
|
9276
|
+
return events;
|
|
9277
|
+
}
|
|
9278
|
+
collectUpdateEvents(op, updatedAt, accountId) {
|
|
9279
|
+
var _a, _b;
|
|
9280
|
+
const events = [];
|
|
9281
|
+
const config = this.EntityConfig[op.entityType];
|
|
9282
|
+
const mutualSchema = (_a = config == null ? void 0 : config.mutual) == null ? void 0 : _a.mutualSchema;
|
|
9283
|
+
if (mutualSchema) {
|
|
9284
|
+
const parsedMutualPayload = mutualSchema.parse(op.payload);
|
|
9285
|
+
if (parsedMutualPayload) {
|
|
9286
|
+
for (const [fieldKey, fieldConfig] of Object.entries(
|
|
9287
|
+
((_b = config.mutual) == null ? void 0 : _b.mutualFields) || {}
|
|
9288
|
+
)) {
|
|
9289
|
+
const toMutualIds = fieldConfig.toMutualIds;
|
|
9290
|
+
const mutualPayload = parsedMutualPayload[fieldKey];
|
|
9291
|
+
if (!mutualPayload) continue;
|
|
9292
|
+
events.push({
|
|
9293
|
+
event: EVENT.CORE.ENTITY_MUTUAL_TO_UPDATE,
|
|
9294
|
+
payload: {
|
|
9295
|
+
byEntityType: op.entityType,
|
|
9296
|
+
byEntityId: op.entityId,
|
|
9297
|
+
entityType: fieldConfig.entityType,
|
|
9298
|
+
field: fieldKey,
|
|
9299
|
+
mutualIds: toMutualIds ? toMutualIds(mutualPayload) : mutualPayload,
|
|
9300
|
+
customContext: toMutualIds ? mutualPayload : {},
|
|
9301
|
+
publishedAt: updatedAt
|
|
9302
|
+
}
|
|
9303
|
+
});
|
|
9304
|
+
}
|
|
9305
|
+
}
|
|
9306
|
+
}
|
|
9307
|
+
events.push({
|
|
9308
|
+
event: EVENT.CORE.ENTITY_UPDATED,
|
|
9309
|
+
payload: {
|
|
9310
|
+
entityType: op.entityType,
|
|
9311
|
+
entityId: op.entityId,
|
|
9312
|
+
updatedByAccountId: accountId,
|
|
9313
|
+
publishedAt: updatedAt
|
|
9314
|
+
}
|
|
9315
|
+
});
|
|
9316
|
+
return events;
|
|
9317
|
+
}
|
|
9318
|
+
};
|
|
9319
|
+
|
|
7896
9320
|
// services/DependencyContainer.ts
|
|
7897
9321
|
var DependencyContainer = class {
|
|
7898
9322
|
constructor(config) {
|
|
@@ -7985,6 +9409,13 @@ var DependencyContainer = class {
|
|
|
7985
9409
|
this.dynamodbClient
|
|
7986
9410
|
);
|
|
7987
9411
|
}
|
|
9412
|
+
get websocketRepository() {
|
|
9413
|
+
return this.createCachedInstance(
|
|
9414
|
+
WebSocketRepository,
|
|
9415
|
+
this.coreTable,
|
|
9416
|
+
this.dynamodbClient
|
|
9417
|
+
);
|
|
9418
|
+
}
|
|
7988
9419
|
get getEntityController() {
|
|
7989
9420
|
return this.createCachedInstance(
|
|
7990
9421
|
GetEntityController,
|
|
@@ -8068,6 +9499,62 @@ var DependencyContainer = class {
|
|
|
8068
9499
|
get listTagsController() {
|
|
8069
9500
|
return this.createCachedInstance(ListTagsController, this.tagRepository);
|
|
8070
9501
|
}
|
|
9502
|
+
get transactionService() {
|
|
9503
|
+
return this.createCachedInstance(
|
|
9504
|
+
TransactionService,
|
|
9505
|
+
this.config.EntityConfig,
|
|
9506
|
+
this.config.EmailAuthEnabledEntities,
|
|
9507
|
+
this.entityRepository,
|
|
9508
|
+
this.dynamodbClient,
|
|
9509
|
+
this.publishEvent,
|
|
9510
|
+
this.entityServiceLifeCycle,
|
|
9511
|
+
this.eventUtils
|
|
9512
|
+
);
|
|
9513
|
+
}
|
|
9514
|
+
get executeTransactionController() {
|
|
9515
|
+
return this.createCachedInstance(
|
|
9516
|
+
ExecuteTransactionController,
|
|
9517
|
+
this.transactionService
|
|
9518
|
+
);
|
|
9519
|
+
}
|
|
9520
|
+
get createTicketController() {
|
|
9521
|
+
return this.createCachedInstance(CreateTicketController, this);
|
|
9522
|
+
}
|
|
9523
|
+
};
|
|
9524
|
+
|
|
9525
|
+
// helpers/transactional.ts
|
|
9526
|
+
var transactional = {
|
|
9527
|
+
createEntity: (entityType, payload) => {
|
|
9528
|
+
const _a = payload, { entityId } = _a, rest = __objRest(_a, ["entityId"]);
|
|
9529
|
+
return __spreadValues({
|
|
9530
|
+
operation: "createEntity",
|
|
9531
|
+
entityType,
|
|
9532
|
+
payload: rest
|
|
9533
|
+
}, entityId && { entityId });
|
|
9534
|
+
},
|
|
9535
|
+
updateEntity: (entityType, entityId, payload) => {
|
|
9536
|
+
const _a = payload, { $condition } = _a, rest = __objRest(_a, ["$condition"]);
|
|
9537
|
+
return __spreadValues({
|
|
9538
|
+
operation: "updateEntity",
|
|
9539
|
+
entityType,
|
|
9540
|
+
entityId,
|
|
9541
|
+
payload: rest
|
|
9542
|
+
}, $condition && { condition: $condition });
|
|
9543
|
+
},
|
|
9544
|
+
adjustEntity: (entityType, entityId, adjustments) => {
|
|
9545
|
+
const _a = adjustments, { $condition } = _a, rest = __objRest(_a, ["$condition"]);
|
|
9546
|
+
return __spreadValues({
|
|
9547
|
+
operation: "adjustEntity",
|
|
9548
|
+
entityType,
|
|
9549
|
+
entityId,
|
|
9550
|
+
adjustments: rest
|
|
9551
|
+
}, $condition && { condition: $condition });
|
|
9552
|
+
},
|
|
9553
|
+
deleteEntity: (entityType, entityId) => ({
|
|
9554
|
+
operation: "deleteEntity",
|
|
9555
|
+
entityType,
|
|
9556
|
+
entityId
|
|
9557
|
+
})
|
|
8071
9558
|
};
|
|
8072
9559
|
|
|
8073
9560
|
// index.ts
|
|
@@ -8083,6 +9570,10 @@ var CoreFactory = class {
|
|
|
8083
9570
|
this.prejoinProcessor = handler3(dependencyContainer);
|
|
8084
9571
|
this.tagProcessor = handler5(dependencyContainer);
|
|
8085
9572
|
this.appHandler = appHandler(dependencyContainer);
|
|
9573
|
+
this.wsConnect = connect(dependencyContainer);
|
|
9574
|
+
this.wsDisconnect = disconnect(dependencyContainer);
|
|
9575
|
+
this.wsDefault = $default(dependencyContainer);
|
|
9576
|
+
this.wsBroadcast = broadcast(dependencyContainer);
|
|
8086
9577
|
}
|
|
8087
9578
|
};
|
|
8088
9579
|
var index_default = CoreFactory;
|
|
@@ -8098,6 +9589,8 @@ export {
|
|
|
8098
9589
|
StandardError,
|
|
8099
9590
|
StandardErrorCode,
|
|
8100
9591
|
TagRepository,
|
|
9592
|
+
TransactionService,
|
|
9593
|
+
WebSocketRepository,
|
|
8101
9594
|
appHandler,
|
|
8102
9595
|
handler as createEntityProcessor,
|
|
8103
9596
|
index_default as default,
|
|
@@ -8105,6 +9598,11 @@ export {
|
|
|
8105
9598
|
handler3 as prejoinProcessor,
|
|
8106
9599
|
handler4 as replicationProcessor,
|
|
8107
9600
|
setupCommonRoutes,
|
|
8108
|
-
handler5 as tagProcessor
|
|
9601
|
+
handler5 as tagProcessor,
|
|
9602
|
+
transactional,
|
|
9603
|
+
broadcast as wsBroadcast,
|
|
9604
|
+
connect as wsConnect,
|
|
9605
|
+
$default as wsDefault,
|
|
9606
|
+
disconnect as wsDisconnect
|
|
8109
9607
|
};
|
|
8110
9608
|
//# sourceMappingURL=index.js.map
|