@uipath/uipath-typescript 1.1.0 → 1.1.2

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.
@@ -3876,6 +3876,16 @@ class ExecutionContext {
3876
3876
  * Checks if code is running in a browser environment
3877
3877
  */
3878
3878
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
3879
+ const isInActionCenter = isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
3880
+
3881
+ /**
3882
+ * Session storage keys used by the auth module
3883
+ */
3884
+ const AUTH_STORAGE_KEYS = {
3885
+ TOKEN_PREFIX: 'uipath_sdk_user_token-',
3886
+ OAUTH_CONTEXT: 'uipath_sdk_oauth_context',
3887
+ CODE_VERIFIER: 'uipath_sdk_code_verifier',
3888
+ };
3879
3889
 
3880
3890
  // Type guard to check if config has OAuth credentials
3881
3891
  function hasOAuthConfig(config) {
@@ -4169,6 +4179,102 @@ function getErrorDetails(error) {
4169
4179
  };
4170
4180
  }
4171
4181
 
4182
+ var ActionCenterEventNames;
4183
+ (function (ActionCenterEventNames) {
4184
+ ActionCenterEventNames["TOKENREFRESHED"] = "AC.tokenRefreshed";
4185
+ ActionCenterEventNames["REFRESHTOKEN"] = "AC.refreshToken";
4186
+ })(ActionCenterEventNames || (ActionCenterEventNames = {}));
4187
+
4188
+ const AUTHENTICATION_TIMEOUT = 8000;
4189
+ class ActionCenterTokenManager {
4190
+ constructor(config, onTokenRefreshed) {
4191
+ this.config = config;
4192
+ this.onTokenRefreshed = onTokenRefreshed;
4193
+ this.parentOrigin = new URLSearchParams(window.location.search).get('basedomain');
4194
+ this.refreshPromise = null;
4195
+ }
4196
+ async refreshAccessToken(tokenInfo) {
4197
+ if (!this.isTokenExpired(tokenInfo)) {
4198
+ return tokenInfo.token;
4199
+ }
4200
+ if (this.refreshPromise) {
4201
+ return this.refreshPromise;
4202
+ }
4203
+ this.refreshPromise = new Promise((resolve, reject) => {
4204
+ const content = {
4205
+ clientId: this.config.clientId,
4206
+ scope: this.config.scope,
4207
+ };
4208
+ this.sendMessageToParent(ActionCenterEventNames.REFRESHTOKEN, content);
4209
+ const messageListener = (event) => {
4210
+ if (event.origin !== this.parentOrigin)
4211
+ return;
4212
+ if (event.data?.eventType !== ActionCenterEventNames.TOKENREFRESHED)
4213
+ return;
4214
+ clearTimeout(timer);
4215
+ if (event.data?.content?.token) {
4216
+ const { accessToken, expiresAt } = event.data.content.token;
4217
+ this.onTokenRefreshed({ token: accessToken, type: 'secret', expiresAt });
4218
+ resolve(accessToken);
4219
+ }
4220
+ else {
4221
+ reject(new AuthenticationError({
4222
+ message: 'Failed to fetch access token',
4223
+ statusCode: HttpStatus.UNAUTHORIZED,
4224
+ }));
4225
+ }
4226
+ this.refreshPromise = null;
4227
+ this.cleanup(messageListener);
4228
+ };
4229
+ const timer = setTimeout(() => {
4230
+ reject(new AuthenticationError({
4231
+ message: 'Failed to fetch access token',
4232
+ statusCode: HttpStatus.UNAUTHORIZED,
4233
+ }));
4234
+ this.refreshPromise = null;
4235
+ this.cleanup(messageListener);
4236
+ }, AUTHENTICATION_TIMEOUT);
4237
+ window.addEventListener('message', messageListener);
4238
+ });
4239
+ return this.refreshPromise;
4240
+ }
4241
+ isTokenExpired(tokenInfo) {
4242
+ if (!tokenInfo?.expiresAt) {
4243
+ return true;
4244
+ }
4245
+ return new Date() >= tokenInfo.expiresAt;
4246
+ }
4247
+ sendMessageToParent(eventType, content) {
4248
+ if (window.parent && this.isValidOrigin(this.parentOrigin)) {
4249
+ try {
4250
+ window.parent.postMessage({ eventType, content }, this.parentOrigin);
4251
+ }
4252
+ catch (error) {
4253
+ console.warn('Failed to send message to Action Center', JSON.stringify(error));
4254
+ }
4255
+ }
4256
+ }
4257
+ cleanup(messageListener) {
4258
+ window.removeEventListener('message', messageListener);
4259
+ }
4260
+ isValidOrigin(origin) {
4261
+ const ALLOWED_ORIGINS = ['https://alpha.uipath.com', 'https://staging.uipath.com', 'https://cloud.uipath.com'];
4262
+ if (!origin) {
4263
+ return false;
4264
+ }
4265
+ if (ALLOWED_ORIGINS.includes(origin)) {
4266
+ return true;
4267
+ }
4268
+ try {
4269
+ const url = new URL(origin);
4270
+ return url.hostname === 'localhost';
4271
+ }
4272
+ catch {
4273
+ return false;
4274
+ }
4275
+ }
4276
+ }
4277
+
4172
4278
  /**
4173
4279
  * TokenManager is responsible for managing authentication tokens.
4174
4280
  * It provides token operations for a specific client ID.
@@ -4186,8 +4292,12 @@ class TokenManager {
4186
4292
  this.executionContext = executionContext;
4187
4293
  this.config = config;
4188
4294
  this.isOAuth = isOAuth;
4189
- this.STORAGE_KEY_PREFIX = 'uipath_sdk_user_token-';
4190
4295
  this.refreshPromise = null;
4296
+ this.actionCenterTokenManager = null;
4297
+ if (isInActionCenter) {
4298
+ this.actionCenterTokenManager = new ActionCenterTokenManager(config, (tokenInfo) => this.setToken(tokenInfo));
4299
+ this.isOAuth = false;
4300
+ }
4191
4301
  }
4192
4302
  /**
4193
4303
  * Checks if a token is expired
@@ -4215,6 +4325,9 @@ class TokenManager {
4215
4325
  message: 'No authentication token available. Make sure to initialize the SDK first.'
4216
4326
  });
4217
4327
  }
4328
+ if (this.actionCenterTokenManager) {
4329
+ return await this.actionCenterTokenManager.refreshAccessToken(tokenInfo);
4330
+ }
4218
4331
  // For secret-based tokens, they never expire
4219
4332
  if (tokenInfo.type === 'secret') {
4220
4333
  return tokenInfo.token;
@@ -4240,7 +4353,7 @@ class TokenManager {
4240
4353
  * Gets the storage key for this TokenManager instance
4241
4354
  */
4242
4355
  _getStorageKey() {
4243
- return `${this.STORAGE_KEY_PREFIX}${this.config.clientId}`;
4356
+ return `${AUTH_STORAGE_KEYS.TOKEN_PREFIX}${this.config.clientId}`;
4244
4357
  }
4245
4358
  /**
4246
4359
  * Loads token from session storage if available
@@ -4359,9 +4472,6 @@ class TokenManager {
4359
4472
  clearToken() {
4360
4473
  this.currentToken = undefined;
4361
4474
  this.executionContext.set('tokenInfo', undefined);
4362
- const headers = this.executionContext.getHeaders();
4363
- delete headers['Authorization'];
4364
- this.executionContext.setHeaders(headers);
4365
4475
  // Remove from session storage if this is an OAuth token
4366
4476
  if (isBrowser && this.isOAuth) {
4367
4477
  try {
@@ -4377,10 +4487,6 @@ class TokenManager {
4377
4487
  */
4378
4488
  _updateExecutionContext(tokenInfo) {
4379
4489
  this.executionContext.set('tokenInfo', tokenInfo);
4380
- // Update authorization header
4381
- this.executionContext.setHeaders({
4382
- 'Authorization': `Bearer ${tokenInfo.token}`
4383
- });
4384
4490
  }
4385
4491
  /**
4386
4492
  * Refreshes the access token using the stored refresh token.
@@ -4468,8 +4574,15 @@ const IDENTITY_ENDPOINTS = {
4468
4574
 
4469
4575
  class AuthService {
4470
4576
  constructor(config, executionContext) {
4471
- // Check if we should use stored OAuth context instead of provided config
4472
- const storedContext = AuthService.getStoredOAuthContext();
4577
+ // Only use stored OAuth context when completing an active callback (URL has ?code=).
4578
+ // If stored context exists but we're NOT in a callback, it's stale from a
4579
+ // failed/abandoned flow (e.g. scope mismatch, invalid redirect URI) and must
4580
+ // be cleared so the fresh config takes effect.
4581
+ const isCallback = AuthService.isInOAuthCallback();
4582
+ const storedContext = isCallback ? AuthService.getStoredOAuthContext() : null;
4583
+ if (!isCallback) {
4584
+ AuthService._clearStoredOAuthContext();
4585
+ }
4473
4586
  const effectiveConfig = storedContext ? AuthService._mergeConfigWithContext(config, storedContext) : config;
4474
4587
  this.config = effectiveConfig;
4475
4588
  const isOAuth = hasOAuthConfig(effectiveConfig);
@@ -4486,7 +4599,7 @@ class AuthService {
4486
4599
  return false;
4487
4600
  const urlParams = new URLSearchParams(window.location.search);
4488
4601
  const code = urlParams.get('code');
4489
- const hasCodeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
4602
+ const hasCodeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4490
4603
  return !!(code && hasCodeVerifier);
4491
4604
  }
4492
4605
  /**
@@ -4497,7 +4610,7 @@ class AuthService {
4497
4610
  return null;
4498
4611
  }
4499
4612
  try {
4500
- const stored = sessionStorage.getItem('uipath_sdk_oauth_context');
4613
+ const stored = sessionStorage.getItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4501
4614
  if (!stored) {
4502
4615
  return null;
4503
4616
  }
@@ -4505,17 +4618,33 @@ class AuthService {
4505
4618
  // Validate required fields
4506
4619
  if (!context.codeVerifier || !context.clientId || !context.redirectUri ||
4507
4620
  !context.baseUrl || !context.orgName) {
4508
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4621
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4509
4622
  return null;
4510
4623
  }
4511
4624
  return context;
4512
4625
  }
4513
4626
  catch (error) {
4514
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4627
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4515
4628
  console.warn('Failed to parse stored OAuth context from session storage', error);
4516
4629
  return null;
4517
4630
  }
4518
4631
  }
4632
+ /**
4633
+ * Clear stale OAuth context from session storage.
4634
+ * Called when there is no active OAuth callback, meaning any stored context
4635
+ * is left over from a failed or abandoned flow.
4636
+ */
4637
+ static _clearStoredOAuthContext() {
4638
+ if (!isBrowser)
4639
+ return;
4640
+ try {
4641
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4642
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4643
+ }
4644
+ catch {
4645
+ // Ignore storage errors
4646
+ }
4647
+ }
4519
4648
  /**
4520
4649
  * Merges provided config with stored OAuth context, prioritizing stored values
4521
4650
  */
@@ -4586,7 +4715,7 @@ class AuthService {
4586
4715
  throw new Error('OAuth flow is only supported in browser environments');
4587
4716
  }
4588
4717
  // Check if we have a stored code verifier indicating we're in an OAuth flow
4589
- const codeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
4718
+ const codeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4590
4719
  const isInOAuthFlow = codeVerifier !== null;
4591
4720
  const urlParams = new URLSearchParams(window.location.search);
4592
4721
  const code = urlParams.get('code');
@@ -4595,7 +4724,7 @@ class AuthService {
4595
4724
  // We're expecting a callback - validate parameters
4596
4725
  if (!code) {
4597
4726
  // Clear stored state on error
4598
- sessionStorage.removeItem('uipath_sdk_code_verifier');
4727
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4599
4728
  throw new Error('Authorization code missing in OAuth callback');
4600
4729
  }
4601
4730
  // Validate the authorization code format before using it
@@ -4603,7 +4732,7 @@ class AuthService {
4603
4732
  const codePattern = /^[A-Za-z0-9\-._~+/]+=*$/;
4604
4733
  if (!codePattern.test(code)) {
4605
4734
  // Clear stored state on error
4606
- sessionStorage.removeItem('uipath_sdk_code_verifier');
4735
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4607
4736
  throw new Error('Invalid authorization code format');
4608
4737
  }
4609
4738
  // Authorization code is present and validated, so we can exchange it for a token.
@@ -4644,6 +4773,24 @@ class AuthService {
4644
4773
  hasValidToken() {
4645
4774
  return this.tokenManager.hasValidToken();
4646
4775
  }
4776
+ /**
4777
+ * Clears all authentication state including tokens and stored OAuth context.
4778
+ */
4779
+ logout() {
4780
+ this.tokenManager.clearToken();
4781
+ // Clear OAuth context from session storage. These are normally cleaned up in _handleOAuthCallback after a successful
4782
+ // token exchange, but if a user calls logout() while an OAuth flow is
4783
+ // mid-redirect (before callback completes), they'd be left behind.
4784
+ if (isBrowser) {
4785
+ try {
4786
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4787
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4788
+ }
4789
+ catch (error) {
4790
+ console.warn('Failed to clear OAuth context from session storage', error);
4791
+ }
4792
+ }
4793
+ }
4647
4794
  /**
4648
4795
  * Get the current token
4649
4796
  */
@@ -4775,8 +4922,8 @@ class AuthService {
4775
4922
  tenantName: this.config.tenantName,
4776
4923
  scope
4777
4924
  };
4778
- sessionStorage.setItem('uipath_sdk_oauth_context', JSON.stringify(oauthContext));
4779
- sessionStorage.setItem('uipath_sdk_code_verifier', codeVerifier);
4925
+ sessionStorage.setItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT, JSON.stringify(oauthContext));
4926
+ sessionStorage.setItem(AUTH_STORAGE_KEYS.CODE_VERIFIER, codeVerifier);
4780
4927
  const authUrl = this.getAuthorizationUrl({
4781
4928
  clientId,
4782
4929
  redirectUri,
@@ -4786,7 +4933,7 @@ class AuthService {
4786
4933
  window.location.href = authUrl;
4787
4934
  }
4788
4935
  async _handleOAuthCallback(code, clientId, redirectUri) {
4789
- const codeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
4936
+ const codeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4790
4937
  if (!codeVerifier) {
4791
4938
  throw new Error('Code verifier not found in session storage. Authentication may have been interrupted.');
4792
4939
  }
@@ -4797,8 +4944,8 @@ class AuthService {
4797
4944
  codeVerifier
4798
4945
  });
4799
4946
  // Clear OAuth context and code verifier after successful token exchange
4800
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4801
- sessionStorage.removeItem('uipath_sdk_code_verifier');
4947
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4948
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4802
4949
  const url = new URL(window.location.href);
4803
4950
  url.searchParams.delete('code');
4804
4951
  url.searchParams.delete('state');
@@ -4806,14 +4953,42 @@ class AuthService {
4806
4953
  }
4807
4954
  }
4808
4955
 
4956
+ /**
4957
+ * Check if config has all required base fields
4958
+ */
4959
+ function hasRequiredBaseFields(config) {
4960
+ return Boolean(config.baseUrl && config.orgName && config.tenantName);
4961
+ }
4962
+ /**
4963
+ * Check if config has exactly one authentication method (secret XOR oauth)
4964
+ * Returns true if exactly one auth method is present, false otherwise
4965
+ */
4966
+ function hasValidAuthConfig(config) {
4967
+ const hasSecret = hasSecretConfig(config);
4968
+ const hasOAuth = hasOAuthConfig(config);
4969
+ // XOR: exactly one auth method, not both, not neither
4970
+ return hasSecret !== hasOAuth;
4971
+ }
4809
4972
  function validateConfig(config) {
4810
- if (!config.baseUrl || !config.orgName || !config.tenantName) {
4973
+ if (!hasRequiredBaseFields(config)) {
4811
4974
  throw new Error('Missing required configuration: baseUrl, orgName, and tenantName are required');
4812
4975
  }
4813
- if (!hasSecretConfig(config) && !hasOAuthConfig(config)) {
4814
- throw new Error('Invalid configuration: must provide either secret or (clientId, redirectUri, and scope)');
4976
+ const hasSecret = hasSecretConfig(config);
4977
+ const hasOAuth = hasOAuthConfig(config);
4978
+ if (hasSecret && hasOAuth) {
4979
+ throw new Error('Invalid configuration: cannot provide both secret and OAuth credentials. Choose one authentication method.');
4980
+ }
4981
+ if (!hasSecret && !hasOAuth) {
4982
+ throw new Error('Invalid configuration: must provide either secret or OAuth credentials (clientId, redirectUri, and scope)');
4815
4983
  }
4816
4984
  }
4985
+ /**
4986
+ * Check if partial config has all required fields for a complete SDK config
4987
+ * Requires base fields and exactly one authentication method (secret XOR oauth)
4988
+ */
4989
+ function isCompleteConfig(config) {
4990
+ return hasRequiredBaseFields(config) && hasValidAuthConfig(config);
4991
+ }
4817
4992
  function normalizeBaseUrl(url) {
4818
4993
  return url.endsWith('/') ? url.slice(0, -1) : url;
4819
4994
  }
@@ -4824,7 +4999,7 @@ function normalizeBaseUrl(url) {
4824
4999
  // Connection string placeholder that will be replaced during build
4825
5000
  const CONNECTION_STRING = "InstrumentationKey=a6efa11d-1feb-4508-9738-e13e12dcae5e;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/;ApplicationId=7c58eb1c-9581-4ba6-839e-11725848a037";
4826
5001
  // SDK Version placeholder
4827
- const SDK_VERSION = "1.1.0";
5002
+ const SDK_VERSION = "1.1.2";
4828
5003
  const VERSION = "Version";
4829
5004
  const SERVICE = "Service";
4830
5005
  const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
@@ -5032,6 +5207,65 @@ const telemetryClient = TelemetryClient.getInstance();
5032
5207
  /**
5033
5208
  * SDK Track decorator and function for telemetry
5034
5209
  */
5210
+ /**
5211
+ * Common tracking logic shared between method and function decorators
5212
+ */
5213
+ function createTrackedFunction(originalFunction, nameOrOptions, fallbackName, opts) {
5214
+ return function (...args) {
5215
+ // Determine if we should track this call
5216
+ let shouldTrack = true;
5217
+ if (opts.condition !== undefined) {
5218
+ if (typeof opts.condition === 'function') {
5219
+ shouldTrack = opts.condition.apply(this, args);
5220
+ }
5221
+ else {
5222
+ shouldTrack = opts.condition;
5223
+ }
5224
+ }
5225
+ // Track the event if enabled
5226
+ if (shouldTrack) {
5227
+ // Use the full name provided in the decorator (e.g., "Queue.GetAll")
5228
+ const serviceMethod = typeof nameOrOptions === 'string'
5229
+ ? nameOrOptions
5230
+ : fallbackName;
5231
+ // Use 'Sdk.Run' as the name and serviceMethod as the service
5232
+ telemetryClient.track(serviceMethod, SDK_RUN_EVENT, opts.attributes);
5233
+ }
5234
+ // Execute the original function
5235
+ return originalFunction.apply(this, args);
5236
+ };
5237
+ }
5238
+ /**
5239
+ * Track decorator that can be used to automatically track function calls
5240
+ *
5241
+ * Usage:
5242
+ * @track("Service.Method")
5243
+ * function myFunction() { ... }
5244
+ *
5245
+ * @track("Queue.GetAll")
5246
+ * async getAll() { ... }
5247
+ *
5248
+ * @track("Tasks.Create")
5249
+ * async create() { ... }
5250
+ *
5251
+ * @track("Assets.Update", { condition: false })
5252
+ * function myFunction() { ... }
5253
+ *
5254
+ * @track("Processes.Start", { attributes: { customProp: "value" } })
5255
+ * function myFunction() { ... }
5256
+ */
5257
+ function track(nameOrOptions, options) {
5258
+ return function decorator(_target, propertyKey, descriptor) {
5259
+ const opts = typeof nameOrOptions === 'object' ? nameOrOptions : options || {};
5260
+ if (descriptor && typeof descriptor.value === 'function') {
5261
+ // Method decorator
5262
+ descriptor.value = createTrackedFunction(descriptor.value, nameOrOptions, propertyKey || 'unknown_method', opts);
5263
+ return descriptor;
5264
+ }
5265
+ // Function decorator
5266
+ return (originalFunction) => createTrackedFunction(originalFunction, nameOrOptions, originalFunction.name || 'unknown_function', opts);
5267
+ };
5268
+ }
5035
5269
  /**
5036
5270
  * Direct tracking function
5037
5271
  */
@@ -5094,19 +5328,71 @@ class SDKInternalsRegistry {
5094
5328
  }
5095
5329
  }
5096
5330
 
5097
- var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5331
+ /**
5332
+ * UiPath meta tag names for runtime configuration.
5333
+ *
5334
+ * These meta tags are injected at deployment time by the Apps Service
5335
+ * to configure SDK authentication and asset resolution in production.
5336
+ */
5337
+ var UiPathMetaTags;
5338
+ (function (UiPathMetaTags) {
5339
+ // SDK/OAuth configuration
5340
+ UiPathMetaTags["CLIENT_ID"] = "uipath:client-id";
5341
+ UiPathMetaTags["SCOPE"] = "uipath:scope";
5342
+ UiPathMetaTags["ORG_NAME"] = "uipath:org-name";
5343
+ UiPathMetaTags["TENANT_NAME"] = "uipath:tenant-name";
5344
+ UiPathMetaTags["BASE_URL"] = "uipath:base-url";
5345
+ UiPathMetaTags["REDIRECT_URI"] = "uipath:redirect-uri";
5346
+ // Asset resolution and routing
5347
+ UiPathMetaTags["CDN_BASE"] = "uipath:cdn-base";
5348
+ UiPathMetaTags["APP_BASE"] = "uipath:app-base";
5349
+ })(UiPathMetaTags || (UiPathMetaTags = {}));
5350
+
5351
+ /**
5352
+ * Get the content of a meta tag by name.
5353
+ * Returns undefined if not in browser environment or meta tag is not found.
5354
+ */
5355
+ function getMetaTagContent(name) {
5356
+ if (!isBrowser)
5357
+ return undefined;
5358
+ return document.querySelector(`meta[name="${name}"]`)?.content;
5359
+ }
5360
+ /**
5361
+ * Load configuration from HTML meta tags injected at runtime.
5362
+ * These meta tags are injected by @uipath/coded-apps during build
5363
+ * or by the Apps service during deployment.
5364
+ *
5365
+ * Returns partial config with values found, or null if no meta tags present.
5366
+ */
5367
+ function loadFromMetaTags() {
5368
+ if (!isBrowser)
5369
+ return null;
5370
+ const config = {
5371
+ clientId: getMetaTagContent(UiPathMetaTags.CLIENT_ID),
5372
+ scope: getMetaTagContent(UiPathMetaTags.SCOPE),
5373
+ orgName: getMetaTagContent(UiPathMetaTags.ORG_NAME),
5374
+ tenantName: getMetaTagContent(UiPathMetaTags.TENANT_NAME),
5375
+ baseUrl: getMetaTagContent(UiPathMetaTags.BASE_URL),
5376
+ redirectUri: getMetaTagContent(UiPathMetaTags.REDIRECT_URI),
5377
+ };
5378
+ const hasAnyValue = Object.values(config).some(Boolean);
5379
+ return hasAnyValue ? config : null;
5380
+ }
5381
+
5382
+ var _UiPath_instances, _UiPath_config, _UiPath_authService, _UiPath_initialized, _UiPath_partialConfig, _UiPath_initializeWithConfig, _UiPath_loadConfig;
5098
5383
  /**
5099
5384
  * UiPath - Core SDK class for authentication and configuration management.
5100
5385
  *
5101
5386
  * Handles authentication, configuration, and provides access to SDK internals
5102
5387
  * for service instantiation in the modular pattern.
5103
5388
  *
5389
+ * Supports two usage patterns:
5390
+ * 1. Full config in constructor — for server-side or explicit configuration
5391
+ * 2. No config / partial config — loads from meta tags injected by @uipath/coded-apps plugin
5392
+ *
5104
5393
  * @example
5105
5394
  * ```typescript
5106
- * // Modular pattern
5107
- * import { UiPath } from '@uipath/uipath-typescript/core';
5108
- * import { Entities } from '@uipath/uipath-typescript/entities';
5109
- *
5395
+ * // Explicit config
5110
5396
  * const sdk = new UiPath({
5111
5397
  * baseUrl: 'https://cloud.uipath.com',
5112
5398
  * orgName: 'myorg',
@@ -5115,70 +5401,47 @@ var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5115
5401
  * redirectUri: 'http://localhost:3000/callback',
5116
5402
  * scope: 'OR.Users OR.Robots'
5117
5403
  * });
5118
- *
5119
5404
  * await sdk.initialize();
5405
+ * ```
5120
5406
  *
5121
- * const entitiesService = new Entities(sdk);
5122
- * const allEntities = await entitiesService.getAll();
5407
+ * @example
5408
+ * ```typescript
5409
+ * // Auto-load from meta tags (coded apps)
5410
+ * const sdk = new UiPath();
5411
+ * await sdk.initialize();
5123
5412
  * ```
5124
5413
  */
5125
5414
  class UiPath {
5126
5415
  constructor(config) {
5416
+ _UiPath_instances.add(this);
5127
5417
  // Private fields - true runtime privacy, not visible via Object.keys()
5128
5418
  _UiPath_config.set(this, void 0);
5129
5419
  _UiPath_authService.set(this, void 0);
5130
5420
  _UiPath_initialized.set(this, false);
5131
- // Validate and normalize the configuration
5132
- validateConfig(config);
5133
- const hasSecretAuth = hasSecretConfig(config);
5134
- const hasOAuthAuth = hasOAuthConfig(config);
5135
- // Initialize core components
5136
- const internalConfig = new UiPathConfig({
5137
- baseUrl: normalizeBaseUrl(config.baseUrl),
5138
- orgName: config.orgName,
5139
- tenantName: config.tenantName,
5140
- secret: hasSecretAuth ? config.secret : undefined,
5141
- clientId: hasOAuthAuth ? config.clientId : undefined,
5142
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5143
- scope: hasOAuthAuth ? config.scope : undefined
5144
- });
5145
- const executionContext = new ExecutionContext();
5146
- __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5147
- __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5148
- // Store internals in SDKInternalsRegistry (not visible on instance)
5149
- SDKInternalsRegistry.set(this, {
5150
- config: internalConfig,
5151
- context: executionContext,
5152
- tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5153
- });
5154
- // Expose read-only config for user convenience
5155
- this.config = {
5156
- baseUrl: internalConfig.baseUrl,
5157
- orgName: internalConfig.orgName,
5158
- tenantName: internalConfig.tenantName
5159
- };
5160
- // Initialize telemetry with SDK configuration
5161
- telemetryClient.initialize({
5162
- baseUrl: config.baseUrl,
5163
- orgName: config.orgName,
5164
- tenantName: config.tenantName,
5165
- clientId: hasOAuthAuth ? config.clientId : undefined,
5166
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5167
- });
5168
- // Track SDK initialization
5169
- trackEvent('Sdk.Auth');
5170
- // Auto-initialize for secret-based auth
5171
- if (hasSecretAuth) {
5172
- __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret);
5173
- __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5421
+ _UiPath_partialConfig.set(this, void 0);
5422
+ // Load configuration from meta tags
5423
+ const configFromMetaTags = loadFromMetaTags();
5424
+ // Merge configuration: constructor config overrides meta tags
5425
+ const mergedConfig = config ? { ...configFromMetaTags, ...config } : configFromMetaTags;
5426
+ if (mergedConfig && isCompleteConfig(mergedConfig)) {
5427
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, mergedConfig);
5428
+ }
5429
+ else if (config) {
5430
+ __classPrivateFieldSet(this, _UiPath_partialConfig, config, "f");
5174
5431
  }
5175
5432
  }
5176
5433
  /**
5177
5434
  * Initialize the SDK based on the provided configuration.
5178
5435
  * This method handles both OAuth flow initiation and completion automatically.
5179
5436
  * For secret-based authentication, initialization is automatic and this returns immediately.
5437
+ * If no config was provided in constructor, loads from meta tags.
5180
5438
  */
5181
5439
  async initialize() {
5440
+ // Load config from meta tags if not provided in constructor
5441
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5442
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5443
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5444
+ }
5182
5445
  // For secret-based auth, it's already initialized in constructor
5183
5446
  if (hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5184
5447
  return;
@@ -5225,6 +5488,11 @@ class UiPath {
5225
5488
  if (!AuthService.isInOAuthCallback()) {
5226
5489
  throw new Error('Not in OAuth callback state. Call initialize() first to start OAuth flow.');
5227
5490
  }
5491
+ // Load config if not yet initialized
5492
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5493
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5494
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5495
+ }
5228
5496
  try {
5229
5497
  const success = await __classPrivateFieldGet(this, _UiPath_authService, "f").authenticate(__classPrivateFieldGet(this, _UiPath_config, "f"));
5230
5498
  if (success && this.isAuthenticated()) {
@@ -5242,16 +5510,85 @@ class UiPath {
5242
5510
  * Check if the user is authenticated (has valid token)
5243
5511
  */
5244
5512
  isAuthenticated() {
5245
- return __classPrivateFieldGet(this, _UiPath_authService, "f").hasValidToken();
5513
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.hasValidToken() ?? false;
5246
5514
  }
5247
5515
  /**
5248
5516
  * Get the current authentication token
5249
5517
  */
5250
5518
  getToken() {
5251
- return __classPrivateFieldGet(this, _UiPath_authService, "f").getToken();
5519
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.getToken();
5252
5520
  }
5253
- }
5254
- _UiPath_config = new WeakMap(), _UiPath_authService = new WeakMap(), _UiPath_initialized = new WeakMap();
5521
+ /**
5522
+ * Logout from the SDK, clearing all authentication state.
5523
+ * After calling this method, the user will need to re-initialize to authenticate again.
5524
+ */
5525
+ logout() {
5526
+ // Secret-based auth has no session to end — skip silently
5527
+ if (__classPrivateFieldGet(this, _UiPath_config, "f") && hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5528
+ return;
5529
+ }
5530
+ __classPrivateFieldGet(this, _UiPath_authService, "f")?.logout();
5531
+ __classPrivateFieldSet(this, _UiPath_initialized, false, "f");
5532
+ }
5533
+ }
5534
+ _UiPath_config = new WeakMap(), _UiPath_authService = new WeakMap(), _UiPath_initialized = new WeakMap(), _UiPath_partialConfig = new WeakMap(), _UiPath_instances = new WeakSet(), _UiPath_initializeWithConfig = function _UiPath_initializeWithConfig(config) {
5535
+ // Validate and normalize the configuration
5536
+ validateConfig(config);
5537
+ const hasSecretAuth = hasSecretConfig(config);
5538
+ const hasOAuthAuth = hasOAuthConfig(config);
5539
+ // Initialize core components
5540
+ const internalConfig = new UiPathConfig({
5541
+ baseUrl: normalizeBaseUrl(config.baseUrl),
5542
+ orgName: config.orgName,
5543
+ tenantName: config.tenantName,
5544
+ secret: hasSecretAuth ? config.secret : undefined,
5545
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5546
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5547
+ scope: hasOAuthAuth ? config.scope : undefined
5548
+ });
5549
+ const executionContext = new ExecutionContext();
5550
+ __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5551
+ __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5552
+ // Store internals in SDKInternalsRegistry (not visible on instance)
5553
+ SDKInternalsRegistry.set(this, {
5554
+ config: internalConfig,
5555
+ context: executionContext,
5556
+ tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5557
+ });
5558
+ // Expose read-only config for user convenience
5559
+ this.config = {
5560
+ baseUrl: internalConfig.baseUrl,
5561
+ orgName: internalConfig.orgName,
5562
+ tenantName: internalConfig.tenantName
5563
+ };
5564
+ // Initialize telemetry with SDK configuration
5565
+ telemetryClient.initialize({
5566
+ baseUrl: config.baseUrl,
5567
+ orgName: config.orgName,
5568
+ tenantName: config.tenantName,
5569
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5570
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5571
+ });
5572
+ // Track SDK initialization
5573
+ trackEvent('Sdk.Auth');
5574
+ /** Auto-initialize for secret-based auth
5575
+ * When viewed in Action Center, initialize tokenInfo with empty token. When an sdk call is made Action Center passes the token to sdk.
5576
+ */
5577
+ if (hasSecretAuth || isInActionCenter) {
5578
+ __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret ?? '');
5579
+ __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5580
+ }
5581
+ }, _UiPath_loadConfig = function _UiPath_loadConfig() {
5582
+ // Load from meta tags
5583
+ const metaConfig = loadFromMetaTags();
5584
+ // Merge with any partial config from constructor (constructor overrides meta tags)
5585
+ const merged = { ...metaConfig, ...__classPrivateFieldGet(this, _UiPath_partialConfig, "f") };
5586
+ if (!isCompleteConfig(merged)) {
5587
+ throw new Error('UiPath SDK configuration not found. ' +
5588
+ 'Ensure @uipath/coded-apps plugin is set up in your bundler to inject configuration during development and build.');
5589
+ }
5590
+ return merged;
5591
+ };
5255
5592
 
5256
5593
  /**
5257
5594
  * Constants used throughout the pagination system
@@ -5276,4 +5613,4 @@ function getLimitedPageSize(pageSize) {
5276
5613
  return Math.max(1, Math.min(pageSize, MAX_PAGE_SIZE));
5277
5614
  }
5278
5615
 
5279
- export { AuthenticationError, AuthorizationError, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, ErrorType, HttpStatus, MAX_PAGE_SIZE, NetworkError, NotFoundError, RateLimitError, ServerError, UiPath, UiPathError, ValidationError, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError };
5616
+ export { APP_NAME, AuthenticationError, AuthorizationError, CLOUD_CLIENT_ID, CLOUD_ORGANIZATION_NAME, CLOUD_REDIRECT_URI, CLOUD_ROLE_NAME, CLOUD_TENANT_NAME, CLOUD_URL, CONNECTION_STRING, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, ErrorType, HttpStatus, MAX_PAGE_SIZE, NetworkError, NotFoundError, RateLimitError, SDK_LOGGER_NAME, SDK_RUN_EVENT, SDK_SERVICE_NAME, SDK_VERSION, SERVICE, ServerError, UNKNOWN, UiPath, UiPathError, VERSION, ValidationError, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError, telemetryClient, track, trackEvent };