@lenne.tech/nest-server 12.1.0 → 12.2.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 +18 -6
- package/.claude/rules/configurable-features.md +5 -4
- package/.claude/rules/package-management.md +16 -1
- package/.claude/rules/persistence.md +26 -0
- package/.claude/rules/testing.md +102 -28
- package/CLAUDE.md +3 -2
- package/FRAMEWORK-API.md +17 -2
- package/README.md +24 -3
- package/dist/core/common/helpers/file.helper.js +3 -4
- package/dist/core/common/helpers/file.helper.js.map +1 -1
- package/dist/core/common/helpers/graphql-ws-connection.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +41 -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 +14 -19
- 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/persistence-runtime.registry.d.ts +5 -1
- package/dist/core/common/persistence/persistence-runtime.registry.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.d.ts +2 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +145 -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-dialect.d.ts +2 -0
- package/dist/core/common/persistence/sql/sql-dialect.js +14 -2
- package/dist/core/common/persistence/sql/sql-dialect.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/core-cron-jobs.service.d.ts +27 -0
- package/dist/core/common/services/core-cron-jobs.service.js +269 -13
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/core-redis-pubsub.js +5 -5
- package/dist/core/common/services/core-redis-pubsub.js.map +1 -1
- package/dist/core/common/services/core-redis.service.d.ts +6 -0
- package/dist/core/common/services/core-redis.service.js +57 -0
- package/dist/core/common/services/core-redis.service.js.map +1 -1
- 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/better-auth/better-auth-sql.helper.d.ts +1 -0
- package/dist/core/modules/better-auth/better-auth-sql.helper.js +41 -14
- package/dist/core/modules/better-auth/better-auth-sql.helper.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-sql.store.d.ts +4 -7
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js +23 -16
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +12 -2
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +82 -5
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/error-code/error-codes.d.ts +54 -0
- package/dist/core/modules/error-code/error-codes.js +48 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -1
- package/dist/core/modules/hub/hub-buffer.js +3 -4
- package/dist/core/modules/hub/hub-buffer.js.map +1 -1
- package/dist/core/modules/migrate/index.js.map +1 -1
- package/dist/core/modules/migrate/migration-runner.d.ts +6 -0
- package/dist/core/modules/migrate/migration-runner.js +28 -2
- package/dist/core/modules/migrate/migration-runner.js.map +1 -1
- package/dist/core/modules/migrate/mongo-state-store.d.ts +0 -1
- package/dist/core/modules/migrate/mongo-state-store.js +0 -5
- package/dist/core/modules/migrate/mongo-state-store.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 +142 -0
- package/dist/core/modules/sync/core-sync.service.js +1208 -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 +8 -3
- package/dist/core/modules/tenant/core-tenant.guard.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 +6 -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/docs/REQUEST-LIFECYCLE.md +3 -2
- package/docs/choosing-a-database.md +7 -4
- package/docs/offline-sync-protocol.md +410 -0
- package/docs/security-overrides.md +14 -0
- package/migration-guides/12.0.x-to-12.1.x.md +9 -4
- package/migration-guides/12.1.0-to-12.1.1.md +125 -0
- package/migration-guides/12.1.x-to-12.2.x.md +154 -0
- package/package.json +10 -8
- package/src/core/common/helpers/file.helper.ts +7 -5
- package/src/core/common/helpers/graphql-ws-connection.helper.ts +3 -2
- package/src/core/common/interfaces/cron-job-config.interface.ts +7 -2
- package/src/core/common/interfaces/server-options.interface.ts +149 -0
- 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 +22 -23
- 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/persistence-runtime.registry.ts +16 -5
- 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 +194 -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-dialect.ts +38 -1
- package/src/core/common/persistence/sql/sql-errors.ts +5 -1
- package/src/core/common/persistence/sql/sql-executor.interface.ts +4 -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/core-cron-jobs.service.ts +441 -27
- package/src/core/common/services/core-redis-pubsub.ts +8 -6
- package/src/core/common/services/core-redis.service.ts +99 -0
- package/src/core/common/services/crud.service.ts +257 -19
- package/src/core/modules/better-auth/README.md +25 -1
- package/src/core/modules/better-auth/better-auth-sql.helper.ts +56 -24
- package/src/core/modules/better-auth/better-auth.config.ts +4 -3
- package/src/core/modules/better-auth/core-better-auth-sql.store.ts +28 -21
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +122 -6
- package/src/core/modules/better-auth/core-better-auth.module.ts +2 -2
- package/src/core/modules/error-code/error-codes.ts +59 -0
- package/src/core/modules/hub/README.md +5 -2
- package/src/core/modules/hub/hub-buffer.ts +13 -7
- package/src/core/modules/migrate/README.md +20 -11
- package/src/core/modules/migrate/index.ts +1 -0
- package/src/core/modules/migrate/migration-runner.ts +68 -3
- package/src/core/modules/migrate/mongo-state-store.ts +7 -30
- 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 +188 -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 +1728 -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/README.md +1 -0
- package/src/core/modules/tenant/core-tenant.guard.ts +16 -3
- 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
|
@@ -60,6 +60,7 @@ export declare const ErrorCode: {
|
|
|
60
60
|
REQUEST_BODY_TOO_LARGE: string;
|
|
61
61
|
RESOURCE_NOT_FOUND: string;
|
|
62
62
|
RESOURCE_ALREADY_EXISTS: string;
|
|
63
|
+
VERSION_CONFLICT: string;
|
|
63
64
|
FILE_NOT_FOUND: string;
|
|
64
65
|
FILE_UPLOAD_FAILED: string;
|
|
65
66
|
FILE_TYPE_NOT_ALLOWED: string;
|
|
@@ -78,6 +79,11 @@ export declare const ErrorCode: {
|
|
|
78
79
|
AI_RATE_LIMITED: string;
|
|
79
80
|
AI_PROVIDER_ERROR: string;
|
|
80
81
|
AI_CONNECTION_INVALID_URL: string;
|
|
82
|
+
SYNC_RESYNC_REQUIRED: string;
|
|
83
|
+
SYNC_MODEL_NOT_FOUND: string;
|
|
84
|
+
SYNC_INVALID_REQUEST: string;
|
|
85
|
+
SYNC_ORIGIN_REFUSED: string;
|
|
86
|
+
SYNC_STORE_UNAVAILABLE: string;
|
|
81
87
|
DEMO_ERROR: string;
|
|
82
88
|
FEATURE_NOT_AVAILABLE: string;
|
|
83
89
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { InputType } from '@nestjs/graphql';
|
|
11
|
+
import { Restricted } from '../../../../core/common/decorators/restricted.decorator.js';
|
|
12
|
+
import { UnifiedField } from '../../../../core/common/decorators/unified-field.decorator.js';
|
|
13
|
+
import { RoleEnum } from '../../../../core/common/enums/role.enum.js';
|
|
14
|
+
import { SyncNoteInput } from './sync-note.input.js';
|
|
15
|
+
let SyncNoteCreateInput = class SyncNoteCreateInput extends SyncNoteInput {
|
|
16
|
+
title = undefined;
|
|
17
|
+
};
|
|
18
|
+
__decorate([
|
|
19
|
+
UnifiedField({ description: 'Title of the note', roles: RoleEnum.S_EVERYONE }),
|
|
20
|
+
__metadata("design:type", String)
|
|
21
|
+
], SyncNoteCreateInput.prototype, "title", void 0);
|
|
22
|
+
SyncNoteCreateInput = __decorate([
|
|
23
|
+
InputType({ description: 'Input to create a synchronized note' }),
|
|
24
|
+
Restricted(RoleEnum.ADMIN)
|
|
25
|
+
], SyncNoteCreateInput);
|
|
26
|
+
export { SyncNoteCreateInput };
|
|
27
|
+
//# sourceMappingURL=sync-note-create.input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-note-create.input.js","sourceRoot":"","sources":["../../../../../src/server/modules/sync-note/inputs/sync-note-create.input.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,4DAA4D,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,+DAA+D,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK9C,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,aAAa;IAE3C,KAAK,GAAW,SAAS,CAAC;CACpC,CAAA;AADU;IADR,YAAY,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;kDAC5C;AAFxB,mBAAmB;IAF/B,SAAS,CAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;IACjE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;GACd,mBAAmB,CAG/B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { InputType } from '@nestjs/graphql';
|
|
11
|
+
import { Restricted } from '../../../../core/common/decorators/restricted.decorator.js';
|
|
12
|
+
import { UnifiedField } from '../../../../core/common/decorators/unified-field.decorator.js';
|
|
13
|
+
import { RoleEnum } from '../../../../core/common/enums/role.enum.js';
|
|
14
|
+
import { CoreInput } from '../../../../core/common/inputs/core-input.input.js';
|
|
15
|
+
let SyncNoteInput = class SyncNoteInput extends CoreInput {
|
|
16
|
+
body = undefined;
|
|
17
|
+
priority = undefined;
|
|
18
|
+
title = undefined;
|
|
19
|
+
};
|
|
20
|
+
__decorate([
|
|
21
|
+
UnifiedField({ description: 'Text of the note', isOptional: true, roles: RoleEnum.S_EVERYONE }),
|
|
22
|
+
__metadata("design:type", String)
|
|
23
|
+
], SyncNoteInput.prototype, "body", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
UnifiedField({ description: 'Priority of the note', isOptional: true, roles: RoleEnum.S_EVERYONE }),
|
|
26
|
+
__metadata("design:type", Number)
|
|
27
|
+
], SyncNoteInput.prototype, "priority", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
UnifiedField({ description: 'Title of the note', isOptional: true, roles: RoleEnum.S_EVERYONE }),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], SyncNoteInput.prototype, "title", void 0);
|
|
32
|
+
SyncNoteInput = __decorate([
|
|
33
|
+
InputType({ description: 'Input to change a synchronized note' }),
|
|
34
|
+
Restricted(RoleEnum.ADMIN)
|
|
35
|
+
], SyncNoteInput);
|
|
36
|
+
export { SyncNoteInput };
|
|
37
|
+
//# sourceMappingURL=sync-note.input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-note.input.js","sourceRoot":"","sources":["../../../../../src/server/modules/sync-note/inputs/sync-note.input.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,4DAA4D,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,+DAA+D,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,oDAAoD,CAAC;AAQxE,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,SAAS;IAE1C,IAAI,GAAY,SAAS,CAAC;IAG1B,QAAQ,GAAY,SAAS,CAAC;IAG9B,KAAK,GAAY,SAAS,CAAC;CAC5B,CAAA;AAPC;IADC,YAAY,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;2CACtE;AAG1B;IADC,YAAY,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;+CACtE;AAG9B;IADC,YAAY,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;4CACtE;AARhB,aAAa;IAFzB,SAAS,CAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;IACjE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;GACd,aAAa,CASzB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Types } from 'mongoose';
|
|
2
|
+
import { CorePersistenceModel } from '../../../core/common/models/core-persistence.model.js';
|
|
3
|
+
export declare class SyncNote extends CorePersistenceModel {
|
|
4
|
+
body?: string;
|
|
5
|
+
createdBy?: string | Types.ObjectId;
|
|
6
|
+
priority?: number;
|
|
7
|
+
title?: string;
|
|
8
|
+
securityCheck(user: any, force?: boolean): this;
|
|
9
|
+
}
|
|
10
|
+
export declare const SyncNoteSchema: any;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
11
|
+
import { Restricted } from '../../../core/common/decorators/restricted.decorator.js';
|
|
12
|
+
import { UnifiedField } from '../../../core/common/decorators/unified-field.decorator.js';
|
|
13
|
+
import { RoleEnum } from '../../../core/common/enums/role.enum.js';
|
|
14
|
+
import { equalIds } from '../../../core/common/helpers/id.helper.js';
|
|
15
|
+
import { CorePersistenceModel } from '../../../core/common/models/core-persistence.model.js';
|
|
16
|
+
import { objectIdType, Schema as MongooseSchema, SchemaFactory, } from '../../../core/common/persistence/mongo/mongoose-compat.js';
|
|
17
|
+
import { PersistedModel } from '../../../core/common/persistence/persisted-model.decorator.js';
|
|
18
|
+
import { SyncField } from '../../../core/modules/sync/core-sync.decorators.js';
|
|
19
|
+
let SyncNote = class SyncNote extends CorePersistenceModel {
|
|
20
|
+
body = undefined;
|
|
21
|
+
createdBy = undefined;
|
|
22
|
+
priority = undefined;
|
|
23
|
+
title = undefined;
|
|
24
|
+
securityCheck(user, force) {
|
|
25
|
+
if (force || user?.hasRole?.([RoleEnum.ADMIN]) || (user?.id && equalIds(this.createdBy, user))) {
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
__decorate([
|
|
32
|
+
UnifiedField({ description: 'Text of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE }),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], SyncNote.prototype, "body", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
UnifiedField({
|
|
37
|
+
description: 'ID of the user who created the note',
|
|
38
|
+
isOptional: true,
|
|
39
|
+
mongoose: { type: objectIdType() },
|
|
40
|
+
roles: RoleEnum.S_EVERYONE,
|
|
41
|
+
swaggerApiOptions: { type: String },
|
|
42
|
+
type: () => String,
|
|
43
|
+
}),
|
|
44
|
+
__metadata("design:type", Object)
|
|
45
|
+
], SyncNote.prototype, "createdBy", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
SyncField('reject'),
|
|
48
|
+
UnifiedField({ description: 'Priority of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE }),
|
|
49
|
+
__metadata("design:type", Number)
|
|
50
|
+
], SyncNote.prototype, "priority", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
UnifiedField({ description: 'Title of the note', isOptional: true, mongoose: true, roles: RoleEnum.S_EVERYONE }),
|
|
53
|
+
__metadata("design:type", String)
|
|
54
|
+
], SyncNote.prototype, "title", void 0);
|
|
55
|
+
SyncNote = __decorate([
|
|
56
|
+
PersistedModel({
|
|
57
|
+
sync: {
|
|
58
|
+
roles: {
|
|
59
|
+
create: [RoleEnum.S_USER],
|
|
60
|
+
delete: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
61
|
+
pull: [RoleEnum.S_USER],
|
|
62
|
+
update: [RoleEnum.ADMIN, RoleEnum.S_CREATOR],
|
|
63
|
+
},
|
|
64
|
+
strategy: 'merge',
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
MongooseSchema({ timestamps: true }),
|
|
68
|
+
ObjectType({ description: 'Note synchronized to offline clients' }),
|
|
69
|
+
Restricted(RoleEnum.ADMIN)
|
|
70
|
+
], SyncNote);
|
|
71
|
+
export { SyncNote };
|
|
72
|
+
export const SyncNoteSchema = SchemaFactory.createForClass(SyncNote);
|
|
73
|
+
//# sourceMappingURL=sync-note.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-note.model.js","sourceRoot":"","sources":["../../../../src/server/modules/sync-note/sync-note.model.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uDAAuD,CAAC;AAC7F,OAAO,EACL,YAAY,EACZ,MAAM,IAAI,cAAc,EACxB,aAAa,GACd,MAAM,2DAA2D,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,oDAAoD,CAAC;AA8BxE,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,oBAAoB;IAEhD,IAAI,GAAY,SAAS,CAAC;IAW1B,SAAS,GAA6B,SAAS,CAAC;IAKhD,QAAQ,GAAY,SAAS,CAAC;IAG9B,KAAK,GAAY,SAAS,CAAC;IAGlB,aAAa,CAAC,IAAS,EAAE,KAAe;QAC/C,IAAI,KAAK,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YAC/F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAA;AA5BC;IADC,YAAY,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;sCACtF;AAW1B;IARC,YAAY,CAAC;QACZ,WAAW,EAAE,qCAAqC;QAClD,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE;QAClC,KAAK,EAAE,QAAQ,CAAC,UAAU;QAC1B,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACnC,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM;KACnB,CAAC;;2CAC8C;AAKhD;IAFC,SAAS,CAAC,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;0CACtF;AAG9B;IADC,YAAY,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;;uCACtF;AArBhB,QAAQ;IAdpB,cAAc,CAAC;QACd,IAAI,EAAE;YACJ,KAAK,EAAE;gBACL,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACzB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC;gBAC5C,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC;aAC7C;YACD,QAAQ,EAAE,OAAO;SAClB;KACF,CAAC;IACD,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;IACnE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;GACd,QAAQ,CA8BpB;;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Module } from '@nestjs/common';
|
|
8
|
+
import { CorePersistenceModule } from '../../../core/common/persistence/core-persistence.module.js';
|
|
9
|
+
import { SyncNote, SyncNoteSchema } from './sync-note.model.js';
|
|
10
|
+
import { SyncNoteService } from './sync-note.service.js';
|
|
11
|
+
let SyncNoteModule = class SyncNoteModule {
|
|
12
|
+
};
|
|
13
|
+
SyncNoteModule = __decorate([
|
|
14
|
+
Module({
|
|
15
|
+
exports: [SyncNoteService],
|
|
16
|
+
imports: [CorePersistenceModule.forFeature([{ model: SyncNote, name: SyncNote.name, schema: SyncNoteSchema }])],
|
|
17
|
+
providers: [SyncNoteService],
|
|
18
|
+
})
|
|
19
|
+
], SyncNoteModule);
|
|
20
|
+
export { SyncNoteModule };
|
|
21
|
+
//# sourceMappingURL=sync-note.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-note.module.js","sourceRoot":"","sources":["../../../../src/server/modules/sync-note/sync-note.module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAWlD,IAAM,cAAc,GAApB,MAAM,cAAc;CAAG,CAAA;AAAjB,cAAc;IAL1B,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,OAAO,EAAE,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;QAC/G,SAAS,EAAE,CAAC,eAAe,CAAC;KAC7B,CAAC;GACW,cAAc,CAAG"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DataStore } from '../../../core/common/persistence/data-store.interface.js';
|
|
2
|
+
import { ConfigService } from '../../../core/common/services/config.service.js';
|
|
3
|
+
import { CrudService } from '../../../core/common/services/crud.service.js';
|
|
4
|
+
import { SyncNoteCreateInput } from './inputs/sync-note-create.input.js';
|
|
5
|
+
import { SyncNoteInput } from './inputs/sync-note.input.js';
|
|
6
|
+
import { SyncNote } from './sync-note.model.js';
|
|
7
|
+
export declare class SyncNoteService extends CrudService<SyncNote, SyncNoteCreateInput, SyncNoteInput> {
|
|
8
|
+
protected readonly configService: ConfigService;
|
|
9
|
+
constructor(configService: ConfigService, store: DataStore<SyncNote>);
|
|
10
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Injectable } from '@nestjs/common';
|
|
14
|
+
import { InjectStore } from '../../../core/common/persistence/inject-store.decorator.js';
|
|
15
|
+
import { ConfigService } from '../../../core/common/services/config.service.js';
|
|
16
|
+
import { CrudService } from '../../../core/common/services/crud.service.js';
|
|
17
|
+
import { SyncService } from '../../../core/modules/sync/core-sync.decorators.js';
|
|
18
|
+
import { SyncNoteCreateInput } from './inputs/sync-note-create.input.js';
|
|
19
|
+
import { SyncNoteInput } from './inputs/sync-note.input.js';
|
|
20
|
+
import { SyncNote } from './sync-note.model.js';
|
|
21
|
+
let SyncNoteService = class SyncNoteService extends CrudService {
|
|
22
|
+
configService;
|
|
23
|
+
constructor(configService, store) {
|
|
24
|
+
super({ configService, dataStore: store, mainModelConstructor: SyncNote });
|
|
25
|
+
this.configService = configService;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
SyncNoteService = __decorate([
|
|
29
|
+
SyncService({ createInput: SyncNoteCreateInput, model: SyncNote, updateInput: SyncNoteInput }),
|
|
30
|
+
Injectable(),
|
|
31
|
+
__param(1, InjectStore(SyncNote)),
|
|
32
|
+
__metadata("design:paramtypes", [ConfigService, Object])
|
|
33
|
+
], SyncNoteService);
|
|
34
|
+
export { SyncNoteService };
|
|
35
|
+
//# sourceMappingURL=sync-note.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-note.service.js","sourceRoot":"","sources":["../../../../src/server/modules/sync-note/sync-note.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,4DAA4D,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQzC,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,WAAyD;IAE9D;IAD9B,YAC8B,aAA4B,EACjC,KAA0B;QAEjD,KAAK,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAC,CAAC;QAH/C,kBAAa,GAAb,aAAa,CAAe;IAI1D,CAAC;CACF,CAAA;AAPY,eAAe;IAF3B,WAAW,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;IAC9F,UAAU,EAAE;IAIR,WAAA,WAAW,CAAC,QAAQ,CAAC,CAAA;qCADqB,aAAa;GAF/C,eAAe,CAO3B"}
|
|
@@ -41,7 +41,7 @@ The `CoreModule` is a dynamic module that bootstraps the entire framework:
|
|
|
41
41
|
| **Security Pipeline** | 4 global interceptors, global validation pipe, middleware stack |
|
|
42
42
|
| **Mongoose Plugins** | Auto-registration of ID, password, audit, and role guard plugins |
|
|
43
43
|
| **GraphQL Subscriptions** | WebSocket support with JWT/session authentication (cluster-wide when `redis` is configured — see the Subscriptions row under GraphQL Features) |
|
|
44
|
-
| **Central Redis (optional)** | `CoreRedisService` — globally provided **and exported** by `CoreModule`, always present but **inert unless `redis` is configured** ("presence implies enabled"). Injected with `@Optional()`; every consumer keeps a process-local fallback. One service serves all features: shared client (`getClient()`), one cached subscriber (`getSubscriber()` — a subscribing client cannot run commands), dedicated connections (`createClient(label)`); all tracked and quit on shutdown. Keys are namespaced by the framework per key via `key(...)`, **not** through ioredis's own `keyPrefix` (that would collide with BullMQ's prefix). Requires the OPTIONAL peer `ioredis` — configured but missing **fails the boot**. Switches on: exact cross-replica rate limits, cron deduplication, `CoreRedisPubSub` as `PUB_SUB`, tenant-cache invalidation broadcast, Hub collector mirroring, MCP session registry |
|
|
44
|
+
| **Central Redis (optional)** | `CoreRedisService` — globally provided **and exported** by `CoreModule`, always present but **inert unless `redis` is configured** ("presence implies enabled"). Injected with `@Optional()`; every consumer keeps a process-local fallback. One service serves all features: shared client (`getClient()`), one cached subscriber (`getSubscriber()` — a subscribing client cannot run commands), dedicated connections (`createClient(label)`); all tracked and quit on shutdown. Keys are namespaced by the framework per key via `key(...)`, **not** through ioredis's own `keyPrefix` (that would collide with BullMQ's prefix). Requires the OPTIONAL peer `ioredis` — configured but missing **fails the boot**. Switches on: exact cross-replica rate limits, cron deduplication, `CoreRedisPubSub` as `PUB_SUB`, tenant-cache invalidation broadcast, Better-Auth user-cache (roles/verification) invalidation broadcast, Hub collector mirroring, MCP session registry |
|
|
45
45
|
| **Central S3 (optional)** | `CoreS3Service` — globally provided **and exported** by `CoreModule`, inert unless `s3` is configured *and* names a `bucket` (a bucket-less block is ignored with a warning). Backs `file.storage: 's3'` and TUS staging (`tus.s3Staging`). Requires the OPTIONAL peers `@aws-sdk/client-s3` (+ `@aws-sdk/s3-request-presigner` for `presignedDownloads`) — configured but missing **fails the boot**. `@aws-sdk/lib-storage` (optional) uploads streams of unknown length in parts; without it they are buffered in memory, with one boot warning |
|
|
46
46
|
| **Configuration System** | `config.env.ts` with ENV variables, `NEST_SERVER_CONFIG` JSON, `NSC__*` prefixes |
|
|
47
47
|
| **Cookie Handling** | Enabled by default (`cookies: true`), configurable via `ICookiesConfig` with `exposeTokenInBody` option |
|
|
@@ -114,7 +114,7 @@ JWT-based authentication for existing projects:
|
|
|
114
114
|
| **Tenant Isolation** | Header-based multi-tenant isolation with membership validation (opt-in) |
|
|
115
115
|
| **Tenant Guard** | `CoreTenantGuard` validates tenant membership — and, with `multiTenancy.isTenantActive` (11.42.0), that the tenant is not deactivated; system roles (`S_EVERYONE`, `S_USER`, `S_VERIFIED`) are checked as OR alternatives before real roles; hierarchy roles (`@Roles(DefaultHR.MEMBER)`), `@SkipTenantCheck()`, BetterAuth auto-skip (`betterAuth.skipTenantCheck`). It runs AFTER the role guard (4 → 4b below); where registration order puts it first — `CoreModule` registers it ahead of a project's `AuthModule`, so with legacy JWTs nobody is identified yet — it lets the application's role guard (`ROLE_GUARD` token) identify the caller first |
|
|
116
116
|
| **Tenant Plugin Safety Net** | Mongoose tenant plugin throws `ForbiddenException` when tenant-schema is accessed without valid tenant context. Its post hooks (`find`, `findOne`, `findOneAnd*`) additionally check every RETURNED row (`assertRowsInTenantScope()`): a row of a tenant outside the caller's scope withholds the whole result with 403. The decisions live in `common/persistence/policies/tenant.policy.ts`, which every data store shares |
|
|
117
|
-
| **Data Store** | `DataStore<T>` (`common/persistence/`) is the database-neutral port below the CrudService pipeline; every `ModuleService` has one (`this.dataStore`, derived from `mainDbModel`, or passed as `dataStore`). On MongoDB it runs through Mongoose model methods, so every plugin fires. On PostgreSQL (`SqlDataStore`, phase 1) the same pipeline runs on plain records: before every statement the store applies the policies the plugins call (tenant filter and stamping, safety net, audit, password, role guard, system roles), the statement runs in its own transaction with the request's tenant scope so FORCED row-level security binds it (a query without a scope fails with 42501 → 403), and every returned row passes the tenant row check. References populate with one batched `id $in` read through the target model's store. Mongoose-only APIs (`aggregate`, `getModel`, native collection/connection) refuse on a SQL-stored model, and so does the Mongoose model itself (every data method of a model routed to SQL throws a named error). Since phase 2 the core's own models — users, tenant memberships, API tokens — are registered this way and their services run on the routed store; the port gained `updateOne` / `deleteOne` (atomic first match), `updateMany`, `deleteMany` and `updateById(…, { timestamps: false })`. Since phase 3 Better-Auth follows the user model: with the users on a SQL source it runs its own Kysely adapter on that source's application pool, one `users` row per user, and the framework's reads of Better-Auth's data (session lookup by token in the middleware, token service, JWKS, passkey challenge mappings, e-mail-verified hook, user mapper, system setup, migration status, the MCP OAuth subject's roles) go through `BetterAuthSqlStore` — see `.claude/rules/better-auth.md` §11. Since phase 4 the AI module (eleven models, MCP OAuth clients, codes and refresh tokens) and the S3 / filesystem file metadata (`fileMetadataCollection()`, used by the file service, the TUS hand-off and the Hub) follow their routed store too; the port gained `sum()` and `find(…, { exclude })`, and an expiry sweep removes expired rows of TTL models and expired Better-Auth sessions on SQL, where no TTL index does. `CorePersistenceModule.forFeature()` + `@InjectStore()` register and inject the store; the `database` configuration routes each model to its source. Since phase 5 (12.1.0) MongoDB's libraries are optional peers: the core reaches them through `common/persistence/mongo/` (decorators that record the declaration and apply `@nestjs/mongoose`'s where installed, tokens, ObjectIds, GridFS), `CoreModule` connects MongoDB only when a source uses it, `forFeature()` provides the model tokens itself (a stand-in that refuses data access where no MongoDB is connected), and `database: false` runs without any database; the port gained `find(…, { sample })`, and the SQL update compiler skips a field given as `undefined` as Mongoose does |
|
|
117
|
+
| **Data Store** | `DataStore<T>` (`common/persistence/`) is the database-neutral port below the CrudService pipeline; every `ModuleService` has one (`this.dataStore`, derived from `mainDbModel`, or passed as `dataStore`). On MongoDB it runs through Mongoose model methods, so every plugin fires. On PostgreSQL (`SqlDataStore`, phase 1) the same pipeline runs on plain records: before every statement the store applies the policies the plugins call (tenant filter and stamping, safety net, audit, password, role guard, system roles), the statement runs in its own transaction with the request's tenant scope so FORCED row-level security binds it (a query without a scope fails with 42501 → 403), and every returned row passes the tenant row check. References populate with one batched `id $in` read through the target model's store. Mongoose-only APIs (`aggregate`, `getModel`, native collection/connection) refuse on a SQL-stored model, and so does the Mongoose model itself (every data method of a model routed to SQL throws a named error). Since phase 2 the core's own models — users, tenant memberships, API tokens — are registered this way and their services run on the routed store; the port gained `updateOne` / `deleteOne` (atomic first match), `updateMany`, `deleteMany` and `updateById(…, { timestamps: false })`. Since phase 3 Better-Auth follows the user model: with the users on a SQL source (PostgreSQL; MySQL / MariaDB since 12.1.1) it runs its own Kysely adapter on that source's application pool, one `users` row per user, and the framework's reads of Better-Auth's data (session lookup by token in the middleware, token service, JWKS, passkey challenge mappings, e-mail-verified hook, user mapper, system setup, migration status, the MCP OAuth subject's roles) go through `BetterAuthSqlStore` — see `.claude/rules/better-auth.md` §11. Since phase 4 the AI module (eleven models, MCP OAuth clients, codes and refresh tokens) and the S3 / filesystem file metadata (`fileMetadataCollection()`, used by the file service, the TUS hand-off and the Hub) follow their routed store too; the port gained `sum()` and `find(…, { exclude })`, and an expiry sweep removes expired rows of TTL models and expired Better-Auth sessions on SQL, where no TTL index does. `CorePersistenceModule.forFeature()` + `@InjectStore()` register and inject the store; the `database` configuration routes each model to its source. Since phase 5 (12.1.0) MongoDB's libraries are optional peers: the core reaches them through `common/persistence/mongo/` (decorators that record the declaration and apply `@nestjs/mongoose`'s where installed, tokens, ObjectIds, GridFS), `CoreModule` connects MongoDB only when a source uses it, `forFeature()` provides the model tokens itself (a stand-in that refuses data access where no MongoDB is connected), and `database: false` runs without any database; the port gained `find(…, { sample })`, and the SQL update compiler skips a field given as `undefined` as Mongoose does |
|
|
118
118
|
| **API Tokens** | `apiTokens` config (opt-in): USER tokens act as their user without global roles; TENANT tokens (multi-tenancy only) act with the lowest tenant role in their own tenant. `CoreApiTokenMiddleware` authenticates `Authorization: Bearer` / `x-api-key`; every guard denies a token unless the route declares `@ApiTokenScopes()`. Signed short-lived assertions for embedded pages. See `src/core/modules/api-token/README.md` |
|
|
119
119
|
|
|
120
120
|
### Data & CRUD
|
|
@@ -131,6 +131,7 @@ JWT-based authentication for existing projects:
|
|
|
131
131
|
| **Bulk Operations** | Batch create/update/delete |
|
|
132
132
|
| **Force Mode** | `force: true` bypasses all security checks |
|
|
133
133
|
| **Raw Mode** | `raw: true` skips prepareInput/prepareOutput |
|
|
134
|
+
| **Synchronized models** | `@PersistedModel({ sync })` (offline sync, 12.x): the store writes `version`, `deletedAt` and the change position on every write path (on MongoDB through `mongo/sync-schema.plugin.ts`, applied to these schemas only); `CrudService.delete()` and every port delete leave a tombstone, reads leave tombstones out unless `includeTombstones`, and `ServiceOptions.expectedVersion` makes `update()` / `delete()` one conditional statement (409 `VersionConflictError` on another version). Unique indexes apply to live records only. With the `sync` configuration (12.2.0) the sync module serves `GET/POST /sync/{model}` for models whose CrudService carries `@SyncService()`: `@Roles(S_USER)` on the route, the model's `sync.roles` passed as `serviceOptions.roles` on every CrudService call, every pulled record through `securityCheck()`, a header-less request scoped to the caller's memberships, the 410 resync body written by the controller itself (`src/core/modules/sync/README.md`). Change hints (`GET /sync/hints`, SSE, and the GraphQL subscription `syncHint`) carry `{ model, at }` only, sent from the CrudService's create / update / delete of such a model and delivered to a subscriber only with the model's pull roles and access to the tenant of the change; the SSE stream registers with the WebSocket re-check registry and ends on every invalidation or re-check, so the client reconnects with its current rights. An hourly purge removes tombstones past `sync.retention.tombstonesDays` after moving the retention horizon past them. What a client must delete on logout is in the module's `SECURITY.md`. See `.claude/rules/persistence.md` → "Synchronized models" |
|
|
134
135
|
|
|
135
136
|
### Models & Inputs
|
|
136
137
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Since 12.1.0 a `@lenne.tech/nest-server` project stores its data in **MongoDB** (the default), in **PostgreSQL**, in
|
|
4
4
|
**MySQL 8.4 / MariaDB 11.8**, or in several of them, model by model. The framework's own modules (users, tenants, API
|
|
5
|
-
tokens, AI, file metadata, locks, migrations) run on each, behind one `CrudService` and one security pipeline
|
|
6
|
-
Better-Auth
|
|
5
|
+
tokens, AI, file metadata, locks, migrations) run on each, behind one `CrudService` and one security pipeline, and so
|
|
6
|
+
does Better-Auth (on MySQL / MariaDB since 12.1.1). This document is the decision
|
|
7
7
|
procedure — for a developer starting a project and for an AI agent asked to set one up. Configuration details are in
|
|
8
8
|
`.claude/rules/configurable-features.md` (row "Data Sources"); the code rules in `.claude/rules/persistence.md`.
|
|
9
9
|
|
|
@@ -31,8 +31,11 @@ Work through the steps in order; the first one that decides, decides.
|
|
|
31
31
|
own reaches every tenant's rows unless it filters by `tenantId` itself. The boot says so once per source. A
|
|
32
32
|
trigger-based write guard was measured and not built: it cost up to half of MariaDB's write throughput and left
|
|
33
33
|
the native read open.
|
|
34
|
-
- **Better-Auth
|
|
35
|
-
|
|
34
|
+
- **Better-Auth's tables are created by Better-Auth** (12.1.1+), in the database's default collation — so the
|
|
35
|
+
framework switches that default to `utf8mb4_bin` and back while Better-Auth creates a table, and its tables
|
|
36
|
+
compare byte-wise like the framework's. That switch locks every table of the database, so it runs only on a boot
|
|
37
|
+
that creates one, and waits at most five seconds behind an open transaction before the boot fails. This needs the owner connection (`database.ownerUrl`), as every
|
|
38
|
+
schema change does; Better-Auth's own column types apply there (`timestamp(3)`, `varchar(36)` ids).
|
|
36
39
|
- **An indexed text field holds at most 255 characters** (a longer value is refused with 400); every other text is
|
|
37
40
|
unbounded. Indexing an existing text field later is a type change, i.e. a reviewed migration.
|
|
38
41
|
- **Schema changes are not transactional:** MySQL commits every DDL statement on its own, so a failed change leaves
|