@pax8-cta/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +198 -0
- package/dist/auth/device-code-login.d.ts +40 -0
- package/dist/auth/device-code-login.d.ts.map +1 -0
- package/dist/auth/device-code-login.js +59 -0
- package/dist/auth/device-code-login.js.map +1 -0
- package/dist/auth/gdap-client.d.ts +81 -0
- package/dist/auth/gdap-client.d.ts.map +1 -0
- package/dist/auth/gdap-client.js +128 -0
- package/dist/auth/gdap-client.js.map +1 -0
- package/dist/auth/index.d.ts +19 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +19 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-manager.d.ts +54 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +150 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +27 -0
- package/dist/client.js.map +1 -0
- package/dist/config/client.d.ts +24 -0
- package/dist/config/client.d.ts.map +1 -0
- package/dist/config/client.js +18 -0
- package/dist/config/client.js.map +1 -0
- package/dist/config/index.d.ts +18 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +81 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +271 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +751 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +556 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +116 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +170 -0
- package/dist/constants.js.map +1 -0
- package/dist/dataverse/agent-resolver.d.ts +98 -0
- package/dist/dataverse/agent-resolver.d.ts.map +1 -0
- package/dist/dataverse/agent-resolver.js +185 -0
- package/dist/dataverse/agent-resolver.js.map +1 -0
- package/dist/dataverse/client.d.ts +104 -0
- package/dist/dataverse/client.d.ts.map +1 -0
- package/dist/dataverse/client.js +272 -0
- package/dist/dataverse/client.js.map +1 -0
- package/dist/dataverse/connection-refs.d.ts +115 -0
- package/dist/dataverse/connection-refs.d.ts.map +1 -0
- package/dist/dataverse/connection-refs.js +203 -0
- package/dist/dataverse/connection-refs.js.map +1 -0
- package/dist/dataverse/index.d.ts +20 -0
- package/dist/dataverse/index.d.ts.map +1 -0
- package/dist/dataverse/index.js +20 -0
- package/dist/dataverse/index.js.map +1 -0
- package/dist/dataverse/solution-ops.d.ts +100 -0
- package/dist/dataverse/solution-ops.d.ts.map +1 -0
- package/dist/dataverse/solution-ops.js +288 -0
- package/dist/dataverse/solution-ops.js.map +1 -0
- package/dist/errors.d.ts +171 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +178 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mock/demo-data.d.ts +213 -0
- package/dist/mock/demo-data.d.ts.map +1 -0
- package/dist/mock/demo-data.js +1096 -0
- package/dist/mock/demo-data.js.map +1 -0
- package/dist/mock/demo-deployment-store.d.ts +77 -0
- package/dist/mock/demo-deployment-store.d.ts.map +1 -0
- package/dist/mock/demo-deployment-store.js +85 -0
- package/dist/mock/demo-deployment-store.js.map +1 -0
- package/dist/powerplatform/admin-client.d.ts +226 -0
- package/dist/powerplatform/admin-client.d.ts.map +1 -0
- package/dist/powerplatform/admin-client.js +315 -0
- package/dist/powerplatform/admin-client.js.map +1 -0
- package/dist/powerplatform/index.d.ts +18 -0
- package/dist/powerplatform/index.d.ts.map +1 -0
- package/dist/powerplatform/index.js +18 -0
- package/dist/powerplatform/index.js.map +1 -0
- package/dist/powerplatform/tenant-discovery.d.ts +100 -0
- package/dist/powerplatform/tenant-discovery.d.ts.map +1 -0
- package/dist/powerplatform/tenant-discovery.js +205 -0
- package/dist/powerplatform/tenant-discovery.js.map +1 -0
- package/dist/preconditions/check.d.ts +41 -0
- package/dist/preconditions/check.d.ts.map +1 -0
- package/dist/preconditions/check.js +173 -0
- package/dist/preconditions/check.js.map +1 -0
- package/dist/preconditions/index.d.ts +20 -0
- package/dist/preconditions/index.d.ts.map +1 -0
- package/dist/preconditions/index.js +20 -0
- package/dist/preconditions/index.js.map +1 -0
- package/dist/preconditions/loader.d.ts +33 -0
- package/dist/preconditions/loader.d.ts.map +1 -0
- package/dist/preconditions/loader.js +65 -0
- package/dist/preconditions/loader.js.map +1 -0
- package/dist/preconditions/schema.d.ts +103 -0
- package/dist/preconditions/schema.d.ts.map +1 -0
- package/dist/preconditions/schema.js +93 -0
- package/dist/preconditions/schema.js.map +1 -0
- package/dist/preconditions/types.d.ts +118 -0
- package/dist/preconditions/types.d.ts.map +1 -0
- package/dist/preconditions/types.js +17 -0
- package/dist/preconditions/types.js.map +1 -0
- package/dist/queue/index.d.ts +17 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +17 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/memory-queue.d.ts +86 -0
- package/dist/queue/memory-queue.d.ts.map +1 -0
- package/dist/queue/memory-queue.js +221 -0
- package/dist/queue/memory-queue.js.map +1 -0
- package/dist/services/audit-log.d.ts +59 -0
- package/dist/services/audit-log.d.ts.map +1 -0
- package/dist/services/audit-log.js +193 -0
- package/dist/services/audit-log.js.map +1 -0
- package/dist/services/auth-error-parser.d.ts +36 -0
- package/dist/services/auth-error-parser.d.ts.map +1 -0
- package/dist/services/auth-error-parser.js +90 -0
- package/dist/services/auth-error-parser.js.map +1 -0
- package/dist/services/deployment-doctor.d.ts +109 -0
- package/dist/services/deployment-doctor.d.ts.map +1 -0
- package/dist/services/deployment-doctor.js +476 -0
- package/dist/services/deployment-doctor.js.map +1 -0
- package/dist/services/deployment-notifications.d.ts +41 -0
- package/dist/services/deployment-notifications.d.ts.map +1 -0
- package/dist/services/deployment-notifications.js +161 -0
- package/dist/services/deployment-notifications.js.map +1 -0
- package/dist/services/deployment-progress.d.ts +89 -0
- package/dist/services/deployment-progress.d.ts.map +1 -0
- package/dist/services/deployment-progress.js +244 -0
- package/dist/services/deployment-progress.js.map +1 -0
- package/dist/services/deployment-service.d.ts +97 -0
- package/dist/services/deployment-service.d.ts.map +1 -0
- package/dist/services/deployment-service.js +375 -0
- package/dist/services/deployment-service.js.map +1 -0
- package/dist/services/drift-analyzer.d.ts +86 -0
- package/dist/services/drift-analyzer.d.ts.map +1 -0
- package/dist/services/drift-analyzer.js +273 -0
- package/dist/services/drift-analyzer.js.map +1 -0
- package/dist/services/environment-setup.d.ts +97 -0
- package/dist/services/environment-setup.d.ts.map +1 -0
- package/dist/services/environment-setup.js +250 -0
- package/dist/services/environment-setup.js.map +1 -0
- package/dist/services/health-check.d.ts +168 -0
- package/dist/services/health-check.d.ts.map +1 -0
- package/dist/services/health-check.js +705 -0
- package/dist/services/health-check.js.map +1 -0
- package/dist/services/index.d.ts +39 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +39 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/logger.d.ts +139 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +268 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/notification-service.d.ts +55 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/risk-analyzer.d.ts +252 -0
- package/dist/services/risk-analyzer.d.ts.map +1 -0
- package/dist/services/risk-analyzer.js +866 -0
- package/dist/services/risk-analyzer.js.map +1 -0
- package/dist/services/rollback.d.ts +57 -0
- package/dist/services/rollback.d.ts.map +1 -0
- package/dist/services/rollback.js +270 -0
- package/dist/services/rollback.js.map +1 -0
- package/dist/services/scheduler.d.ts +80 -0
- package/dist/services/scheduler.d.ts.map +1 -0
- package/dist/services/scheduler.js +350 -0
- package/dist/services/scheduler.js.map +1 -0
- package/dist/services/secrets.d.ts +31 -0
- package/dist/services/secrets.d.ts.map +1 -0
- package/dist/services/secrets.js +206 -0
- package/dist/services/secrets.js.map +1 -0
- package/dist/services/settings-service.d.ts +132 -0
- package/dist/services/settings-service.d.ts.map +1 -0
- package/dist/services/settings-service.js +378 -0
- package/dist/services/settings-service.js.map +1 -0
- package/dist/services/solution-diff.d.ts +127 -0
- package/dist/services/solution-diff.d.ts.map +1 -0
- package/dist/services/solution-diff.js +260 -0
- package/dist/services/solution-diff.js.map +1 -0
- package/dist/services/solution-mode-detector.d.ts +35 -0
- package/dist/services/solution-mode-detector.d.ts.map +1 -0
- package/dist/services/solution-mode-detector.js +84 -0
- package/dist/services/solution-mode-detector.js.map +1 -0
- package/dist/services/tenant-resolver.d.ts +55 -0
- package/dist/services/tenant-resolver.d.ts.map +1 -0
- package/dist/services/tenant-resolver.js +126 -0
- package/dist/services/tenant-resolver.js.map +1 -0
- package/dist/services/unmanaged-customizations.d.ts +104 -0
- package/dist/services/unmanaged-customizations.d.ts.map +1 -0
- package/dist/services/unmanaged-customizations.js +521 -0
- package/dist/services/unmanaged-customizations.js.map +1 -0
- package/dist/services/url-templater.d.ts +184 -0
- package/dist/services/url-templater.d.ts.map +1 -0
- package/dist/services/url-templater.js +327 -0
- package/dist/services/url-templater.js.map +1 -0
- package/dist/services/version-checker.d.ts +108 -0
- package/dist/services/version-checker.d.ts.map +1 -0
- package/dist/services/version-checker.js +403 -0
- package/dist/services/version-checker.js.map +1 -0
- package/dist/services/waves.d.ts +90 -0
- package/dist/services/waves.d.ts.map +1 -0
- package/dist/services/waves.js +222 -0
- package/dist/services/waves.js.map +1 -0
- package/dist/services/webhook.d.ts +95 -0
- package/dist/services/webhook.d.ts.map +1 -0
- package/dist/services/webhook.js +244 -0
- package/dist/services/webhook.js.map +1 -0
- package/dist/utils/deployment-tools.d.ts +110 -0
- package/dist/utils/deployment-tools.d.ts.map +1 -0
- package/dist/utils/deployment-tools.js +121 -0
- package/dist/utils/deployment-tools.js.map +1 -0
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Centralized constants for the Pax8 CTA application
|
|
18
|
+
*
|
|
19
|
+
* All magic numbers, timeouts, and configuration values should be defined here
|
|
20
|
+
* to ensure consistency and maintainability across the codebase.
|
|
21
|
+
*/
|
|
22
|
+
/** One second in milliseconds */
|
|
23
|
+
export declare const ONE_SECOND_MS = 1000;
|
|
24
|
+
/** One minute in milliseconds */
|
|
25
|
+
export declare const ONE_MINUTE_MS: number;
|
|
26
|
+
/** One hour in milliseconds */
|
|
27
|
+
export declare const ONE_HOUR_MS: number;
|
|
28
|
+
/** One day in milliseconds */
|
|
29
|
+
export declare const ONE_DAY_MS: number;
|
|
30
|
+
/** One week in milliseconds */
|
|
31
|
+
export declare const ONE_WEEK_MS: number;
|
|
32
|
+
/** One month in milliseconds (approximate: 30 days) */
|
|
33
|
+
export declare const ONE_MONTH_MS: number;
|
|
34
|
+
/** Power Platform Administrator role definition ID (Azure AD built-in role) */
|
|
35
|
+
export declare const POWER_PLATFORM_ADMIN_ROLE_ID = "11648597-926c-4cf3-9c36-bcebb0ba8dcc";
|
|
36
|
+
/** Buffer time before token expiry to trigger a refresh (5 minutes) */
|
|
37
|
+
export declare const TOKEN_REFRESH_BUFFER_MS: number;
|
|
38
|
+
/** Default cache TTL for secrets manager (5 minutes) */
|
|
39
|
+
export declare const DEFAULT_SECRETS_CACHE_TTL_MS: number;
|
|
40
|
+
/** Maximum iterations when searching for next cron match (~1 year of minutes) */
|
|
41
|
+
export declare const MAX_SCHEDULE_ITERATIONS: number;
|
|
42
|
+
/** Default max concurrent tenant deployments */
|
|
43
|
+
export declare const DEFAULT_DEPLOYMENT_CONCURRENCY = 3;
|
|
44
|
+
/** Duration to cache health check results (15 minutes) */
|
|
45
|
+
export declare const HEALTH_CHECK_CACHE_DURATION_MS: number;
|
|
46
|
+
/** Default number of retries for health check endpoint requests */
|
|
47
|
+
export declare const DEFAULT_HEALTH_CHECK_RETRIES = 3;
|
|
48
|
+
/** Default expected HTTP status for health check endpoints */
|
|
49
|
+
export declare const DEFAULT_HEALTH_CHECK_EXPECTED_STATUS = 200;
|
|
50
|
+
/** Default number of retries for webhook delivery */
|
|
51
|
+
export declare const DEFAULT_WEBHOOK_RETRIES = 3;
|
|
52
|
+
/** Default concurrency for in-memory queue processing */
|
|
53
|
+
export declare const DEFAULT_MEMORY_QUEUE_CONCURRENCY = 5;
|
|
54
|
+
/** Default max retries for in-memory queue jobs */
|
|
55
|
+
export declare const DEFAULT_MEMORY_QUEUE_RETRIES = 3;
|
|
56
|
+
/** Default retry delay for in-memory queue jobs (5 seconds) */
|
|
57
|
+
export declare const DEFAULT_MEMORY_QUEUE_RETRY_DELAY_MS: number;
|
|
58
|
+
/** Initial delay before retrying failed jobs (10 seconds) */
|
|
59
|
+
export declare const JOB_RETRY_INITIAL_DELAY_MS: number;
|
|
60
|
+
/** How long to keep completed jobs in the queue (24 hours) */
|
|
61
|
+
export declare const COMPLETED_JOB_RETENTION_MS: number;
|
|
62
|
+
/** Maximum number of completed jobs to keep */
|
|
63
|
+
export declare const COMPLETED_JOB_MAX_COUNT = 1000;
|
|
64
|
+
/** How long to keep failed jobs in the queue (7 days) */
|
|
65
|
+
export declare const FAILED_JOB_RETENTION_MS: number;
|
|
66
|
+
/** How long to keep scheduled job records (7 days) */
|
|
67
|
+
export declare const SCHEDULED_JOB_RETENTION_MS: number;
|
|
68
|
+
/** Maximum scheduled jobs to keep */
|
|
69
|
+
export declare const SCHEDULED_JOB_MAX_COUNT = 100;
|
|
70
|
+
/** How long to keep failed scheduled job records (30 days) */
|
|
71
|
+
export declare const SCHEDULED_FAILED_JOB_RETENTION_MS: number;
|
|
72
|
+
/** Default number of retry attempts for deployment jobs */
|
|
73
|
+
export declare const DEFAULT_JOB_ATTEMPTS = 3;
|
|
74
|
+
/** Default polling interval when checking import status (5 seconds) */
|
|
75
|
+
export declare const SOLUTION_IMPORT_POLL_INTERVAL_MS: number;
|
|
76
|
+
/** Default timeout for solution import operations (5 minutes) */
|
|
77
|
+
export declare const SOLUTION_IMPORT_TIMEOUT_MS: number;
|
|
78
|
+
/** Extended timeout for large solution imports (10 minutes) */
|
|
79
|
+
export declare const SOLUTION_IMPORT_EXTENDED_TIMEOUT_MS: number;
|
|
80
|
+
/** Default timeout for rollback operations (10 minutes) */
|
|
81
|
+
export declare const ROLLBACK_TIMEOUT_MS: number;
|
|
82
|
+
/** Default timeout for health check operations (30 seconds) */
|
|
83
|
+
export declare const HEALTH_CHECK_TIMEOUT_MS: number;
|
|
84
|
+
/** Default number of retries for health checks */
|
|
85
|
+
export declare const HEALTH_CHECK_DEFAULT_RETRIES = 2;
|
|
86
|
+
/** Default window for approval (24 hours) */
|
|
87
|
+
export declare const DEFAULT_APPROVAL_WINDOW_MS: number;
|
|
88
|
+
/** Maximum number of audit entries to keep in memory */
|
|
89
|
+
export declare const AUDIT_LOG_MAX_ENTRIES = 10000;
|
|
90
|
+
/** Default rate limit - max requests per duration */
|
|
91
|
+
export declare const DEFAULT_RATE_LIMIT_MAX = 10;
|
|
92
|
+
/** Default rate limit duration (1 minute) */
|
|
93
|
+
export declare const DEFAULT_RATE_LIMIT_DURATION_MS: number;
|
|
94
|
+
/**
|
|
95
|
+
* Default worker concurrency
|
|
96
|
+
* Set to 3 for SQLite safety - better-sqlite3 can struggle with >3-5 concurrent writes
|
|
97
|
+
* For production with high concurrency needs, use PostgreSQL instead
|
|
98
|
+
*/
|
|
99
|
+
export declare const DEFAULT_WORKER_CONCURRENCY = 3;
|
|
100
|
+
/** Minimum time to display a deployment step (for UI legibility) */
|
|
101
|
+
export declare const MIN_STEP_DISPLAY_MS = 600;
|
|
102
|
+
/** Delay between starting tenant deployments in live view */
|
|
103
|
+
export declare const TENANT_START_STAGGER_MS = 300;
|
|
104
|
+
/** Maximum concurrent tenant deployments in demo mode */
|
|
105
|
+
export declare const MAX_CONCURRENT_DEMO_TENANTS = 2;
|
|
106
|
+
/** SSE heartbeat interval to keep connection alive (30 seconds) */
|
|
107
|
+
export declare const SSE_HEARTBEAT_INTERVAL_MS: number;
|
|
108
|
+
/** SSE connection timeout - max time before stream is closed (10 minutes) */
|
|
109
|
+
export declare const SSE_TIMEOUT_MS: number;
|
|
110
|
+
/** Default delay between cancellation checks during step processing */
|
|
111
|
+
export declare const CANCELLATION_CHECK_INTERVAL_MS = 200;
|
|
112
|
+
/** One hour in seconds (for duration strings like "1h") */
|
|
113
|
+
export declare const ONE_HOUR_SECONDS = 3600;
|
|
114
|
+
/** One day in seconds */
|
|
115
|
+
export declare const ONE_DAY_SECONDS: number;
|
|
116
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Centralized constants for the Pax8 CTA application
|
|
18
|
+
*
|
|
19
|
+
* All magic numbers, timeouts, and configuration values should be defined here
|
|
20
|
+
* to ensure consistency and maintainability across the codebase.
|
|
21
|
+
*/
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// TIME CONSTANTS (in milliseconds)
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/** One second in milliseconds */
|
|
26
|
+
export const ONE_SECOND_MS = 1000;
|
|
27
|
+
/** One minute in milliseconds */
|
|
28
|
+
export const ONE_MINUTE_MS = 60 * ONE_SECOND_MS;
|
|
29
|
+
/** One hour in milliseconds */
|
|
30
|
+
export const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
|
|
31
|
+
/** One day in milliseconds */
|
|
32
|
+
export const ONE_DAY_MS = 24 * ONE_HOUR_MS;
|
|
33
|
+
/** One week in milliseconds */
|
|
34
|
+
export const ONE_WEEK_MS = 7 * ONE_DAY_MS;
|
|
35
|
+
/** One month in milliseconds (approximate: 30 days) */
|
|
36
|
+
export const ONE_MONTH_MS = 30 * ONE_DAY_MS;
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// AZURE AD / GDAP ROLE IDS
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/** Power Platform Administrator role definition ID (Azure AD built-in role) */
|
|
41
|
+
export const POWER_PLATFORM_ADMIN_ROLE_ID = "11648597-926c-4cf3-9c36-bcebb0ba8dcc";
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// TOKEN MANAGEMENT
|
|
44
|
+
// ============================================================================
|
|
45
|
+
/** Buffer time before token expiry to trigger a refresh (5 minutes) */
|
|
46
|
+
export const TOKEN_REFRESH_BUFFER_MS = 5 * ONE_MINUTE_MS;
|
|
47
|
+
/** Default cache TTL for secrets manager (5 minutes) */
|
|
48
|
+
export const DEFAULT_SECRETS_CACHE_TTL_MS = 5 * ONE_MINUTE_MS;
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// SCHEDULER
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/** Maximum iterations when searching for next cron match (~1 year of minutes) */
|
|
53
|
+
export const MAX_SCHEDULE_ITERATIONS = 366 * 24 * 60;
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// DEPLOYMENT
|
|
56
|
+
// ============================================================================
|
|
57
|
+
/** Default max concurrent tenant deployments */
|
|
58
|
+
export const DEFAULT_DEPLOYMENT_CONCURRENCY = 3;
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// HEALTH CHECK
|
|
61
|
+
// ============================================================================
|
|
62
|
+
/** Duration to cache health check results (15 minutes) */
|
|
63
|
+
export const HEALTH_CHECK_CACHE_DURATION_MS = 15 * ONE_MINUTE_MS;
|
|
64
|
+
/** Default number of retries for health check endpoint requests */
|
|
65
|
+
export const DEFAULT_HEALTH_CHECK_RETRIES = 3;
|
|
66
|
+
/** Default expected HTTP status for health check endpoints */
|
|
67
|
+
export const DEFAULT_HEALTH_CHECK_EXPECTED_STATUS = 200;
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// WEBHOOK
|
|
70
|
+
// ============================================================================
|
|
71
|
+
/** Default number of retries for webhook delivery */
|
|
72
|
+
export const DEFAULT_WEBHOOK_RETRIES = 3;
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// MEMORY QUEUE
|
|
75
|
+
// ============================================================================
|
|
76
|
+
/** Default concurrency for in-memory queue processing */
|
|
77
|
+
export const DEFAULT_MEMORY_QUEUE_CONCURRENCY = 5;
|
|
78
|
+
/** Default max retries for in-memory queue jobs */
|
|
79
|
+
export const DEFAULT_MEMORY_QUEUE_RETRIES = 3;
|
|
80
|
+
/** Default retry delay for in-memory queue jobs (5 seconds) */
|
|
81
|
+
export const DEFAULT_MEMORY_QUEUE_RETRY_DELAY_MS = 5 * ONE_SECOND_MS;
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// QUEUE CONFIGURATION
|
|
84
|
+
// ============================================================================
|
|
85
|
+
/** Initial delay before retrying failed jobs (10 seconds) */
|
|
86
|
+
export const JOB_RETRY_INITIAL_DELAY_MS = 10 * ONE_SECOND_MS;
|
|
87
|
+
/** How long to keep completed jobs in the queue (24 hours) */
|
|
88
|
+
export const COMPLETED_JOB_RETENTION_MS = ONE_DAY_MS;
|
|
89
|
+
/** Maximum number of completed jobs to keep */
|
|
90
|
+
export const COMPLETED_JOB_MAX_COUNT = 1000;
|
|
91
|
+
/** How long to keep failed jobs in the queue (7 days) */
|
|
92
|
+
export const FAILED_JOB_RETENTION_MS = ONE_WEEK_MS;
|
|
93
|
+
/** How long to keep scheduled job records (7 days) */
|
|
94
|
+
export const SCHEDULED_JOB_RETENTION_MS = ONE_WEEK_MS;
|
|
95
|
+
/** Maximum scheduled jobs to keep */
|
|
96
|
+
export const SCHEDULED_JOB_MAX_COUNT = 100;
|
|
97
|
+
/** How long to keep failed scheduled job records (30 days) */
|
|
98
|
+
export const SCHEDULED_FAILED_JOB_RETENTION_MS = ONE_MONTH_MS;
|
|
99
|
+
/** Default number of retry attempts for deployment jobs */
|
|
100
|
+
export const DEFAULT_JOB_ATTEMPTS = 3;
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// SOLUTION IMPORT/EXPORT
|
|
103
|
+
// ============================================================================
|
|
104
|
+
/** Default polling interval when checking import status (5 seconds) */
|
|
105
|
+
export const SOLUTION_IMPORT_POLL_INTERVAL_MS = 5 * ONE_SECOND_MS;
|
|
106
|
+
/** Default timeout for solution import operations (5 minutes) */
|
|
107
|
+
export const SOLUTION_IMPORT_TIMEOUT_MS = 5 * ONE_MINUTE_MS;
|
|
108
|
+
/** Extended timeout for large solution imports (10 minutes) */
|
|
109
|
+
export const SOLUTION_IMPORT_EXTENDED_TIMEOUT_MS = 10 * ONE_MINUTE_MS;
|
|
110
|
+
/** Default timeout for rollback operations (10 minutes) */
|
|
111
|
+
export const ROLLBACK_TIMEOUT_MS = 10 * ONE_MINUTE_MS;
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// HEALTH CHECK
|
|
114
|
+
// ============================================================================
|
|
115
|
+
/** Default timeout for health check operations (30 seconds) */
|
|
116
|
+
export const HEALTH_CHECK_TIMEOUT_MS = 30 * ONE_SECOND_MS;
|
|
117
|
+
/** Default number of retries for health checks */
|
|
118
|
+
export const HEALTH_CHECK_DEFAULT_RETRIES = 2;
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// APPROVAL WORKFLOW
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/** Default window for approval (24 hours) */
|
|
123
|
+
export const DEFAULT_APPROVAL_WINDOW_MS = ONE_DAY_MS;
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// AUDIT LOG
|
|
126
|
+
// ============================================================================
|
|
127
|
+
/** Maximum number of audit entries to keep in memory */
|
|
128
|
+
export const AUDIT_LOG_MAX_ENTRIES = 10000;
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// API RATE LIMITING
|
|
131
|
+
// ============================================================================
|
|
132
|
+
/** Default rate limit - max requests per duration */
|
|
133
|
+
export const DEFAULT_RATE_LIMIT_MAX = 10;
|
|
134
|
+
/** Default rate limit duration (1 minute) */
|
|
135
|
+
export const DEFAULT_RATE_LIMIT_DURATION_MS = ONE_MINUTE_MS;
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// WORKER CONFIGURATION
|
|
138
|
+
// ============================================================================
|
|
139
|
+
/**
|
|
140
|
+
* Default worker concurrency
|
|
141
|
+
* Set to 3 for SQLite safety - better-sqlite3 can struggle with >3-5 concurrent writes
|
|
142
|
+
* For production with high concurrency needs, use PostgreSQL instead
|
|
143
|
+
*/
|
|
144
|
+
export const DEFAULT_WORKER_CONCURRENCY = 3;
|
|
145
|
+
// ============================================================================
|
|
146
|
+
// SSE/LIVE UPDATES
|
|
147
|
+
// ============================================================================
|
|
148
|
+
/** Minimum time to display a deployment step (for UI legibility) */
|
|
149
|
+
export const MIN_STEP_DISPLAY_MS = 600;
|
|
150
|
+
/** Delay between starting tenant deployments in live view */
|
|
151
|
+
export const TENANT_START_STAGGER_MS = 300;
|
|
152
|
+
/** Maximum concurrent tenant deployments in demo mode */
|
|
153
|
+
export const MAX_CONCURRENT_DEMO_TENANTS = 2;
|
|
154
|
+
/** SSE heartbeat interval to keep connection alive (30 seconds) */
|
|
155
|
+
export const SSE_HEARTBEAT_INTERVAL_MS = 30 * ONE_SECOND_MS;
|
|
156
|
+
/** SSE connection timeout - max time before stream is closed (10 minutes) */
|
|
157
|
+
export const SSE_TIMEOUT_MS = 10 * ONE_MINUTE_MS;
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// RETRY CONFIGURATION
|
|
160
|
+
// ============================================================================
|
|
161
|
+
/** Default delay between cancellation checks during step processing */
|
|
162
|
+
export const CANCELLATION_CHECK_INTERVAL_MS = 200;
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// TIME DURATIONS (in seconds, for compatibility with parseDuration)
|
|
165
|
+
// ============================================================================
|
|
166
|
+
/** One hour in seconds (for duration strings like "1h") */
|
|
167
|
+
export const ONE_HOUR_SECONDS = 3600;
|
|
168
|
+
/** One day in seconds */
|
|
169
|
+
export const ONE_DAY_SECONDS = 24 * ONE_HOUR_SECONDS;
|
|
170
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { DataverseClient, SolutionRecord } from "./client.js";
|
|
17
|
+
/**
|
|
18
|
+
* Bot (Copilot) record from Dataverse
|
|
19
|
+
*/
|
|
20
|
+
export interface BotRecord {
|
|
21
|
+
botid: string;
|
|
22
|
+
name: string;
|
|
23
|
+
schemaname?: string;
|
|
24
|
+
solutionid?: string;
|
|
25
|
+
statecode: number;
|
|
26
|
+
statuscode: number;
|
|
27
|
+
createdon: string;
|
|
28
|
+
modifiedon: string;
|
|
29
|
+
componentstate?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parsed M365 agent URL info
|
|
33
|
+
*/
|
|
34
|
+
export interface ParsedAgentUrl {
|
|
35
|
+
titleId: string;
|
|
36
|
+
possibleBotId: string | null;
|
|
37
|
+
prefix: string | null;
|
|
38
|
+
originalUrl: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolved agent info with solution details
|
|
42
|
+
*/
|
|
43
|
+
export interface ResolvedAgent {
|
|
44
|
+
bot: BotRecord;
|
|
45
|
+
solution: SolutionRecord;
|
|
46
|
+
titleId: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolves M365 agent URLs to Dataverse solutions for export
|
|
50
|
+
*/
|
|
51
|
+
export declare class AgentResolver {
|
|
52
|
+
private client;
|
|
53
|
+
constructor(client: DataverseClient);
|
|
54
|
+
/**
|
|
55
|
+
* Parse an M365 agent URL to extract the titleId
|
|
56
|
+
*
|
|
57
|
+
* URL format: https://m365.cloud.microsoft/chat/?titleId=P_8cfc4e6f-267e-db15-c6e7-3fc47a54f61e
|
|
58
|
+
*
|
|
59
|
+
* The titleId appears to be formatted as: {prefix}_{guid}
|
|
60
|
+
* Where prefix might indicate the type (P = Published?)
|
|
61
|
+
*/
|
|
62
|
+
parseAgentUrl(url: string): ParsedAgentUrl;
|
|
63
|
+
/**
|
|
64
|
+
* Query all bots in the environment
|
|
65
|
+
*/
|
|
66
|
+
listBots(): Promise<BotRecord[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Get a bot by its ID
|
|
69
|
+
*/
|
|
70
|
+
getBotById(botId: string): Promise<BotRecord | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Search for a bot by name (partial match)
|
|
73
|
+
*/
|
|
74
|
+
searchBotsByName(searchTerm: string): Promise<BotRecord[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Find the solution containing a specific bot
|
|
77
|
+
*
|
|
78
|
+
* Uses the solutioncomponent table to find which solution contains the bot
|
|
79
|
+
*/
|
|
80
|
+
findSolutionForBot(botId: string): Promise<SolutionRecord | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Resolve an M365 agent URL to its containing solution
|
|
83
|
+
*
|
|
84
|
+
* This tries multiple strategies:
|
|
85
|
+
* 1. Direct bot ID lookup (if titleId contains a valid GUID)
|
|
86
|
+
* 2. Search all bots for a matching ID pattern
|
|
87
|
+
* 3. Query solution components
|
|
88
|
+
*/
|
|
89
|
+
resolveUrlToSolution(url: string): Promise<ResolvedAgent>;
|
|
90
|
+
/**
|
|
91
|
+
* List all bots with their containing solutions
|
|
92
|
+
*/
|
|
93
|
+
listBotsWithSolutions(): Promise<Array<{
|
|
94
|
+
bot: BotRecord;
|
|
95
|
+
solution: SolutionRecord | null;
|
|
96
|
+
}>>;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=agent-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-resolver.d.ts","sourceRoot":"","sources":["../../src/dataverse/agent-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAaD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD;;GAEG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAE3C;;;;;;;OAOG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc;IAsC1C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAQtC;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAkB1D;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAShE;;;;OAIG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA6BvE;;;;;;;OAOG;IACG,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA+C/D;;OAEG;IACG,qBAAqB,IAAI,OAAO,CACpC,KAAK,CAAC;QAAE,GAAG,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE,CAAC,CAC3D;CAWF"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { AgentResolutionError, ErrorCode, DataverseApiError } from "../errors.js";
|
|
17
|
+
// Component types for bots in solutioncomponent table
|
|
18
|
+
// (unused constant kept for documentation - actual values are in componentTypes array)
|
|
19
|
+
/**
|
|
20
|
+
* Resolves M365 agent URLs to Dataverse solutions for export
|
|
21
|
+
*/
|
|
22
|
+
export class AgentResolver {
|
|
23
|
+
client;
|
|
24
|
+
constructor(client) {
|
|
25
|
+
this.client = client;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse an M365 agent URL to extract the titleId
|
|
29
|
+
*
|
|
30
|
+
* URL format: https://m365.cloud.microsoft/chat/?titleId=P_8cfc4e6f-267e-db15-c6e7-3fc47a54f61e
|
|
31
|
+
*
|
|
32
|
+
* The titleId appears to be formatted as: {prefix}_{guid}
|
|
33
|
+
* Where prefix might indicate the type (P = Published?)
|
|
34
|
+
*/
|
|
35
|
+
parseAgentUrl(url) {
|
|
36
|
+
const parsed = new URL(url);
|
|
37
|
+
const titleId = parsed.searchParams.get("titleId");
|
|
38
|
+
if (!titleId) {
|
|
39
|
+
throw new AgentResolutionError(ErrorCode.AGENT_URL_INVALID, "No titleId parameter found in URL", { agentUrl: url });
|
|
40
|
+
}
|
|
41
|
+
// Try to extract the GUID portion from titleId
|
|
42
|
+
// Format appears to be: P_8cfc4e6f-267e-db15-c6e7-3fc47a54f61e
|
|
43
|
+
const parts = titleId.split("_");
|
|
44
|
+
let prefix = null;
|
|
45
|
+
let possibleBotId = null;
|
|
46
|
+
if (parts.length >= 2) {
|
|
47
|
+
prefix = parts[0];
|
|
48
|
+
// The remaining parts might form a GUID (with dashes already present)
|
|
49
|
+
possibleBotId = parts.slice(1).join("_");
|
|
50
|
+
// Validate it looks like a GUID
|
|
51
|
+
const guidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
52
|
+
if (!guidPattern.test(possibleBotId)) {
|
|
53
|
+
possibleBotId = null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
titleId,
|
|
58
|
+
possibleBotId,
|
|
59
|
+
prefix,
|
|
60
|
+
originalUrl: url,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Query all bots in the environment
|
|
65
|
+
*/
|
|
66
|
+
async listBots() {
|
|
67
|
+
const result = await this.client.get("/bots", {
|
|
68
|
+
$select: "botid,name,schemaname,statecode,statuscode,createdon,modifiedon,componentstate",
|
|
69
|
+
$orderby: "modifiedon desc",
|
|
70
|
+
});
|
|
71
|
+
return result.value;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get a bot by its ID
|
|
75
|
+
*/
|
|
76
|
+
async getBotById(botId) {
|
|
77
|
+
try {
|
|
78
|
+
const result = await this.client.get(`/bots(${botId})`, {
|
|
79
|
+
$select: "botid,name,schemaname,statecode,statuscode,createdon,modifiedon,componentstate",
|
|
80
|
+
});
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// Bot not found - check by typed error code or status code
|
|
85
|
+
if ((error instanceof DataverseApiError && error.statusCode === 404) ||
|
|
86
|
+
(error instanceof Error && error.message.includes("404"))) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Search for a bot by name (partial match)
|
|
94
|
+
*/
|
|
95
|
+
async searchBotsByName(searchTerm) {
|
|
96
|
+
const result = await this.client.get("/bots", {
|
|
97
|
+
$select: "botid,name,schemaname,statecode,statuscode,createdon,modifiedon,componentstate",
|
|
98
|
+
$filter: `contains(name, '${searchTerm}')`,
|
|
99
|
+
$orderby: "modifiedon desc",
|
|
100
|
+
});
|
|
101
|
+
return result.value;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Find the solution containing a specific bot
|
|
105
|
+
*
|
|
106
|
+
* Uses the solutioncomponent table to find which solution contains the bot
|
|
107
|
+
*/
|
|
108
|
+
async findSolutionForBot(botId) {
|
|
109
|
+
// Search solutioncomponents for this bot
|
|
110
|
+
// Try multiple component types as the exact type for bots varies
|
|
111
|
+
const componentTypes = [10109, 10034, 300]; // Different possible bot component types
|
|
112
|
+
for (const componentType of componentTypes) {
|
|
113
|
+
const result = await this.client.get("/solutioncomponents", {
|
|
114
|
+
$select: "solutioncomponentid,componenttype,objectid,_solutionid_value",
|
|
115
|
+
$filter: `objectid eq '${botId}' and componenttype eq ${componentType}`,
|
|
116
|
+
});
|
|
117
|
+
if (result.value.length > 0) {
|
|
118
|
+
const component = result.value[0];
|
|
119
|
+
const solution = await this.client.get(`/solutions(${component._solutionid_value})`, {
|
|
120
|
+
$select: "solutionid,uniquename,friendlyname,version,ismanaged",
|
|
121
|
+
});
|
|
122
|
+
return solution;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve an M365 agent URL to its containing solution
|
|
129
|
+
*
|
|
130
|
+
* This tries multiple strategies:
|
|
131
|
+
* 1. Direct bot ID lookup (if titleId contains a valid GUID)
|
|
132
|
+
* 2. Search all bots for a matching ID pattern
|
|
133
|
+
* 3. Query solution components
|
|
134
|
+
*/
|
|
135
|
+
async resolveUrlToSolution(url) {
|
|
136
|
+
const parsed = this.parseAgentUrl(url);
|
|
137
|
+
// Strategy 1: Try direct bot ID lookup
|
|
138
|
+
if (parsed.possibleBotId) {
|
|
139
|
+
const bot = await this.getBotById(parsed.possibleBotId);
|
|
140
|
+
if (bot) {
|
|
141
|
+
const solution = await this.findSolutionForBot(bot.botid);
|
|
142
|
+
if (solution) {
|
|
143
|
+
return { bot, solution, titleId: parsed.titleId };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Strategy 2: List all bots and try to match by ID pattern
|
|
148
|
+
const allBots = await this.listBots();
|
|
149
|
+
// Try to find a bot whose ID matches part of the titleId
|
|
150
|
+
for (const bot of allBots) {
|
|
151
|
+
if (parsed.titleId.toLowerCase().includes(bot.botid.toLowerCase().replace(/-/g, ""))) {
|
|
152
|
+
const solution = await this.findSolutionForBot(bot.botid);
|
|
153
|
+
if (solution) {
|
|
154
|
+
return { bot, solution, titleId: parsed.titleId };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Strategy 3: Try matching by name containing the titleId prefix
|
|
159
|
+
if (parsed.prefix) {
|
|
160
|
+
const matchingBots = await this.searchBotsByName(parsed.prefix);
|
|
161
|
+
for (const bot of matchingBots) {
|
|
162
|
+
const solution = await this.findSolutionForBot(bot.botid);
|
|
163
|
+
if (solution) {
|
|
164
|
+
return { bot, solution, titleId: parsed.titleId };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
throw new AgentResolutionError(ErrorCode.AGENT_RESOLUTION_FAILED, `Could not resolve agent URL to a solution. titleId: ${parsed.titleId}\n` +
|
|
169
|
+
`Tried: direct lookup, pattern matching across ${allBots.length} bots.\n` +
|
|
170
|
+
`The titleId format may require M365 Graph API access to resolve.`, { agentUrl: url });
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* List all bots with their containing solutions
|
|
174
|
+
*/
|
|
175
|
+
async listBotsWithSolutions() {
|
|
176
|
+
const bots = await this.listBots();
|
|
177
|
+
const results = [];
|
|
178
|
+
for (const bot of bots) {
|
|
179
|
+
const solution = await this.findSolutionForBot(bot.botid);
|
|
180
|
+
results.push({ bot, solution });
|
|
181
|
+
}
|
|
182
|
+
return results;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=agent-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-resolver.js","sourceRoot":"","sources":["../../src/dataverse/agent-resolver.ts"],"names":[],"mappings":"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"}
|