@acorex-platform/module-integration-management-client 0.0.21

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.
Files changed (31) hide show
  1. package/fesm2022/acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs +102 -0
  2. package/fesm2022/acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-integration-management-client-contracts.mjs +163 -0
  4. package/fesm2022/acorex-platform-module-integration-management-client-contracts.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs +53 -0
  6. package/fesm2022/acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs +60 -0
  8. package/fesm2022/acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs +30 -0
  10. package/fesm2022/acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-integration-management-client-integration-connection-lifecycle.dispatcher-DRWR9ysx.mjs +45 -0
  12. package/fesm2022/acorex-platform-module-integration-management-client-integration-connection-lifecycle.dispatcher-DRWR9ysx.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs +176 -0
  14. package/fesm2022/acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs +406 -0
  16. package/fesm2022/acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs +52 -0
  18. package/fesm2022/acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs +27 -0
  20. package/fesm2022/acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs +65 -0
  22. package/fesm2022/acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs +42 -0
  24. package/fesm2022/acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs.map +1 -0
  25. package/fesm2022/acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs +83 -0
  26. package/fesm2022/acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-module-integration-management-client.mjs +776 -0
  28. package/fesm2022/acorex-platform-module-integration-management-client.mjs.map +1 -0
  29. package/package.json +28 -0
  30. package/types/acorex-platform-module-integration-management-client-contracts.d.ts +191 -0
  31. package/types/acorex-platform-module-integration-management-client.d.ts +74 -0
@@ -0,0 +1,776 @@
1
+ import { AXP_INTEGRATION_CONNECTION_STATUS, AXP_INTEGRATION_CONNECTION_SCOPE, AXP_INTEGRATION_CATEGORY, AXPIntegrationNotConnectedError, AXPIntegrationExpiredError, AXPIntegrationMissingScopeError } from '@acorex-platform/framework-shared/core';
2
+ import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
3
+ import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
4
+ import * as i0 from '@angular/core';
5
+ import { inject, Injectable, NgModule } from '@angular/core';
6
+ import { isEmpty, trim, defaultTo } from 'lodash';
7
+ import { RootConfig, AXPAdministrationPermissionKeys, AXMIntegrationManagementMenuKeys, AXMIntegrationManagementCommandKeys, AXMIntegrationManagementQueryKeys } from '@acorex-platform/module-integration-management-client/contracts';
8
+ import { AXPIntegrationRuntimeService, AXPIntegrationProviderRegistryService, AXP_INTEGRATION_SECRET_STORE, AXP_INTEGRATION_RUNTIME_PROVIDER, AXP_PROTECTED_ROUTE_GUARDS, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_INTEGRATION_DOMAIN_PROVIDER } from '@acorex-platform/framework-client/common';
9
+ import { AXP_MODULE_MANIFEST_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER } from '@acorex-platform/framework-client/core';
10
+ import { AXPRuntimeModule, provideCommandSetups, provideQuerySetups } from '@acorex-platform/framework-client/runtime';
11
+ import { CommonModule } from '@angular/common';
12
+ import { ROUTES } from '@angular/router';
13
+ import { AXPCommonMenuKeys, AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
14
+ import { firstValueFrom } from 'rxjs';
15
+ import { AXPRootLayoutComponent } from '@acorex-platform/framework-client/themes/default';
16
+
17
+ //#endregion
18
+
19
+ //#region ---- Credential helpers ----
20
+ const AXP_INTEGRATION_CREDENTIAL_MASK = '••••••••';
21
+ function hasConfigCredential(config) {
22
+ return (!isEmpty(trim(String(config['apiKey'] ?? ''))) ||
23
+ !isEmpty(trim(String(config['accessToken'] ?? ''))) ||
24
+ !isEmpty(trim(String(config['refreshToken'] ?? ''))) ||
25
+ !isEmpty(trim(String(config['clientSecret'] ?? ''))) ||
26
+ !isEmpty(trim(String(config['botToken'] ?? ''))));
27
+ }
28
+ function isMaskedIntegrationCredential(value) {
29
+ const normalized = trim(value ?? '');
30
+ return !normalized || normalized === AXP_INTEGRATION_CREDENTIAL_MASK;
31
+ }
32
+ /** Clears runtime OAuth/token fields while keeping reconnect-friendly client settings. */
33
+ function scrubDisconnectedConnectionConfig(config) {
34
+ if (!config) {
35
+ return null;
36
+ }
37
+ const next = { ...config };
38
+ delete next['accessToken'];
39
+ delete next['refreshToken'];
40
+ delete next['tokenExpiresAt'];
41
+ delete next['oauthTokenJson'];
42
+ delete next['authorizationUrl'];
43
+ delete next['token'];
44
+ delete next['password'];
45
+ delete next['apiToken'];
46
+ delete next['apiKey'];
47
+ delete next['botToken'];
48
+ return next;
49
+ }
50
+ function hasConfiguredIntegrationCredentials(connection) {
51
+ if (!connection || connection.status !== AXP_INTEGRATION_CONNECTION_STATUS.Connected) {
52
+ return false;
53
+ }
54
+ if (connection.isRevoked || connection.isDisabled) {
55
+ return false;
56
+ }
57
+ if (!isEmpty(trim(defaultTo(connection.secretRef, '')))) {
58
+ return true;
59
+ }
60
+ const config = (connection.config ?? {});
61
+ return hasConfigCredential(config);
62
+ }
63
+ //#endregion
64
+ //#region ---- Safe mapper ----
65
+ function toSafeIntegrationConnectionDto(connection) {
66
+ const secretRef = defaultTo(connection.secretRef, '');
67
+ const config = (connection.config ?? {});
68
+ const hasConfigSecret = hasConfigCredential(config);
69
+ const hasSecret = !isEmpty(trim(secretRef)) || hasConfigSecret;
70
+ return {
71
+ id: connection.id,
72
+ providerId: connection.providerId,
73
+ connectionScope: connection.connectionScope,
74
+ connectionKey: connection.connectionKey,
75
+ displayName: connection.displayName,
76
+ authMethodType: connection.authMethodType,
77
+ status: connection.status,
78
+ instanceUrl: connection.instanceUrl,
79
+ externalAccountId: connection.externalAccountId,
80
+ externalAccountName: connection.externalAccountName,
81
+ grantedScopes: connection.grantedScopes,
82
+ expiresAt: connection.expiresAt,
83
+ lastConnectedAt: connection.lastConnectedAt,
84
+ lastValidatedAt: connection.lastValidatedAt,
85
+ lastSyncAt: connection.lastSyncAt,
86
+ lastErrorCode: connection.lastErrorCode,
87
+ lastErrorMessage: connection.lastErrorMessage,
88
+ isRevoked: connection.isRevoked,
89
+ isDisabled: connection.isDisabled,
90
+ config: connection.config,
91
+ hasSecret,
92
+ secretPreview: hasSecret ? '••••••••' : null,
93
+ };
94
+ }
95
+ //#endregion
96
+ //#region ---- Connection manager ----
97
+ class AXMIntegrationConnectionManager {
98
+ constructor() {
99
+ //#region ---- Services & Dependencies ----
100
+ this.entityService = inject(AXPEntityService);
101
+ this.sessionService = inject(AXPSessionService);
102
+ }
103
+ //#endregion
104
+ //#region ---- Accessors ----
105
+ connectionAccessor() {
106
+ return this.entityService
107
+ .withEntity(RootConfig.module.name, RootConfig.entities.integrationConnection.name)
108
+ .data();
109
+ }
110
+ getSessionContext() {
111
+ const tenantId = this.sessionService.tenant?.id;
112
+ const applicationId = this.sessionService.application?.id;
113
+ const userId = this.sessionService.user?.id;
114
+ if (!tenantId || !applicationId || !userId) {
115
+ throw new Error('Integration operations require an authenticated user, tenant, and application context.');
116
+ }
117
+ return { tenantId, applicationId, userId };
118
+ }
119
+ ownershipFilters(tenantId, applicationId, userId) {
120
+ const filters = [
121
+ { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },
122
+ { field: 'scopeInfo.applicationId', operator: { type: 'equal' }, value: applicationId },
123
+ ];
124
+ if (userId) {
125
+ filters.push({ field: 'scopeInfo.userId', operator: { type: 'equal' }, value: userId });
126
+ }
127
+ return filters;
128
+ }
129
+ buildOwnershipInfo(tenantId, applicationId, connectionScope, userId) {
130
+ return {
131
+ tenantId,
132
+ applicationId,
133
+ ...(connectionScope === AXP_INTEGRATION_CONNECTION_SCOPE.User ? { userId } : {}),
134
+ };
135
+ }
136
+ //#endregion
137
+ //#region ---- Queries ----
138
+ async listForCurrentUser(connectionScope) {
139
+ const { tenantId, applicationId, userId } = this.getSessionContext();
140
+ const result = await this.connectionAccessor().query({
141
+ skip: 0,
142
+ take: 1000,
143
+ filter: {
144
+ logic: 'and',
145
+ filters: [
146
+ ...this.ownershipFilters(tenantId, applicationId),
147
+ ...(connectionScope
148
+ ? [{ field: 'connectionScope', operator: { type: 'equal' }, value: connectionScope }]
149
+ : []),
150
+ {
151
+ logic: 'or',
152
+ filters: [
153
+ {
154
+ field: 'connectionScope',
155
+ operator: { type: 'equal' },
156
+ value: AXP_INTEGRATION_CONNECTION_SCOPE.Tenant,
157
+ },
158
+ {
159
+ logic: 'and',
160
+ filters: [
161
+ {
162
+ field: 'connectionScope',
163
+ operator: { type: 'equal' },
164
+ value: AXP_INTEGRATION_CONNECTION_SCOPE.User,
165
+ },
166
+ { field: 'scopeInfo.userId', operator: { type: 'equal' }, value: userId },
167
+ ],
168
+ },
169
+ ],
170
+ },
171
+ ],
172
+ },
173
+ });
174
+ return (result.items ?? []).filter((item) => {
175
+ if (item.connectionScope === AXP_INTEGRATION_CONNECTION_SCOPE.Tenant) {
176
+ return true;
177
+ }
178
+ return item.scopeInfo?.userId === userId;
179
+ });
180
+ }
181
+ async findByUniqueKey(input) {
182
+ const ctx = this.getSessionContext();
183
+ const tenantId = input.tenantId ?? ctx.tenantId;
184
+ const applicationId = input.applicationId ?? ctx.applicationId;
185
+ const userId = input.userId ?? ctx.userId;
186
+ const filters = [
187
+ ...this.ownershipFilters(tenantId, applicationId, input.connectionScope === AXP_INTEGRATION_CONNECTION_SCOPE.User ? userId : undefined),
188
+ { field: 'providerId', operator: { type: 'equal' }, value: input.providerId },
189
+ { field: 'connectionScope', operator: { type: 'equal' }, value: input.connectionScope },
190
+ { field: 'connectionKey', operator: { type: 'equal' }, value: input.connectionKey },
191
+ ];
192
+ const result = await this.connectionAccessor().query({
193
+ skip: 0,
194
+ take: 1,
195
+ filter: { logic: 'and', filters },
196
+ });
197
+ return result.items?.[0] ?? null;
198
+ }
199
+ async getByIdForCurrentUser(connectionId) {
200
+ const connection = await this.connectionAccessor().byKey(connectionId);
201
+ if (!connection) {
202
+ return null;
203
+ }
204
+ return this.assertOwnership(connection) ? connection : null;
205
+ }
206
+ //#endregion
207
+ //#region ---- Mutations ----
208
+ async upsertConnection(data) {
209
+ const { tenantId, applicationId, userId } = this.getSessionContext();
210
+ const existing = await this.findByUniqueKey({
211
+ providerId: data.providerId,
212
+ connectionScope: data.connectionScope,
213
+ connectionKey: data.connectionKey,
214
+ tenantId,
215
+ applicationId,
216
+ userId: data.connectionScope === AXP_INTEGRATION_CONNECTION_SCOPE.User ? userId : undefined,
217
+ });
218
+ const scopeInfo = this.buildOwnershipInfo(tenantId, applicationId, data.connectionScope, userId);
219
+ const payload = {
220
+ ...data,
221
+ scopeInfo,
222
+ isRevoked: defaultTo(data.isRevoked, false),
223
+ isDisabled: defaultTo(data.isDisabled, false),
224
+ status: data.status ?? AXP_INTEGRATION_CONNECTION_STATUS.Connected,
225
+ lastConnectedAt: data.lastConnectedAt ?? new Date().toISOString(),
226
+ };
227
+ if (existing) {
228
+ await this.connectionAccessor().update(existing.id, payload);
229
+ const updated = await this.connectionAccessor().byKey(existing.id);
230
+ if (!updated) {
231
+ throw new Error('Connection not found after update.');
232
+ }
233
+ return updated;
234
+ }
235
+ const createPayload = {
236
+ providerId: data.providerId,
237
+ connectionScope: data.connectionScope,
238
+ connectionKey: data.connectionKey,
239
+ displayName: data.displayName,
240
+ authMethodType: data.authMethodType,
241
+ scopeInfo,
242
+ isRevoked: defaultTo(data.isRevoked, false),
243
+ isDisabled: defaultTo(data.isDisabled, false),
244
+ status: data.status ?? AXP_INTEGRATION_CONNECTION_STATUS.Connected,
245
+ lastConnectedAt: data.lastConnectedAt ?? new Date().toISOString(),
246
+ instanceUrl: data.instanceUrl ?? null,
247
+ externalAccountId: data.externalAccountId ?? null,
248
+ externalAccountName: data.externalAccountName ?? null,
249
+ grantedScopes: data.grantedScopes ?? null,
250
+ secretRef: data.secretRef ?? null,
251
+ expiresAt: data.expiresAt ?? null,
252
+ lastValidatedAt: data.lastValidatedAt ?? null,
253
+ lastSyncAt: data.lastSyncAt ?? null,
254
+ lastErrorCode: data.lastErrorCode ?? null,
255
+ lastErrorMessage: data.lastErrorMessage ?? null,
256
+ config: data.config ?? null,
257
+ };
258
+ const id = await this.connectionAccessor().create(createPayload);
259
+ const created = await this.connectionAccessor().byKey(id);
260
+ if (!created) {
261
+ throw new Error('Connection not found after create.');
262
+ }
263
+ return created;
264
+ }
265
+ async updateConnection(connectionId, patch) {
266
+ const existing = await this.getByIdForCurrentUser(connectionId);
267
+ if (!existing) {
268
+ throw new Error('Connection not found or access denied.');
269
+ }
270
+ await this.connectionAccessor().update(connectionId, patch);
271
+ const updated = await this.connectionAccessor().byKey(connectionId);
272
+ if (!updated) {
273
+ throw new Error('Connection not found after update.');
274
+ }
275
+ return updated;
276
+ }
277
+ async deleteConnection(connectionId) {
278
+ const existing = await this.getByIdForCurrentUser(connectionId);
279
+ if (!existing) {
280
+ throw new Error('Connection not found or access denied.');
281
+ }
282
+ await this.connectionAccessor().delete(connectionId);
283
+ }
284
+ //#endregion
285
+ //#region ---- Authorization ----
286
+ assertOwnership(connection) {
287
+ const { tenantId, applicationId, userId } = this.getSessionContext();
288
+ if (connection.scopeInfo?.tenantId !== tenantId) {
289
+ return false;
290
+ }
291
+ if (connection.scopeInfo?.applicationId !== applicationId) {
292
+ return false;
293
+ }
294
+ if (connection.connectionScope === AXP_INTEGRATION_CONNECTION_SCOPE.Tenant) {
295
+ return true;
296
+ }
297
+ return connection.scopeInfo?.userId === userId;
298
+ }
299
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationConnectionManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
300
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationConnectionManager, providedIn: 'root' }); }
301
+ }
302
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationConnectionManager, decorators: [{
303
+ type: Injectable,
304
+ args: [{ providedIn: 'root' }]
305
+ }] });
306
+
307
+ const IntegrationManagementManifest = {
308
+ name: RootConfig.module.name,
309
+ version: '1.0.0',
310
+ title: RootConfig.module.title,
311
+ icon: RootConfig.module.icon,
312
+ i18n: RootConfig.config.i18n,
313
+ type: 'platform',
314
+ domain: 'platform',
315
+ required: false,
316
+ };
317
+
318
+ //#region ----- Imports -----
319
+ //#endregion
320
+ //#region ----- Menu Provider -----
321
+ class AXMIntegrationManagementMenuProvider {
322
+ constructor() {
323
+ this.sessionService = inject(AXPSessionService);
324
+ }
325
+ async provide(context) {
326
+ const isAuthorized = await firstValueFrom(this.sessionService.isAuthorized$);
327
+ if (!isAuthorized) {
328
+ return;
329
+ }
330
+ const appName = this.sessionService.application?.name;
331
+ context.find(AXPCommonMenuKeys.Administration).addItems([
332
+ {
333
+ name: AXMIntegrationManagementMenuKeys.Integrations,
334
+ priority: 1000,
335
+ text: '@integration-management:pages.integrations.title',
336
+ type: 'menu',
337
+ icon: 'fa-light fa-plug',
338
+ path: `/${appName}/admin/integrations`,
339
+ policy: {
340
+ features: [RootConfig.module.name],
341
+ permissions: [AXPAdministrationPermissionKeys.MaintainConnections],
342
+ },
343
+ },
344
+ ]);
345
+ }
346
+ }
347
+ //#endregion
348
+
349
+ //#endregion
350
+ //#region ---- Permission Definition Provider ----
351
+ /**
352
+ * Registers Integrations section capabilities under Administration.
353
+ */
354
+ class AXMIntegrationManagementPermissionDefinitionProvider {
355
+ async define(context) {
356
+ const keys = AXPAdministrationPermissionKeys;
357
+ const groups = AXPCommonPermissionGroupKeys;
358
+ const P = '@common:administration.permissions';
359
+ const G = '@common:permission-groups';
360
+ context.addGroup(groups.Administration.Root, `${G}.administration.title`, `${G}.administration.description`, { order: 120 });
361
+ context
362
+ .addGroup(groups.Administration.Integrations, `${G}.administration-integrations.title`, `${G}.administration-integrations.description`, { parent: groups.Administration.Root, order: 20 })
363
+ .addPermission(keys.ViewIntegrations, `${P}.view-integrations.title`, `${P}.view-integrations.description`)
364
+ .endPermission()
365
+ .addPermission(keys.MaintainConnections, `${P}.maintain-connections.title`, `${P}.maintain-connections.description`)
366
+ .endPermission()
367
+ .addPermission(keys.ManageIntegrationActions, `${P}.manage-integration-actions.title`, `${P}.manage-integration-actions.description`)
368
+ .endPermission()
369
+ .endGroup();
370
+ }
371
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementPermissionDefinitionProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
372
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementPermissionDefinitionProvider }); }
373
+ }
374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementPermissionDefinitionProvider, decorators: [{
375
+ type: Injectable
376
+ }] });
377
+
378
+ //#region ---- Imports ----
379
+ //#endregion
380
+ //#region ---- Settings Provider ----
381
+ const I18N$1 = '@integration-management:settings';
382
+ class AXMIntegrationManagementSettingProvider {
383
+ async provide(context) {
384
+ if (context.hasGroup('integrations')) {
385
+ return;
386
+ }
387
+ context
388
+ .addGroup('integrations', `${I18N$1}.group.nav-title`, `${I18N$1}.group.description`, 'fa-light fa-plug', `${I18N$1}.group.title`, 45)
389
+ .endGroup();
390
+ }
391
+ }
392
+ //#endregion
393
+
394
+ const I18N = '@integration-management:settings.domains.other';
395
+ /** Fallback domain for connectors not yet assigned to a first-class integration domain. */
396
+ class AXMIntegrationLegacyDomainProvider {
397
+ async provide(context) {
398
+ context.register({
399
+ id: 'other',
400
+ module: RootConfig.module.name,
401
+ displayName: `${I18N}.title`,
402
+ description: `${I18N}.description`,
403
+ icon: 'fa-light fa-plug',
404
+ category: AXP_INTEGRATION_CATEGORY.Other,
405
+ capabilities: [],
406
+ sortOrder: 999,
407
+ });
408
+ }
409
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationLegacyDomainProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
410
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationLegacyDomainProvider }); }
411
+ }
412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationLegacyDomainProvider, decorators: [{
413
+ type: Injectable
414
+ }] });
415
+
416
+ //#region ---- Runtime service implementation ----
417
+ class AXMIntegrationRuntimeServiceImpl extends AXPIntegrationRuntimeService {
418
+ constructor() {
419
+ super(...arguments);
420
+ this.registry = inject(AXPIntegrationProviderRegistryService);
421
+ this.connectionManager = inject(AXMIntegrationConnectionManager);
422
+ this.secretStore = inject(AXP_INTEGRATION_SECRET_STORE, { optional: true });
423
+ this.runtimeProviders = inject(AXP_INTEGRATION_RUNTIME_PROVIDER, { optional: true });
424
+ }
425
+ async getProvider(id) {
426
+ return this.registry.getOrThrow(id);
427
+ }
428
+ async listProviders() {
429
+ return this.registry.list();
430
+ }
431
+ async getConnection(options) {
432
+ const connection = await this.resolveConnection(options);
433
+ return toSafeIntegrationConnectionDto(connection);
434
+ }
435
+ async withClient(options, fn) {
436
+ const connection = await this.resolveConnection(options);
437
+ if (!connection.secretRef) {
438
+ throw new AXPIntegrationNotConnectedError(options.providerId);
439
+ }
440
+ const ctx = await this.buildRuntimeContext({
441
+ ...toSafeIntegrationConnectionDto(connection),
442
+ secretRef: connection.secretRef,
443
+ });
444
+ const hooks = await this.resolveRuntimeHooks(options.providerId);
445
+ if (!hooks?.createClient) {
446
+ throw new Error(`Integration provider '${options.providerId}' does not expose a runtime client.`);
447
+ }
448
+ const client = await hooks.createClient(ctx);
449
+ return fn(client, ctx);
450
+ }
451
+ async buildRuntimeContext(connection) {
452
+ const { tenantId, applicationId, userId } = this.connectionManager.getSessionContext();
453
+ return {
454
+ tenantId,
455
+ applicationId,
456
+ userId,
457
+ connectionId: connection.id,
458
+ providerId: connection.providerId,
459
+ connectionScope: connection.connectionScope,
460
+ connectionKey: connection.connectionKey,
461
+ authMethodType: connection.authMethodType,
462
+ instanceUrl: connection.instanceUrl,
463
+ config: connection.config,
464
+ secretRef: connection.secretRef,
465
+ };
466
+ }
467
+ async resolveConnection(options) {
468
+ const provider = await this.registry.getOrThrow(options.providerId);
469
+ const connectionScope = options.connectionScope ?? 'user';
470
+ const connectionKey = defaultTo(options.connectionKey, provider.defaultConnectionKey ?? 'default');
471
+ if (options.requiredCapabilities?.length) {
472
+ const missing = options.requiredCapabilities.filter((c) => !provider.capabilities.includes(c));
473
+ if (missing.length) {
474
+ throw new Error(`Provider '${provider.id}' is missing capabilities: ${missing.join(', ')}`);
475
+ }
476
+ }
477
+ const connection = await this.connectionManager.findByUniqueKey({
478
+ providerId: options.providerId,
479
+ connectionScope,
480
+ connectionKey,
481
+ });
482
+ if (!connection || connection.status !== AXP_INTEGRATION_CONNECTION_STATUS.Connected) {
483
+ throw new AXPIntegrationNotConnectedError(options.providerId);
484
+ }
485
+ if (connection.expiresAt && new Date(connection.expiresAt).getTime() < Date.now()) {
486
+ throw new AXPIntegrationExpiredError(options.providerId, connection.id);
487
+ }
488
+ if (options.requiredScopes?.length && connection.grantedScopes) {
489
+ const missingScopes = options.requiredScopes.filter((s) => !connection.grantedScopes.includes(s));
490
+ if (!isEmpty(missingScopes)) {
491
+ throw new AXPIntegrationMissingScopeError(options.providerId, missingScopes);
492
+ }
493
+ }
494
+ return connection;
495
+ }
496
+ async resolveRuntimeHooks(providerId) {
497
+ const providers = this.runtimeProviders ?? [];
498
+ for (const provider of providers) {
499
+ const resolved = provider instanceof Promise ? await provider : provider;
500
+ if (resolved.providerId === providerId) {
501
+ return resolved.getHooks();
502
+ }
503
+ }
504
+ return null;
505
+ }
506
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRuntimeServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
507
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRuntimeServiceImpl, providedIn: 'root' }); }
508
+ }
509
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationRuntimeServiceImpl, decorators: [{
510
+ type: Injectable,
511
+ args: [{ providedIn: 'root' }]
512
+ }] });
513
+
514
+ //#region ---- Integration connection status ----
515
+ /** Matches integration-connections-panel `isProviderConnected` semantics. */
516
+ function isActiveIntegrationConnection(connection) {
517
+ if (!connection) {
518
+ return false;
519
+ }
520
+ return (connection.status === AXP_INTEGRATION_CONNECTION_STATUS.Connected &&
521
+ !connection.isRevoked &&
522
+ !connection.isDisabled);
523
+ }
524
+ //#endregion
525
+
526
+ //#region ---- Integration expression scope ----
527
+ /**
528
+ * Exposes integration connection checks in expression strings, e.g.
529
+ * `{{ integration.isUserConnected('telegram') }}`.
530
+ */
531
+ class AXMIntegrationEvaluatorScopeProvider {
532
+ constructor() {
533
+ this.connectionManager = inject(AXMIntegrationConnectionManager);
534
+ }
535
+ async provide(context) {
536
+ context.addScope('integration', {
537
+ isUserConnected: (providerId, connectionKey) => this.isConnected(providerId, AXP_INTEGRATION_CONNECTION_SCOPE.User, connectionKey),
538
+ isTenantConfigured: (providerId, connectionKey) => this.isConnected(providerId, AXP_INTEGRATION_CONNECTION_SCOPE.Tenant, connectionKey),
539
+ });
540
+ }
541
+ async isConnected(providerId, scope, connectionKey) {
542
+ const normalizedProviderId = String(providerId ?? '').trim();
543
+ if (!normalizedProviderId) {
544
+ return false;
545
+ }
546
+ const connection = await this.connectionManager.findByUniqueKey({
547
+ providerId: normalizedProviderId,
548
+ connectionScope: scope,
549
+ connectionKey: defaultTo(connectionKey, 'default'),
550
+ });
551
+ return isActiveIntegrationConnection(connection);
552
+ }
553
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationEvaluatorScopeProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
554
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationEvaluatorScopeProvider }); }
555
+ }
556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationEvaluatorScopeProvider, decorators: [{
557
+ type: Injectable
558
+ }] });
559
+
560
+ //#region ----- Imports -----
561
+ //#endregion
562
+ //#region ----- Routes -----
563
+ function integrationManagementRoutesFactory() {
564
+ return [
565
+ {
566
+ path: ':app/admin/integrations',
567
+ canActivate: [...AXP_PROTECTED_ROUTE_GUARDS],
568
+ data: { tab: true, rootLayout: true },
569
+ loadComponent: () => AXPRootLayoutComponent,
570
+ children: [
571
+ {
572
+ path: '',
573
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integrations-page.component-Q-SHidYA.mjs').then((c) => c.AXMIntegrationsPageComponent),
574
+ data: { reuse: true },
575
+ },
576
+ ],
577
+ },
578
+ ];
579
+ }
580
+ //#endregion
581
+
582
+ const integrationOAuthCallbackRoutes = [
583
+ // App-agnostic callback first — must win over `:appName/...` (else appName="integrations").
584
+ {
585
+ path: 'integrations/oauth/callback/:providerId',
586
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
587
+ },
588
+ // Legacy app-prefixed callback (older provider redirect URI configs).
589
+ {
590
+ path: ':appName/integrations/oauth/callback/:providerId',
591
+ loadComponent: () => import('./acorex-platform-module-integration-management-client-integration-oauth-callback-page.component-XhloXUsZ.mjs').then((c) => c.AXMIntegrationOAuthCallbackPageComponent),
592
+ },
593
+ ];
594
+
595
+ //#region ---- Imports ----
596
+ //#endregion
597
+ //#region ---- Module ----
598
+ class AXMIntegrationManagementModule {
599
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
600
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementModule, imports: [CommonModule, AXPRuntimeModule] }); }
601
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementModule, providers: [
602
+ {
603
+ provide: ROUTES,
604
+ multi: true,
605
+ useFactory: () => [...integrationManagementRoutesFactory(), ...integrationOAuthCallbackRoutes],
606
+ },
607
+ {
608
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
609
+ useValue: IntegrationManagementManifest,
610
+ multi: true,
611
+ },
612
+ {
613
+ provide: AXP_PERMISSION_DEFINITION_PROVIDER,
614
+ useClass: AXMIntegrationManagementPermissionDefinitionProvider,
615
+ multi: true,
616
+ },
617
+ {
618
+ provide: AXP_MENU_PROVIDER,
619
+ useClass: AXMIntegrationManagementMenuProvider,
620
+ multi: true,
621
+ },
622
+ {
623
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
624
+ useClass: AXMIntegrationManagementSettingProvider,
625
+ multi: true,
626
+ },
627
+ {
628
+ provide: AXP_INTEGRATION_DOMAIN_PROVIDER,
629
+ useClass: AXMIntegrationLegacyDomainProvider,
630
+ multi: true,
631
+ },
632
+ {
633
+ provide: AXPIntegrationRuntimeService,
634
+ useClass: AXMIntegrationRuntimeServiceImpl,
635
+ },
636
+ {
637
+ provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
638
+ useClass: AXMIntegrationEvaluatorScopeProvider,
639
+ multi: true,
640
+ },
641
+ provideCommandSetups([
642
+ {
643
+ key: AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials,
644
+ command: () => import('./acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs').then((c) => c.ConnectWithCredentialsCommand),
645
+ },
646
+ {
647
+ key: AXMIntegrationManagementCommandKeys.ConnectionDisconnect,
648
+ command: () => import('./acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs').then((c) => c.DisconnectConnectionCommand),
649
+ },
650
+ {
651
+ key: AXMIntegrationManagementCommandKeys.ConnectionDelete,
652
+ command: () => import('./acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs').then((c) => c.DeleteConnectionCommand),
653
+ },
654
+ {
655
+ key: AXMIntegrationManagementCommandKeys.ConnectionUpdate,
656
+ command: () => import('./acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs').then((c) => c.UpdateConnectionCommand),
657
+ },
658
+ {
659
+ key: AXMIntegrationManagementCommandKeys.ConnectionValidate,
660
+ command: () => import('./acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs').then((c) => c.ValidateConnectionCommand),
661
+ },
662
+ ]),
663
+ provideQuerySetups([
664
+ {
665
+ key: AXMIntegrationManagementQueryKeys.DomainList,
666
+ loader: () => import('./acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs').then((c) => c.ListDomainsQuery),
667
+ },
668
+ {
669
+ key: AXMIntegrationManagementQueryKeys.ProviderList,
670
+ loader: () => import('./acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs').then((c) => c.ListProvidersQuery),
671
+ },
672
+ {
673
+ key: AXMIntegrationManagementQueryKeys.ProviderGet,
674
+ loader: () => import('./acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs').then((c) => c.GetProviderQuery),
675
+ },
676
+ {
677
+ key: AXMIntegrationManagementQueryKeys.ConnectionListMine,
678
+ loader: () => import('./acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs').then((c) => c.ListMyConnectionsQuery),
679
+ },
680
+ ]),
681
+ ], imports: [CommonModule, AXPRuntimeModule] }); }
682
+ }
683
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMIntegrationManagementModule, decorators: [{
684
+ type: NgModule,
685
+ args: [{
686
+ imports: [CommonModule, AXPRuntimeModule],
687
+ providers: [
688
+ {
689
+ provide: ROUTES,
690
+ multi: true,
691
+ useFactory: () => [...integrationManagementRoutesFactory(), ...integrationOAuthCallbackRoutes],
692
+ },
693
+ {
694
+ provide: AXP_MODULE_MANIFEST_PROVIDER,
695
+ useValue: IntegrationManagementManifest,
696
+ multi: true,
697
+ },
698
+ {
699
+ provide: AXP_PERMISSION_DEFINITION_PROVIDER,
700
+ useClass: AXMIntegrationManagementPermissionDefinitionProvider,
701
+ multi: true,
702
+ },
703
+ {
704
+ provide: AXP_MENU_PROVIDER,
705
+ useClass: AXMIntegrationManagementMenuProvider,
706
+ multi: true,
707
+ },
708
+ {
709
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
710
+ useClass: AXMIntegrationManagementSettingProvider,
711
+ multi: true,
712
+ },
713
+ {
714
+ provide: AXP_INTEGRATION_DOMAIN_PROVIDER,
715
+ useClass: AXMIntegrationLegacyDomainProvider,
716
+ multi: true,
717
+ },
718
+ {
719
+ provide: AXPIntegrationRuntimeService,
720
+ useClass: AXMIntegrationRuntimeServiceImpl,
721
+ },
722
+ {
723
+ provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
724
+ useClass: AXMIntegrationEvaluatorScopeProvider,
725
+ multi: true,
726
+ },
727
+ provideCommandSetups([
728
+ {
729
+ key: AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials,
730
+ command: () => import('./acorex-platform-module-integration-management-client-connect-with-credentials.command-DO_zqjHV.mjs').then((c) => c.ConnectWithCredentialsCommand),
731
+ },
732
+ {
733
+ key: AXMIntegrationManagementCommandKeys.ConnectionDisconnect,
734
+ command: () => import('./acorex-platform-module-integration-management-client-disconnect-connection.command-B4HeDA1n.mjs').then((c) => c.DisconnectConnectionCommand),
735
+ },
736
+ {
737
+ key: AXMIntegrationManagementCommandKeys.ConnectionDelete,
738
+ command: () => import('./acorex-platform-module-integration-management-client-delete-connection.command-DQ_kn8dH.mjs').then((c) => c.DeleteConnectionCommand),
739
+ },
740
+ {
741
+ key: AXMIntegrationManagementCommandKeys.ConnectionUpdate,
742
+ command: () => import('./acorex-platform-module-integration-management-client-update-connection.command-BNMR-t12.mjs').then((c) => c.UpdateConnectionCommand),
743
+ },
744
+ {
745
+ key: AXMIntegrationManagementCommandKeys.ConnectionValidate,
746
+ command: () => import('./acorex-platform-module-integration-management-client-validate-connection.command-CGtb_GPX.mjs').then((c) => c.ValidateConnectionCommand),
747
+ },
748
+ ]),
749
+ provideQuerySetups([
750
+ {
751
+ key: AXMIntegrationManagementQueryKeys.DomainList,
752
+ loader: () => import('./acorex-platform-module-integration-management-client-list-domains.query--GGD6J46.mjs').then((c) => c.ListDomainsQuery),
753
+ },
754
+ {
755
+ key: AXMIntegrationManagementQueryKeys.ProviderList,
756
+ loader: () => import('./acorex-platform-module-integration-management-client-list-providers.query-ODKJ_UhI.mjs').then((c) => c.ListProvidersQuery),
757
+ },
758
+ {
759
+ key: AXMIntegrationManagementQueryKeys.ProviderGet,
760
+ loader: () => import('./acorex-platform-module-integration-management-client-get-provider.query-Ds10RwnU.mjs').then((c) => c.GetProviderQuery),
761
+ },
762
+ {
763
+ key: AXMIntegrationManagementQueryKeys.ConnectionListMine,
764
+ loader: () => import('./acorex-platform-module-integration-management-client-list-my-connections.query-CmHu1qFm.mjs').then((c) => c.ListMyConnectionsQuery),
765
+ },
766
+ ]),
767
+ ],
768
+ }]
769
+ }] });
770
+
771
+ /**
772
+ * Generated bundle index. Do not edit.
773
+ */
774
+
775
+ export { AXMIntegrationConnectionManager, AXMIntegrationManagementModule, AXP_INTEGRATION_CREDENTIAL_MASK, IntegrationManagementManifest, hasConfiguredIntegrationCredentials, isMaskedIntegrationCredential, scrubDisconnectedConnectionConfig, toSafeIntegrationConnectionDto };
776
+ //# sourceMappingURL=acorex-platform-module-integration-management-client.mjs.map