@twin.org/api-tenant-processor 0.0.3-next.39 → 0.0.3-next.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/entities/tenant.js +0 -8
- package/dist/es/entities/tenant.js.map +1 -1
- package/dist/es/index.js +3 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/ITenantServiceConfig.js +4 -0
- package/dist/es/models/ITenantServiceConfig.js.map +1 -0
- package/dist/es/models/ITenantServiceConstructorOptions.js +2 -0
- package/dist/es/models/ITenantServiceConstructorOptions.js.map +1 -0
- package/dist/es/models/api/ITenantListRequest.js.map +1 -1
- package/dist/es/tenantAdminService.js +5 -17
- package/dist/es/tenantAdminService.js.map +1 -1
- package/dist/es/tenantRoutes.js +9 -11
- package/dist/es/tenantRoutes.js.map +1 -1
- package/dist/es/tenantService.js +51 -0
- package/dist/es/tenantService.js.map +1 -0
- package/dist/types/entities/tenant.d.ts +0 -4
- package/dist/types/index.d.ts +3 -0
- package/dist/types/models/ITenantServiceConfig.d.ts +5 -0
- package/dist/types/models/ITenantServiceConstructorOptions.d.ts +15 -0
- package/dist/types/models/api/ITenantListRequest.d.ts +5 -0
- package/dist/types/tenantAdminService.d.ts +4 -7
- package/dist/types/tenantRoutes.d.ts +1 -1
- package/dist/types/tenantService.d.ts +27 -0
- package/docs/changelog.md +14 -0
- package/docs/reference/classes/Tenant.md +0 -8
- package/docs/reference/classes/TenantAdminService.md +5 -9
- package/docs/reference/classes/TenantService.md +79 -0
- package/docs/reference/index.md +3 -0
- package/docs/reference/interfaces/ITenantListRequest.md +7 -0
- package/docs/reference/interfaces/ITenantServiceConfig.md +3 -0
- package/docs/reference/interfaces/ITenantServiceConstructorOptions.md +25 -0
- package/package.json +2 -2
|
@@ -29,10 +29,6 @@ let Tenant = class Tenant {
|
|
|
29
29
|
* The origin available to the public for accessing the API.
|
|
30
30
|
*/
|
|
31
31
|
publicOrigin;
|
|
32
|
-
/**
|
|
33
|
-
* Indicates whether the tenant is the node tenant.
|
|
34
|
-
*/
|
|
35
|
-
isNodeTenant;
|
|
36
32
|
};
|
|
37
33
|
__decorate([
|
|
38
34
|
property({ type: "string", isPrimary: true }),
|
|
@@ -58,10 +54,6 @@ __decorate([
|
|
|
58
54
|
property({ type: "string", optional: true, isSecondary: true }),
|
|
59
55
|
__metadata("design:type", String)
|
|
60
56
|
], Tenant.prototype, "publicOrigin", void 0);
|
|
61
|
-
__decorate([
|
|
62
|
-
property({ type: "boolean" }),
|
|
63
|
-
__metadata("design:type", Boolean)
|
|
64
|
-
], Tenant.prototype, "isNodeTenant", void 0);
|
|
65
57
|
Tenant = __decorate([
|
|
66
58
|
entity()
|
|
67
59
|
], Tenant);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../../src/entities/tenant.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAM;IAClB;;OAEG;IAEI,EAAE,CAAU;IAEnB;;OAEG;IAEI,MAAM,CAAU;IAEvB;;OAEG;IAEI,KAAK,CAAU;IAEtB;;OAEG;IAEI,WAAW,CAAU;IAE5B;;OAEG;IAEI,YAAY,CAAU;IAE7B;;OAEG;IAEI,YAAY,CAAU;
|
|
1
|
+
{"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../../src/entities/tenant.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAM;IAClB;;OAEG;IAEI,EAAE,CAAU;IAEnB;;OAEG;IAEI,MAAM,CAAU;IAEvB;;OAEG;IAEI,KAAK,CAAU;IAEtB;;OAEG;IAEI,WAAW,CAAU;IAE5B;;OAEG;IAEI,YAAY,CAAU;IAE7B;;OAEG;IAEI,YAAY,CAAU;CAC7B,CAAA;AA/BO;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;;kCAC3B;AAMZ;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;;sCACzB;AAMhB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;qCACP;AAMf;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;2CACD;AAMrB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;4CACA;AAMtB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;;4CACnC;AAnCjB,MAAM;IADlB,MAAM,EAAE;GACI,MAAM,CAoClB","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { entity, property } from \"@twin.org/entity\";\n\n/**\n * Class defining the storage for node tenants.\n */\n@entity()\nexport class Tenant {\n\t/**\n\t * The unique identifier for the tenant.\n\t */\n\t@property({ type: \"string\", isPrimary: true })\n\tpublic id!: string;\n\n\t/**\n\t * The api key for the tenant.\n\t */\n\t@property({ type: \"string\", isSecondary: true })\n\tpublic apiKey!: string;\n\n\t/**\n\t * The label of the tenant.\n\t */\n\t@property({ type: \"string\" })\n\tpublic label!: string;\n\n\t/**\n\t * The date the tenant was created.\n\t */\n\t@property({ type: \"string\" })\n\tpublic dateCreated!: string;\n\n\t/**\n\t * The date the tenant was modified.\n\t */\n\t@property({ type: \"string\" })\n\tpublic dateModified!: string;\n\n\t/**\n\t * The origin available to the public for accessing the API.\n\t */\n\t@property({ type: \"string\", optional: true, isSecondary: true })\n\tpublic publicOrigin?: string;\n}\n"]}
|
package/dist/es/index.js
CHANGED
|
@@ -14,10 +14,13 @@ export * from "./models/ITenantAdminServiceConfig.js";
|
|
|
14
14
|
export * from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
15
15
|
export * from "./models/ITenantProcessorConfig.js";
|
|
16
16
|
export * from "./models/ITenantProcessorConstructorOptions.js";
|
|
17
|
+
export * from "./models/ITenantServiceConfig.js";
|
|
18
|
+
export * from "./models/ITenantServiceConstructorOptions.js";
|
|
17
19
|
export * from "./schema.js";
|
|
18
20
|
export * from "./tenantAdminService.js";
|
|
19
21
|
export * from "./tenantIdContextIdHandler.js";
|
|
20
22
|
export * from "./tenantProcessor.js";
|
|
21
23
|
export * from "./tenantRoutes.js";
|
|
24
|
+
export * from "./tenantService.js";
|
|
22
25
|
export * from "./utils/tenantIdHelper.js";
|
|
23
26
|
//# sourceMappingURL=index.js.map
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uCAAuC,CAAC;AACtD,cAAc,iDAAiD,CAAC;AAChE,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./entities/tenant.js\";\nexport * from \"./models/api/ITenantCreateRequest.js\";\nexport * from \"./models/api/ITenantGetByApiKeyRequest.js\";\nexport * from \"./models/api/ITenantGetByIdRequest.js\";\nexport * from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nexport * from \"./models/api/ITenantGetResponse.js\";\nexport * from \"./models/api/ITenantListRequest.js\";\nexport * from \"./models/api/ITenantListResponse.js\";\nexport * from \"./models/api/ITenantRemoveRequest.js\";\nexport * from \"./models/api/ITenantUpdateRequest.js\";\nexport * from \"./models/ITenantAdminServiceConfig.js\";\nexport * from \"./models/ITenantAdminServiceConstructorOptions.js\";\nexport * from \"./models/ITenantProcessorConfig.js\";\nexport * from \"./models/ITenantProcessorConstructorOptions.js\";\nexport * from \"./schema.js\";\nexport * from \"./tenantAdminService.js\";\nexport * from \"./tenantIdContextIdHandler.js\";\nexport * from \"./tenantProcessor.js\";\nexport * from \"./tenantRoutes.js\";\nexport * from \"./utils/tenantIdHelper.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uCAAuC,CAAC;AACtD,cAAc,iDAAiD,CAAC;AAChE,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,kCAAkC,CAAC;AACjD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2025 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./entities/tenant.js\";\nexport * from \"./models/api/ITenantCreateRequest.js\";\nexport * from \"./models/api/ITenantGetByApiKeyRequest.js\";\nexport * from \"./models/api/ITenantGetByIdRequest.js\";\nexport * from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nexport * from \"./models/api/ITenantGetResponse.js\";\nexport * from \"./models/api/ITenantListRequest.js\";\nexport * from \"./models/api/ITenantListResponse.js\";\nexport * from \"./models/api/ITenantRemoveRequest.js\";\nexport * from \"./models/api/ITenantUpdateRequest.js\";\nexport * from \"./models/ITenantAdminServiceConfig.js\";\nexport * from \"./models/ITenantAdminServiceConstructorOptions.js\";\nexport * from \"./models/ITenantProcessorConfig.js\";\nexport * from \"./models/ITenantProcessorConstructorOptions.js\";\nexport * from \"./models/ITenantServiceConfig.js\";\nexport * from \"./models/ITenantServiceConstructorOptions.js\";\nexport * from \"./schema.js\";\nexport * from \"./tenantAdminService.js\";\nexport * from \"./tenantIdContextIdHandler.js\";\nexport * from \"./tenantProcessor.js\";\nexport * from \"./tenantRoutes.js\";\nexport * from \"./tenantService.js\";\nexport * from \"./utils/tenantIdHelper.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITenantServiceConfig.js","sourceRoot":"","sources":["../../../src/models/ITenantServiceConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the tenant service\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface ITenantServiceConfig {}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ITenantServiceConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/ITenantServiceConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantServiceConfig } from \"./ITenantServiceConfig.js\";\n\n/**\n * Options for the Tenant Service constructor.\n */\nexport interface ITenantServiceConstructorOptions {\n\t/**\n\t * The entity storage for the tenants.\n\t * @default tenant\n\t */\n\ttenantEntityStorageType?: string;\n\n\t/**\n\t * Configuration for the service.\n\t */\n\tconfig?: ITenantServiceConfig;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ITenantListRequest.js","sourceRoot":"","sources":["../../../../src/models/api/ITenantListRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The list of tenants.\n */\nexport interface ITenantListRequest {\n\t/**\n\t * The query parameters.\n\t */\n\tquery: {\n\t\t/**\n\t\t * The cursor to get the next chunk of tenants.\n\t\t */\n\t\tcursor?: string;\n\n\t\t/**\n\t\t * The number of tenants to return.\n\t\t */\n\t\tlimit?: string;\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ITenantListRequest.js","sourceRoot":"","sources":["../../../../src/models/api/ITenantListRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * The list of tenants.\n */\nexport interface ITenantListRequest {\n\t/**\n\t * The query parameters.\n\t */\n\tquery: {\n\t\t/**\n\t\t * The properties to include in the returned tenants, separated by commas.\n\t\t * If not provided, all properties will be returned.\n\t\t */\n\t\tproperties?: string;\n\n\t\t/**\n\t\t * The cursor to get the next chunk of tenants.\n\t\t */\n\t\tcursor?: string;\n\n\t\t/**\n\t\t * The number of tenants to return.\n\t\t */\n\t\tlimit?: string;\n\t};\n}\n"]}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { GeneralError, Guards, Is,
|
|
2
|
-
import { ComparisonOperator } from "@twin.org/entity";
|
|
1
|
+
import { GeneralError, Guards, Is, NotFoundError, Url } from "@twin.org/core";
|
|
3
2
|
import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
|
|
4
3
|
import { Tenant } from "./entities/tenant.js";
|
|
5
4
|
import { TenantIdHelper } from "./utils/tenantIdHelper.js";
|
|
6
5
|
/**
|
|
7
|
-
* Service for performing
|
|
6
|
+
* Service for performing tenant administration operations.
|
|
8
7
|
*/
|
|
9
8
|
export class TenantAdminService {
|
|
10
9
|
/**
|
|
@@ -117,7 +116,6 @@ export class TenantAdminService {
|
|
|
117
116
|
tenantEntity.dateModified = tenantEntity.dateCreated;
|
|
118
117
|
tenantEntity.label = tenant.label;
|
|
119
118
|
tenantEntity.publicOrigin = publicOrigin;
|
|
120
|
-
tenantEntity.isNodeTenant = tenant.isNodeTenant;
|
|
121
119
|
await this._entityStorageConnector.set(tenantEntity);
|
|
122
120
|
return tenantEntity.id;
|
|
123
121
|
}
|
|
@@ -156,7 +154,6 @@ export class TenantAdminService {
|
|
|
156
154
|
tenantEntity.dateModified = new Date(Date.now()).toISOString();
|
|
157
155
|
tenantEntity.label = tenant.label ?? currentTenant.label;
|
|
158
156
|
tenantEntity.publicOrigin = publicOrigin ?? currentTenant.publicOrigin;
|
|
159
|
-
tenantEntity.isNodeTenant = tenant.isNodeTenant ?? currentTenant.isNodeTenant;
|
|
160
157
|
await this._entityStorageConnector.set(tenantEntity);
|
|
161
158
|
}
|
|
162
159
|
/**
|
|
@@ -170,22 +167,13 @@ export class TenantAdminService {
|
|
|
170
167
|
}
|
|
171
168
|
/**
|
|
172
169
|
* Query tenants with pagination.
|
|
173
|
-
* @param
|
|
174
|
-
* @param options.isNodeTenant Whether to filter for node admin tenants.
|
|
170
|
+
* @param properties The properties to include in the returned tenants.
|
|
175
171
|
* @param cursor The cursor to start from.
|
|
176
172
|
* @param limit The maximum number of tenants to return.
|
|
177
173
|
* @returns The tenants and the next cursor if more tenants are available.
|
|
178
174
|
*/
|
|
179
|
-
async query(
|
|
180
|
-
const
|
|
181
|
-
if (Is.boolean(options?.isNodeTenant)) {
|
|
182
|
-
conditions.push({
|
|
183
|
-
property: "isNodeTenant",
|
|
184
|
-
value: options.isNodeTenant,
|
|
185
|
-
comparison: ComparisonOperator.Equals
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
const result = await this._entityStorageConnector.query(conditions.length > 0 ? { conditions } : undefined, undefined, undefined, cursor, limit);
|
|
175
|
+
async query(properties, cursor, limit) {
|
|
176
|
+
const result = await this._entityStorageConnector.query(undefined, undefined, properties, cursor, limit);
|
|
189
177
|
return {
|
|
190
178
|
tenants: result.entities,
|
|
191
179
|
cursor: result.cursor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantAdminService.js","sourceRoot":"","sources":["../../src/tenantAdminService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantAdminComponent, ITenant } from \"@twin.org/api-models\";\nimport { GeneralError, Guards, Is, Url, NotFoundError } from \"@twin.org/core\";\nimport { ComparisonOperator } from \"@twin.org/entity\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { Tenant } from \"./entities/tenant.js\";\nimport type { ITenantAdminServiceConstructorOptions } from \"./models/ITenantAdminServiceConstructorOptions.js\";\nimport { TenantIdHelper } from \"./utils/tenantIdHelper.js\";\n\n/**\n * Service for performing email messaging operations to a connector.\n */\nexport class TenantAdminService implements ITenantAdminComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantAdminService>();\n\n\t/**\n\t * Entity storage connector used by the service.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\n\n\t/**\n\t * Create a new instance of TenantAdminService.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options?: ITenantAdminServiceConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn TenantAdminService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async get(tenantId: string): Promise<ITenant> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(tenantId);\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", tenantId);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its api key.\n\t * @param apiKey The api key of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async getByApiKey(apiKey: string): Promise<ITenant> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(apiKey), apiKey, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(apiKey, \"apiKey\");\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", apiKey);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its public origin.\n\t * @param publicOrigin The origin of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async getByPublicOrigin(publicOrigin: string): Promise<ITenant> {\n\t\tGuards.stringValue(TenantAdminService.CLASS_NAME, nameof(publicOrigin), publicOrigin);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(publicOrigin, \"publicOrigin\");\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", publicOrigin);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Create a tenant.\n\t * @param tenant The tenant to store.\n\t * @returns The tenant id.\n\t */\n\tpublic async create(\n\t\ttenant: Omit<ITenant, \"id\" | \"dateCreated\" | \"dateModified\"> & { id?: string }\n\t): Promise<string> {\n\t\tGuards.objectValue<ITenant>(TenantAdminService.CLASS_NAME, nameof(tenant), tenant);\n\t\tif (Is.stringValue(tenant.id)) {\n\t\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.id), tenant.id, 32);\n\t\t}\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tGuards.stringHexLength(\n\t\t\t\tTenantAdminService.CLASS_NAME,\n\t\t\t\tnameof(tenant.apiKey),\n\t\t\t\ttenant.apiKey,\n\t\t\t\t32\n\t\t\t);\n\t\t}\n\n\t\tlet publicOrigin: string | undefined;\n\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\tUrl.guard(TenantAdminService.CLASS_NAME, nameof(tenant.publicOrigin), tenant.publicOrigin);\n\n\t\t\tconst url = new Url(tenant.publicOrigin);\n\t\t\tconst parts = url.parts();\n\t\t\tpublicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : \"\"}`;\n\t\t}\n\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tconst existingApiKey = await this._entityStorageConnector.get(tenant.apiKey, \"apiKey\");\n\t\t\tif (Is.object(existingApiKey) && existingApiKey.id !== tenant.id) {\n\t\t\t\tthrow new GeneralError(TenantAdminService.CLASS_NAME, \"apiKeyAlreadyInUse\");\n\t\t\t}\n\t\t}\n\n\t\tconst tenantEntity = new Tenant();\n\t\ttenantEntity.id = tenant.id ?? TenantIdHelper.generateTenantId();\n\t\ttenantEntity.apiKey = tenant.apiKey ?? TenantIdHelper.generateApiKey();\n\t\ttenantEntity.dateCreated = new Date(Date.now()).toISOString();\n\t\ttenantEntity.dateModified = tenantEntity.dateCreated;\n\t\ttenantEntity.label = tenant.label;\n\t\ttenantEntity.publicOrigin = publicOrigin;\n\t\ttenantEntity.isNodeTenant = tenant.isNodeTenant;\n\n\t\tawait this._entityStorageConnector.set(tenantEntity);\n\n\t\treturn tenantEntity.id;\n\t}\n\n\t/**\n\t * Update a tenant.\n\t * @param tenant The tenant to update.\n\t * @returns The nothing.\n\t */\n\tpublic async update(\n\t\ttenant: Partial<Omit<ITenant, \"dateCreated\" | \"dateModified\">>\n\t): Promise<void> {\n\t\tGuards.objectValue<ITenant>(TenantAdminService.CLASS_NAME, nameof(tenant), tenant);\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.id), tenant.id, 32);\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tGuards.stringHexLength(\n\t\t\t\tTenantAdminService.CLASS_NAME,\n\t\t\t\tnameof(tenant.apiKey),\n\t\t\t\ttenant.apiKey,\n\t\t\t\t32\n\t\t\t);\n\t\t}\n\n\t\tlet publicOrigin: string | undefined;\n\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\tUrl.guard(TenantAdminService.CLASS_NAME, nameof(tenant.publicOrigin), tenant.publicOrigin);\n\n\t\t\tconst url = new Url(tenant.publicOrigin);\n\t\t\tconst parts = url.parts();\n\t\t\tpublicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : \"\"}`;\n\t\t}\n\n\t\tconst currentTenant = await this._entityStorageConnector.get(tenant.id);\n\t\tif (!Is.object(currentTenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", tenant.id);\n\t\t}\n\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tconst existingApiKey = await this._entityStorageConnector.get(tenant.apiKey, \"apiKey\");\n\t\t\tif (Is.object(existingApiKey) && existingApiKey.id !== currentTenant.id) {\n\t\t\t\tthrow new GeneralError(TenantAdminService.CLASS_NAME, \"apiKeyAlreadyInUse\");\n\t\t\t}\n\t\t}\n\n\t\tconst tenantEntity = new Tenant();\n\t\ttenantEntity.id = tenant.id;\n\t\ttenantEntity.apiKey = tenant.apiKey ?? currentTenant.apiKey;\n\t\ttenantEntity.dateCreated = currentTenant.dateCreated;\n\t\ttenantEntity.dateModified = new Date(Date.now()).toISOString();\n\t\ttenantEntity.label = tenant.label ?? currentTenant.label;\n\t\ttenantEntity.publicOrigin = publicOrigin ?? currentTenant.publicOrigin;\n\t\ttenantEntity.isNodeTenant = tenant.isNodeTenant ?? currentTenant.isNodeTenant;\n\n\t\tawait this._entityStorageConnector.set(tenantEntity);\n\t}\n\n\t/**\n\t * Remove a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(tenantId: string): Promise<void> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\treturn this._entityStorageConnector.remove(tenantId);\n\t}\n\n\t/**\n\t * Query tenants with pagination.\n\t * @param options Optional query options.\n\t * @param options.isNodeTenant Whether to filter for node admin tenants.\n\t * @param cursor The cursor to start from.\n\t * @param limit The maximum number of tenants to return.\n\t * @returns The tenants and the next cursor if more tenants are available.\n\t */\n\tpublic async query(\n\t\toptions?: { isNodeTenant?: boolean },\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ tenants: ITenant[]; cursor?: string }> {\n\t\tconst conditions = [];\n\n\t\tif (Is.boolean(options?.isNodeTenant)) {\n\t\t\tconditions.push({\n\t\t\t\tproperty: \"isNodeTenant\",\n\t\t\t\tvalue: options.isNodeTenant,\n\t\t\t\tcomparison: ComparisonOperator.Equals\n\t\t\t});\n\t\t}\n\n\t\tconst result = await this._entityStorageConnector.query(\n\t\t\tconditions.length > 0 ? { conditions } : undefined,\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tcursor,\n\t\t\tlimit\n\t\t);\n\n\t\treturn {\n\t\t\ttenants: result.entities as ITenant[],\n\t\t\tcursor: result.cursor\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tenantAdminService.js","sourceRoot":"","sources":["../../src/tenantAdminService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenant, ITenantAdminComponent } from \"@twin.org/api-models\";\nimport { GeneralError, Guards, Is, NotFoundError, Url } from \"@twin.org/core\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { Tenant } from \"./entities/tenant.js\";\nimport type { ITenantAdminServiceConstructorOptions } from \"./models/ITenantAdminServiceConstructorOptions.js\";\nimport { TenantIdHelper } from \"./utils/tenantIdHelper.js\";\n\n/**\n * Service for performing tenant administration operations.\n */\nexport class TenantAdminService implements ITenantAdminComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantAdminService>();\n\n\t/**\n\t * Entity storage connector used by the service.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\n\n\t/**\n\t * Create a new instance of TenantAdminService.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options?: ITenantAdminServiceConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn TenantAdminService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async get(tenantId: string): Promise<ITenant> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(tenantId);\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", tenantId);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its api key.\n\t * @param apiKey The api key of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async getByApiKey(apiKey: string): Promise<ITenant> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(apiKey), apiKey, 32);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(apiKey, \"apiKey\");\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", apiKey);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Get a tenant by its public origin.\n\t * @param publicOrigin The origin of the tenant.\n\t * @returns The tenant.\n\t * @throws Error if the tenant is not found.\n\t */\n\tpublic async getByPublicOrigin(publicOrigin: string): Promise<ITenant> {\n\t\tGuards.stringValue(TenantAdminService.CLASS_NAME, nameof(publicOrigin), publicOrigin);\n\n\t\tlet tenant;\n\n\t\ttry {\n\t\t\ttenant = await this._entityStorageConnector.get(publicOrigin, \"publicOrigin\");\n\t\t} catch {}\n\n\t\tif (!Is.object(tenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", publicOrigin);\n\t\t}\n\n\t\treturn tenant;\n\t}\n\n\t/**\n\t * Create a tenant.\n\t * @param tenant The tenant to store.\n\t * @returns The tenant id.\n\t */\n\tpublic async create(\n\t\ttenant: Omit<ITenant, \"id\" | \"dateCreated\" | \"dateModified\"> & { id?: string }\n\t): Promise<string> {\n\t\tGuards.objectValue<ITenant>(TenantAdminService.CLASS_NAME, nameof(tenant), tenant);\n\t\tif (Is.stringValue(tenant.id)) {\n\t\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.id), tenant.id, 32);\n\t\t}\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tGuards.stringHexLength(\n\t\t\t\tTenantAdminService.CLASS_NAME,\n\t\t\t\tnameof(tenant.apiKey),\n\t\t\t\ttenant.apiKey,\n\t\t\t\t32\n\t\t\t);\n\t\t}\n\n\t\tlet publicOrigin: string | undefined;\n\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\tUrl.guard(TenantAdminService.CLASS_NAME, nameof(tenant.publicOrigin), tenant.publicOrigin);\n\n\t\t\tconst url = new Url(tenant.publicOrigin);\n\t\t\tconst parts = url.parts();\n\t\t\tpublicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : \"\"}`;\n\t\t}\n\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tconst existingApiKey = await this._entityStorageConnector.get(tenant.apiKey, \"apiKey\");\n\t\t\tif (Is.object(existingApiKey) && existingApiKey.id !== tenant.id) {\n\t\t\t\tthrow new GeneralError(TenantAdminService.CLASS_NAME, \"apiKeyAlreadyInUse\");\n\t\t\t}\n\t\t}\n\n\t\tconst tenantEntity = new Tenant();\n\t\ttenantEntity.id = tenant.id ?? TenantIdHelper.generateTenantId();\n\t\ttenantEntity.apiKey = tenant.apiKey ?? TenantIdHelper.generateApiKey();\n\t\ttenantEntity.dateCreated = new Date(Date.now()).toISOString();\n\t\ttenantEntity.dateModified = tenantEntity.dateCreated;\n\t\ttenantEntity.label = tenant.label;\n\t\ttenantEntity.publicOrigin = publicOrigin;\n\n\t\tawait this._entityStorageConnector.set(tenantEntity);\n\n\t\treturn tenantEntity.id;\n\t}\n\n\t/**\n\t * Update a tenant.\n\t * @param tenant The tenant to update.\n\t * @returns The nothing.\n\t */\n\tpublic async update(\n\t\ttenant: Partial<Omit<ITenant, \"dateCreated\" | \"dateModified\">>\n\t): Promise<void> {\n\t\tGuards.objectValue<ITenant>(TenantAdminService.CLASS_NAME, nameof(tenant), tenant);\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenant.id), tenant.id, 32);\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tGuards.stringHexLength(\n\t\t\t\tTenantAdminService.CLASS_NAME,\n\t\t\t\tnameof(tenant.apiKey),\n\t\t\t\ttenant.apiKey,\n\t\t\t\t32\n\t\t\t);\n\t\t}\n\n\t\tlet publicOrigin: string | undefined;\n\t\tif (Is.stringValue(tenant.publicOrigin)) {\n\t\t\tUrl.guard(TenantAdminService.CLASS_NAME, nameof(tenant.publicOrigin), tenant.publicOrigin);\n\n\t\t\tconst url = new Url(tenant.publicOrigin);\n\t\t\tconst parts = url.parts();\n\t\t\tpublicOrigin = `${parts.schema}://${parts.host}${Is.integer(parts.port) ? `:${parts.port}` : \"\"}`;\n\t\t}\n\n\t\tconst currentTenant = await this._entityStorageConnector.get(tenant.id);\n\t\tif (!Is.object(currentTenant)) {\n\t\t\tthrow new NotFoundError(TenantAdminService.CLASS_NAME, \"tenantNotFound\", tenant.id);\n\t\t}\n\n\t\tif (Is.stringValue(tenant.apiKey)) {\n\t\t\tconst existingApiKey = await this._entityStorageConnector.get(tenant.apiKey, \"apiKey\");\n\t\t\tif (Is.object(existingApiKey) && existingApiKey.id !== currentTenant.id) {\n\t\t\t\tthrow new GeneralError(TenantAdminService.CLASS_NAME, \"apiKeyAlreadyInUse\");\n\t\t\t}\n\t\t}\n\n\t\tconst tenantEntity = new Tenant();\n\t\ttenantEntity.id = tenant.id;\n\t\ttenantEntity.apiKey = tenant.apiKey ?? currentTenant.apiKey;\n\t\ttenantEntity.dateCreated = currentTenant.dateCreated;\n\t\ttenantEntity.dateModified = new Date(Date.now()).toISOString();\n\t\ttenantEntity.label = tenant.label ?? currentTenant.label;\n\t\ttenantEntity.publicOrigin = publicOrigin ?? currentTenant.publicOrigin;\n\n\t\tawait this._entityStorageConnector.set(tenantEntity);\n\t}\n\n\t/**\n\t * Remove a tenant by its id.\n\t * @param tenantId The id of the tenant.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(tenantId: string): Promise<void> {\n\t\tGuards.stringHexLength(TenantAdminService.CLASS_NAME, nameof(tenantId), tenantId, 32);\n\n\t\treturn this._entityStorageConnector.remove(tenantId);\n\t}\n\n\t/**\n\t * Query tenants with pagination.\n\t * @param properties The properties to include in the returned tenants.\n\t * @param cursor The cursor to start from.\n\t * @param limit The maximum number of tenants to return.\n\t * @returns The tenants and the next cursor if more tenants are available.\n\t */\n\tpublic async query(\n\t\tproperties: (keyof ITenant)[] | undefined,\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{ tenants: ITenant[]; cursor?: string }> {\n\t\tconst result = await this._entityStorageConnector.query(\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tproperties,\n\t\t\tcursor,\n\t\t\tlimit\n\t\t);\n\n\t\treturn {\n\t\t\ttenants: result.entities as ITenant[],\n\t\t\tcursor: result.cursor\n\t\t};\n\t}\n}\n"]}
|
package/dist/es/tenantRoutes.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { HttpParameterHelper } from "@twin.org/api-models";
|
|
1
4
|
import { Coerce, ComponentFactory, Guards, Is } from "@twin.org/core";
|
|
2
5
|
import { HeaderHelper, HeaderTypes, HttpStatusCode } from "@twin.org/web";
|
|
3
6
|
/**
|
|
@@ -45,8 +48,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
45
48
|
label: "node",
|
|
46
49
|
dateCreated: "2026-01-19T03:59:35.742Z",
|
|
47
50
|
dateModified: "2026-01-19T03:59:35.742Z",
|
|
48
|
-
publicOrigin: "https://example.com:4321"
|
|
49
|
-
isNodeTenant: false
|
|
51
|
+
publicOrigin: "https://example.com:4321"
|
|
50
52
|
}
|
|
51
53
|
]
|
|
52
54
|
}
|
|
@@ -90,8 +92,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
90
92
|
label: "node",
|
|
91
93
|
dateCreated: "2026-01-19T03:59:35.742Z",
|
|
92
94
|
dateModified: "2026-01-19T03:59:35.742Z",
|
|
93
|
-
publicOrigin: "https://example.com:4321"
|
|
94
|
-
isNodeTenant: false
|
|
95
|
+
publicOrigin: "https://example.com:4321"
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
}
|
|
@@ -121,8 +122,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
121
122
|
label: "node",
|
|
122
123
|
dateCreated: "2026-01-19T03:59:35.742Z",
|
|
123
124
|
dateModified: "2026-01-19T03:59:35.742Z",
|
|
124
|
-
publicOrigin: "https://example.com:4321"
|
|
125
|
-
isNodeTenant: false
|
|
125
|
+
publicOrigin: "https://example.com:4321"
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
}
|
|
@@ -205,8 +205,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
205
205
|
body: {
|
|
206
206
|
apiKey: "ad7a5b0b816ca314b69c813ae1368232",
|
|
207
207
|
label: "node",
|
|
208
|
-
publicOrigin: "https://example.com:4321"
|
|
209
|
-
isNodeTenant: false
|
|
208
|
+
publicOrigin: "https://example.com:4321"
|
|
210
209
|
}
|
|
211
210
|
}
|
|
212
211
|
}
|
|
@@ -239,8 +238,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
239
238
|
body: {
|
|
240
239
|
apiKey: "ad7a5b0b816ca314b69c813ae1368232",
|
|
241
240
|
label: "node",
|
|
242
|
-
publicOrigin: "https://example.com:4321"
|
|
243
|
-
isNodeTenant: false
|
|
241
|
+
publicOrigin: "https://example.com:4321"
|
|
244
242
|
}
|
|
245
243
|
}
|
|
246
244
|
}
|
|
@@ -273,7 +271,7 @@ export function generateRestRoutesTenants(baseRouteName, componentName) {
|
|
|
273
271
|
export async function tenantList(httpRequestContext, componentName, request) {
|
|
274
272
|
const hostingComponent = ComponentFactory.get(httpRequestContext.hostingComponentType ?? "hosting");
|
|
275
273
|
const component = ComponentFactory.get(componentName);
|
|
276
|
-
const result = await component.query(
|
|
274
|
+
const result = await component.query(HttpParameterHelper.arrayFromString(request.query?.properties), request.query?.cursor, Coerce.integer(request.query?.limit));
|
|
277
275
|
const headers = {};
|
|
278
276
|
if (Is.stringValue(result.cursor)) {
|
|
279
277
|
headers[HeaderTypes.Link] = HeaderHelper.createLinkHeader(await hostingComponent.buildPublicUrl(httpRequestContext.serverRequest.url), { cursor: result.cursor }, "next");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenantRoutes.js","sourceRoot":"","sources":["../../src/tenantRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type {\n\tICreatedResponse,\n\tIHostingComponent,\n\tIHttpRequestContext,\n\tINoContentResponse,\n\tIRestRoute,\n\tITag,\n\tITenantAdminComponent\n} from \"@twin.org/api-models\";\nimport { Coerce, ComponentFactory, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderHelper, HeaderTypes, HttpStatusCode } from \"@twin.org/web\";\nimport type { ITenantCreateRequest } from \"./models/api/ITenantCreateRequest.js\";\nimport type { ITenantGetByApiKeyRequest } from \"./models/api/ITenantGetByApiKeyRequest.js\";\nimport type { ITenantGetByIdRequest } from \"./models/api/ITenantGetByIdRequest.js\";\nimport type { ITenantGetByPublicOriginRequest } from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nimport type { ITenantGetResponse } from \"./models/api/ITenantGetResponse.js\";\nimport type { ITenantListRequest } from \"./models/api/ITenantListRequest.js\";\nimport type { ITenantListResponse } from \"./models/api/ITenantListResponse.js\";\nimport type { ITenantRemoveRequest } from \"./models/api/ITenantRemoveRequest.js\";\nimport type { ITenantUpdateRequest } from \"./models/api/ITenantUpdateRequest.js\";\n\n/**\n * The source used when communicating about these routes.\n */\nconst ROUTES_SOURCE = \"tenantRoutes\";\n\n/**\n * The tag to associate with the routes.\n */\nexport const tagsTenants: ITag[] = [\n\t{\n\t\tname: \"Tenants\",\n\t\tdescription: \"Tenants endpoints for the REST server.\"\n\t}\n];\n\n/**\n * The REST routes for tenant management.\n * @param baseRouteName Prefix to prepend to the paths.\n * @param componentName The name of the component to use in the routes stored in the ComponentFactory.\n * @returns The generated routes.\n */\nexport function generateRestRoutesTenants(\n\tbaseRouteName: string,\n\tcomponentName: string\n): IRestRoute[] {\n\tconst tenantListRoute: IRestRoute<ITenantListRequest, ITenantListResponse> = {\n\t\toperationId: \"tenantList\",\n\t\tsummary: \"Get the list of tenants\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantList(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantListResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantListResponse\",\n\t\t\t\t\t\tdescription: \"The response for the list tenants request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t[HeaderTypes.Link]: '<https://api.twin.org/tenants/1>; rel=\"next\"'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\t\tisNodeTenant: false\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByIdRoute: IRestRoute<ITenantGetByIdRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetById\",\n\t\tsummary: \"Get the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantById(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantGetByIdRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantGetByIdRequestExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByIdResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by id request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\tisNodeTenant: false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByApiKeyRoute: IRestRoute<ITenantGetByApiKeyRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetByApiKey\",\n\t\tsummary: \"Get the tenant by api key\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/api-key/:apiKey`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByApiKey(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByApiKeyResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by api key request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\t\tisNodeTenant: false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByPublicOriginRoute: IRestRoute = {\n\t\toperationId: \"tenantGetByPublicOrigin\",\n\t\tsummary: \"Get the tenant by public origin\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/public-origin/:publicOrigin`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByPublicOrigin(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByPublicOriginResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by public origin request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantRemoveRoute: IRestRoute<ITenantRemoveRequest, INoContentResponse> = {\n\t\toperationId: \"tenantRemove\",\n\t\tsummary: \"Remove the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"DELETE\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantRemove(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantRemoveRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantRemoveRequestExample\",\n\t\t\t\t\tdescription: \"The request for the remove tenant by id request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantCreateRoute: IRestRoute<ITenantCreateRequest, ICreatedResponse> = {\n\t\toperationId: \"tenantCreate\",\n\t\tsummary: \"Create a new tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"POST\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantCreate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantCreateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantCreateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the create tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\tisNodeTenant: false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ICreatedResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantUpdateRoute: IRestRoute<ITenantUpdateRequest, INoContentResponse> = {\n\t\toperationId: \"tenantUpdate\",\n\t\tsummary: \"Update an existing tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"PUT\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantUpdate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantUpdateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantUpdateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the update tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\",\n\t\t\t\t\t\t\tisNodeTenant: false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\treturn [\n\t\ttenantListRoute,\n\t\ttenantCreateRoute,\n\t\ttenantGetByIdRoute,\n\t\ttenantGetByApiKeyRoute,\n\t\ttenantGetByPublicOriginRoute,\n\t\ttenantRemoveRoute,\n\t\ttenantUpdateRoute\n\t];\n}\n\n/**\n * Get the list of tenants.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantList(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantListRequest\n): Promise<ITenantListResponse> {\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.query(\n\t\tundefined,\n\t\trequest.query?.cursor,\n\t\tCoerce.integer(request.query?.limit)\n\t);\n\n\tconst headers: ITenantListResponse[\"headers\"] = {};\n\n\tif (Is.stringValue(result.cursor)) {\n\t\theaders[HeaderTypes.Link] = HeaderHelper.createLinkHeader(\n\t\t\tawait hostingComponent.buildPublicUrl(httpRequestContext.serverRequest.url),\n\t\t\t{ cursor: result.cursor },\n\t\t\t\"next\"\n\t\t);\n\t}\n\n\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\thttpRequestContext.serverRequest.url\n\t);\n\n\treturn {\n\t\theaders,\n\t\tbody: result.tenants.map(t => ({ ...t, publicOrigin: t.publicOrigin ?? defaultPublicOrigin }))\n\t};\n}\n\n/**\n * Get the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantById(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByIdRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.get(request.pathParams.id);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by api key.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByApiKey(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByApiKeyRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.apiKey), request.pathParams.apiKey);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.getByApiKey(request.pathParams.apiKey);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by public origin.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByPublicOrigin(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByPublicOriginRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(\n\t\tROUTES_SOURCE,\n\t\tnameof(request.pathParams.publicOrigin),\n\t\trequest.pathParams.publicOrigin\n\t);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.getByPublicOrigin(request.pathParams.publicOrigin);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Remove the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantRemove(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantRemoveRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.remove(request.pathParams.id);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n\n/**\n * Create the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantCreate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantCreateRequest\n): Promise<ICreatedResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst createdId = await component.create(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.created,\n\t\theaders: {\n\t\t\t[HeaderTypes.Location]: createdId\n\t\t}\n\t};\n}\n\n/**\n * Update the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantUpdate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantUpdateRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.update(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tenantRoutes.js","sourceRoot":"","sources":["../../src/tenantRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tHttpParameterHelper,\n\ttype ICreatedResponse,\n\ttype IHostingComponent,\n\ttype IHttpRequestContext,\n\ttype INoContentResponse,\n\ttype IRestRoute,\n\ttype ITag,\n\ttype ITenantAdminComponent\n} from \"@twin.org/api-models\";\nimport { Coerce, ComponentFactory, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderHelper, HeaderTypes, HttpStatusCode } from \"@twin.org/web\";\nimport type { ITenantCreateRequest } from \"./models/api/ITenantCreateRequest.js\";\nimport type { ITenantGetByApiKeyRequest } from \"./models/api/ITenantGetByApiKeyRequest.js\";\nimport type { ITenantGetByIdRequest } from \"./models/api/ITenantGetByIdRequest.js\";\nimport type { ITenantGetByPublicOriginRequest } from \"./models/api/ITenantGetByPublicOriginRequest.js\";\nimport type { ITenantGetResponse } from \"./models/api/ITenantGetResponse.js\";\nimport type { ITenantListRequest } from \"./models/api/ITenantListRequest.js\";\nimport type { ITenantListResponse } from \"./models/api/ITenantListResponse.js\";\nimport type { ITenantRemoveRequest } from \"./models/api/ITenantRemoveRequest.js\";\nimport type { ITenantUpdateRequest } from \"./models/api/ITenantUpdateRequest.js\";\n\n/**\n * The source used when communicating about these routes.\n */\nconst ROUTES_SOURCE = \"tenantRoutes\";\n\n/**\n * The tag to associate with the routes.\n */\nexport const tagsTenants: ITag[] = [\n\t{\n\t\tname: \"Tenants\",\n\t\tdescription: \"Tenants endpoints for the REST server.\"\n\t}\n];\n\n/**\n * The REST routes for tenant management.\n * @param baseRouteName Prefix to prepend to the paths.\n * @param componentName The name of the component to use in the routes stored in the ComponentFactory.\n * @returns The generated routes.\n */\nexport function generateRestRoutesTenants(\n\tbaseRouteName: string,\n\tcomponentName: string\n): IRestRoute[] {\n\tconst tenantListRoute: IRestRoute<ITenantListRequest, ITenantListResponse> = {\n\t\toperationId: \"tenantList\",\n\t\tsummary: \"Get the list of tenants\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantList(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantListResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantListResponse\",\n\t\t\t\t\t\tdescription: \"The response for the list tenants request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t[HeaderTypes.Link]: '<https://api.twin.org/tenants/1>; rel=\"next\"'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByIdRoute: IRestRoute<ITenantGetByIdRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetById\",\n\t\tsummary: \"Get the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantById(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantGetByIdRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantGetByIdRequestExample\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByIdResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by id request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByApiKeyRoute: IRestRoute<ITenantGetByApiKeyRequest, ITenantGetResponse> = {\n\t\toperationId: \"tenantGetByApiKey\",\n\t\tsummary: \"Get the tenant by api key\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/api-key/:apiKey`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByApiKey(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByApiKeyResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by api key request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tdateModified: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantGetByPublicOriginRoute: IRestRoute = {\n\t\toperationId: \"tenantGetByPublicOrigin\",\n\t\tsummary: \"Get the tenant by public origin\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"GET\",\n\t\tpath: `${baseRouteName}/public-origin/:publicOrigin`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantByPublicOrigin(httpRequestContext, componentName, request),\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ITenantGetResponse>(),\n\t\t\t\texamples: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tenantGetByPublicOriginResponse\",\n\t\t\t\t\t\tdescription: \"The response for the get tenant by public origin request.\",\n\t\t\t\t\t\tresponse: {\n\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\",\n\t\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\t\tdateCreated: \"2026-01-19T03:59:35.742Z\",\n\t\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantRemoveRoute: IRestRoute<ITenantRemoveRequest, INoContentResponse> = {\n\t\toperationId: \"tenantRemove\",\n\t\tsummary: \"Remove the tenant by id\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"DELETE\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantRemove(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantRemoveRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantRemoveRequestExample\",\n\t\t\t\t\tdescription: \"The request for the remove tenant by id request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantCreateRoute: IRestRoute<ITenantCreateRequest, ICreatedResponse> = {\n\t\toperationId: \"tenantCreate\",\n\t\tsummary: \"Create a new tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"POST\",\n\t\tpath: `${baseRouteName}/`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantCreate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantCreateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantCreateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the create tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<ICreatedResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\tconst tenantUpdateRoute: IRestRoute<ITenantUpdateRequest, INoContentResponse> = {\n\t\toperationId: \"tenantUpdate\",\n\t\tsummary: \"Update an existing tenant\",\n\t\ttag: tagsTenants[0].name,\n\t\tmethod: \"PUT\",\n\t\tpath: `${baseRouteName}/:id`,\n\t\thandler: async (httpRequestContext, request) =>\n\t\t\ttenantUpdate(httpRequestContext, componentName, request),\n\t\trequestType: {\n\t\t\ttype: nameof<ITenantUpdateRequest>(),\n\t\t\texamples: [\n\t\t\t\t{\n\t\t\t\t\tid: \"tenantUpdateRequestExample\",\n\t\t\t\t\tdescription: \"The request for the update tenant request.\",\n\t\t\t\t\trequest: {\n\t\t\t\t\t\tpathParams: {\n\t\t\t\t\t\t\tid: \"2a39d6e62d98aa5372432f2e5d2208d4\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tapiKey: \"ad7a5b0b816ca314b69c813ae1368232\",\n\t\t\t\t\t\t\tlabel: \"node\",\n\t\t\t\t\t\t\tpublicOrigin: \"https://example.com:4321\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\tresponseType: [\n\t\t\t{\n\t\t\t\ttype: nameof<INoContentResponse>()\n\t\t\t}\n\t\t],\n\t\trequiredScope: [\"tenant-admin\"]\n\t};\n\n\treturn [\n\t\ttenantListRoute,\n\t\ttenantCreateRoute,\n\t\ttenantGetByIdRoute,\n\t\ttenantGetByApiKeyRoute,\n\t\ttenantGetByPublicOriginRoute,\n\t\ttenantRemoveRoute,\n\t\ttenantUpdateRoute\n\t];\n}\n\n/**\n * Get the list of tenants.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantList(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantListRequest\n): Promise<ITenantListResponse> {\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst result = await component.query(\n\t\tHttpParameterHelper.arrayFromString(request.query?.properties),\n\t\trequest.query?.cursor,\n\t\tCoerce.integer(request.query?.limit)\n\t);\n\n\tconst headers: ITenantListResponse[\"headers\"] = {};\n\n\tif (Is.stringValue(result.cursor)) {\n\t\theaders[HeaderTypes.Link] = HeaderHelper.createLinkHeader(\n\t\t\tawait hostingComponent.buildPublicUrl(httpRequestContext.serverRequest.url),\n\t\t\t{ cursor: result.cursor },\n\t\t\t\"next\"\n\t\t);\n\t}\n\n\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\thttpRequestContext.serverRequest.url\n\t);\n\n\treturn {\n\t\theaders,\n\t\tbody: result.tenants.map(t => ({ ...t, publicOrigin: t.publicOrigin ?? defaultPublicOrigin }))\n\t};\n}\n\n/**\n * Get the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantById(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByIdRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.get(request.pathParams.id);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by api key.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByApiKey(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByApiKeyRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.apiKey), request.pathParams.apiKey);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.getByApiKey(request.pathParams.apiKey);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Get the tenant by public origin.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantByPublicOrigin(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantGetByPublicOriginRequest\n): Promise<ITenantGetResponse> {\n\tGuards.stringValue(\n\t\tROUTES_SOURCE,\n\t\tnameof(request.pathParams.publicOrigin),\n\t\trequest.pathParams.publicOrigin\n\t);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst hostingComponent = ComponentFactory.get<IHostingComponent>(\n\t\thttpRequestContext.hostingComponentType ?? \"hosting\"\n\t);\n\n\tconst result = await component.getByPublicOrigin(request.pathParams.publicOrigin);\n\n\tif (!Is.stringValue(result.publicOrigin)) {\n\t\tconst defaultPublicOrigin = await hostingComponent.getPublicOrigin(\n\t\t\thttpRequestContext.serverRequest.url\n\t\t);\n\n\t\tresult.publicOrigin ??= defaultPublicOrigin;\n\t}\n\n\treturn {\n\t\tbody: result\n\t};\n}\n\n/**\n * Remove the tenant by id.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantRemove(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantRemoveRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.remove(request.pathParams.id);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n\n/**\n * Create the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantCreate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantCreateRequest\n): Promise<ICreatedResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tconst createdId = await component.create(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.created,\n\t\theaders: {\n\t\t\t[HeaderTypes.Location]: createdId\n\t\t}\n\t};\n}\n\n/**\n * Update the tenant.\n * @param httpRequestContext The request context for the API.\n * @param componentName The name of the component to use in the routes.\n * @param request The request.\n * @returns The response object with additional http response properties.\n */\nexport async function tenantUpdate(\n\thttpRequestContext: IHttpRequestContext,\n\tcomponentName: string,\n\trequest: ITenantUpdateRequest\n): Promise<INoContentResponse> {\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.pathParams.id), request.pathParams.id);\n\tGuards.stringValue(ROUTES_SOURCE, nameof(request.body), request.body);\n\tconst component = ComponentFactory.get<ITenantAdminComponent>(componentName);\n\n\tawait component.update(request.body);\n\n\treturn {\n\t\tstatusCode: HttpStatusCode.noContent\n\t};\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ContextIdKeys, ContextIdStore } from "@twin.org/context";
|
|
2
|
+
import { Is } from "@twin.org/core";
|
|
3
|
+
import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
|
|
4
|
+
/**
|
|
5
|
+
* Service for performing tenant administration operations.
|
|
6
|
+
*/
|
|
7
|
+
export class TenantService {
|
|
8
|
+
/**
|
|
9
|
+
* Runtime name for the class.
|
|
10
|
+
*/
|
|
11
|
+
static CLASS_NAME = "TenantService";
|
|
12
|
+
/**
|
|
13
|
+
* Entity storage connector used by the service.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
_entityStorageConnector;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new instance of TenantService.
|
|
19
|
+
* @param options The options for the connector.
|
|
20
|
+
*/
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this._entityStorageConnector = EntityStorageConnectorFactory.get(options?.tenantEntityStorageType ?? "tenant");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Returns the class name of the component.
|
|
26
|
+
* @returns The class name of the component.
|
|
27
|
+
*/
|
|
28
|
+
className() {
|
|
29
|
+
return TenantService.CLASS_NAME;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run a per tenant operation.
|
|
33
|
+
* @param method The method to run for each tenant.
|
|
34
|
+
* @returns Nothing.
|
|
35
|
+
*/
|
|
36
|
+
async runPerTenant(method) {
|
|
37
|
+
let cursor;
|
|
38
|
+
const contextIds = (await ContextIdStore.getContextIds()) ?? {};
|
|
39
|
+
do {
|
|
40
|
+
const result = await this._entityStorageConnector.query(undefined, undefined, ["id"], cursor);
|
|
41
|
+
for (const tenant of result.entities) {
|
|
42
|
+
contextIds[ContextIdKeys.Tenant] = tenant.id;
|
|
43
|
+
await ContextIdStore.run(contextIds, async () => {
|
|
44
|
+
await method();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
cursor = result.cursor;
|
|
48
|
+
} while (Is.stringValue(cursor));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=tenantService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenantService.js","sourceRoot":"","sources":["../../src/tenantService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EACN,6BAA6B,EAE7B,MAAM,iCAAiC,CAAC;AAKzC;;GAEG;AACH,MAAM,OAAO,aAAa;IACzB;;OAEG;IACI,MAAM,CAAU,UAAU,mBAAmC;IAEpE;;;OAGG;IACc,uBAAuB,CAAkC;IAE1E;;;OAGG;IACH,YAAY,OAA+C;QAC1D,IAAI,CAAC,uBAAuB,GAAG,6BAA6B,CAAC,GAAG,CAC/D,OAAO,EAAE,uBAAuB,IAAI,QAAQ,CAC5C,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,aAAa,CAAC,UAAU,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,YAAY,CAAC,MAA2B;QACpD,IAAI,MAA0B,CAAC;QAE/B,MAAM,UAAU,GAAG,CAAC,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC;QAEhE,GAAG,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAE9F,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;gBAE7C,MAAM,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;oBAC/C,MAAM,MAAM,EAAE,CAAC;gBAChB,CAAC,CAAC,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACxB,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE;IAClC,CAAC","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ITenantComponent } from \"@twin.org/api-models\";\nimport { ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { Is } from \"@twin.org/core\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { Tenant } from \"./entities/tenant.js\";\nimport type { ITenantAdminServiceConstructorOptions } from \"./models/ITenantAdminServiceConstructorOptions.js\";\n\n/**\n * Service for performing tenant administration operations.\n */\nexport class TenantService implements ITenantComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<TenantService>();\n\n\t/**\n\t * Entity storage connector used by the service.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<Tenant>;\n\n\t/**\n\t * Create a new instance of TenantService.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options?: ITenantAdminServiceConstructorOptions) {\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions?.tenantEntityStorageType ?? \"tenant\"\n\t\t);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn TenantService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Run a per tenant operation.\n\t * @param method The method to run for each tenant.\n\t * @returns Nothing.\n\t */\n\tpublic async runPerTenant(method: () => Promise<void>): Promise<void> {\n\t\tlet cursor: string | undefined;\n\n\t\tconst contextIds = (await ContextIdStore.getContextIds()) ?? {};\n\n\t\tdo {\n\t\t\tconst result = await this._entityStorageConnector.query(undefined, undefined, [\"id\"], cursor);\n\n\t\t\tfor (const tenant of result.entities) {\n\t\t\t\tcontextIds[ContextIdKeys.Tenant] = tenant.id;\n\n\t\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\t\tawait method();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcursor = result.cursor;\n\t\t} while (Is.stringValue(cursor));\n\t}\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -12,9 +12,12 @@ export * from "./models/ITenantAdminServiceConfig.js";
|
|
|
12
12
|
export * from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
13
13
|
export * from "./models/ITenantProcessorConfig.js";
|
|
14
14
|
export * from "./models/ITenantProcessorConstructorOptions.js";
|
|
15
|
+
export * from "./models/ITenantServiceConfig.js";
|
|
16
|
+
export * from "./models/ITenantServiceConstructorOptions.js";
|
|
15
17
|
export * from "./schema.js";
|
|
16
18
|
export * from "./tenantAdminService.js";
|
|
17
19
|
export * from "./tenantIdContextIdHandler.js";
|
|
18
20
|
export * from "./tenantProcessor.js";
|
|
19
21
|
export * from "./tenantRoutes.js";
|
|
22
|
+
export * from "./tenantService.js";
|
|
20
23
|
export * from "./utils/tenantIdHelper.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ITenantServiceConfig } from "./ITenantServiceConfig.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for the Tenant Service constructor.
|
|
4
|
+
*/
|
|
5
|
+
export interface ITenantServiceConstructorOptions {
|
|
6
|
+
/**
|
|
7
|
+
* The entity storage for the tenants.
|
|
8
|
+
* @default tenant
|
|
9
|
+
*/
|
|
10
|
+
tenantEntityStorageType?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the service.
|
|
13
|
+
*/
|
|
14
|
+
config?: ITenantServiceConfig;
|
|
15
|
+
}
|
|
@@ -6,6 +6,11 @@ export interface ITenantListRequest {
|
|
|
6
6
|
* The query parameters.
|
|
7
7
|
*/
|
|
8
8
|
query: {
|
|
9
|
+
/**
|
|
10
|
+
* The properties to include in the returned tenants, separated by commas.
|
|
11
|
+
* If not provided, all properties will be returned.
|
|
12
|
+
*/
|
|
13
|
+
properties?: string;
|
|
9
14
|
/**
|
|
10
15
|
* The cursor to get the next chunk of tenants.
|
|
11
16
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ITenant, ITenantAdminComponent } from "@twin.org/api-models";
|
|
2
2
|
import type { ITenantAdminServiceConstructorOptions } from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
3
3
|
/**
|
|
4
|
-
* Service for performing
|
|
4
|
+
* Service for performing tenant administration operations.
|
|
5
5
|
*/
|
|
6
6
|
export declare class TenantAdminService implements ITenantAdminComponent {
|
|
7
7
|
/**
|
|
@@ -61,15 +61,12 @@ export declare class TenantAdminService implements ITenantAdminComponent {
|
|
|
61
61
|
remove(tenantId: string): Promise<void>;
|
|
62
62
|
/**
|
|
63
63
|
* Query tenants with pagination.
|
|
64
|
-
* @param
|
|
65
|
-
* @param options.isNodeTenant Whether to filter for node admin tenants.
|
|
64
|
+
* @param properties The properties to include in the returned tenants.
|
|
66
65
|
* @param cursor The cursor to start from.
|
|
67
66
|
* @param limit The maximum number of tenants to return.
|
|
68
67
|
* @returns The tenants and the next cursor if more tenants are available.
|
|
69
68
|
*/
|
|
70
|
-
query(
|
|
71
|
-
isNodeTenant?: boolean;
|
|
72
|
-
}, cursor?: string, limit?: number): Promise<{
|
|
69
|
+
query(properties: (keyof ITenant)[] | undefined, cursor?: string, limit?: number): Promise<{
|
|
73
70
|
tenants: ITenant[];
|
|
74
71
|
cursor?: string;
|
|
75
72
|
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ICreatedResponse, type IHttpRequestContext, type INoContentResponse, type IRestRoute, type ITag } from "@twin.org/api-models";
|
|
2
2
|
import type { ITenantCreateRequest } from "./models/api/ITenantCreateRequest.js";
|
|
3
3
|
import type { ITenantGetByApiKeyRequest } from "./models/api/ITenantGetByApiKeyRequest.js";
|
|
4
4
|
import type { ITenantGetByIdRequest } from "./models/api/ITenantGetByIdRequest.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ITenantComponent } from "@twin.org/api-models";
|
|
2
|
+
import type { ITenantAdminServiceConstructorOptions } from "./models/ITenantAdminServiceConstructorOptions.js";
|
|
3
|
+
/**
|
|
4
|
+
* Service for performing tenant administration operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare class TenantService implements ITenantComponent {
|
|
7
|
+
/**
|
|
8
|
+
* Runtime name for the class.
|
|
9
|
+
*/
|
|
10
|
+
static readonly CLASS_NAME: string;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new instance of TenantService.
|
|
13
|
+
* @param options The options for the connector.
|
|
14
|
+
*/
|
|
15
|
+
constructor(options?: ITenantAdminServiceConstructorOptions);
|
|
16
|
+
/**
|
|
17
|
+
* Returns the class name of the component.
|
|
18
|
+
* @returns The class name of the component.
|
|
19
|
+
*/
|
|
20
|
+
className(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Run a per tenant operation.
|
|
23
|
+
* @param method The method to run for each tenant.
|
|
24
|
+
* @returns Nothing.
|
|
25
|
+
*/
|
|
26
|
+
runPerTenant(method: () => Promise<void>): Promise<void>;
|
|
27
|
+
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.40](https://github.com/iotaledger/twin-api/compare/api-tenant-processor-v0.0.3-next.39...api-tenant-processor-v0.0.3-next.40) (2026-06-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add tenant component ([#145](https://github.com/iotaledger/twin-api/issues/145)) ([a440c53](https://github.com/iotaledger/twin-api/commit/a440c53f36618946daee7372fe664f8ace341a08))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/api-models bumped from 0.0.3-next.39 to 0.0.3-next.40
|
|
16
|
+
|
|
3
17
|
## [0.0.3-next.39](https://github.com/iotaledger/twin-api/compare/api-tenant-processor-v0.0.3-next.38...api-tenant-processor-v0.0.3-next.39) (2026-06-02)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -59,11 +59,3 @@ The date the tenant was modified.
|
|
|
59
59
|
> `optional` **publicOrigin?**: `string`
|
|
60
60
|
|
|
61
61
|
The origin available to the public for accessing the API.
|
|
62
|
-
|
|
63
|
-
***
|
|
64
|
-
|
|
65
|
-
### isNodeTenant {#isnodetenant}
|
|
66
|
-
|
|
67
|
-
> **isNodeTenant**: `boolean`
|
|
68
|
-
|
|
69
|
-
Indicates whether the tenant is the node tenant.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Class: TenantAdminService
|
|
2
2
|
|
|
3
|
-
Service for performing
|
|
3
|
+
Service for performing tenant administration operations.
|
|
4
4
|
|
|
5
5
|
## Implements
|
|
6
6
|
|
|
@@ -224,21 +224,17 @@ Nothing.
|
|
|
224
224
|
|
|
225
225
|
### query() {#query}
|
|
226
226
|
|
|
227
|
-
> **query**(`
|
|
227
|
+
> **query**(`properties`, `cursor?`, `limit?`): `Promise`\<\{ `tenants`: `ITenant`[]; `cursor?`: `string`; \}\>
|
|
228
228
|
|
|
229
229
|
Query tenants with pagination.
|
|
230
230
|
|
|
231
231
|
#### Parameters
|
|
232
232
|
|
|
233
|
-
#####
|
|
234
|
-
|
|
235
|
-
Optional query options.
|
|
236
|
-
|
|
237
|
-
###### isNodeTenant?
|
|
233
|
+
##### properties
|
|
238
234
|
|
|
239
|
-
`
|
|
235
|
+
keyof `ITenant`[] \| `undefined`
|
|
240
236
|
|
|
241
|
-
|
|
237
|
+
The properties to include in the returned tenants.
|
|
242
238
|
|
|
243
239
|
##### cursor?
|
|
244
240
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Class: TenantService
|
|
2
|
+
|
|
3
|
+
Service for performing tenant administration operations.
|
|
4
|
+
|
|
5
|
+
## Implements
|
|
6
|
+
|
|
7
|
+
- `ITenantComponent`
|
|
8
|
+
|
|
9
|
+
## Constructors
|
|
10
|
+
|
|
11
|
+
### Constructor
|
|
12
|
+
|
|
13
|
+
> **new TenantService**(`options?`): `TenantService`
|
|
14
|
+
|
|
15
|
+
Create a new instance of TenantService.
|
|
16
|
+
|
|
17
|
+
#### Parameters
|
|
18
|
+
|
|
19
|
+
##### options?
|
|
20
|
+
|
|
21
|
+
[`ITenantAdminServiceConstructorOptions`](../interfaces/ITenantAdminServiceConstructorOptions.md)
|
|
22
|
+
|
|
23
|
+
The options for the connector.
|
|
24
|
+
|
|
25
|
+
#### Returns
|
|
26
|
+
|
|
27
|
+
`TenantService`
|
|
28
|
+
|
|
29
|
+
## Properties
|
|
30
|
+
|
|
31
|
+
### CLASS\_NAME {#class_name}
|
|
32
|
+
|
|
33
|
+
> `readonly` `static` **CLASS\_NAME**: `string`
|
|
34
|
+
|
|
35
|
+
Runtime name for the class.
|
|
36
|
+
|
|
37
|
+
## Methods
|
|
38
|
+
|
|
39
|
+
### className() {#classname}
|
|
40
|
+
|
|
41
|
+
> **className**(): `string`
|
|
42
|
+
|
|
43
|
+
Returns the class name of the component.
|
|
44
|
+
|
|
45
|
+
#### Returns
|
|
46
|
+
|
|
47
|
+
`string`
|
|
48
|
+
|
|
49
|
+
The class name of the component.
|
|
50
|
+
|
|
51
|
+
#### Implementation of
|
|
52
|
+
|
|
53
|
+
`ITenantComponent.className`
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
57
|
+
### runPerTenant() {#runpertenant}
|
|
58
|
+
|
|
59
|
+
> **runPerTenant**(`method`): `Promise`\<`void`\>
|
|
60
|
+
|
|
61
|
+
Run a per tenant operation.
|
|
62
|
+
|
|
63
|
+
#### Parameters
|
|
64
|
+
|
|
65
|
+
##### method
|
|
66
|
+
|
|
67
|
+
() => `Promise`\<`void`\>
|
|
68
|
+
|
|
69
|
+
The method to run for each tenant.
|
|
70
|
+
|
|
71
|
+
#### Returns
|
|
72
|
+
|
|
73
|
+
`Promise`\<`void`\>
|
|
74
|
+
|
|
75
|
+
Nothing.
|
|
76
|
+
|
|
77
|
+
#### Implementation of
|
|
78
|
+
|
|
79
|
+
`ITenantComponent.runPerTenant`
|
package/docs/reference/index.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
- [TenantAdminService](classes/TenantAdminService.md)
|
|
7
7
|
- [TenantIdContextIdHandler](classes/TenantIdContextIdHandler.md)
|
|
8
8
|
- [TenantProcessor](classes/TenantProcessor.md)
|
|
9
|
+
- [TenantService](classes/TenantService.md)
|
|
9
10
|
- [TenantIdHelper](classes/TenantIdHelper.md)
|
|
10
11
|
|
|
11
12
|
## Interfaces
|
|
@@ -14,6 +15,8 @@
|
|
|
14
15
|
- [ITenantAdminServiceConstructorOptions](interfaces/ITenantAdminServiceConstructorOptions.md)
|
|
15
16
|
- [ITenantProcessorConfig](interfaces/ITenantProcessorConfig.md)
|
|
16
17
|
- [ITenantProcessorConstructorOptions](interfaces/ITenantProcessorConstructorOptions.md)
|
|
18
|
+
- [ITenantServiceConfig](interfaces/ITenantServiceConfig.md)
|
|
19
|
+
- [ITenantServiceConstructorOptions](interfaces/ITenantServiceConstructorOptions.md)
|
|
17
20
|
- [ITenantCreateRequest](interfaces/ITenantCreateRequest.md)
|
|
18
21
|
- [ITenantGetByApiKeyRequest](interfaces/ITenantGetByApiKeyRequest.md)
|
|
19
22
|
- [ITenantGetByIdRequest](interfaces/ITenantGetByIdRequest.md)
|
|
@@ -10,6 +10,13 @@ The list of tenants.
|
|
|
10
10
|
|
|
11
11
|
The query parameters.
|
|
12
12
|
|
|
13
|
+
#### properties?
|
|
14
|
+
|
|
15
|
+
> `optional` **properties?**: `string`
|
|
16
|
+
|
|
17
|
+
The properties to include in the returned tenants, separated by commas.
|
|
18
|
+
If not provided, all properties will be returned.
|
|
19
|
+
|
|
13
20
|
#### cursor?
|
|
14
21
|
|
|
15
22
|
> `optional` **cursor?**: `string`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Interface: ITenantServiceConstructorOptions
|
|
2
|
+
|
|
3
|
+
Options for the Tenant Service constructor.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
### tenantEntityStorageType? {#tenantentitystoragetype}
|
|
8
|
+
|
|
9
|
+
> `optional` **tenantEntityStorageType?**: `string`
|
|
10
|
+
|
|
11
|
+
The entity storage for the tenants.
|
|
12
|
+
|
|
13
|
+
#### Default
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
tenant
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
***
|
|
20
|
+
|
|
21
|
+
### config? {#config}
|
|
22
|
+
|
|
23
|
+
> `optional` **config?**: [`ITenantServiceConfig`](ITenantServiceConfig.md)
|
|
24
|
+
|
|
25
|
+
Configuration for the service.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/api-tenant-processor",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.40",
|
|
4
4
|
"description": "Tenant resolution services and route handlers that derive tenant context from API keys.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/api-models": "0.0.3-next.
|
|
17
|
+
"@twin.org/api-models": "0.0.3-next.40",
|
|
18
18
|
"@twin.org/context": "next",
|
|
19
19
|
"@twin.org/core": "next",
|
|
20
20
|
"@twin.org/entity": "next",
|