@signal24/dk-server-foundation 26.213.615
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/.gitattributes +2 -0
- package/.gitlab-ci.yml +49 -0
- package/.oxlintrc.json +40 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +15 -0
- package/.serena/project.yml +111 -0
- package/.vscode/launch.json +15 -0
- package/.vscode/settings.json +12 -0
- package/.yarnrc.yml +5 -0
- package/CLAUDE.md +279 -0
- package/LICENSE +21 -0
- package/README.md +439 -0
- package/TEST_MIGRATION_GUIDE.md +348 -0
- package/dist/resources/proto/generated/test/test.d.ts +224 -0
- package/dist/resources/proto/generated/test/test.d.ts.map +1 -0
- package/dist/resources/proto/generated/test/test.js +2376 -0
- package/dist/resources/proto/generated/test/test.js.map +1 -0
- package/dist/src/app/base.d.ts +37 -0
- package/dist/src/app/base.d.ts.map +1 -0
- package/dist/src/app/base.js +244 -0
- package/dist/src/app/base.js.map +1 -0
- package/dist/src/app/config.d.ts +91 -0
- package/dist/src/app/config.d.ts.map +1 -0
- package/dist/src/app/config.js +33 -0
- package/dist/src/app/config.js.map +1 -0
- package/dist/src/app/config.loader.d.ts +14 -0
- package/dist/src/app/config.loader.d.ts.map +1 -0
- package/dist/src/app/config.loader.js +67 -0
- package/dist/src/app/config.loader.js.map +1 -0
- package/dist/src/app/const.d.ts +3 -0
- package/dist/src/app/const.d.ts.map +1 -0
- package/dist/src/app/const.js +6 -0
- package/dist/src/app/const.js.map +1 -0
- package/dist/src/app/dev.d.ts +6 -0
- package/dist/src/app/dev.d.ts.map +1 -0
- package/dist/src/app/dev.js +78 -0
- package/dist/src/app/dev.js.map +1 -0
- package/dist/src/app/index.d.ts +7 -0
- package/dist/src/app/index.d.ts.map +1 -0
- package/dist/src/app/index.js +12 -0
- package/dist/src/app/index.js.map +1 -0
- package/dist/src/app/openapi.d.ts +4 -0
- package/dist/src/app/openapi.d.ts.map +1 -0
- package/dist/src/app/openapi.js +6 -0
- package/dist/src/app/openapi.js.map +1 -0
- package/dist/src/app/resolver.d.ts +11 -0
- package/dist/src/app/resolver.d.ts.map +1 -0
- package/dist/src/app/resolver.js +60 -0
- package/dist/src/app/resolver.js.map +1 -0
- package/dist/src/app/shutdown.d.ts +12 -0
- package/dist/src/app/shutdown.d.ts.map +1 -0
- package/dist/src/app/shutdown.js +63 -0
- package/dist/src/app/shutdown.js.map +1 -0
- package/dist/src/app/state.d.ts +16 -0
- package/dist/src/app/state.d.ts.map +1 -0
- package/dist/src/app/state.js +12 -0
- package/dist/src/app/state.js.map +1 -0
- package/dist/src/auth/index.d.ts +3 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +6 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/jwt.d.ts +76 -0
- package/dist/src/auth/jwt.d.ts.map +1 -0
- package/dist/src/auth/jwt.js +218 -0
- package/dist/src/auth/jwt.js.map +1 -0
- package/dist/src/auth/provider.d.ts +15 -0
- package/dist/src/auth/provider.d.ts.map +1 -0
- package/dist/src/auth/provider.js +50 -0
- package/dist/src/auth/provider.js.map +1 -0
- package/dist/src/cli/dksf-dev.d.ts +3 -0
- package/dist/src/cli/dksf-dev.d.ts.map +1 -0
- package/dist/src/cli/dksf-dev.js +359 -0
- package/dist/src/cli/dksf-dev.js.map +1 -0
- package/dist/src/cli/dksf-gen-proto.d.ts +3 -0
- package/dist/src/cli/dksf-gen-proto.d.ts.map +1 -0
- package/dist/src/cli/dksf-gen-proto.js +164 -0
- package/dist/src/cli/dksf-gen-proto.js.map +1 -0
- package/dist/src/cli/dksf-install.d.ts +3 -0
- package/dist/src/cli/dksf-install.d.ts.map +1 -0
- package/dist/src/cli/dksf-install.js +10 -0
- package/dist/src/cli/dksf-install.js.map +1 -0
- package/dist/src/cli/dksf-test.d.ts +3 -0
- package/dist/src/cli/dksf-test.d.ts.map +1 -0
- package/dist/src/cli/dksf-test.js +91 -0
- package/dist/src/cli/dksf-test.js.map +1 -0
- package/dist/src/cli/dksf-update.d.ts +3 -0
- package/dist/src/cli/dksf-update.d.ts.map +1 -0
- package/dist/src/cli/dksf-update.js +86 -0
- package/dist/src/cli/dksf-update.js.map +1 -0
- package/dist/src/database/common.d.ts +84 -0
- package/dist/src/database/common.d.ts.map +1 -0
- package/dist/src/database/common.js +380 -0
- package/dist/src/database/common.js.map +1 -0
- package/dist/src/database/dialect.d.ts +10 -0
- package/dist/src/database/dialect.d.ts.map +1 -0
- package/dist/src/database/dialect.js +56 -0
- package/dist/src/database/dialect.js.map +1 -0
- package/dist/src/database/entity.d.ts +62 -0
- package/dist/src/database/entity.d.ts.map +1 -0
- package/dist/src/database/entity.js +198 -0
- package/dist/src/database/entity.js.map +1 -0
- package/dist/src/database/index.d.ts +8 -0
- package/dist/src/database/index.d.ts.map +1 -0
- package/dist/src/database/index.js +15 -0
- package/dist/src/database/index.js.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts +11 -0
- package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationResetCommand.js +149 -0
- package/dist/src/database/migration/MigrationResetCommand.js.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts +11 -0
- package/dist/src/database/migration/MigrationRunCommand.d.ts.map +1 -0
- package/dist/src/database/migration/MigrationRunCommand.js +118 -0
- package/dist/src/database/migration/MigrationRunCommand.js.map +1 -0
- package/dist/src/database/migration/characters.d.ts +14 -0
- package/dist/src/database/migration/characters.d.ts.map +1 -0
- package/dist/src/database/migration/characters.js +56 -0
- package/dist/src/database/migration/characters.js.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts +11 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts.map +1 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js +104 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.js.map +1 -0
- package/dist/src/database/migration/create/comparator.d.ts +3 -0
- package/dist/src/database/migration/create/comparator.d.ts.map +1 -0
- package/dist/src/database/migration/create/comparator.js +408 -0
- package/dist/src/database/migration/create/comparator.js.map +1 -0
- package/dist/src/database/migration/create/db-reader.d.ts +5 -0
- package/dist/src/database/migration/create/db-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/db-reader.js +473 -0
- package/dist/src/database/migration/create/db-reader.js.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts +3 -0
- package/dist/src/database/migration/create/ddl-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/ddl-generator.js +725 -0
- package/dist/src/database/migration/create/ddl-generator.js.map +1 -0
- package/dist/src/database/migration/create/entity-reader.d.ts +4 -0
- package/dist/src/database/migration/create/entity-reader.d.ts.map +1 -0
- package/dist/src/database/migration/create/entity-reader.js +408 -0
- package/dist/src/database/migration/create/entity-reader.js.map +1 -0
- package/dist/src/database/migration/create/file-generator.d.ts +2 -0
- package/dist/src/database/migration/create/file-generator.d.ts.map +1 -0
- package/dist/src/database/migration/create/file-generator.js +55 -0
- package/dist/src/database/migration/create/file-generator.js.map +1 -0
- package/dist/src/database/migration/create/prompt.d.ts +4 -0
- package/dist/src/database/migration/create/prompt.d.ts.map +1 -0
- package/dist/src/database/migration/create/prompt.js +55 -0
- package/dist/src/database/migration/create/prompt.js.map +1 -0
- package/dist/src/database/migration/create/schema-model.d.ts +109 -0
- package/dist/src/database/migration/create/schema-model.d.ts.map +1 -0
- package/dist/src/database/migration/create/schema-model.js +24 -0
- package/dist/src/database/migration/create/schema-model.js.map +1 -0
- package/dist/src/database/migration/helpers.d.ts +2 -0
- package/dist/src/database/migration/helpers.d.ts.map +1 -0
- package/dist/src/database/migration/helpers.js +8 -0
- package/dist/src/database/migration/helpers.js.map +1 -0
- package/dist/src/database/migration/index.d.ts +9 -0
- package/dist/src/database/migration/index.d.ts.map +1 -0
- package/dist/src/database/migration/index.js +43 -0
- package/dist/src/database/migration/index.js.map +1 -0
- package/dist/src/database/migration/migration.entity.d.ts +8 -0
- package/dist/src/database/migration/migration.entity.d.ts.map +1 -0
- package/dist/src/database/migration/migration.entity.js +16 -0
- package/dist/src/database/migration/migration.entity.js.map +1 -0
- package/dist/src/database/mysql.d.ts +16 -0
- package/dist/src/database/mysql.d.ts.map +1 -0
- package/dist/src/database/mysql.js +140 -0
- package/dist/src/database/mysql.js.map +1 -0
- package/dist/src/database/postgres.d.ts +16 -0
- package/dist/src/database/postgres.d.ts.map +1 -0
- package/dist/src/database/postgres.js +91 -0
- package/dist/src/database/postgres.js.map +1 -0
- package/dist/src/database/types.d.ts +21 -0
- package/dist/src/database/types.d.ts.map +1 -0
- package/dist/src/database/types.js +27 -0
- package/dist/src/database/types.js.map +1 -0
- package/dist/src/health/health.module.d.ts +6 -0
- package/dist/src/health/health.module.d.ts.map +1 -0
- package/dist/src/health/health.module.js +32 -0
- package/dist/src/health/health.module.js.map +1 -0
- package/dist/src/health/healthcheck.controller.d.ts +10 -0
- package/dist/src/health/healthcheck.controller.d.ts.map +1 -0
- package/dist/src/health/healthcheck.controller.js +30 -0
- package/dist/src/health/healthcheck.controller.js.map +1 -0
- package/dist/src/health/healthcheck.service.d.ts +8 -0
- package/dist/src/health/healthcheck.service.d.ts.map +1 -0
- package/dist/src/health/healthcheck.service.js +20 -0
- package/dist/src/health/healthcheck.service.js.map +1 -0
- package/dist/src/health/index.d.ts +3 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +6 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/helpers/async/context.d.ts +11 -0
- package/dist/src/helpers/async/context.d.ts.map +1 -0
- package/dist/src/helpers/async/context.js +75 -0
- package/dist/src/helpers/async/context.js.map +1 -0
- package/dist/src/helpers/async/process.d.ts +16 -0
- package/dist/src/helpers/async/process.d.ts.map +1 -0
- package/dist/src/helpers/async/process.js +44 -0
- package/dist/src/helpers/async/process.js.map +1 -0
- package/dist/src/helpers/async/promise.d.ts +5 -0
- package/dist/src/helpers/async/promise.d.ts.map +1 -0
- package/dist/src/helpers/async/promise.js +27 -0
- package/dist/src/helpers/async/promise.js.map +1 -0
- package/dist/src/helpers/data/array.d.ts +3 -0
- package/dist/src/helpers/data/array.d.ts.map +1 -0
- package/dist/src/helpers/data/array.js +17 -0
- package/dist/src/helpers/data/array.js.map +1 -0
- package/dist/src/helpers/data/objects.d.ts +12 -0
- package/dist/src/helpers/data/objects.d.ts.map +1 -0
- package/dist/src/helpers/data/objects.js +75 -0
- package/dist/src/helpers/data/objects.js.map +1 -0
- package/dist/src/helpers/data/serialization.d.ts +4 -0
- package/dist/src/helpers/data/serialization.d.ts.map +1 -0
- package/dist/src/helpers/data/serialization.js +15 -0
- package/dist/src/helpers/data/serialization.js.map +1 -0
- package/dist/src/helpers/data/transformer.d.ts +13 -0
- package/dist/src/helpers/data/transformer.d.ts.map +1 -0
- package/dist/src/helpers/data/transformer.js +55 -0
- package/dist/src/helpers/data/transformer.js.map +1 -0
- package/dist/src/helpers/framework/decorators.d.ts +5 -0
- package/dist/src/helpers/framework/decorators.d.ts.map +1 -0
- package/dist/src/helpers/framework/decorators.js +39 -0
- package/dist/src/helpers/framework/decorators.js.map +1 -0
- package/dist/src/helpers/framework/event.d.ts +3 -0
- package/dist/src/helpers/framework/event.d.ts.map +1 -0
- package/dist/src/helpers/framework/event.js +20 -0
- package/dist/src/helpers/framework/event.js.map +1 -0
- package/dist/src/helpers/framework/injection.d.ts +7 -0
- package/dist/src/helpers/framework/injection.d.ts.map +1 -0
- package/dist/src/helpers/framework/injection.js +52 -0
- package/dist/src/helpers/framework/injection.js.map +1 -0
- package/dist/src/helpers/index.d.ts +22 -0
- package/dist/src/helpers/index.d.ts.map +1 -0
- package/dist/src/helpers/index.js +32 -0
- package/dist/src/helpers/index.js.map +1 -0
- package/dist/src/helpers/io/package.d.ts +5 -0
- package/dist/src/helpers/io/package.d.ts.map +1 -0
- package/dist/src/helpers/io/package.js +31 -0
- package/dist/src/helpers/io/package.js.map +1 -0
- package/dist/src/helpers/io/stream.d.ts +18 -0
- package/dist/src/helpers/io/stream.d.ts.map +1 -0
- package/dist/src/helpers/io/stream.js +91 -0
- package/dist/src/helpers/io/stream.js.map +1 -0
- package/dist/src/helpers/redis/broadcast.d.ts +12 -0
- package/dist/src/helpers/redis/broadcast.d.ts.map +1 -0
- package/dist/src/helpers/redis/broadcast.js +99 -0
- package/dist/src/helpers/redis/broadcast.js.map +1 -0
- package/dist/src/helpers/redis/cache.d.ts +7 -0
- package/dist/src/helpers/redis/cache.d.ts.map +1 -0
- package/dist/src/helpers/redis/cache.js +28 -0
- package/dist/src/helpers/redis/cache.js.map +1 -0
- package/dist/src/helpers/redis/mutex.d.ts +24 -0
- package/dist/src/helpers/redis/mutex.d.ts.map +1 -0
- package/dist/src/helpers/redis/mutex.js +240 -0
- package/dist/src/helpers/redis/mutex.js.map +1 -0
- package/dist/src/helpers/redis/redis.d.ts +11 -0
- package/dist/src/helpers/redis/redis.d.ts.map +1 -0
- package/dist/src/helpers/redis/redis.js +59 -0
- package/dist/src/helpers/redis/redis.js.map +1 -0
- package/dist/src/helpers/security/crypto.d.ts +26 -0
- package/dist/src/helpers/security/crypto.d.ts.map +1 -0
- package/dist/src/helpers/security/crypto.js +121 -0
- package/dist/src/helpers/security/crypto.js.map +1 -0
- package/dist/src/helpers/security/validation.d.ts +4 -0
- package/dist/src/helpers/security/validation.d.ts.map +1 -0
- package/dist/src/helpers/security/validation.js +25 -0
- package/dist/src/helpers/security/validation.js.map +1 -0
- package/dist/src/helpers/utils/date.d.ts +4 -0
- package/dist/src/helpers/utils/date.d.ts.map +1 -0
- package/dist/src/helpers/utils/date.js +23 -0
- package/dist/src/helpers/utils/date.js.map +1 -0
- package/dist/src/helpers/utils/error.d.ts +24 -0
- package/dist/src/helpers/utils/error.d.ts.map +1 -0
- package/dist/src/helpers/utils/error.js +168 -0
- package/dist/src/helpers/utils/error.js.map +1 -0
- package/dist/src/helpers/utils/jsx.d.ts +3 -0
- package/dist/src/helpers/utils/jsx.d.ts.map +1 -0
- package/dist/src/helpers/utils/jsx.js +13 -0
- package/dist/src/helpers/utils/jsx.js.map +1 -0
- package/dist/src/helpers/utils/uuid.d.ts +3 -0
- package/dist/src/helpers/utils/uuid.d.ts.map +1 -0
- package/dist/src/helpers/utils/uuid.js +14 -0
- package/dist/src/helpers/utils/uuid.js.map +1 -0
- package/dist/src/http/auth.d.ts +46 -0
- package/dist/src/http/auth.d.ts.map +1 -0
- package/dist/src/http/auth.js +162 -0
- package/dist/src/http/auth.js.map +1 -0
- package/dist/src/http/context.d.ts +5 -0
- package/dist/src/http/context.d.ts.map +1 -0
- package/dist/src/http/context.js +22 -0
- package/dist/src/http/context.js.map +1 -0
- package/dist/src/http/cors.d.ts +36 -0
- package/dist/src/http/cors.d.ts.map +1 -0
- package/dist/src/http/cors.js +171 -0
- package/dist/src/http/cors.js.map +1 -0
- package/dist/src/http/errors.d.ts +3 -0
- package/dist/src/http/errors.d.ts.map +1 -0
- package/dist/src/http/errors.js +10 -0
- package/dist/src/http/errors.js.map +1 -0
- package/dist/src/http/index.d.ts +24 -0
- package/dist/src/http/index.d.ts.map +1 -0
- package/dist/src/http/index.js +25 -0
- package/dist/src/http/index.js.map +1 -0
- package/dist/src/http/kernel.d.ts +17 -0
- package/dist/src/http/kernel.d.ts.map +1 -0
- package/dist/src/http/kernel.js +133 -0
- package/dist/src/http/kernel.js.map +1 -0
- package/dist/src/http/middleware.d.ts +12 -0
- package/dist/src/http/middleware.d.ts.map +1 -0
- package/dist/src/http/middleware.js +61 -0
- package/dist/src/http/middleware.js.map +1 -0
- package/dist/src/http/overrides.d.ts +2 -0
- package/dist/src/http/overrides.d.ts.map +1 -0
- package/dist/src/http/overrides.js +19 -0
- package/dist/src/http/overrides.js.map +1 -0
- package/dist/src/http/store.d.ts +33 -0
- package/dist/src/http/store.d.ts.map +1 -0
- package/dist/src/http/store.js +102 -0
- package/dist/src/http/store.js.map +1 -0
- package/dist/src/http/uploads.d.ts +7 -0
- package/dist/src/http/uploads.d.ts.map +1 -0
- package/dist/src/http/uploads.js +8 -0
- package/dist/src/http/uploads.js.map +1 -0
- package/dist/src/http/workflow.d.ts +18 -0
- package/dist/src/http/workflow.d.ts.map +1 -0
- package/dist/src/http/workflow.js +181 -0
- package/dist/src/http/workflow.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/cli/invoke.d.ts +5 -0
- package/dist/src/services/cli/invoke.d.ts.map +1 -0
- package/dist/src/services/cli/invoke.js +45 -0
- package/dist/src/services/cli/invoke.js.map +1 -0
- package/dist/src/services/cli/repl.d.ts +5 -0
- package/dist/src/services/cli/repl.d.ts.map +1 -0
- package/dist/src/services/cli/repl.js +71 -0
- package/dist/src/services/cli/repl.js.map +1 -0
- package/dist/src/services/cli.d.ts +12 -0
- package/dist/src/services/cli.d.ts.map +1 -0
- package/dist/src/services/cli.js +76 -0
- package/dist/src/services/cli.js.map +1 -0
- package/dist/src/services/index.d.ts +7 -0
- package/dist/src/services/index.d.ts.map +1 -0
- package/dist/src/services/index.js +10 -0
- package/dist/src/services/index.js.map +1 -0
- package/dist/src/services/leader.d.ts +32 -0
- package/dist/src/services/leader.d.ts.map +1 -0
- package/dist/src/services/leader.js +174 -0
- package/dist/src/services/leader.js.map +1 -0
- package/dist/src/services/logger.d.ts +35 -0
- package/dist/src/services/logger.d.ts.map +1 -0
- package/dist/src/services/logger.js +245 -0
- package/dist/src/services/logger.js.map +1 -0
- package/dist/src/services/mail/index.d.ts +61 -0
- package/dist/src/services/mail/index.d.ts.map +1 -0
- package/dist/src/services/mail/index.js +90 -0
- package/dist/src/services/mail/index.js.map +1 -0
- package/dist/src/services/mail/postmark.d.ts +11 -0
- package/dist/src/services/mail/postmark.d.ts.map +1 -0
- package/dist/src/services/mail/postmark.js +42 -0
- package/dist/src/services/mail/postmark.js.map +1 -0
- package/dist/src/services/mail/smtp.d.ts +11 -0
- package/dist/src/services/mail/smtp.d.ts.map +1 -0
- package/dist/src/services/mail/smtp.js +61 -0
- package/dist/src/services/mail/smtp.js.map +1 -0
- package/dist/src/services/mesh.d.ts +65 -0
- package/dist/src/services/mesh.d.ts.map +1 -0
- package/dist/src/services/mesh.js +422 -0
- package/dist/src/services/mesh.js.map +1 -0
- package/dist/src/services/worker/bootstrap.d.ts +3 -0
- package/dist/src/services/worker/bootstrap.d.ts.map +1 -0
- package/dist/src/services/worker/bootstrap.js +70 -0
- package/dist/src/services/worker/bootstrap.js.map +1 -0
- package/dist/src/services/worker/cli.d.ts +23 -0
- package/dist/src/services/worker/cli.d.ts.map +1 -0
- package/dist/src/services/worker/cli.js +81 -0
- package/dist/src/services/worker/cli.js.map +1 -0
- package/dist/src/services/worker/entity.d.ts +18 -0
- package/dist/src/services/worker/entity.d.ts.map +1 -0
- package/dist/src/services/worker/entity.js +16 -0
- package/dist/src/services/worker/entity.js.map +1 -0
- package/dist/src/services/worker/index.d.ts +9 -0
- package/dist/src/services/worker/index.d.ts.map +1 -0
- package/dist/src/services/worker/index.js +40 -0
- package/dist/src/services/worker/index.js.map +1 -0
- package/dist/src/services/worker/observer.d.ts +18 -0
- package/dist/src/services/worker/observer.d.ts.map +1 -0
- package/dist/src/services/worker/observer.js +172 -0
- package/dist/src/services/worker/observer.js.map +1 -0
- package/dist/src/services/worker/queue.d.ts +8 -0
- package/dist/src/services/worker/queue.d.ts.map +1 -0
- package/dist/src/services/worker/queue.js +31 -0
- package/dist/src/services/worker/queue.js.map +1 -0
- package/dist/src/services/worker/runner.d.ts +17 -0
- package/dist/src/services/worker/runner.d.ts.map +1 -0
- package/dist/src/services/worker/runner.js +131 -0
- package/dist/src/services/worker/runner.js.map +1 -0
- package/dist/src/services/worker/types.d.ts +26 -0
- package/dist/src/services/worker/types.d.ts.map +1 -0
- package/dist/src/services/worker/types.js +29 -0
- package/dist/src/services/worker/types.js.map +1 -0
- package/dist/src/srpc/SrpcByteStream.d.ts +67 -0
- package/dist/src/srpc/SrpcByteStream.d.ts.map +1 -0
- package/dist/src/srpc/SrpcByteStream.js +319 -0
- package/dist/src/srpc/SrpcByteStream.js.map +1 -0
- package/dist/src/srpc/SrpcClient.d.ts +75 -0
- package/dist/src/srpc/SrpcClient.d.ts.map +1 -0
- package/dist/src/srpc/SrpcClient.js +445 -0
- package/dist/src/srpc/SrpcClient.js.map +1 -0
- package/dist/src/srpc/SrpcServer.d.ts +54 -0
- package/dist/src/srpc/SrpcServer.d.ts.map +1 -0
- package/dist/src/srpc/SrpcServer.js +456 -0
- package/dist/src/srpc/SrpcServer.js.map +1 -0
- package/dist/src/srpc/index.d.ts +7 -0
- package/dist/src/srpc/index.d.ts.map +1 -0
- package/dist/src/srpc/index.js +12 -0
- package/dist/src/srpc/index.js.map +1 -0
- package/dist/src/srpc/types.d.ts +129 -0
- package/dist/src/srpc/types.d.ts.map +1 -0
- package/dist/src/srpc/types.js +65 -0
- package/dist/src/srpc/types.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -0
- package/dist/src/telemetry/index.d.ts.map +1 -0
- package/dist/src/telemetry/index.js +5 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts +22 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts.map +1 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js +248 -0
- package/dist/src/telemetry/otel/MariaDBInstrumentation.js.map +1 -0
- package/dist/src/telemetry/otel/helpers.d.ts +27 -0
- package/dist/src/telemetry/otel/helpers.d.ts.map +1 -0
- package/dist/src/telemetry/otel/helpers.js +126 -0
- package/dist/src/telemetry/otel/helpers.js.map +1 -0
- package/dist/src/telemetry/otel/index.d.ts +14 -0
- package/dist/src/telemetry/otel/index.d.ts.map +1 -0
- package/dist/src/telemetry/otel/index.js +132 -0
- package/dist/src/telemetry/otel/index.js.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts +6 -0
- package/dist/src/telemetry/otel/metrics.controller.d.ts.map +1 -0
- package/dist/src/telemetry/otel/metrics.controller.js +63 -0
- package/dist/src/telemetry/otel/metrics.controller.js.map +1 -0
- package/dist/src/telemetry/sentry.d.ts +9 -0
- package/dist/src/telemetry/sentry.d.ts.map +1 -0
- package/dist/src/telemetry/sentry.js +62 -0
- package/dist/src/telemetry/sentry.js.map +1 -0
- package/dist/src/testapp/bootstrap.d.ts +1 -0
- package/dist/src/testapp/bootstrap.d.ts.map +1 -0
- package/dist/src/testapp/bootstrap.js +18 -0
- package/dist/src/testapp/bootstrap.js.map +1 -0
- package/dist/src/testapp/sample.d.ts +6 -0
- package/dist/src/testapp/sample.d.ts.map +1 -0
- package/dist/src/testapp/sample.js +228 -0
- package/dist/src/testapp/sample.js.map +1 -0
- package/dist/src/testapp/srpc-test.d.ts +27 -0
- package/dist/src/testapp/srpc-test.d.ts.map +1 -0
- package/dist/src/testapp/srpc-test.js +570 -0
- package/dist/src/testapp/srpc-test.js.map +1 -0
- package/dist/src/testing/expect.d.ts +25 -0
- package/dist/src/testing/expect.d.ts.map +1 -0
- package/dist/src/testing/expect.js +151 -0
- package/dist/src/testing/expect.js.map +1 -0
- package/dist/src/testing/fixtures.d.ts +19 -0
- package/dist/src/testing/fixtures.d.ts.map +1 -0
- package/dist/src/testing/fixtures.js +69 -0
- package/dist/src/testing/fixtures.js.map +1 -0
- package/dist/src/testing/index.d.ts +260 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +345 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/testing/requests.d.ts +10 -0
- package/dist/src/testing/requests.d.ts.map +1 -0
- package/dist/src/testing/requests.js +56 -0
- package/dist/src/testing/requests.js.map +1 -0
- package/dist/src/testing/sql.d.ts +11 -0
- package/dist/src/testing/sql.d.ts.map +1 -0
- package/dist/src/testing/sql.js +55 -0
- package/dist/src/testing/sql.js.map +1 -0
- package/dist/src/types/index.d.ts +57 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +73 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/phone.d.ts +11 -0
- package/dist/src/types/phone.d.ts.map +1 -0
- package/dist/src/types/phone.js +73 -0
- package/dist/src/types/phone.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/README.md +38 -0
- package/docs/authentication.md +215 -0
- package/docs/cli.md +302 -0
- package/docs/configuration.md +176 -0
- package/docs/database.md +422 -0
- package/docs/getting-started.md +154 -0
- package/docs/health.md +53 -0
- package/docs/helpers.md +436 -0
- package/docs/http.md +253 -0
- package/docs/leader-service.md +98 -0
- package/docs/logging.md +150 -0
- package/docs/mail.md +161 -0
- package/docs/mesh-service.md +204 -0
- package/docs/srpc.md +261 -0
- package/docs/telemetry.md +166 -0
- package/docs/testing.md +222 -0
- package/docs/types.md +215 -0
- package/docs/worker.md +174 -0
- package/lefthook.yml +12 -0
- package/openapi.yaml +109 -0
- package/package.json +133 -0
- package/patches/@deepkit+type+1.0.19.patch +38 -0
- package/resources/proto/generated/test/test.ts +2721 -0
- package/resources/proto/sample.proto +85 -0
- package/resources/proto/test.proto +178 -0
- package/src/app/base.ts +257 -0
- package/src/app/config.loader.ts +66 -0
- package/src/app/config.ts +120 -0
- package/src/app/const.ts +4 -0
- package/src/app/dev.ts +70 -0
- package/src/app/index.ts +6 -0
- package/src/app/openapi.ts +3 -0
- package/src/app/resolver.ts +49 -0
- package/src/app/shutdown.ts +55 -0
- package/src/app/state.ts +19 -0
- package/src/auth/index.ts +2 -0
- package/src/auth/jwt.ts +275 -0
- package/src/auth/provider.ts +57 -0
- package/src/cli/dksf-dev.ts +363 -0
- package/src/cli/dksf-gen-proto.ts +176 -0
- package/src/cli/dksf-install.ts +11 -0
- package/src/cli/dksf-test.ts +95 -0
- package/src/cli/dksf-update.ts +101 -0
- package/src/database/CLAUDE.md +390 -0
- package/src/database/common.ts +385 -0
- package/src/database/dialect.ts +43 -0
- package/src/database/entity.ts +285 -0
- package/src/database/index.ts +7 -0
- package/src/database/migration/MigrationResetCommand.ts +152 -0
- package/src/database/migration/MigrationRunCommand.ts +118 -0
- package/src/database/migration/characters.ts +53 -0
- package/src/database/migration/create/MigrationCreateCommand.ts +94 -0
- package/src/database/migration/create/comparator.ts +467 -0
- package/src/database/migration/create/db-reader.ts +510 -0
- package/src/database/migration/create/ddl-generator.ts +755 -0
- package/src/database/migration/create/entity-reader.ts +462 -0
- package/src/database/migration/create/file-generator.ts +52 -0
- package/src/database/migration/create/prompt.ts +49 -0
- package/src/database/migration/create/schema-model.ts +102 -0
- package/src/database/migration/helpers.ts +3 -0
- package/src/database/migration/index.ts +35 -0
- package/src/database/migration/migration.entity.ts +10 -0
- package/src/database/mysql.ts +140 -0
- package/src/database/postgres.ts +97 -0
- package/src/database/types.ts +18 -0
- package/src/health/health.module.ts +30 -0
- package/src/health/healthcheck.controller.ts +17 -0
- package/src/health/healthcheck.service.ts +15 -0
- package/src/health/index.ts +2 -0
- package/src/helpers/CLAUDE.md +71 -0
- package/src/helpers/async/context.ts +67 -0
- package/src/helpers/async/process.ts +49 -0
- package/src/helpers/async/promise.ts +16 -0
- package/src/helpers/data/array.ts +11 -0
- package/src/helpers/data/objects.ts +64 -0
- package/src/helpers/data/serialization.ts +11 -0
- package/src/helpers/data/transformer.ts +54 -0
- package/src/helpers/framework/decorators.ts +27 -0
- package/src/helpers/framework/event.ts +11 -0
- package/src/helpers/framework/injection.ts +47 -0
- package/src/helpers/index.ts +34 -0
- package/src/helpers/io/package.ts +26 -0
- package/src/helpers/io/stream.ts +79 -0
- package/src/helpers/redis/broadcast.ts +94 -0
- package/src/helpers/redis/cache.ts +28 -0
- package/src/helpers/redis/mutex.ts +260 -0
- package/src/helpers/redis/redis.ts +60 -0
- package/src/helpers/security/crypto.ts +133 -0
- package/src/helpers/security/validation.ts +16 -0
- package/src/helpers/utils/date.ts +13 -0
- package/src/helpers/utils/error.ts +155 -0
- package/src/helpers/utils/jsx.ts +8 -0
- package/src/helpers/utils/uuid.ts +8 -0
- package/src/http/auth.ts +156 -0
- package/src/http/context.ts +15 -0
- package/src/http/cors.ts +159 -0
- package/src/http/errors.ts +9 -0
- package/src/http/index.ts +19 -0
- package/src/http/kernel.ts +138 -0
- package/src/http/middleware.ts +59 -0
- package/src/http/overrides.ts +20 -0
- package/src/http/store.ts +86 -0
- package/src/http/uploads.ts +6 -0
- package/src/http/workflow.ts +167 -0
- package/src/index.ts +19 -0
- package/src/services/cli/invoke.ts +39 -0
- package/src/services/cli/repl.ts +67 -0
- package/src/services/cli.ts +74 -0
- package/src/services/index.ts +6 -0
- package/src/services/leader.ts +201 -0
- package/src/services/logger.ts +258 -0
- package/src/services/mail/index.ts +117 -0
- package/src/services/mail/postmark.ts +37 -0
- package/src/services/mail/smtp.ts +46 -0
- package/src/services/mesh.ts +508 -0
- package/src/services/worker/CLAUDE.md +77 -0
- package/src/services/worker/bootstrap.ts +58 -0
- package/src/services/worker/cli.ts +63 -0
- package/src/services/worker/entity.ts +22 -0
- package/src/services/worker/index.ts +30 -0
- package/src/services/worker/observer.ts +180 -0
- package/src/services/worker/queue.ts +34 -0
- package/src/services/worker/runner.ts +146 -0
- package/src/services/worker/types.ts +32 -0
- package/src/srpc/CLAUDE.md +194 -0
- package/src/srpc/SRPC_MIGRATION_GUIDE.md +348 -0
- package/src/srpc/SrpcByteStream.ts +382 -0
- package/src/srpc/SrpcClient.ts +512 -0
- package/src/srpc/SrpcServer.ts +575 -0
- package/src/srpc/index.ts +15 -0
- package/src/srpc/types.ts +144 -0
- package/src/telemetry/index.ts +1 -0
- package/src/telemetry/otel/MariaDBInstrumentation.ts +297 -0
- package/src/telemetry/otel/helpers.ts +117 -0
- package/src/telemetry/otel/index.ts +150 -0
- package/src/telemetry/otel/metrics.controller.ts +50 -0
- package/src/telemetry/sentry.ts +58 -0
- package/src/testapp/bootstrap.ts +17 -0
- package/src/testapp/sample.ts +220 -0
- package/src/testapp/srpc-test.ts +684 -0
- package/src/testing/expect.ts +148 -0
- package/src/testing/fixtures.ts +62 -0
- package/src/testing/index.ts +355 -0
- package/src/testing/requests.ts +68 -0
- package/src/testing/sql.ts +50 -0
- package/src/types/index.ts +64 -0
- package/src/types/phone.ts +64 -0
- package/tests/app/app.spec.ts +53 -0
- package/tests/app/type.spec.ts +22 -0
- package/tests/auth/jwt.spec.ts +90 -0
- package/tests/database/entity.spec.ts +382 -0
- package/tests/database/locks.spec.ts +142 -0
- package/tests/database/migration-create-integration.spec.ts +234 -0
- package/tests/database/migration-create-unit.spec.ts +3896 -0
- package/tests/helpers/array.spec.ts +80 -0
- package/tests/helpers/cache.spec.ts +202 -0
- package/tests/helpers/crypto.spec.ts +236 -0
- package/tests/helpers/date.spec.ts +94 -0
- package/tests/helpers/error.spec.ts +233 -0
- package/tests/helpers/mutex.spec.ts +354 -0
- package/tests/helpers/objects.spec.ts +212 -0
- package/tests/helpers/package.spec.ts +90 -0
- package/tests/helpers/promise.spec.ts +119 -0
- package/tests/helpers/redis.spec.ts +50 -0
- package/tests/helpers/serialization.spec.ts +150 -0
- package/tests/helpers/stream.spec.ts +225 -0
- package/tests/helpers/validation.spec.ts +133 -0
- package/tests/services/leader.spec.ts +257 -0
- package/tests/services/logger.spec.ts +269 -0
- package/tests/services/mesh.spec.ts +814 -0
- package/tests/shared/db.ts +105 -0
- package/tests/shared/globalSetup.ts +48 -0
- package/tests/shared/helpers.ts +40 -0
- package/tests/srpc/SrpcByteStream.spec.ts +542 -0
- package/tests/tsconfig.json +4 -0
- package/tests/types/index.spec.ts +60 -0
- package/tests/types/phone.spec.ts +140 -0
- package/tsconfig.json +106 -0
- package/tsconfig.test.json +8 -0
- package/types.d.ts +6 -0
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
import { ScopedLogger } from '@deepkit/logger';
|
|
2
|
+
import { createHmac } from 'crypto';
|
|
3
|
+
import { Readable } from 'stream';
|
|
4
|
+
import WebSocket from 'ws';
|
|
5
|
+
|
|
6
|
+
import { ApplicationServer } from '@deepkit/framework';
|
|
7
|
+
|
|
8
|
+
import { ClientMessage, ServerMessage } from '../../resources/proto/generated/test/test';
|
|
9
|
+
import { AutoStart, BaseAppConfig } from '../app';
|
|
10
|
+
import { sleepSecs, uuid7 } from '../helpers';
|
|
11
|
+
import { SrpcByteStream, SrpcClient, SrpcError, SrpcMeta, SrpcServer, SrpcStream } from '../srpc';
|
|
12
|
+
|
|
13
|
+
const TEST_WS_PATH = '/srpc-test';
|
|
14
|
+
|
|
15
|
+
type TestClientOutput = ClientMessage;
|
|
16
|
+
type TestServerOutput = ServerMessage;
|
|
17
|
+
|
|
18
|
+
@AutoStart()
|
|
19
|
+
export class SrpcTesterService {
|
|
20
|
+
private server: SrpcServer<SrpcMeta, TestClientOutput, TestServerOutput>;
|
|
21
|
+
private connectedStream: SrpcStream | undefined;
|
|
22
|
+
public testsCompleted = false;
|
|
23
|
+
public testsFailed = false;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
private logger: ScopedLogger,
|
|
27
|
+
private appConfig: BaseAppConfig,
|
|
28
|
+
private appServer: ApplicationServer
|
|
29
|
+
) {
|
|
30
|
+
// Expand clock drift to keep tests stable on slower systems
|
|
31
|
+
this.appConfig.SRPC_AUTH_CLOCK_DRIFT_MS = 60_000;
|
|
32
|
+
|
|
33
|
+
// Debug: Log what secrets are available via config (not env)
|
|
34
|
+
this.logger.info('Configuration check:', {
|
|
35
|
+
SRPC_AUTH_SECRET: this.appConfig.SRPC_AUTH_SECRET ? '***set***' : 'NOT SET'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Create and configure server
|
|
39
|
+
this.logger.info('Bootstrapping SrpcServer transport', { wsPath: TEST_WS_PATH });
|
|
40
|
+
this.server = new SrpcServer<SrpcMeta, TestClientOutput, TestServerOutput>({
|
|
41
|
+
logger: this.logger.scoped('SrpcServer'),
|
|
42
|
+
clientMessage: ClientMessage,
|
|
43
|
+
serverMessage: ServerMessage,
|
|
44
|
+
wsPath: TEST_WS_PATH,
|
|
45
|
+
debug: false
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Use custom key fetcher to read from app config
|
|
49
|
+
this.server.setClientKeyFetcher(async clientId => {
|
|
50
|
+
const secret = this.getServerSecret();
|
|
51
|
+
this.logger.info('Server fetching key for client:', { clientId, hasSecret: !!secret });
|
|
52
|
+
return secret || false;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
this.setupServerHandlers();
|
|
56
|
+
|
|
57
|
+
// Track connected streams for server-to-client tests
|
|
58
|
+
this.server.registerConnectionHandler(stream => {
|
|
59
|
+
this.connectedStream = stream;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Run tests after a short delay to ensure server is ready
|
|
63
|
+
setTimeout(
|
|
64
|
+
() =>
|
|
65
|
+
this.runTests()
|
|
66
|
+
.then(() => {
|
|
67
|
+
this.logger.info('SRPC tests completed successfully!');
|
|
68
|
+
this.testsCompleted = true;
|
|
69
|
+
})
|
|
70
|
+
.catch(err => {
|
|
71
|
+
this.logger.error('SRPC tests failed:', err);
|
|
72
|
+
this.testsFailed = true;
|
|
73
|
+
throw err;
|
|
74
|
+
}),
|
|
75
|
+
1000
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private get httpPort(): number {
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
return (this.appServer.getHttpWorker()['server']!.address() as any).port;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private setupServerHandlers() {
|
|
85
|
+
// Echo handler
|
|
86
|
+
this.server.registerMessageHandler('uEcho', async (_stream, data) => {
|
|
87
|
+
return { message: `Echo: ${data.message}` };
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Complex data types handler
|
|
91
|
+
this.server.registerMessageHandler('uComplex', async (_stream, data) => {
|
|
92
|
+
const result = `Processed: ${data.stringField}, ${data.intField}, ${data.boolField}`;
|
|
93
|
+
const count = data.arrayField.length + Object.keys(data.mapField).length;
|
|
94
|
+
return { result, count };
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Error handler
|
|
98
|
+
this.server.registerMessageHandler('uError', async (_stream, data) => {
|
|
99
|
+
throw new SrpcError(data.errorMessage, data.userError);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Upload handler (client to server byte stream)
|
|
103
|
+
this.server.registerMessageHandler('uUpload', async (stream, data) => {
|
|
104
|
+
const receiver = SrpcByteStream.createReceiver(stream, data.streamId);
|
|
105
|
+
const chunks: Buffer[] = [];
|
|
106
|
+
|
|
107
|
+
for await (const chunk of receiver) {
|
|
108
|
+
chunks.push(chunk);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const totalBytes = Buffer.concat(chunks).length;
|
|
112
|
+
return { message: `Uploaded ${data.filename}`, bytesReceived: totalBytes };
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Download handler (server to client byte stream)
|
|
116
|
+
this.server.registerMessageHandler('uDownload', async (stream, data) => {
|
|
117
|
+
const testData = Buffer.from(`Test file contents for ${data.filename}`, 'utf-8');
|
|
118
|
+
const sender = SrpcByteStream.createSender(stream);
|
|
119
|
+
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
sender.write(testData);
|
|
122
|
+
sender.end();
|
|
123
|
+
}, 10);
|
|
124
|
+
|
|
125
|
+
return { streamId: sender.id, bytesTotal: testData.length };
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Slow request handler
|
|
129
|
+
this.server.registerMessageHandler('uSlow', async (_stream, data) => {
|
|
130
|
+
const start = Date.now();
|
|
131
|
+
await new Promise(resolve => setTimeout(resolve, data.delayMs));
|
|
132
|
+
const actualDelay = Date.now() - start;
|
|
133
|
+
return { message: 'Completed', actualDelayMs: actualDelay };
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private createClient(clientId: string, autoConnect = true): Promise<SrpcClient<TestClientOutput, TestServerOutput>> {
|
|
138
|
+
const secret = this.getServerSecret();
|
|
139
|
+
|
|
140
|
+
const client = new SrpcClient<TestClientOutput, TestServerOutput>(
|
|
141
|
+
this.logger.scoped('WsClient'),
|
|
142
|
+
`ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
|
|
143
|
+
ClientMessage,
|
|
144
|
+
ServerMessage,
|
|
145
|
+
clientId,
|
|
146
|
+
{ testEnv: 'testapp' },
|
|
147
|
+
secret,
|
|
148
|
+
{ enableReconnect: false }
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
if (!autoConnect) {
|
|
152
|
+
return Promise.resolve(client);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return new Promise<SrpcClient<TestClientOutput, TestServerOutput>>(resolve => {
|
|
156
|
+
client.registerConnectionHandler(() => resolve(client));
|
|
157
|
+
client.connect();
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private async runTests() {
|
|
162
|
+
this.logger.info('Starting SRPC tests...');
|
|
163
|
+
|
|
164
|
+
// Give server time to start
|
|
165
|
+
await sleepSecs(0.5);
|
|
166
|
+
|
|
167
|
+
await this.testConnectionAndAuthentication();
|
|
168
|
+
await this.testClientToServerRPC();
|
|
169
|
+
await this.testServerToClientRPC();
|
|
170
|
+
await this.testByteStreams();
|
|
171
|
+
await this.testConnectionLifecycle();
|
|
172
|
+
await this.testCustomMetadata();
|
|
173
|
+
|
|
174
|
+
// Run legacy raw WebSocket test for backwards compatibility
|
|
175
|
+
await this.testRawWebsocketClient();
|
|
176
|
+
|
|
177
|
+
this.logger.info('All SRPC tests passed!');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private async testConnectionAndAuthentication() {
|
|
181
|
+
this.logger.info('[Test Start] Connection and Authentication');
|
|
182
|
+
|
|
183
|
+
// Test: Valid connection
|
|
184
|
+
this.logger.info('Creating SRPC client with valid credentials');
|
|
185
|
+
const client = await this.createClient(`test-ws-${Date.now()}`);
|
|
186
|
+
if (!client.isConnected) {
|
|
187
|
+
throw new Error('Client should be connected');
|
|
188
|
+
}
|
|
189
|
+
this.logger.info(' ✓ Valid credentials connection');
|
|
190
|
+
|
|
191
|
+
// Clean up for next test
|
|
192
|
+
this.logger.info('Disconnecting valid client before invalid auth test');
|
|
193
|
+
client.disconnect();
|
|
194
|
+
await sleepSecs(0.2);
|
|
195
|
+
|
|
196
|
+
// Test: Invalid signature
|
|
197
|
+
this.logger.info('Attempting connection with invalid signature to ensure rejection');
|
|
198
|
+
|
|
199
|
+
let connectedWithBadSecret = false;
|
|
200
|
+
const badClient = new SrpcClient<TestClientOutput, TestServerOutput>(
|
|
201
|
+
this.logger.scoped('BadWsClient'),
|
|
202
|
+
`ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
|
|
203
|
+
ClientMessage,
|
|
204
|
+
ServerMessage,
|
|
205
|
+
'bad-client',
|
|
206
|
+
{},
|
|
207
|
+
'wrong-secret',
|
|
208
|
+
{ enableReconnect: false }
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
badClient.registerConnectionHandler(() => {
|
|
212
|
+
connectedWithBadSecret = true;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
badClient.connect();
|
|
216
|
+
await sleepSecs(1);
|
|
217
|
+
|
|
218
|
+
if (connectedWithBadSecret) {
|
|
219
|
+
throw new Error('Should not connect with invalid signature');
|
|
220
|
+
}
|
|
221
|
+
this.logger.info('Bad client was rejected as expected');
|
|
222
|
+
this.logger.info(' ✓ Invalid signature rejection');
|
|
223
|
+
|
|
224
|
+
badClient.disconnect();
|
|
225
|
+
this.logger.info('[Test End] Connection and Authentication');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private async testClientToServerRPC() {
|
|
229
|
+
this.logger.info('[Test Start] Client-to-Server RPC');
|
|
230
|
+
|
|
231
|
+
const client = await this.createClient(`test-rpc-ws-${Date.now()}`);
|
|
232
|
+
|
|
233
|
+
// Test: Simple echo (using simplified invoke syntax)
|
|
234
|
+
this.logger.info('Sending uEchoRequest payload');
|
|
235
|
+
const echoResponse = await client.invoke('uEcho', {
|
|
236
|
+
message: 'Hello, SRPC!'
|
|
237
|
+
});
|
|
238
|
+
if (echoResponse.message !== 'Echo: Hello, SRPC!') {
|
|
239
|
+
throw new Error('Echo response mismatch');
|
|
240
|
+
}
|
|
241
|
+
this.logger.info('Received expected uEchoResponse payload');
|
|
242
|
+
this.logger.info(' ✓ Simple echo request');
|
|
243
|
+
|
|
244
|
+
// Test: Complex data types (using simplified invoke syntax)
|
|
245
|
+
this.logger.info('Sending uComplexRequest payload');
|
|
246
|
+
const complexResponse = await client.invoke('uComplex', {
|
|
247
|
+
stringField: 'test',
|
|
248
|
+
intField: 42,
|
|
249
|
+
doubleField: 3.14,
|
|
250
|
+
boolField: true,
|
|
251
|
+
arrayField: ['a', 'b', 'c'],
|
|
252
|
+
mapField: { key1: 'value1', key2: 'value2' }
|
|
253
|
+
});
|
|
254
|
+
if (!complexResponse.result?.includes('test') || complexResponse.count !== 5) {
|
|
255
|
+
throw new Error('Complex data type handling failed');
|
|
256
|
+
}
|
|
257
|
+
this.logger.info('Complex response validated', { response: complexResponse });
|
|
258
|
+
this.logger.info(' ✓ Complex data types');
|
|
259
|
+
|
|
260
|
+
// Test: Error propagation
|
|
261
|
+
this.logger.info('Triggering uErrorRequest to confirm error propagation');
|
|
262
|
+
try {
|
|
263
|
+
await client.invoke('uError', {
|
|
264
|
+
errorMessage: 'Test error',
|
|
265
|
+
userError: false
|
|
266
|
+
});
|
|
267
|
+
throw new Error('Should have thrown error');
|
|
268
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
269
|
+
} catch (err: any) {
|
|
270
|
+
const errorMsg = err?.message || String(err);
|
|
271
|
+
if (!errorMsg || !errorMsg.includes('Test error')) {
|
|
272
|
+
throw new Error(`Error message not propagated correctly. Got: ${errorMsg}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
this.logger.info(' ✓ Application error propagation');
|
|
276
|
+
|
|
277
|
+
// Test: Async request completion
|
|
278
|
+
this.logger.info('Invoking uSlowRequest with 100ms delay');
|
|
279
|
+
const asyncResponse = await client.invoke('uSlow', { delayMs: 100 }, 5000);
|
|
280
|
+
if (asyncResponse.message !== 'Completed') {
|
|
281
|
+
throw new Error(`Async request failed: expected message 'Completed' but got '${asyncResponse.message}'`);
|
|
282
|
+
}
|
|
283
|
+
if (asyncResponse.actualDelayMs < 90) {
|
|
284
|
+
throw new Error(`Async request failed: expected delay >= 90ms but got ${asyncResponse.actualDelayMs}ms`);
|
|
285
|
+
}
|
|
286
|
+
this.logger.info(' ✓ Async request completion');
|
|
287
|
+
|
|
288
|
+
// Test: Request timeout
|
|
289
|
+
this.logger.info('Invoking uSlowRequest with 2000ms delay and 500ms timeout');
|
|
290
|
+
try {
|
|
291
|
+
await client.invoke('uSlow', { delayMs: 2000 }, 500);
|
|
292
|
+
throw new Error('Request should have timed out');
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
294
|
+
} catch (err: any) {
|
|
295
|
+
const errorMsg = err?.message || String(err);
|
|
296
|
+
if (!errorMsg.toLowerCase().includes('timeout') && !errorMsg.includes('Request should have timed out')) {
|
|
297
|
+
throw new Error(`Expected timeout error but got: ${errorMsg}`);
|
|
298
|
+
}
|
|
299
|
+
if (errorMsg.includes('Request should have timed out')) {
|
|
300
|
+
throw new Error('Request did not timeout as expected');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
this.logger.info(' ✓ Request timeout');
|
|
304
|
+
|
|
305
|
+
// Test: Concurrent requests
|
|
306
|
+
this.logger.info('Scheduling 10 concurrent uEchoRequest invocations');
|
|
307
|
+
const requests = Array.from({ length: 10 }, (_, i) => client.invoke('uEcho', { message: `Message ${i}` }));
|
|
308
|
+
const responses = await Promise.all(requests);
|
|
309
|
+
if (responses.length !== 10) {
|
|
310
|
+
throw new Error('Concurrent requests failed');
|
|
311
|
+
}
|
|
312
|
+
this.logger.info('All concurrent responses received');
|
|
313
|
+
this.logger.info(' ✓ Concurrent requests (10)');
|
|
314
|
+
|
|
315
|
+
client.disconnect();
|
|
316
|
+
await sleepSecs(0.2);
|
|
317
|
+
this.logger.info('[Test End] Client-to-Server RPC');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private async testServerToClientRPC() {
|
|
321
|
+
this.logger.info('[Test Start] Server-to-Client RPC');
|
|
322
|
+
|
|
323
|
+
const client = await this.createClient(`test-s2c-ws-${Date.now()}`);
|
|
324
|
+
|
|
325
|
+
// Wait for server to register the stream
|
|
326
|
+
this.logger.info('Waiting for server to register inbound stream');
|
|
327
|
+
await sleepSecs(0.2);
|
|
328
|
+
|
|
329
|
+
if (!this.connectedStream) {
|
|
330
|
+
throw new Error('Server should have registered connected stream');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Test: Server invoking client
|
|
334
|
+
this.logger.info('Registering notify handler on client for server invocation');
|
|
335
|
+
client.registerMessageHandler('dNotify', async data => {
|
|
336
|
+
if (data.notification !== 'Test notification') {
|
|
337
|
+
throw new Error('Notification content mismatch');
|
|
338
|
+
}
|
|
339
|
+
return { acknowledged: true };
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
this.logger.info('Invoking server->client notify workflow (using simplified invoke syntax)');
|
|
343
|
+
const notifyResponse = await this.server.invoke(this.connectedStream, 'dNotify', {
|
|
344
|
+
notification: 'Test notification'
|
|
345
|
+
});
|
|
346
|
+
if (!notifyResponse.acknowledged) {
|
|
347
|
+
throw new Error('Server-to-client invocation failed');
|
|
348
|
+
}
|
|
349
|
+
this.logger.info(' ✓ Server invoking client');
|
|
350
|
+
|
|
351
|
+
// Test: Client computation (using simplified invoke syntax)
|
|
352
|
+
this.logger.info('Registering compute handler on client');
|
|
353
|
+
client.registerMessageHandler('dCompute', async data => {
|
|
354
|
+
let result = data.number;
|
|
355
|
+
if (data.operation === 'square') result = data.number * data.number;
|
|
356
|
+
if (data.operation === 'double') result = data.number * 2;
|
|
357
|
+
return { result };
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
this.logger.info('Invoking compute handler from server');
|
|
361
|
+
const squareResponse = await this.server.invoke(this.connectedStream, 'dCompute', {
|
|
362
|
+
number: 5,
|
|
363
|
+
operation: 'square'
|
|
364
|
+
});
|
|
365
|
+
if (squareResponse.result !== 25) {
|
|
366
|
+
throw new Error('Client computation failed');
|
|
367
|
+
}
|
|
368
|
+
this.logger.info(' ✓ Client computation requests');
|
|
369
|
+
|
|
370
|
+
client.disconnect();
|
|
371
|
+
await sleepSecs(0.2);
|
|
372
|
+
this.logger.info('[Test End] Server-to-Client RPC');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private async testByteStreams() {
|
|
376
|
+
this.logger.info('[Test Start] Byte Streams');
|
|
377
|
+
|
|
378
|
+
const client = await this.createClient(`test-bytes-ws-${Date.now()}`);
|
|
379
|
+
|
|
380
|
+
// Test: Upload (client to server)
|
|
381
|
+
this.logger.info('Starting client->server byte stream upload');
|
|
382
|
+
const uploadData = Buffer.from('Hello from client byte stream!', 'utf-8');
|
|
383
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
384
|
+
const sender = SrpcByteStream.createSender(client as any);
|
|
385
|
+
const uploadPromise = client.invoke('uUpload', {
|
|
386
|
+
streamId: sender.id,
|
|
387
|
+
filename: 'test.txt'
|
|
388
|
+
});
|
|
389
|
+
this.logger.info('Sending upload payload to server');
|
|
390
|
+
sender.write(uploadData);
|
|
391
|
+
sender.end();
|
|
392
|
+
const uploadResponse = await uploadPromise;
|
|
393
|
+
if (uploadResponse.bytesReceived !== uploadData.length) {
|
|
394
|
+
throw new Error('Upload byte count mismatch');
|
|
395
|
+
}
|
|
396
|
+
this.logger.info(' ✓ Upload via byte stream');
|
|
397
|
+
|
|
398
|
+
// Test: Download (server to client)
|
|
399
|
+
this.logger.info('Requesting server->client byte stream download');
|
|
400
|
+
const downloadResponse = await client.invoke('uDownload', {
|
|
401
|
+
filename: 'download.txt'
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
405
|
+
const receiver = SrpcByteStream.createReceiver(client as any, downloadResponse.streamId);
|
|
406
|
+
const downloadChunks: Buffer[] = [];
|
|
407
|
+
for await (const chunk of receiver) {
|
|
408
|
+
downloadChunks.push(chunk);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const receivedData = Buffer.concat(downloadChunks);
|
|
412
|
+
if (receivedData.length !== downloadResponse.bytesTotal) {
|
|
413
|
+
throw new Error('Download byte count mismatch');
|
|
414
|
+
}
|
|
415
|
+
this.logger.info(' ✓ Download via byte stream');
|
|
416
|
+
|
|
417
|
+
// Test: Large stream (1MB)
|
|
418
|
+
const largeData = Buffer.alloc(1024 * 1024);
|
|
419
|
+
for (let i = 0; i < largeData.length; i++) {
|
|
420
|
+
largeData[i] = i % 256;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
424
|
+
const largeSender = SrpcByteStream.createSender(client as any);
|
|
425
|
+
const largeUploadPromise = client.invoke('uUpload', {
|
|
426
|
+
streamId: largeSender.id,
|
|
427
|
+
filename: 'large.bin'
|
|
428
|
+
});
|
|
429
|
+
this.logger.info('Streaming 1MB payload to server for stress test');
|
|
430
|
+
largeSender.write(largeData);
|
|
431
|
+
largeSender.end();
|
|
432
|
+
const largeResponse = await largeUploadPromise;
|
|
433
|
+
if (largeResponse.bytesReceived !== largeData.length) {
|
|
434
|
+
throw new Error('Large stream byte count mismatch');
|
|
435
|
+
}
|
|
436
|
+
this.logger.info(' ✓ Large byte stream (1MB)');
|
|
437
|
+
|
|
438
|
+
// Test: Chunked streaming
|
|
439
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
440
|
+
const chunkSender = SrpcByteStream.createSender(client as any);
|
|
441
|
+
const textChunks = ['Hello ', 'from ', 'chunked ', 'stream!'];
|
|
442
|
+
const chunkUploadPromise = client.invoke('uUpload', {
|
|
443
|
+
streamId: chunkSender.id,
|
|
444
|
+
filename: 'chunked.txt'
|
|
445
|
+
});
|
|
446
|
+
this.logger.info('Writing text chunks sequentially');
|
|
447
|
+
for (const chunk of textChunks) {
|
|
448
|
+
chunkSender.write(Buffer.from(chunk, 'utf-8'));
|
|
449
|
+
}
|
|
450
|
+
chunkSender.end();
|
|
451
|
+
const chunkResponse = await chunkUploadPromise;
|
|
452
|
+
if (chunkResponse.bytesReceived !== textChunks.join('').length) {
|
|
453
|
+
throw new Error('Chunked stream byte count mismatch');
|
|
454
|
+
}
|
|
455
|
+
this.logger.info(' ✓ Chunked streaming');
|
|
456
|
+
|
|
457
|
+
// Test: Node.js Readable stream
|
|
458
|
+
const readableData = 'Stream from Readable!';
|
|
459
|
+
const readable = Readable.from([Buffer.from(readableData, 'utf-8')]);
|
|
460
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
461
|
+
const pipedSender = SrpcByteStream.createSender(client as any);
|
|
462
|
+
const pipedUploadPromise = client.invoke('uUpload', {
|
|
463
|
+
streamId: pipedSender.id,
|
|
464
|
+
filename: 'piped.txt'
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
readable.pipe(pipedSender);
|
|
468
|
+
this.logger.info('Piping readable stream into SRPC sender');
|
|
469
|
+
await new Promise((resolve, reject) => {
|
|
470
|
+
pipedSender.on('finish', resolve);
|
|
471
|
+
pipedSender.on('error', reject);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
const pipedResponse = await pipedUploadPromise;
|
|
475
|
+
if (pipedResponse.bytesReceived !== readableData.length) {
|
|
476
|
+
throw new Error('Piped stream byte count mismatch');
|
|
477
|
+
}
|
|
478
|
+
this.logger.info(' ✓ Node.js Readable stream integration');
|
|
479
|
+
|
|
480
|
+
client.disconnect();
|
|
481
|
+
await sleepSecs(0.2);
|
|
482
|
+
this.logger.info('[Test End] Byte Streams');
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
private async testConnectionLifecycle() {
|
|
486
|
+
this.logger.info('[Test Start] Connection Lifecycle');
|
|
487
|
+
|
|
488
|
+
const events: string[] = [];
|
|
489
|
+
const clientId = `test-lifecycle-ws-${Date.now()}`;
|
|
490
|
+
|
|
491
|
+
this.server.registerConnectionHandler(stream => {
|
|
492
|
+
events.push(`server-connected:${stream.clientId}`);
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
this.server.registerDisconnectHandler((stream, cause) => {
|
|
496
|
+
events.push(`server-disconnected:${stream.clientId}:${cause}`);
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
const client = await this.createClient(clientId, false);
|
|
500
|
+
|
|
501
|
+
client.registerConnectionHandler(() => {
|
|
502
|
+
events.push('client-connected');
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
client.registerDisconnectHandler(() => {
|
|
506
|
+
events.push('client-disconnected');
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
client.connect();
|
|
510
|
+
this.logger.info('Connection lifecycle client initiated', { clientId });
|
|
511
|
+
await this.waitForEvent(() => events.includes('client-connected'), 2_000, 'Client connection event not fired');
|
|
512
|
+
await this.waitForEvent(() => events.some(e => e === `server-connected:${clientId}`), 2_000, 'Server connection event not fired');
|
|
513
|
+
this.logger.info(' ✓ Connection handlers');
|
|
514
|
+
|
|
515
|
+
client.disconnect();
|
|
516
|
+
await this.waitForEvent(() => events.includes('client-disconnected'), 2_000, 'Client disconnection event not fired');
|
|
517
|
+
await this.waitForEvent(
|
|
518
|
+
() => events.some(e => e.startsWith(`server-disconnected:${clientId}:`)),
|
|
519
|
+
2_000,
|
|
520
|
+
'Server disconnection event not fired'
|
|
521
|
+
);
|
|
522
|
+
this.logger.info(' ✓ Disconnection handlers');
|
|
523
|
+
this.logger.info('[Test End] Connection Lifecycle');
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
private async testCustomMetadata() {
|
|
527
|
+
this.logger.info('[Test Start] Custom Metadata');
|
|
528
|
+
|
|
529
|
+
const customMeta = { appVersion: '1.2.3', userId: 'test-user' };
|
|
530
|
+
const clientId = `custom-meta-ws-${Date.now()}`;
|
|
531
|
+
|
|
532
|
+
const metaPromise = new Promise<SrpcMeta>((resolve, reject) => {
|
|
533
|
+
const timeout = setTimeout(() => reject(new Error('Timeout waiting for metadata')), 3000);
|
|
534
|
+
this.server.registerConnectionHandler(stream => {
|
|
535
|
+
if (stream.clientId === clientId) {
|
|
536
|
+
clearTimeout(timeout);
|
|
537
|
+
resolve(stream.meta);
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
const customClient = new SrpcClient<TestClientOutput, TestServerOutput>(
|
|
543
|
+
this.logger.scoped('CustomMetaWsClient'),
|
|
544
|
+
`ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
|
|
545
|
+
ClientMessage,
|
|
546
|
+
ServerMessage,
|
|
547
|
+
clientId,
|
|
548
|
+
customMeta,
|
|
549
|
+
this.getServerSecret(),
|
|
550
|
+
{ enableReconnect: false }
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
this.logger.info('Connecting custom metadata client');
|
|
554
|
+
await new Promise<void>(resolve => {
|
|
555
|
+
customClient.registerConnectionHandler(() => resolve());
|
|
556
|
+
customClient.connect();
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
this.logger.info('Awaiting metadata capture from server-side connection handler');
|
|
560
|
+
const receivedMeta = await metaPromise;
|
|
561
|
+
const normalizedMeta = Object.fromEntries(Object.entries(receivedMeta).map(([key, value]) => [key.toLowerCase(), value]));
|
|
562
|
+
if (normalizedMeta.appversion !== '1.2.3' || normalizedMeta.userid !== 'test-user') {
|
|
563
|
+
throw new Error(`Custom metadata not passed correctly. Got: ${JSON.stringify(normalizedMeta)}`);
|
|
564
|
+
}
|
|
565
|
+
this.logger.info(' ✓ Custom metadata passing');
|
|
566
|
+
|
|
567
|
+
customClient.disconnect();
|
|
568
|
+
await sleepSecs(0.2);
|
|
569
|
+
this.logger.info('[Test End] Custom Metadata');
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
private async testRawWebsocketClient() {
|
|
573
|
+
this.logger.info('[Test Start] Raw WebSocket Client (backwards compatibility)');
|
|
574
|
+
|
|
575
|
+
const secret = this.getServerSecret();
|
|
576
|
+
const clientId = `ws-raw-${Date.now()}`;
|
|
577
|
+
const streamId = uuid7();
|
|
578
|
+
const authv = 1;
|
|
579
|
+
const appv = '0.0.0';
|
|
580
|
+
const ts = Date.now().toString();
|
|
581
|
+
|
|
582
|
+
const signable = `${authv}\n${appv}\n${ts}\n${streamId}\n${clientId}\n`;
|
|
583
|
+
const signature = createHmac('sha256', secret).update(signable).digest('hex');
|
|
584
|
+
|
|
585
|
+
const params = new URLSearchParams({
|
|
586
|
+
authv: String(authv),
|
|
587
|
+
appv,
|
|
588
|
+
ts,
|
|
589
|
+
id: streamId,
|
|
590
|
+
cid: clientId,
|
|
591
|
+
signature
|
|
592
|
+
});
|
|
593
|
+
params.set('m--testEnv', 'testapp-ws');
|
|
594
|
+
|
|
595
|
+
const requestId = uuid7();
|
|
596
|
+
const requestBuffer = ClientMessage.encode({
|
|
597
|
+
requestId,
|
|
598
|
+
reply: false,
|
|
599
|
+
uEchoRequest: { message: 'Hello via raw WS' }
|
|
600
|
+
}).finish();
|
|
601
|
+
|
|
602
|
+
const pongBuffer = ClientMessage.encode({ requestId: '', reply: false, pingPong: {} }).finish();
|
|
603
|
+
|
|
604
|
+
await new Promise<void>((resolve, reject) => {
|
|
605
|
+
const wsUrl = `ws://localhost:${this.httpPort}${TEST_WS_PATH}?${params.toString()}`;
|
|
606
|
+
const ws = new WebSocket(wsUrl);
|
|
607
|
+
|
|
608
|
+
const finish = (err?: Error) => {
|
|
609
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
610
|
+
if ((ws as any)._finished) return;
|
|
611
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
612
|
+
(ws as any)._finished = true;
|
|
613
|
+
clearTimeout(timeout);
|
|
614
|
+
if (err) {
|
|
615
|
+
reject(err);
|
|
616
|
+
} else {
|
|
617
|
+
resolve();
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
ws.once('error', err => {
|
|
622
|
+
finish(err instanceof Error ? err : new Error(String(err)));
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
ws.on('close', code => {
|
|
626
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
627
|
+
if (!(ws as any)._finished) {
|
|
628
|
+
finish(new Error(`WebSocket closed prematurely (code: ${code})`));
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
let requestSent = false;
|
|
633
|
+
|
|
634
|
+
ws.on('message', data => {
|
|
635
|
+
if (!(data instanceof Buffer)) return;
|
|
636
|
+
const message = ServerMessage.decode(data);
|
|
637
|
+
|
|
638
|
+
if (message.pingPong) {
|
|
639
|
+
ws.send(pongBuffer);
|
|
640
|
+
if (!requestSent) {
|
|
641
|
+
ws.send(requestBuffer);
|
|
642
|
+
requestSent = true;
|
|
643
|
+
}
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if (message.reply && message.uEchoResponse) {
|
|
648
|
+
if (message.uEchoResponse.message !== 'Echo: Hello via raw WS') {
|
|
649
|
+
finish(new Error(`Unexpected WebSocket echo response: ${message.uEchoResponse.message}`));
|
|
650
|
+
ws.close();
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
ws.close(1000);
|
|
654
|
+
finish();
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
const timeout = setTimeout(() => {
|
|
659
|
+
ws.close();
|
|
660
|
+
finish(new Error('WebSocket SRPC test timed out'));
|
|
661
|
+
}, 5000);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
this.logger.info(' ✓ Raw WebSocket echo request');
|
|
665
|
+
this.logger.info('[Test End] Raw WebSocket Client (backwards compatibility)');
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
private getServerSecret() {
|
|
669
|
+
const secret = this.appConfig.SRPC_AUTH_SECRET;
|
|
670
|
+
if (!secret) {
|
|
671
|
+
throw new Error('SRPC authentication secret is not configured in AppConfig');
|
|
672
|
+
}
|
|
673
|
+
return secret;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
private async waitForEvent(predicate: () => boolean, timeoutMs: number, errorMessage: string) {
|
|
677
|
+
const deadline = Date.now() + timeoutMs;
|
|
678
|
+
while (Date.now() < deadline) {
|
|
679
|
+
if (predicate()) return;
|
|
680
|
+
await sleepSecs(0.05);
|
|
681
|
+
}
|
|
682
|
+
throw new Error(errorMessage);
|
|
683
|
+
}
|
|
684
|
+
}
|