@lenne.tech/nest-server 12.1.1 → 12.3.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/.claude/rules/architecture.md +1 -0
- package/.claude/rules/better-auth.md +31 -4
- package/.claude/rules/configurable-features.md +8 -6
- package/.claude/rules/package-management.md +29 -2
- package/.claude/rules/persistence.md +27 -1
- package/.claude/rules/testing.md +80 -15
- package/.claude/rules/versioning.md +13 -2
- package/CLAUDE.md +7 -1
- package/FRAMEWORK-API.md +20 -4
- package/README.md +20 -2
- package/dist/config.env.js +2 -2
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/graphql-ws-connection.helper.d.ts +4 -0
- package/dist/core/common/helpers/graphql-ws-connection.helper.js +17 -3
- package/dist/core/common/helpers/graphql-ws-connection.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +49 -0
- package/dist/core/common/interfaces/service-options.interface.d.ts +3 -0
- package/dist/core/common/persistence/core-persistence.module.js +12 -2
- package/dist/core/common/persistence/core-persistence.module.js.map +1 -1
- package/dist/core/common/persistence/data-source.runtime.js +4 -2
- package/dist/core/common/persistence/data-source.runtime.js.map +1 -1
- package/dist/core/common/persistence/data-store.interface.d.ts +24 -9
- package/dist/core/common/persistence/id-format.d.ts +2 -0
- package/dist/core/common/persistence/id-format.js +14 -0
- package/dist/core/common/persistence/id-format.js.map +1 -1
- package/dist/core/common/persistence/model-descriptor.interface.d.ts +6 -0
- package/dist/core/common/persistence/model-metadata.registry.d.ts +2 -1
- package/dist/core/common/persistence/model-metadata.registry.js +20 -2
- package/dist/core/common/persistence/model-metadata.registry.js.map +1 -1
- package/dist/core/common/persistence/mongo/sync-schema.plugin.d.ts +18 -0
- package/dist/core/common/persistence/mongo/sync-schema.plugin.js +368 -0
- package/dist/core/common/persistence/mongo/sync-schema.plugin.js.map +1 -0
- package/dist/core/common/persistence/mongoose-data-store.d.ts +19 -9
- package/dist/core/common/persistence/mongoose-data-store.js +107 -31
- package/dist/core/common/persistence/mongoose-data-store.js.map +1 -1
- package/dist/core/common/persistence/persisted-model.decorator.d.ts +3 -0
- package/dist/core/common/persistence/persisted-model.decorator.js +9 -0
- package/dist/core/common/persistence/persisted-model.decorator.js.map +1 -1
- package/dist/core/common/persistence/policies/sync.policy.d.ts +17 -0
- package/dist/core/common/persistence/policies/sync.policy.js +77 -0
- package/dist/core/common/persistence/policies/sync.policy.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.d.ts +12 -8
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js +82 -29
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js.map +1 -1
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.d.ts +10 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js +61 -4
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js.map +1 -1
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +101 -4
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js.map +1 -1
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.d.ts +10 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js +41 -2
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js.map +1 -1
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js +98 -10
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js.map +1 -1
- package/dist/core/common/persistence/sql/sql-data-store.d.ts +38 -14
- package/dist/core/common/persistence/sql/sql-data-store.js +212 -38
- package/dist/core/common/persistence/sql/sql-data-store.js.map +1 -1
- package/dist/core/common/persistence/sql/sql-errors.d.ts +2 -1
- package/dist/core/common/persistence/sql/sql-errors.js +3 -1
- package/dist/core/common/persistence/sql/sql-errors.js.map +1 -1
- package/dist/core/common/persistence/sync-access.registry.d.ts +17 -0
- package/dist/core/common/persistence/sync-access.registry.js +8 -0
- package/dist/core/common/persistence/sync-access.registry.js.map +1 -0
- package/dist/core/common/persistence/sync-model.d.ts +29 -0
- package/dist/core/common/persistence/sync-model.js +138 -0
- package/dist/core/common/persistence/sync-model.js.map +1 -0
- package/dist/core/common/services/crud.service.d.ts +13 -1
- package/dist/core/common/services/crud.service.js +174 -16
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/modules/ai/core-ai-mcp.controller.d.ts +3 -0
- package/dist/core/modules/ai/core-ai-mcp.controller.js +29 -0
- package/dist/core/modules/ai/core-ai-mcp.controller.js.map +1 -1
- package/dist/core/modules/ai/core-ai.constants.d.ts +2 -0
- package/dist/core/modules/ai/core-ai.constants.js +2 -0
- package/dist/core/modules/ai/core-ai.constants.js.map +1 -1
- package/dist/core/modules/ai/core-ai.controller.d.ts +6 -0
- package/dist/core/modules/ai/core-ai.controller.js +31 -1
- package/dist/core/modules/ai/core-ai.controller.js.map +1 -1
- package/dist/core/modules/ai/core-ai.module.d.ts +2 -0
- package/dist/core/modules/ai/core-ai.module.js +8 -1
- package/dist/core/modules/ai/core-ai.module.js.map +1 -1
- package/dist/core/modules/ai/core-ai.resolver.d.ts +6 -0
- package/dist/core/modules/ai/core-ai.resolver.js +32 -0
- package/dist/core/modules/ai/core-ai.resolver.js.map +1 -1
- package/dist/core/modules/ai/helpers/ai-mcp-oauth-consent.helper.d.ts +65 -1
- package/dist/core/modules/ai/helpers/ai-mcp-oauth-consent.helper.js +6 -3
- package/dist/core/modules/ai/helpers/ai-mcp-oauth-consent.helper.js.map +1 -1
- package/dist/core/modules/ai/helpers/ai-mcp-oauth.helper.js +48 -1
- package/dist/core/modules/ai/helpers/ai-mcp-oauth.helper.js.map +1 -1
- package/dist/core/modules/ai/helpers/ai-tool-authorization.helper.d.ts +9 -0
- package/dist/core/modules/ai/helpers/ai-tool-authorization.helper.js +54 -0
- package/dist/core/modules/ai/helpers/ai-tool-authorization.helper.js.map +1 -0
- package/dist/core/modules/ai/index.d.ts +7 -0
- package/dist/core/modules/ai/index.js +6 -0
- package/dist/core/modules/ai/index.js.map +1 -1
- package/dist/core/modules/ai/inputs/core-ai-settings.input.d.ts +3 -0
- package/dist/core/modules/ai/inputs/core-ai-settings.input.js +31 -0
- package/dist/core/modules/ai/inputs/core-ai-settings.input.js.map +1 -0
- package/dist/core/modules/ai/interfaces/ai-tool.interface.d.ts +2 -0
- package/dist/core/modules/ai/models/core-ai-settings.model.d.ts +4 -0
- package/dist/core/modules/ai/models/core-ai-settings.model.js +30 -0
- package/dist/core/modules/ai/models/core-ai-settings.model.js.map +1 -0
- package/dist/core/modules/ai/models/core-ai-user-setting.model.d.ts +8 -0
- package/dist/core/modules/ai/models/core-ai-user-setting.model.js +45 -0
- package/dist/core/modules/ai/models/core-ai-user-setting.model.js.map +1 -0
- package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +4 -1
- package/dist/core/modules/ai/services/core-ai-conversation.service.js +16 -4
- package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +6 -6
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mcp.service.d.ts +27 -2
- package/dist/core/modules/ai/services/core-ai-mcp.service.js +118 -11
- package/dist/core/modules/ai/services/core-ai-mcp.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt-builder.service.js +9 -6
- package/dist/core/modules/ai/services/core-ai-prompt-builder.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-user-setting.service.d.ts +17 -0
- package/dist/core/modules/ai/services/core-ai-user-setting.service.js +72 -0
- package/dist/core/modules/ai/services/core-ai-user-setting.service.js.map +1 -0
- package/dist/core/modules/ai/services/core-ai.service.d.ts +8 -3
- package/dist/core/modules/ai/services/core-ai.service.js +68 -29
- package/dist/core/modules/ai/services/core-ai.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +3 -1
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +2 -2
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-path-guard.middleware.d.ts +8 -0
- package/dist/core/modules/better-auth/core-better-auth-path-guard.middleware.js +64 -0
- package/dist/core/modules/better-auth/core-better-auth-path-guard.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js +2 -1
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.d.ts +1 -1
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js +5 -3
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js +2 -0
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/index.d.ts +1 -0
- package/dist/core/modules/better-auth/index.js +1 -0
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/error-code/error-codes.d.ts +72 -0
- package/dist/core/modules/error-code/error-codes.js +64 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -1
- package/dist/core/modules/migrate/sql-migration.helper.d.ts +15 -1
- package/dist/core/modules/migrate/sql-migration.helper.js +90 -5
- package/dist/core/modules/migrate/sql-migration.helper.js.map +1 -1
- package/dist/core/modules/sync/core-sync-base.controller.d.ts +7 -0
- package/dist/core/modules/sync/core-sync-base.controller.js +44 -0
- package/dist/core/modules/sync/core-sync-base.controller.js.map +1 -0
- package/dist/core/modules/sync/core-sync-cursor.d.ts +19 -0
- package/dist/core/modules/sync/core-sync-cursor.js +77 -0
- package/dist/core/modules/sync/core-sync-cursor.js.map +1 -0
- package/dist/core/modules/sync/core-sync-hints.controller.d.ts +4 -0
- package/dist/core/modules/sync/core-sync-hints.controller.js +55 -0
- package/dist/core/modules/sync/core-sync-hints.controller.js.map +1 -0
- package/dist/core/modules/sync/core-sync-hints.service.d.ts +28 -0
- package/dist/core/modules/sync/core-sync-hints.service.js +155 -0
- package/dist/core/modules/sync/core-sync-hints.service.js.map +1 -0
- package/dist/core/modules/sync/core-sync-infrastructure.models.d.ts +2 -0
- package/dist/core/modules/sync/core-sync-infrastructure.models.js +17 -0
- package/dist/core/modules/sync/core-sync-infrastructure.models.js.map +1 -0
- package/dist/core/modules/sync/core-sync-mutation.store.d.ts +43 -0
- package/dist/core/modules/sync/core-sync-mutation.store.js +88 -0
- package/dist/core/modules/sync/core-sync-mutation.store.js.map +1 -0
- package/dist/core/modules/sync/core-sync-state.store.d.ts +18 -0
- package/dist/core/modules/sync/core-sync-state.store.js +64 -0
- package/dist/core/modules/sync/core-sync-state.store.js.map +1 -0
- package/dist/core/modules/sync/core-sync.constants.d.ts +28 -0
- package/dist/core/modules/sync/core-sync.constants.js +23 -0
- package/dist/core/modules/sync/core-sync.constants.js.map +1 -0
- package/dist/core/modules/sync/core-sync.controller.d.ts +8 -0
- package/dist/core/modules/sync/core-sync.controller.js +79 -0
- package/dist/core/modules/sync/core-sync.controller.js.map +1 -0
- package/dist/core/modules/sync/core-sync.decorators.d.ts +12 -0
- package/dist/core/modules/sync/core-sync.decorators.js +28 -0
- package/dist/core/modules/sync/core-sync.decorators.js.map +1 -0
- package/dist/core/modules/sync/core-sync.module.d.ts +16 -0
- package/dist/core/modules/sync/core-sync.module.js +50 -0
- package/dist/core/modules/sync/core-sync.module.js.map +1 -0
- package/dist/core/modules/sync/core-sync.resolver.d.ts +9 -0
- package/dist/core/modules/sync/core-sync.resolver.js +46 -0
- package/dist/core/modules/sync/core-sync.resolver.js.map +1 -0
- package/dist/core/modules/sync/core-sync.service.d.ts +143 -0
- package/dist/core/modules/sync/core-sync.service.js +1237 -0
- package/dist/core/modules/sync/core-sync.service.js.map +1 -0
- package/dist/core/modules/sync/interfaces/core-sync.interfaces.d.ts +56 -0
- package/dist/core/modules/sync/interfaces/core-sync.interfaces.js +2 -0
- package/dist/core/modules/sync/interfaces/core-sync.interfaces.js.map +1 -0
- package/dist/core/modules/sync/models/core-sync-hint.model.d.ts +4 -0
- package/dist/core/modules/sync/models/core-sync-hint.model.js +30 -0
- package/dist/core/modules/sync/models/core-sync-hint.model.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.guard.js +14 -0
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.service.d.ts +21 -1
- package/dist/core/modules/tenant/core-tenant.service.js +153 -1
- package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
- package/dist/core.module.js +14 -0
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/error-code/error-codes.d.ts +8 -0
- package/dist/server/modules/sync-note/inputs/sync-note-create.input.d.ts +4 -0
- package/dist/server/modules/sync-note/inputs/sync-note-create.input.js +27 -0
- package/dist/server/modules/sync-note/inputs/sync-note-create.input.js.map +1 -0
- package/dist/server/modules/sync-note/inputs/sync-note.input.d.ts +6 -0
- package/dist/server/modules/sync-note/inputs/sync-note.input.js +37 -0
- package/dist/server/modules/sync-note/inputs/sync-note.input.js.map +1 -0
- package/dist/server/modules/sync-note/sync-note.model.d.ts +10 -0
- package/dist/server/modules/sync-note/sync-note.model.js +73 -0
- package/dist/server/modules/sync-note/sync-note.model.js.map +1 -0
- package/dist/server/modules/sync-note/sync-note.module.d.ts +2 -0
- package/dist/server/modules/sync-note/sync-note.module.js +21 -0
- package/dist/server/modules/sync-note/sync-note.module.js.map +1 -0
- package/dist/server/modules/sync-note/sync-note.service.d.ts +10 -0
- package/dist/server/modules/sync-note/sync-note.service.js +35 -0
- package/dist/server/modules/sync-note/sync-note.service.js.map +1 -0
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +9 -2
- package/dist/test/test.helper.js.map +1 -1
- package/docs/REQUEST-LIFECYCLE.md +4 -2
- package/docs/error-codes.md +14 -0
- package/docs/offline-sync-protocol.md +111 -68
- package/docs/security-overrides.md +14 -0
- package/migration-guides/12.0.x-to-12.1.x.md +0 -1
- package/migration-guides/12.1.x-to-12.2.x.md +154 -0
- package/migration-guides/12.2.x-to-12.3.x.md +440 -0
- package/package.json +23 -21
- package/src/config.env.ts +6 -2
- package/src/core/common/helpers/graphql-ws-connection.helper.ts +32 -4
- package/src/core/common/interfaces/server-options.interface.ts +229 -8
- package/src/core/common/interfaces/service-options.interface.ts +15 -0
- package/src/core/common/persistence/core-persistence.module.ts +21 -2
- package/src/core/common/persistence/data-source.runtime.ts +5 -2
- package/src/core/common/persistence/data-store.interface.ts +65 -12
- package/src/core/common/persistence/id-format.ts +26 -0
- package/src/core/common/persistence/model-descriptor.interface.ts +12 -0
- package/src/core/common/persistence/model-metadata.registry.ts +31 -2
- package/src/core/common/persistence/mongo/sync-schema.plugin.ts +508 -0
- package/src/core/common/persistence/mongoose-data-store.ts +171 -35
- package/src/core/common/persistence/persisted-model.decorator.ts +26 -0
- package/src/core/common/persistence/policies/sync.policy.ts +121 -0
- package/src/core/common/persistence/sql/mysql/mysql-data-store.ts +108 -30
- package/src/core/common/persistence/sql/mysql/mysql-schema.compiler.ts +107 -4
- package/src/core/common/persistence/sql/mysql/mysql-schema.migrator.ts +129 -3
- package/src/core/common/persistence/sql/postgres/postgres-schema.compiler.ts +74 -2
- package/src/core/common/persistence/sql/postgres/postgres-schema.migrator.ts +139 -7
- package/src/core/common/persistence/sql/sql-data-store.ts +325 -44
- package/src/core/common/persistence/sql/sql-errors.ts +5 -1
- package/src/core/common/persistence/sync-access.registry.ts +50 -0
- package/src/core/common/persistence/sync-model.ts +270 -0
- package/src/core/common/services/crud.service.ts +257 -19
- package/src/core/modules/ai/INTEGRATION-CHECKLIST.md +36 -15
- package/src/core/modules/ai/README.md +163 -25
- package/src/core/modules/ai/core-ai-mcp.controller.ts +48 -1
- package/src/core/modules/ai/core-ai.constants.ts +6 -0
- package/src/core/modules/ai/core-ai.controller.ts +36 -1
- package/src/core/modules/ai/core-ai.module.ts +12 -0
- package/src/core/modules/ai/core-ai.resolver.ts +36 -0
- package/src/core/modules/ai/helpers/ai-mcp-oauth-consent.helper.ts +35 -4
- package/src/core/modules/ai/helpers/ai-mcp-oauth.helper.ts +68 -1
- package/src/core/modules/ai/helpers/ai-tool-authorization.helper.ts +99 -0
- package/src/core/modules/ai/index.ts +18 -0
- package/src/core/modules/ai/inputs/core-ai-settings.input.ts +24 -0
- package/src/core/modules/ai/interfaces/ai-hook.interface.ts +1 -1
- package/src/core/modules/ai/interfaces/ai-tool.interface.ts +38 -26
- package/src/core/modules/ai/models/core-ai-mode.model.ts +1 -1
- package/src/core/modules/ai/models/core-ai-settings.model.ts +23 -0
- package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +1 -1
- package/src/core/modules/ai/models/core-ai-user-setting.model.ts +46 -0
- package/src/core/modules/ai/services/core-ai-conversation.service.ts +31 -6
- package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +12 -9
- package/src/core/modules/ai/services/core-ai-mcp.service.ts +206 -13
- package/src/core/modules/ai/services/core-ai-prompt-builder.service.ts +13 -6
- package/src/core/modules/ai/services/core-ai-user-setting.service.ts +85 -0
- package/src/core/modules/ai/services/core-ai.service.ts +134 -35
- package/src/core/modules/api-token/README.md +4 -2
- package/src/core/modules/better-auth/CUSTOMIZATION.md +1 -1
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +7 -0
- package/src/core/modules/better-auth/README.md +32 -1
- package/src/core/modules/better-auth/better-auth.config.ts +12 -1
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +5 -2
- package/src/core/modules/better-auth/core-better-auth-path-guard.middleware.ts +85 -0
- package/src/core/modules/better-auth/core-better-auth-rate-limit.middleware.ts +5 -2
- package/src/core/modules/better-auth/core-better-auth-rate-limiter.service.ts +14 -7
- package/src/core/modules/better-auth/core-better-auth.module.ts +12 -2
- package/src/core/modules/better-auth/index.ts +1 -0
- package/src/core/modules/error-code/error-codes.ts +77 -0
- package/src/core/modules/migrate/sql-migration.helper.ts +141 -7
- package/src/core/modules/sync/INTEGRATION-CHECKLIST.md +95 -0
- package/src/core/modules/sync/README.md +198 -0
- package/src/core/modules/sync/SECURITY.md +65 -0
- package/src/core/modules/sync/core-sync-base.controller.ts +43 -0
- package/src/core/modules/sync/core-sync-cursor.ts +117 -0
- package/src/core/modules/sync/core-sync-hints.controller.ts +52 -0
- package/src/core/modules/sync/core-sync-hints.service.ts +178 -0
- package/src/core/modules/sync/core-sync-infrastructure.models.ts +40 -0
- package/src/core/modules/sync/core-sync-mutation.store.ts +146 -0
- package/src/core/modules/sync/core-sync-state.store.ts +89 -0
- package/src/core/modules/sync/core-sync.constants.ts +51 -0
- package/src/core/modules/sync/core-sync.controller.ts +68 -0
- package/src/core/modules/sync/core-sync.decorators.ts +84 -0
- package/src/core/modules/sync/core-sync.module.ts +75 -0
- package/src/core/modules/sync/core-sync.resolver.ts +35 -0
- package/src/core/modules/sync/core-sync.service.ts +1773 -0
- package/src/core/modules/sync/interfaces/core-sync.interfaces.ts +85 -0
- package/src/core/modules/sync/models/core-sync-hint.model.ts +18 -0
- package/src/core/modules/tenant/INTEGRATION-CHECKLIST.md +12 -1
- package/src/core/modules/tenant/README.md +49 -3
- package/src/core/modules/tenant/core-tenant.guard.ts +26 -2
- package/src/core/modules/tenant/core-tenant.service.ts +287 -2
- package/src/core.module.ts +25 -0
- package/src/index.ts +21 -0
- package/src/server/modules/sync-note/inputs/sync-note-create.input.ts +14 -0
- package/src/server/modules/sync-note/inputs/sync-note.input.ts +23 -0
- package/src/server/modules/sync-note/sync-note.model.ts +77 -0
- package/src/server/modules/sync-note/sync-note.module.ts +16 -0
- package/src/server/modules/sync-note/sync-note.service.ts +25 -0
- package/src/test/test.helper.ts +17 -3
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { InputType } from '@nestjs/graphql';
|
|
2
|
+
|
|
3
|
+
import { Restricted } from '../../../../core/common/decorators/restricted.decorator.js';
|
|
4
|
+
import { UnifiedField } from '../../../../core/common/decorators/unified-field.decorator.js';
|
|
5
|
+
import { RoleEnum } from '../../../../core/common/enums/role.enum.js';
|
|
6
|
+
import { CoreInput } from '../../../../core/common/inputs/core-input.input.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Input of a pushed change of a note — validated and whitelisted like a request body, so a client can set only what
|
|
10
|
+
* is declared here (never `createdBy`, `version` or `deletedAt`)
|
|
11
|
+
*/
|
|
12
|
+
@InputType({ description: 'Input to change a synchronized note' })
|
|
13
|
+
@Restricted(RoleEnum.ADMIN)
|
|
14
|
+
export class SyncNoteInput extends CoreInput {
|
|
15
|
+
@UnifiedField({ description: 'Text of the note', isOptional: true, roles: RoleEnum.S_EVERYONE })
|
|
16
|
+
body?: string = undefined;
|
|
17
|
+
|
|
18
|
+
@UnifiedField({ description: 'Priority of the note', isOptional: true, roles: RoleEnum.S_EVERYONE })
|
|
19
|
+
priority?: number = undefined;
|
|
20
|
+
|
|
21
|
+
@UnifiedField({ description: 'Title of the note', isOptional: true, roles: RoleEnum.S_EVERYONE })
|
|
22
|
+
title?: string = undefined;
|
|
23
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
2
|
+
import type { Types } from 'mongoose';
|
|
3
|
+
|
|
4
|
+
import { Restricted } from '../../../core/common/decorators/restricted.decorator.js';
|
|
5
|
+
import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator.js';
|
|
6
|
+
import { RoleEnum } from '../../../core/common/enums/role.enum.js';
|
|
7
|
+
import { equalIds } from '../../../core/common/helpers/id.helper.js';
|
|
8
|
+
import { CorePersistenceModel } from '../../../core/common/models/core-persistence.model.js';
|
|
9
|
+
import {
|
|
10
|
+
objectIdType,
|
|
11
|
+
Schema as MongooseSchema,
|
|
12
|
+
SchemaFactory,
|
|
13
|
+
} from '../../../core/common/persistence/mongo/mongoose-compat.js';
|
|
14
|
+
import { PersistedModel } from '../../../core/common/persistence/persisted-model.decorator.js';
|
|
15
|
+
import { SyncField } from '../../../core/modules/sync/core-sync.decorators.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A note offered to offline clients — the reference implementation of a synchronized model
|
|
19
|
+
* (`src/core/modules/sync/INTEGRATION-CHECKLIST.md`).
|
|
20
|
+
*
|
|
21
|
+
* Not part of the reference server: `ServerModule` does not import it, so the framework's own suite runs without sync.
|
|
22
|
+
* The sync contract suite (`tests/sync-contract.e2e-spec.ts`) runs on exactly these files.
|
|
23
|
+
*
|
|
24
|
+
* - `sync.roles`: who may pull, create, change and delete through `/sync`. The roles of a project's own routes do not
|
|
25
|
+
* reach the sync routes, so they are declared here; `S_CREATOR` is decided against the stored record.
|
|
26
|
+
* - `sync.strategy: 'merge'`: a change based on an older version keeps the fields the client changed — unless one of
|
|
27
|
+
* them is `@SyncField('reject')`, which still conflicts.
|
|
28
|
+
* - `securityCheck()`: every user sees their own notes. A pull runs every record through it, a push decides with it
|
|
29
|
+
* whether an id belongs to a record the caller may see.
|
|
30
|
+
*/
|
|
31
|
+
@PersistedModel({
|
|
32
|
+
sync: {
|
|
33
|
+
roles: {
|
|
34
|
+
create: [RoleEnum.S_USER],
|
|
35
|
+
delete: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
36
|
+
pull: [RoleEnum.S_USER],
|
|
37
|
+
update: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
38
|
+
},
|
|
39
|
+
strategy: 'merge',
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
@MongooseSchema({ timestamps: true })
|
|
43
|
+
@ObjectType({ description: 'Note synchronized to offline clients' })
|
|
44
|
+
@Restricted(RoleEnum.ADMIN)
|
|
45
|
+
export class SyncNote extends CorePersistenceModel {
|
|
46
|
+
@UnifiedField({ description: 'Text of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE })
|
|
47
|
+
body?: string = undefined;
|
|
48
|
+
|
|
49
|
+
/** Set by `CrudService.create()`; what `S_CREATOR` and `securityCheck()` decide on */
|
|
50
|
+
@UnifiedField({
|
|
51
|
+
description: 'ID of the user who created the note',
|
|
52
|
+
isOptional: true,
|
|
53
|
+
mongoose: { type: objectIdType() },
|
|
54
|
+
roles: RoleEnum.S_EVERYONE,
|
|
55
|
+
swaggerApiOptions: { type: String },
|
|
56
|
+
type: () => String,
|
|
57
|
+
})
|
|
58
|
+
createdBy?: string | Types.ObjectId = undefined;
|
|
59
|
+
|
|
60
|
+
/** A concurrent change of the priority is never merged silently: it answers `conflict` */
|
|
61
|
+
@SyncField('reject')
|
|
62
|
+
@UnifiedField({ description: 'Priority of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE })
|
|
63
|
+
priority?: number = undefined;
|
|
64
|
+
|
|
65
|
+
@UnifiedField({ description: 'Title of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE })
|
|
66
|
+
title?: string = undefined;
|
|
67
|
+
|
|
68
|
+
/** Every user sees the notes they created; administrators see all */
|
|
69
|
+
override securityCheck(user: any, force?: boolean) {
|
|
70
|
+
if (force || user?.hasRole?.([RoleEnum.ADMIN]) || (user?.id && equalIds(this.createdBy, user))) {
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const SyncNoteSchema = SchemaFactory.createForClass(SyncNote);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { CorePersistenceModule } from '../../../core/common/persistence/core-persistence.module.js';
|
|
4
|
+
import { SyncNote, SyncNoteSchema } from './sync-note.model.js';
|
|
5
|
+
import { SyncNoteService } from './sync-note.service.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The synchronized note model and its service. Registered with `CorePersistenceModule.forFeature()`, so the model
|
|
9
|
+
* follows `database` like every other — and only a model registered this way can be synchronized.
|
|
10
|
+
*/
|
|
11
|
+
@Module({
|
|
12
|
+
exports: [SyncNoteService],
|
|
13
|
+
imports: [CorePersistenceModule.forFeature([{ model: SyncNote, name: SyncNote.name, schema: SyncNoteSchema }])],
|
|
14
|
+
providers: [SyncNoteService],
|
|
15
|
+
})
|
|
16
|
+
export class SyncNoteModule {}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import type { DataStore } from '../../../core/common/persistence/data-store.interface.js';
|
|
4
|
+
import { InjectStore } from '../../../core/common/persistence/inject-store.decorator.js';
|
|
5
|
+
import { ConfigService } from '../../../core/common/services/config.service.js';
|
|
6
|
+
import { CrudService } from '../../../core/common/services/crud.service.js';
|
|
7
|
+
import { SyncService } from '../../../core/modules/sync/core-sync.decorators.js';
|
|
8
|
+
import { SyncNoteCreateInput } from './inputs/sync-note-create.input.js';
|
|
9
|
+
import { SyncNoteInput } from './inputs/sync-note.input.js';
|
|
10
|
+
import { SyncNote } from './sync-note.model.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The note service, offered to offline clients: `@SyncService()` puts the model under `/sync/SyncNote`, and every pull
|
|
14
|
+
* and push of it runs through this service — its `process()` pipeline, `securityCheck()`, the tenant policy.
|
|
15
|
+
*/
|
|
16
|
+
@SyncService({ createInput: SyncNoteCreateInput, model: SyncNote, updateInput: SyncNoteInput })
|
|
17
|
+
@Injectable()
|
|
18
|
+
export class SyncNoteService extends CrudService<SyncNote, SyncNoteCreateInput, SyncNoteInput> {
|
|
19
|
+
constructor(
|
|
20
|
+
protected override readonly configService: ConfigService,
|
|
21
|
+
@InjectStore(SyncNote) store: DataStore<SyncNote>,
|
|
22
|
+
) {
|
|
23
|
+
super({ configService, dataStore: store, mainModelConstructor: SyncNote });
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/test/test.helper.ts
CHANGED
|
@@ -7,6 +7,7 @@ import * as util from 'util';
|
|
|
7
7
|
import ws from 'ws';
|
|
8
8
|
|
|
9
9
|
import { getStringIds } from '../core/common/helpers/db.helper.js';
|
|
10
|
+
import { ConfigService } from '../core/common/services/config.service.js';
|
|
10
11
|
import { resolveBetterAuthSessionCookieName } from '../core/modules/better-auth/better-auth-cookie-prefix.helper.js';
|
|
11
12
|
import { isObjectIdLike } from '../core/common/helpers/id.helper.js';
|
|
12
13
|
|
|
@@ -239,6 +240,12 @@ export interface TestMcpOptions {
|
|
|
239
240
|
* Options for `testHelper.mcpSession()`
|
|
240
241
|
*/
|
|
241
242
|
export interface TestMcpSessionOptions extends Omit<TestMcpOptions, 'sessionId' | 'statusCode'> {
|
|
243
|
+
/**
|
|
244
|
+
* Whether the server runs without sessions; then no session id is expected or sent, and
|
|
245
|
+
* `close()` does nothing. Defaults to `ai.mcp.stateless` of the running configuration.
|
|
246
|
+
*/
|
|
247
|
+
stateless?: boolean;
|
|
248
|
+
|
|
242
249
|
/**
|
|
243
250
|
* `clientInfo` sent with `initialize`. Default: `{ name: 'nest-server-test-helper', version: '1.0.0' }`
|
|
244
251
|
*/
|
|
@@ -342,7 +349,7 @@ export interface TestMcpSession {
|
|
|
342
349
|
): Promise<null | TestMcpMessage>;
|
|
343
350
|
|
|
344
351
|
/**
|
|
345
|
-
* `mcp-session-id` the server assigned
|
|
352
|
+
* `mcp-session-id` the server assigned; `''` on a stateless server (`ai.mcp.stateless`)
|
|
346
353
|
*/
|
|
347
354
|
sessionId: string;
|
|
348
355
|
}
|
|
@@ -697,8 +704,12 @@ export class TestHelper {
|
|
|
697
704
|
base,
|
|
698
705
|
);
|
|
699
706
|
expect(init.message?.error).toBeUndefined();
|
|
700
|
-
|
|
701
|
-
const
|
|
707
|
+
// A stateless server (`ai.mcp.stateless`) issues no session id; every request stands alone there.
|
|
708
|
+
const stateless = options.stateless ?? ConfigService.get<{ stateless?: boolean }>('ai.mcp')?.stateless === true;
|
|
709
|
+
if (!stateless) {
|
|
710
|
+
expect(init.sessionId).toBeTruthy();
|
|
711
|
+
}
|
|
712
|
+
const sessionId: string = stateless ? '' : (init.sessionId ?? '');
|
|
702
713
|
await this.mcp({ method: 'notifications/initialized' }, { ...base, sessionId });
|
|
703
714
|
|
|
704
715
|
let nextId = 2;
|
|
@@ -718,6 +729,9 @@ export class TestHelper {
|
|
|
718
729
|
return { ...result, json: TestHelper.parseJsonOrUndefined(result.content?.[0]?.text) };
|
|
719
730
|
},
|
|
720
731
|
close: async () => {
|
|
732
|
+
if (!sessionId) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
721
735
|
await this.rest(path, {
|
|
722
736
|
cookies: base.cookies,
|
|
723
737
|
headers: { ...base.headers, 'mcp-session-id': sessionId },
|