@nolag/core 0.4.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/LICENSE +202 -0
- package/NOTICE +28 -0
- package/README.md +244 -0
- package/dist/common/entities/base.entity.d.ts +12 -0
- package/dist/common/entities/base.entity.d.ts.map +1 -0
- package/dist/common/entities/base.entity.js +31 -0
- package/dist/common/pagination.d.ts +34 -0
- package/dist/common/pagination.d.ts.map +1 -0
- package/dist/common/pagination.js +100 -0
- package/dist/common/utils/secretCipher.d.ts +3 -0
- package/dist/common/utils/secretCipher.d.ts.map +1 -0
- package/dist/common/utils/secretCipher.js +45 -0
- package/dist/common/utils/secretHash.d.ts +15 -0
- package/dist/common/utils/secretHash.d.ts.map +1 -0
- package/dist/common/utils/secretHash.js +46 -0
- package/dist/common/utils/ttlCache.d.ts +13 -0
- package/dist/common/utils/ttlCache.d.ts.map +1 -0
- package/dist/common/utils/ttlCache.js +47 -0
- package/dist/common/validators/isValidTopicName.validator.d.ts +7 -0
- package/dist/common/validators/isValidTopicName.validator.d.ts.map +1 -0
- package/dist/common/validators/isValidTopicName.validator.js +44 -0
- package/dist/core.config.d.ts +10 -0
- package/dist/core.config.d.ts.map +1 -0
- package/dist/core.config.js +41 -0
- package/dist/core.module.d.ts +6 -0
- package/dist/core.module.d.ts.map +1 -0
- package/dist/core.module.js +67 -0
- package/dist/core.options.d.ts +26 -0
- package/dist/core.options.d.ts.map +1 -0
- package/dist/core.options.js +10 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/dist/migrations/1786323955167-InitialSchema.d.ts +7 -0
- package/dist/migrations/1786323955167-InitialSchema.d.ts.map +1 -0
- package/dist/migrations/1786323955167-InitialSchema.js +106 -0
- package/dist/modules/accessScopeModule/accessScope.entity.d.ts +15 -0
- package/dist/modules/accessScopeModule/accessScope.entity.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/accessScope.entity.js +78 -0
- package/dist/modules/accessScopeModule/accessScope.facade.d.ts +22 -0
- package/dist/modules/accessScopeModule/accessScope.facade.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/accessScope.facade.js +103 -0
- package/dist/modules/accessScopeModule/accessScope.module.d.ts +3 -0
- package/dist/modules/accessScopeModule/accessScope.module.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/accessScope.module.js +34 -0
- package/dist/modules/accessScopeModule/accessScope.repository.d.ts +7 -0
- package/dist/modules/accessScopeModule/accessScope.repository.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/accessScope.repository.js +35 -0
- package/dist/modules/accessScopeModule/accessScope.service.d.ts +15 -0
- package/dist/modules/accessScopeModule/accessScope.service.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/accessScope.service.js +87 -0
- package/dist/modules/accessScopeModule/dto/accessScope.dto.d.ts +13 -0
- package/dist/modules/accessScopeModule/dto/accessScope.dto.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/dto/accessScope.dto.js +88 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.d.ts +8 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.js +35 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.service.d.ts +10 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.service.d.ts.map +1 -0
- package/dist/modules/accessScopeModule/query/accessScope.query.service.js +47 -0
- package/dist/modules/actorTokenModule/actorAppAccess.entity.d.ts +19 -0
- package/dist/modules/actorTokenModule/actorAppAccess.entity.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorAppAccess.entity.js +92 -0
- package/dist/modules/actorTokenModule/actorToken.entity.d.ts +23 -0
- package/dist/modules/actorTokenModule/actorToken.entity.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorToken.entity.js +117 -0
- package/dist/modules/actorTokenModule/actorToken.facade.d.ts +35 -0
- package/dist/modules/actorTokenModule/actorToken.facade.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorToken.facade.js +123 -0
- package/dist/modules/actorTokenModule/actorToken.module.d.ts +3 -0
- package/dist/modules/actorTokenModule/actorToken.module.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorToken.module.js +41 -0
- package/dist/modules/actorTokenModule/actorToken.repository.d.ts +11 -0
- package/dist/modules/actorTokenModule/actorToken.repository.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorToken.repository.js +41 -0
- package/dist/modules/actorTokenModule/actorToken.service.d.ts +26 -0
- package/dist/modules/actorTokenModule/actorToken.service.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorToken.service.js +169 -0
- package/dist/modules/actorTokenModule/actorTokenState.entity.d.ts +31 -0
- package/dist/modules/actorTokenModule/actorTokenState.entity.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorTokenState.entity.js +77 -0
- package/dist/modules/actorTokenModule/actorTokenState.repository.d.ts +10 -0
- package/dist/modules/actorTokenModule/actorTokenState.repository.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/actorTokenState.repository.js +54 -0
- package/dist/modules/actorTokenModule/dto/actorToken.dto.d.ts +21 -0
- package/dist/modules/actorTokenModule/dto/actorToken.dto.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/dto/actorToken.dto.js +99 -0
- package/dist/modules/actorTokenModule/enum/EAccessPermission.enum.d.ts +6 -0
- package/dist/modules/actorTokenModule/enum/EAccessPermission.enum.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/enum/EAccessPermission.enum.js +9 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenPrefix.enum.d.ts +5 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenPrefix.enum.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenPrefix.enum.js +8 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenStatus.enum.d.ts +5 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenStatus.enum.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/enum/EActorTokenStatus.enum.js +8 -0
- package/dist/modules/actorTokenModule/enum/EActorType.enum.d.ts +11 -0
- package/dist/modules/actorTokenModule/enum/EActorType.enum.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/enum/EActorType.enum.js +17 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.d.ts +10 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.js +41 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.service.d.ts +10 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.service.d.ts.map +1 -0
- package/dist/modules/actorTokenModule/query/actorToken.query.service.js +47 -0
- package/dist/modules/authzModule/adapters/brokerResponse.adapter.d.ts +128 -0
- package/dist/modules/authzModule/adapters/brokerResponse.adapter.d.ts.map +1 -0
- package/dist/modules/authzModule/adapters/brokerResponse.adapter.js +103 -0
- package/dist/modules/authzModule/authz.facade.d.ts +18 -0
- package/dist/modules/authzModule/authz.facade.d.ts.map +1 -0
- package/dist/modules/authzModule/authz.facade.js +52 -0
- package/dist/modules/authzModule/authz.module.d.ts +3 -0
- package/dist/modules/authzModule/authz.module.d.ts.map +1 -0
- package/dist/modules/authzModule/authz.module.js +50 -0
- package/dist/modules/authzModule/authz.service.d.ts +34 -0
- package/dist/modules/authzModule/authz.service.d.ts.map +1 -0
- package/dist/modules/authzModule/authz.service.js +654 -0
- package/dist/modules/authzModule/dto/authz.dto.d.ts +99 -0
- package/dist/modules/authzModule/dto/authz.dto.d.ts.map +1 -0
- package/dist/modules/authzModule/dto/authz.dto.js +236 -0
- package/dist/modules/lobbyModule/dto/lobby.dto.d.ts +12 -0
- package/dist/modules/lobbyModule/dto/lobby.dto.d.ts.map +1 -0
- package/dist/modules/lobbyModule/dto/lobby.dto.js +79 -0
- package/dist/modules/lobbyModule/lobby.entity.d.ts +16 -0
- package/dist/modules/lobbyModule/lobby.entity.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobby.entity.js +79 -0
- package/dist/modules/lobbyModule/lobby.facade.d.ts +40 -0
- package/dist/modules/lobbyModule/lobby.facade.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobby.facade.js +199 -0
- package/dist/modules/lobbyModule/lobby.module.d.ts +3 -0
- package/dist/modules/lobbyModule/lobby.module.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobby.module.js +36 -0
- package/dist/modules/lobbyModule/lobby.repository.d.ts +9 -0
- package/dist/modules/lobbyModule/lobby.repository.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobby.repository.js +42 -0
- package/dist/modules/lobbyModule/lobby.service.d.ts +41 -0
- package/dist/modules/lobbyModule/lobby.service.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobby.service.js +159 -0
- package/dist/modules/lobbyModule/lobbyRoom.entity.d.ts +11 -0
- package/dist/modules/lobbyModule/lobbyRoom.entity.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobbyRoom.entity.js +52 -0
- package/dist/modules/lobbyModule/lobbyRoom.repository.d.ts +8 -0
- package/dist/modules/lobbyModule/lobbyRoom.repository.d.ts.map +1 -0
- package/dist/modules/lobbyModule/lobbyRoom.repository.js +36 -0
- package/dist/modules/lobbyModule/query/lobby.query.d.ts +7 -0
- package/dist/modules/lobbyModule/query/lobby.query.d.ts.map +1 -0
- package/dist/modules/lobbyModule/query/lobby.query.js +32 -0
- package/dist/modules/lobbyModule/query/lobby.query.service.d.ts +10 -0
- package/dist/modules/lobbyModule/query/lobby.query.service.d.ts.map +1 -0
- package/dist/modules/lobbyModule/query/lobby.query.service.js +42 -0
- package/dist/modules/platformAppModule/dto/platformApp.dto.d.ts +28 -0
- package/dist/modules/platformAppModule/dto/platformApp.dto.d.ts.map +1 -0
- package/dist/modules/platformAppModule/dto/platformApp.dto.js +180 -0
- package/dist/modules/platformAppModule/enum/EAppAccessMode.enum.d.ts +5 -0
- package/dist/modules/platformAppModule/enum/EAppAccessMode.enum.d.ts.map +1 -0
- package/dist/modules/platformAppModule/enum/EAppAccessMode.enum.js +8 -0
- package/dist/modules/platformAppModule/enum/EAppStatus.enum.d.ts +6 -0
- package/dist/modules/platformAppModule/enum/EAppStatus.enum.d.ts.map +1 -0
- package/dist/modules/platformAppModule/enum/EAppStatus.enum.js +9 -0
- package/dist/modules/platformAppModule/platformApp.entity.d.ts +32 -0
- package/dist/modules/platformAppModule/platformApp.entity.d.ts.map +1 -0
- package/dist/modules/platformAppModule/platformApp.entity.js +113 -0
- package/dist/modules/platformAppModule/platformApp.facade.d.ts +25 -0
- package/dist/modules/platformAppModule/platformApp.facade.d.ts.map +1 -0
- package/dist/modules/platformAppModule/platformApp.facade.js +188 -0
- package/dist/modules/platformAppModule/platformApp.module.d.ts +3 -0
- package/dist/modules/platformAppModule/platformApp.module.d.ts.map +1 -0
- package/dist/modules/platformAppModule/platformApp.module.js +29 -0
- package/dist/modules/platformAppModule/platformApp.repository.d.ts +10 -0
- package/dist/modules/platformAppModule/platformApp.repository.d.ts.map +1 -0
- package/dist/modules/platformAppModule/platformApp.repository.js +45 -0
- package/dist/modules/platformAppModule/query/platformApp.query.d.ts +9 -0
- package/dist/modules/platformAppModule/query/platformApp.query.d.ts.map +1 -0
- package/dist/modules/platformAppModule/query/platformApp.query.js +40 -0
- package/dist/modules/platformAppModule/query/platformApp.query.service.d.ts +10 -0
- package/dist/modules/platformAppModule/query/platformApp.query.service.d.ts.map +1 -0
- package/dist/modules/platformAppModule/query/platformApp.query.service.js +45 -0
- package/dist/modules/projectConfigModule/dto/projectConfig.dto.d.ts +116 -0
- package/dist/modules/projectConfigModule/dto/projectConfig.dto.d.ts.map +1 -0
- package/dist/modules/projectConfigModule/dto/projectConfig.dto.js +566 -0
- package/dist/modules/projectConfigModule/projectConfig.facade.d.ts +18 -0
- package/dist/modules/projectConfigModule/projectConfig.facade.d.ts.map +1 -0
- package/dist/modules/projectConfigModule/projectConfig.facade.js +71 -0
- package/dist/modules/projectConfigModule/projectConfig.module.d.ts +3 -0
- package/dist/modules/projectConfigModule/projectConfig.module.d.ts.map +1 -0
- package/dist/modules/projectConfigModule/projectConfig.module.js +23 -0
- package/dist/modules/projectConfigModule/projectConfig.service.d.ts +12 -0
- package/dist/modules/projectConfigModule/projectConfig.service.d.ts.map +1 -0
- package/dist/modules/projectConfigModule/projectConfig.service.js +411 -0
- package/dist/modules/projectModule/dto/project.dto.d.ts +15 -0
- package/dist/modules/projectModule/dto/project.dto.d.ts.map +1 -0
- package/dist/modules/projectModule/dto/project.dto.js +86 -0
- package/dist/modules/projectModule/project.entity.d.ts +14 -0
- package/dist/modules/projectModule/project.entity.d.ts.map +1 -0
- package/dist/modules/projectModule/project.entity.js +74 -0
- package/dist/modules/projectModule/project.facade.d.ts +27 -0
- package/dist/modules/projectModule/project.facade.d.ts.map +1 -0
- package/dist/modules/projectModule/project.facade.js +150 -0
- package/dist/modules/projectModule/project.module.d.ts +3 -0
- package/dist/modules/projectModule/project.module.d.ts.map +1 -0
- package/dist/modules/projectModule/project.module.js +25 -0
- package/dist/modules/projectModule/project.repository.d.ts +9 -0
- package/dist/modules/projectModule/project.repository.d.ts.map +1 -0
- package/dist/modules/projectModule/project.repository.js +42 -0
- package/dist/modules/projectModule/query/project.query.d.ts +7 -0
- package/dist/modules/projectModule/query/project.query.d.ts.map +1 -0
- package/dist/modules/projectModule/query/project.query.js +32 -0
- package/dist/modules/projectModule/query/project.query.service.d.ts +10 -0
- package/dist/modules/projectModule/query/project.query.service.d.ts.map +1 -0
- package/dist/modules/projectModule/query/project.query.service.js +43 -0
- package/dist/modules/roomModule/dto/room.dto.d.ts +17 -0
- package/dist/modules/roomModule/dto/room.dto.d.ts.map +1 -0
- package/dist/modules/roomModule/dto/room.dto.js +123 -0
- package/dist/modules/roomModule/dto/roomActorAccess.dto.d.ts +21 -0
- package/dist/modules/roomModule/dto/roomActorAccess.dto.d.ts.map +1 -0
- package/dist/modules/roomModule/dto/roomActorAccess.dto.js +135 -0
- package/dist/modules/roomModule/enum/ERoomStatus.enum.d.ts +5 -0
- package/dist/modules/roomModule/enum/ERoomStatus.enum.d.ts.map +1 -0
- package/dist/modules/roomModule/enum/ERoomStatus.enum.js +8 -0
- package/dist/modules/roomModule/query/room.query.d.ts +9 -0
- package/dist/modules/roomModule/query/room.query.d.ts.map +1 -0
- package/dist/modules/roomModule/query/room.query.js +40 -0
- package/dist/modules/roomModule/query/room.query.service.d.ts +10 -0
- package/dist/modules/roomModule/query/room.query.service.d.ts.map +1 -0
- package/dist/modules/roomModule/query/room.query.service.js +45 -0
- package/dist/modules/roomModule/room.entity.d.ts +17 -0
- package/dist/modules/roomModule/room.entity.d.ts.map +1 -0
- package/dist/modules/roomModule/room.entity.js +90 -0
- package/dist/modules/roomModule/room.facade.d.ts +30 -0
- package/dist/modules/roomModule/room.facade.d.ts.map +1 -0
- package/dist/modules/roomModule/room.facade.js +154 -0
- package/dist/modules/roomModule/room.module.d.ts +3 -0
- package/dist/modules/roomModule/room.module.d.ts.map +1 -0
- package/dist/modules/roomModule/room.module.js +39 -0
- package/dist/modules/roomModule/room.repository.d.ts +10 -0
- package/dist/modules/roomModule/room.repository.d.ts.map +1 -0
- package/dist/modules/roomModule/room.repository.js +48 -0
- package/dist/modules/roomModule/room.service.d.ts +26 -0
- package/dist/modules/roomModule/room.service.d.ts.map +1 -0
- package/dist/modules/roomModule/room.service.js +130 -0
- package/dist/modules/roomModule/roomActorAccess.entity.d.ts +22 -0
- package/dist/modules/roomModule/roomActorAccess.entity.d.ts.map +1 -0
- package/dist/modules/roomModule/roomActorAccess.entity.js +101 -0
- package/dist/modules/roomModule/roomActorAccess.facade.d.ts +20 -0
- package/dist/modules/roomModule/roomActorAccess.facade.d.ts.map +1 -0
- package/dist/modules/roomModule/roomActorAccess.facade.js +134 -0
- package/dist/modules/roomModule/roomActorAccess.repository.d.ts +15 -0
- package/dist/modules/roomModule/roomActorAccess.repository.d.ts.map +1 -0
- package/dist/modules/roomModule/roomActorAccess.repository.js +81 -0
- package/dist/modules/signingKeyModule/dto/signingKey.dto.d.ts +14 -0
- package/dist/modules/signingKeyModule/dto/signingKey.dto.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/dto/signingKey.dto.js +57 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyPrefix.enum.d.ts +5 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyPrefix.enum.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyPrefix.enum.js +8 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyStatus.enum.d.ts +5 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyStatus.enum.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/enum/ESigningKeyStatus.enum.js +8 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.d.ts +8 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.js +33 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.service.d.ts +10 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.service.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/query/signingKey.query.service.js +52 -0
- package/dist/modules/signingKeyModule/signingKey.entity.d.ts +16 -0
- package/dist/modules/signingKeyModule/signingKey.entity.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/signingKey.entity.js +85 -0
- package/dist/modules/signingKeyModule/signingKey.facade.d.ts +25 -0
- package/dist/modules/signingKeyModule/signingKey.facade.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/signingKey.facade.js +90 -0
- package/dist/modules/signingKeyModule/signingKey.module.d.ts +3 -0
- package/dist/modules/signingKeyModule/signingKey.module.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/signingKey.module.js +35 -0
- package/dist/modules/signingKeyModule/signingKey.repository.d.ts +11 -0
- package/dist/modules/signingKeyModule/signingKey.repository.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/signingKey.repository.js +39 -0
- package/dist/modules/signingKeyModule/signingKey.service.d.ts +40 -0
- package/dist/modules/signingKeyModule/signingKey.service.d.ts.map +1 -0
- package/dist/modules/signingKeyModule/signingKey.service.js +259 -0
- package/dist/schema.d.ts +19 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +33 -0
- package/dist/utils/clientToken.d.ts +2 -0
- package/dist/utils/clientToken.d.ts.map +1 -0
- package/dist/utils/clientToken.js +6 -0
- package/dist/utils/exceptions.d.ts +16 -0
- package/dist/utils/exceptions.d.ts.map +1 -0
- package/dist/utils/exceptions.js +24 -0
- package/dist/utils/guid.d.ts +4 -0
- package/dist/utils/guid.d.ts.map +1 -0
- package/dist/utils/guid.js +16 -0
- package/package.json +127 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
NoLag Core
|
|
2
|
+
Copyright 2026 NoLag
|
|
3
|
+
|
|
4
|
+
This product includes software developed at NoLag (https://nolag.app).
|
|
5
|
+
|
|
6
|
+
TRADEMARKS
|
|
7
|
+
|
|
8
|
+
The Apache License does not grant permission to use the trade names,
|
|
9
|
+
trademarks, service marks or product names of the licensor (section 6).
|
|
10
|
+
|
|
11
|
+
The NoLag name, the NoLag logotype and the isotype mark shipped in
|
|
12
|
+
ui/public/favicon.svg and ui/src/components/NolagMark.vue are trademarks of
|
|
13
|
+
NoLag and are not licensed under Apache 2.0. The code is yours to fork and
|
|
14
|
+
redistribute; the marks are not. If you run a modified version, please replace
|
|
15
|
+
them with your own, so that nobody is misled about who is responsible for
|
|
16
|
+
what they are running.
|
|
17
|
+
|
|
18
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
19
|
+
you may not use this file except in compliance with the License.
|
|
20
|
+
You may obtain a copy of the License at
|
|
21
|
+
|
|
22
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
23
|
+
|
|
24
|
+
Unless required by applicable law or agreed to in writing, software
|
|
25
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
26
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
27
|
+
See the License for the specific language governing permissions and
|
|
28
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# nolag-core
|
|
2
|
+
|
|
3
|
+
The authorization and configuration core of [NoLag](https://nolag.app), under Apache 2.0.
|
|
4
|
+
|
|
5
|
+
`nolag-core` answers one question: **may this actor touch this topic?**
|
|
6
|
+
|
|
7
|
+
It is a **library**, not a service. It owns projects, apps, rooms, lobbies, access scopes, actors,
|
|
8
|
+
tokens and signing keys, and it exposes facades that answer what a broker needs in order to accept a
|
|
9
|
+
connection and route a message. Nothing else.
|
|
10
|
+
|
|
11
|
+
There is no transport here, and no opinion about who is calling. Mounting it behind authentication is
|
|
12
|
+
the host's job: NoLag mounts these facades behind its own, and the example host in this repository
|
|
13
|
+
mounts them behind none. What core does keep is the authentication of **actors**, which is the
|
|
14
|
+
product: whether an access token is real, whether a client token was signed by the right key, and
|
|
15
|
+
what either may reach.
|
|
16
|
+
|
|
17
|
+
> **Status: early development.** Nothing is released yet, the schema and HTTP contract will change,
|
|
18
|
+
> and there is no stability guarantee. Do not run this in production.
|
|
19
|
+
|
|
20
|
+
## Why it exists
|
|
21
|
+
|
|
22
|
+
NoLag's data plane ([kraken](https://github.com/NoLagApp/kraken)) and every client SDK are already
|
|
23
|
+
open source. The piece missing from a self-hosted stack was the logic that decides who may do what.
|
|
24
|
+
This repository is that piece, so the whole system can be run without depending on NoLag's hosted
|
|
25
|
+
service.
|
|
26
|
+
|
|
27
|
+
Run your own broker, your own kraken, your own core, your own Postgres. NoLag runs the same container
|
|
28
|
+
image published from this repository. No fork, no separate proprietary build.
|
|
29
|
+
|
|
30
|
+
## Where it sits
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
clients (js, react-native, go, python SDKs)
|
|
34
|
+
|
|
|
35
|
+
kraken <- data plane, Apache 2.0
|
|
36
|
+
|
|
|
37
|
+
may this actor touch this topic?
|
|
38
|
+
|
|
|
39
|
+
┌─────────────────────────────────────────┐
|
|
40
|
+
│ your host: routing + your auth │ <- you write this, or use example/
|
|
41
|
+
│ ┌───────────────────────────────────┐ │
|
|
42
|
+
│ │ @nolag/core │ │ <- this repo, Apache 2.0
|
|
43
|
+
│ └───────────────────────────────────┘ │
|
|
44
|
+
└─────────────────────────────────────────┘
|
|
45
|
+
|
|
|
46
|
+
PostgreSQL
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
There is no external message broker in that picture, and none is required: kraken's default fan-out
|
|
50
|
+
is in-process, so a single node needs nothing but itself. Point it at MQTT instead when you want a
|
|
51
|
+
broker you already operate.
|
|
52
|
+
|
|
53
|
+
Kraken caches authorization decisions, so core is not in the path of every message. It is consulted
|
|
54
|
+
when a connection is established, periodically to confirm a session is still valid, and when an actor
|
|
55
|
+
subscribes to something it has not been granted yet.
|
|
56
|
+
|
|
57
|
+
## Mounting it
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { CoreModule, coreEntities, allCoreMigrations, AuthzFacade } from "@nolag/core";
|
|
61
|
+
|
|
62
|
+
@Module({
|
|
63
|
+
imports: [
|
|
64
|
+
TypeOrmModule.forRoot({
|
|
65
|
+
// Explicit arrays, not a glob. A glob relative to your own source will
|
|
66
|
+
// never reach node_modules, and core's tables would silently not exist.
|
|
67
|
+
entities: [...coreEntities, ...myEntities],
|
|
68
|
+
migrations: [...allCoreMigrations, ...myMigrations],
|
|
69
|
+
}),
|
|
70
|
+
CoreModule.forRoot({ signingKeyEncryptionKey: process.env.SIGNING_KEY }),
|
|
71
|
+
],
|
|
72
|
+
})
|
|
73
|
+
export class MyHostModule {}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Core binds to TypeORM's **default** connection. It does not open one of its own,
|
|
77
|
+
so its tables have to be on the DataSource you already have. If your host owns
|
|
78
|
+
entity classes for these same tables, register both: TypeORM maps two classes to
|
|
79
|
+
one table without complaint, and a write through one class only touches the
|
|
80
|
+
columns that class declares.
|
|
81
|
+
|
|
82
|
+
Then inject `AuthzFacade` behind whatever authentication you already have.
|
|
83
|
+
|
|
84
|
+
## The contract
|
|
85
|
+
|
|
86
|
+
Four questions the broker asks, and the facade methods that answer them:
|
|
87
|
+
|
|
88
|
+
| Broker calls | Facade |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| on connect | `validateActor(accessToken)` |
|
|
91
|
+
| periodically, for a live session | `revalidateActor(actorTokenId)` |
|
|
92
|
+
| on a subscribe it has not cached | `checkRoomAccess(actorTokenId, pattern)` |
|
|
93
|
+
| on subscribe and unsubscribe | `updateSubscription(...)` |
|
|
94
|
+
|
|
95
|
+
Responses must go through the exported `toBroker*` adapters rather than serialising a DTO. That file
|
|
96
|
+
is the wire contract, and routing everything through it is what stops a field rename from silently
|
|
97
|
+
changing what every deployed broker receives.
|
|
98
|
+
|
|
99
|
+
Plus configuration facades for project, app, room, lobby, access scope, actor token and signing key,
|
|
100
|
+
and whole-project export and import, so state can be moved in and out without a database dump.
|
|
101
|
+
|
|
102
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the resolution model, the topic addressing scheme
|
|
103
|
+
and the schema.
|
|
104
|
+
|
|
105
|
+
## What it is not
|
|
106
|
+
|
|
107
|
+
Deliberately absent, and staying absent:
|
|
108
|
+
|
|
109
|
+
- billing, plans, subscriptions, metering, usage aggregation
|
|
110
|
+
- organizations, users, teams, invitations
|
|
111
|
+
- broker fleet management, version registries, upgrade orchestration
|
|
112
|
+
- NoLag's hosted portal and app builder
|
|
113
|
+
- **any authentication of its callers**, which is the host's job
|
|
114
|
+
|
|
115
|
+
The repository ships an example host and a small admin UI over it, both covered below. Neither is the
|
|
116
|
+
NoLag portal, and neither is meant for production.
|
|
117
|
+
|
|
118
|
+
Core enforces limits it is given as plain numbers. It has no concept of what they cost or where they
|
|
119
|
+
came from. Anything that only exists because someone runs this as a commercial service lives outside
|
|
120
|
+
this repository.
|
|
121
|
+
|
|
122
|
+
## Trying it
|
|
123
|
+
|
|
124
|
+
The compose stack exists so you can see the whole system working in a few minutes on your own
|
|
125
|
+
machine. **It is not a production deployment**, and it is not trying to be one. See
|
|
126
|
+
[what it is not](#what-the-quickstart-is-not) before you point anything real at it.
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
./quickstart/quickstart.sh
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
That generates `.env`, brings up Postgres, core, kraken and the admin UI, and imports a demo project.
|
|
133
|
+
The first run compiles kraken from source, which takes a few minutes; after that it is seconds.
|
|
134
|
+
|
|
135
|
+
When it finishes:
|
|
136
|
+
|
|
137
|
+
| | |
|
|
138
|
+
| --- | --- |
|
|
139
|
+
| Admin UI | http://localhost:3401 |
|
|
140
|
+
| Core API | http://localhost:3400, with OpenAPI at `/swagger` |
|
|
141
|
+
| Broker | ws://localhost:8410/ws |
|
|
142
|
+
|
|
143
|
+
The demo project's access tokens are written to `quickstart/credentials.json`. They are shown once,
|
|
144
|
+
because core stores only their hashes.
|
|
145
|
+
|
|
146
|
+
Nothing asks you for a credential, because the example host authenticates nobody. Every published
|
|
147
|
+
port binds to `127.0.0.1` for exactly that reason.
|
|
148
|
+
|
|
149
|
+
Connecting is then the same as against hosted NoLag:
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
import { NoLag } from "@nolag/js-sdk";
|
|
153
|
+
|
|
154
|
+
const client = NoLag(accessToken, { url: "ws://localhost:8410/ws" });
|
|
155
|
+
await client.connect();
|
|
156
|
+
client.subscribe("chat/general/messages");
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Stop with `docker compose down`, or `docker compose down -v` to discard the data too.
|
|
160
|
+
|
|
161
|
+
### The example host
|
|
162
|
+
|
|
163
|
+
`example/` is the shortest host that does anything useful: it owns the DataSource, mounts
|
|
164
|
+
`CoreModule`, and exposes the facades through thin controllers. About two hundred lines, and worth
|
|
165
|
+
reading before you write your own.
|
|
166
|
+
|
|
167
|
+
It installs `@nolag/core` from a packed tarball rather than compiling it alongside, so a missing
|
|
168
|
+
export or peer fails the build there instead of quietly working.
|
|
169
|
+
|
|
170
|
+
**It authenticates nobody**, and says so at every boot. That is not an omission: core has no opinion
|
|
171
|
+
about who may call it, and an example with a token check is an example people copy into production.
|
|
172
|
+
|
|
173
|
+
### The admin UI
|
|
174
|
+
|
|
175
|
+
A small browser surface over the example host: list projects, read one, create one from a
|
|
176
|
+
configuration document, and delete one.
|
|
177
|
+
|
|
178
|
+
**Do not expose it, or the host it talks to.** Anyone who reaches either can read and destroy every
|
|
179
|
+
project and mint credentials for any of them. Set `CORS_ORIGINS` if you serve the UI from somewhere
|
|
180
|
+
other than the compose default; `*` is rejected rather than honoured.
|
|
181
|
+
|
|
182
|
+
### Without any of it
|
|
183
|
+
|
|
184
|
+
The library is the deliverable. Drop `example/`, `ui/` and the compose file entirely, write your own
|
|
185
|
+
host, and nothing about the authorization path changes.
|
|
186
|
+
|
|
187
|
+
### What the quickstart is not
|
|
188
|
+
|
|
189
|
+
It is a demonstration, not a deployment. Everything below is a deliberate omission, not an oversight,
|
|
190
|
+
and the list is here so nobody has to discover them the hard way:
|
|
191
|
+
|
|
192
|
+
- **No authentication at all** on the example host, and **no TLS anywhere**. Everything is plaintext
|
|
193
|
+
HTTP over loopback. Reaching the port is the same as owning every project behind it.
|
|
194
|
+
- **Secrets sit in a plaintext `.env`** that the script generates and chmods to 600. That is not
|
|
195
|
+
secret management.
|
|
196
|
+
- **Postgres runs in a container** with a local volume and no backups, no replication and no tuning.
|
|
197
|
+
- **One node.** No clustering, no failover, no horizontal scale. Kraken's in-process fan-out means a
|
|
198
|
+
restart drops every connection.
|
|
199
|
+
- **Message history is off**, and the store is in-memory. Anything kraken did record would die with
|
|
200
|
+
the container.
|
|
201
|
+
- **The admin UI has no accounts and no login**, because the host behind it has none either.
|
|
202
|
+
|
|
203
|
+
The part worth keeping in a real deployment is the library and the shape of the wiring: the host owns
|
|
204
|
+
the DataSource, passes core's entities and migrations into it, and mounts the facades behind real
|
|
205
|
+
authentication. The rest belongs to whatever you already use to run things.
|
|
206
|
+
|
|
207
|
+
## Verifying a deployment
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
docker compose up -d --wait
|
|
211
|
+
npm run test:stack
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
19 tests drive the running stack with a real `@nolag/js-sdk` client: authentication, a pub/sub round
|
|
215
|
+
trip, restricted apps, private rooms, and isolation between two tenants.
|
|
216
|
+
|
|
217
|
+
The library has its own suites, which need Postgres but not the whole stack:
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
./scripts/test-db.sh # create and migrate the test database
|
|
221
|
+
npm test # unit
|
|
222
|
+
npm run test:e2e # against real Postgres
|
|
223
|
+
npm run test:package # pack, install into a scratch project, boot it
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`test:package` is the one that catches what nothing else can. Everything else tests the source; that
|
|
227
|
+
one tests the artefact, the way a consumer gets it. A NestJS library can compile, pass every test, and
|
|
228
|
+
still be broken on install: a peer shipped as a dependency gives the consumer two copies of TypeORM
|
|
229
|
+
and two metadata registries, a `files` omission makes an import resolve to nothing, and neither is
|
|
230
|
+
visible from inside the repository.
|
|
231
|
+
|
|
232
|
+
The suite starts by checking that a token core never issued is refused. Kraken's default auth backend
|
|
233
|
+
is a static token file with an allow-all switch, and a stack wired that way accepts everything, so a
|
|
234
|
+
happy-path test would pass green while proving nothing. If that first check fails, every test in the
|
|
235
|
+
file fails with the reason rather than reporting a mostly-passing run.
|
|
236
|
+
|
|
237
|
+
## Licence
|
|
238
|
+
|
|
239
|
+
Apache License 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
240
|
+
|
|
241
|
+
## Contributing
|
|
242
|
+
|
|
243
|
+
Issues are welcome; code contributions are not accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) for
|
|
244
|
+
why, and for what that does and does not mean for the licence on the code you already have.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseEntity } from "typeorm";
|
|
2
|
+
export interface IBaseTimeEntity {
|
|
3
|
+
createdAt: Date;
|
|
4
|
+
updatedAt: Date;
|
|
5
|
+
deletedAt?: Date | null;
|
|
6
|
+
}
|
|
7
|
+
export declare abstract class BaseTimeEntity extends BaseEntity implements IBaseTimeEntity {
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
deletedAt?: Date | null;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=base.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.entity.d.ts","sourceRoot":"","sources":["../../../src/common/entities/base.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIX,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,8BAAsB,cACpB,SAAQ,UACR,YAAW,eAAe;IAI1B,SAAS,EAAG,IAAI,CAAC;IAIjB,SAAS,EAAG,IAAI,CAAC;IAIjB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BaseTimeEntity = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
class BaseTimeEntity extends typeorm_1.BaseEntity {
|
|
15
|
+
createdAt;
|
|
16
|
+
updatedAt;
|
|
17
|
+
deletedAt;
|
|
18
|
+
}
|
|
19
|
+
exports.BaseTimeEntity = BaseTimeEntity;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, typeorm_1.CreateDateColumn)({ name: "created_at", type: "timestamptz" }),
|
|
22
|
+
__metadata("design:type", Date)
|
|
23
|
+
], BaseTimeEntity.prototype, "createdAt", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, typeorm_1.UpdateDateColumn)({ name: "updated_at", type: "timestamptz" }),
|
|
26
|
+
__metadata("design:type", Date)
|
|
27
|
+
], BaseTimeEntity.prototype, "updatedAt", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, typeorm_1.DeleteDateColumn)({ name: "deleted_at", type: "timestamptz", nullable: true }),
|
|
30
|
+
__metadata("design:type", Object)
|
|
31
|
+
], BaseTimeEntity.prototype, "deletedAt", void 0);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Logger } from "@nestjs/common";
|
|
2
|
+
import type { FindOptionsOrder, FindOptionsWhere, ObjectLiteral, SelectQueryBuilder } from "typeorm";
|
|
3
|
+
export interface PaginatedResult<T> {
|
|
4
|
+
data: T[];
|
|
5
|
+
pagination: {
|
|
6
|
+
total: number;
|
|
7
|
+
page: number;
|
|
8
|
+
pageCount: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface QueryOptions {
|
|
12
|
+
allRecords?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare enum DefaultPagination {
|
|
15
|
+
Page = "1",
|
|
16
|
+
Limit = "10"
|
|
17
|
+
}
|
|
18
|
+
export interface IBaseQuery<T extends ObjectLiteral> {
|
|
19
|
+
page?: string;
|
|
20
|
+
limit?: string;
|
|
21
|
+
order?: FindOptionsOrder<T>;
|
|
22
|
+
}
|
|
23
|
+
export declare abstract class BaseQuery<T> {
|
|
24
|
+
page: string;
|
|
25
|
+
limit: string;
|
|
26
|
+
orderBy?: string[];
|
|
27
|
+
get order(): FindOptionsOrder<T> | undefined;
|
|
28
|
+
get queryParams(): FindOptionsWhere<T>;
|
|
29
|
+
}
|
|
30
|
+
export declare class BasePaginationService {
|
|
31
|
+
protected readonly logger: Logger;
|
|
32
|
+
paginate<T extends ObjectLiteral>(qb: SelectQueryBuilder<T>, query: IBaseQuery<T>, options?: QueryOptions): Promise<PaginatedResult<T>>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/common/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAajB,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAE3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,oBAAY,iBAAiB;IAC3B,IAAI,MAAM;IACV,KAAK,OAAO;CACb;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,aAAa;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAC7B;AAED,8BAAsB,SAAS,CAAC,CAAC;IAG/B,IAAI,EAAE,MAAM,CAA0B;IAItC,KAAK,EAAE,MAAM,CAA2B;IAMxC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,IAAI,KAAK,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAK3C;IAED,IAAI,WAAW,IAAI,gBAAgB,CAAC,CAAC,CAAC,CASrC;CACF;AAED,qBAAa,qBAAqB;IAChC,SAAS,CAAC,QAAQ,CAAC,MAAM,SAA0C;IAE7D,QAAQ,CAAC,CAAC,SAAS,aAAa,EACpC,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACzB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CA6D/B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BasePaginationService = exports.BaseQuery = exports.DefaultPagination = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
var DefaultPagination;
|
|
16
|
+
(function (DefaultPagination) {
|
|
17
|
+
DefaultPagination["Page"] = "1";
|
|
18
|
+
DefaultPagination["Limit"] = "10";
|
|
19
|
+
})(DefaultPagination || (exports.DefaultPagination = DefaultPagination = {}));
|
|
20
|
+
class BaseQuery {
|
|
21
|
+
page = DefaultPagination.Page;
|
|
22
|
+
limit = DefaultPagination.Limit;
|
|
23
|
+
orderBy;
|
|
24
|
+
get order() {
|
|
25
|
+
if (!this.orderBy)
|
|
26
|
+
return undefined;
|
|
27
|
+
return Object.fromEntries(this.orderBy.map((i) => i.split(":")));
|
|
28
|
+
}
|
|
29
|
+
get queryParams() {
|
|
30
|
+
const query = {};
|
|
31
|
+
Object.keys(this).forEach((key) => {
|
|
32
|
+
const value = this[key];
|
|
33
|
+
if (!["page", "limit", "order", "orderBy"].includes(key) && value) {
|
|
34
|
+
query[key] = value;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return query;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.BaseQuery = BaseQuery;
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, class_validator_1.IsString)(),
|
|
43
|
+
(0, class_validator_1.IsOptional)(),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], BaseQuery.prototype, "page", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, class_validator_1.IsString)(),
|
|
48
|
+
(0, class_validator_1.IsOptional)(),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], BaseQuery.prototype, "limit", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, class_validator_1.IsOptional)(),
|
|
53
|
+
(0, class_validator_1.IsArray)(),
|
|
54
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
55
|
+
__metadata("design:type", Array)
|
|
56
|
+
], BaseQuery.prototype, "orderBy", void 0);
|
|
57
|
+
class BasePaginationService {
|
|
58
|
+
logger = new common_1.Logger(BasePaginationService.name);
|
|
59
|
+
async paginate(qb, query, options) {
|
|
60
|
+
const page = Number(query.page) || 1;
|
|
61
|
+
const rawLimit = Number(query.limit) || 10;
|
|
62
|
+
const limit = Math.min(Math.max(rawLimit, 1), 100);
|
|
63
|
+
const alias = qb.alias;
|
|
64
|
+
if (!options?.allRecords) {
|
|
65
|
+
qb.skip((page - 1) * limit).take(limit);
|
|
66
|
+
}
|
|
67
|
+
if (query.order) {
|
|
68
|
+
const metadata = qb.expressionMap.mainAlias?.metadata;
|
|
69
|
+
if (metadata) {
|
|
70
|
+
const validColumns = new Set(metadata.columns.map((col) => col.propertyName));
|
|
71
|
+
for (const [field, direction] of Object.entries(query.order)) {
|
|
72
|
+
if (!validColumns.has(field)) {
|
|
73
|
+
this.logger.error(`Invalid sort field "${field}" on ${metadata.name}. ` +
|
|
74
|
+
`Valid: ${Array.from(validColumns).join(", ")}`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const normalized = String(direction).toUpperCase();
|
|
78
|
+
if (normalized !== "ASC" && normalized !== "DESC") {
|
|
79
|
+
this.logger.error(`Invalid sort direction "${direction}" for "${field}".`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
qb.addOrderBy(`${alias}.${field}`, normalized);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.logger.warn("Entity metadata unavailable. Skipping ORDER BY for safety.");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const [data, total] = await qb.getManyAndCount();
|
|
90
|
+
return {
|
|
91
|
+
data,
|
|
92
|
+
pagination: {
|
|
93
|
+
total,
|
|
94
|
+
page,
|
|
95
|
+
pageCount: Math.ceil(total / limit),
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.BasePaginationService = BasePaginationService;
|