@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.
package/dist/index.mjs CHANGED
@@ -3883,6 +3883,16 @@ class ExecutionContext {
3883
3883
  * Checks if code is running in a browser environment
3884
3884
  */
3885
3885
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
3886
+ const isInActionCenter = isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
3887
+
3888
+ /**
3889
+ * Session storage keys used by the auth module
3890
+ */
3891
+ const AUTH_STORAGE_KEYS = {
3892
+ TOKEN_PREFIX: 'uipath_sdk_user_token-',
3893
+ OAUTH_CONTEXT: 'uipath_sdk_oauth_context',
3894
+ CODE_VERIFIER: 'uipath_sdk_code_verifier',
3895
+ };
3886
3896
 
3887
3897
  // Type guard to check if config has OAuth credentials
3888
3898
  function hasOAuthConfig(config) {
@@ -4190,6 +4200,102 @@ function getErrorDetails(error) {
4190
4200
  };
4191
4201
  }
4192
4202
 
4203
+ var ActionCenterEventNames;
4204
+ (function (ActionCenterEventNames) {
4205
+ ActionCenterEventNames["TOKENREFRESHED"] = "AC.tokenRefreshed";
4206
+ ActionCenterEventNames["REFRESHTOKEN"] = "AC.refreshToken";
4207
+ })(ActionCenterEventNames || (ActionCenterEventNames = {}));
4208
+
4209
+ const AUTHENTICATION_TIMEOUT = 8000;
4210
+ class ActionCenterTokenManager {
4211
+ constructor(config, onTokenRefreshed) {
4212
+ this.config = config;
4213
+ this.onTokenRefreshed = onTokenRefreshed;
4214
+ this.parentOrigin = new URLSearchParams(window.location.search).get('basedomain');
4215
+ this.refreshPromise = null;
4216
+ }
4217
+ async refreshAccessToken(tokenInfo) {
4218
+ if (!this.isTokenExpired(tokenInfo)) {
4219
+ return tokenInfo.token;
4220
+ }
4221
+ if (this.refreshPromise) {
4222
+ return this.refreshPromise;
4223
+ }
4224
+ this.refreshPromise = new Promise((resolve, reject) => {
4225
+ const content = {
4226
+ clientId: this.config.clientId,
4227
+ scope: this.config.scope,
4228
+ };
4229
+ this.sendMessageToParent(ActionCenterEventNames.REFRESHTOKEN, content);
4230
+ const messageListener = (event) => {
4231
+ if (event.origin !== this.parentOrigin)
4232
+ return;
4233
+ if (event.data?.eventType !== ActionCenterEventNames.TOKENREFRESHED)
4234
+ return;
4235
+ clearTimeout(timer);
4236
+ if (event.data?.content?.token) {
4237
+ const { accessToken, expiresAt } = event.data.content.token;
4238
+ this.onTokenRefreshed({ token: accessToken, type: 'secret', expiresAt });
4239
+ resolve(accessToken);
4240
+ }
4241
+ else {
4242
+ reject(new AuthenticationError({
4243
+ message: 'Failed to fetch access token',
4244
+ statusCode: HttpStatus.UNAUTHORIZED,
4245
+ }));
4246
+ }
4247
+ this.refreshPromise = null;
4248
+ this.cleanup(messageListener);
4249
+ };
4250
+ const timer = setTimeout(() => {
4251
+ reject(new AuthenticationError({
4252
+ message: 'Failed to fetch access token',
4253
+ statusCode: HttpStatus.UNAUTHORIZED,
4254
+ }));
4255
+ this.refreshPromise = null;
4256
+ this.cleanup(messageListener);
4257
+ }, AUTHENTICATION_TIMEOUT);
4258
+ window.addEventListener('message', messageListener);
4259
+ });
4260
+ return this.refreshPromise;
4261
+ }
4262
+ isTokenExpired(tokenInfo) {
4263
+ if (!tokenInfo?.expiresAt) {
4264
+ return true;
4265
+ }
4266
+ return new Date() >= tokenInfo.expiresAt;
4267
+ }
4268
+ sendMessageToParent(eventType, content) {
4269
+ if (window.parent && this.isValidOrigin(this.parentOrigin)) {
4270
+ try {
4271
+ window.parent.postMessage({ eventType, content }, this.parentOrigin);
4272
+ }
4273
+ catch (error) {
4274
+ console.warn('Failed to send message to Action Center', JSON.stringify(error));
4275
+ }
4276
+ }
4277
+ }
4278
+ cleanup(messageListener) {
4279
+ window.removeEventListener('message', messageListener);
4280
+ }
4281
+ isValidOrigin(origin) {
4282
+ const ALLOWED_ORIGINS = ['https://alpha.uipath.com', 'https://staging.uipath.com', 'https://cloud.uipath.com'];
4283
+ if (!origin) {
4284
+ return false;
4285
+ }
4286
+ if (ALLOWED_ORIGINS.includes(origin)) {
4287
+ return true;
4288
+ }
4289
+ try {
4290
+ const url = new URL(origin);
4291
+ return url.hostname === 'localhost';
4292
+ }
4293
+ catch {
4294
+ return false;
4295
+ }
4296
+ }
4297
+ }
4298
+
4193
4299
  /**
4194
4300
  * TokenManager is responsible for managing authentication tokens.
4195
4301
  * It provides token operations for a specific client ID.
@@ -4207,8 +4313,12 @@ class TokenManager {
4207
4313
  this.executionContext = executionContext;
4208
4314
  this.config = config;
4209
4315
  this.isOAuth = isOAuth;
4210
- this.STORAGE_KEY_PREFIX = 'uipath_sdk_user_token-';
4211
4316
  this.refreshPromise = null;
4317
+ this.actionCenterTokenManager = null;
4318
+ if (isInActionCenter) {
4319
+ this.actionCenterTokenManager = new ActionCenterTokenManager(config, (tokenInfo) => this.setToken(tokenInfo));
4320
+ this.isOAuth = false;
4321
+ }
4212
4322
  }
4213
4323
  /**
4214
4324
  * Checks if a token is expired
@@ -4236,6 +4346,9 @@ class TokenManager {
4236
4346
  message: 'No authentication token available. Make sure to initialize the SDK first.'
4237
4347
  });
4238
4348
  }
4349
+ if (this.actionCenterTokenManager) {
4350
+ return await this.actionCenterTokenManager.refreshAccessToken(tokenInfo);
4351
+ }
4239
4352
  // For secret-based tokens, they never expire
4240
4353
  if (tokenInfo.type === 'secret') {
4241
4354
  return tokenInfo.token;
@@ -4261,7 +4374,7 @@ class TokenManager {
4261
4374
  * Gets the storage key for this TokenManager instance
4262
4375
  */
4263
4376
  _getStorageKey() {
4264
- return `${this.STORAGE_KEY_PREFIX}${this.config.clientId}`;
4377
+ return `${AUTH_STORAGE_KEYS.TOKEN_PREFIX}${this.config.clientId}`;
4265
4378
  }
4266
4379
  /**
4267
4380
  * Loads token from session storage if available
@@ -4380,9 +4493,6 @@ class TokenManager {
4380
4493
  clearToken() {
4381
4494
  this.currentToken = undefined;
4382
4495
  this.executionContext.set('tokenInfo', undefined);
4383
- const headers = this.executionContext.getHeaders();
4384
- delete headers['Authorization'];
4385
- this.executionContext.setHeaders(headers);
4386
4496
  // Remove from session storage if this is an OAuth token
4387
4497
  if (isBrowser && this.isOAuth) {
4388
4498
  try {
@@ -4398,10 +4508,6 @@ class TokenManager {
4398
4508
  */
4399
4509
  _updateExecutionContext(tokenInfo) {
4400
4510
  this.executionContext.set('tokenInfo', tokenInfo);
4401
- // Update authorization header
4402
- this.executionContext.setHeaders({
4403
- 'Authorization': `Bearer ${tokenInfo.token}`
4404
- });
4405
4511
  }
4406
4512
  /**
4407
4513
  * Refreshes the access token using the stored refresh token.
@@ -4605,8 +4711,15 @@ const IDENTITY_ENDPOINTS = {
4605
4711
 
4606
4712
  class AuthService {
4607
4713
  constructor(config, executionContext) {
4608
- // Check if we should use stored OAuth context instead of provided config
4609
- const storedContext = AuthService.getStoredOAuthContext();
4714
+ // Only use stored OAuth context when completing an active callback (URL has ?code=).
4715
+ // If stored context exists but we're NOT in a callback, it's stale from a
4716
+ // failed/abandoned flow (e.g. scope mismatch, invalid redirect URI) and must
4717
+ // be cleared so the fresh config takes effect.
4718
+ const isCallback = AuthService.isInOAuthCallback();
4719
+ const storedContext = isCallback ? AuthService.getStoredOAuthContext() : null;
4720
+ if (!isCallback) {
4721
+ AuthService._clearStoredOAuthContext();
4722
+ }
4610
4723
  const effectiveConfig = storedContext ? AuthService._mergeConfigWithContext(config, storedContext) : config;
4611
4724
  this.config = effectiveConfig;
4612
4725
  const isOAuth = hasOAuthConfig(effectiveConfig);
@@ -4623,7 +4736,7 @@ class AuthService {
4623
4736
  return false;
4624
4737
  const urlParams = new URLSearchParams(window.location.search);
4625
4738
  const code = urlParams.get('code');
4626
- const hasCodeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
4739
+ const hasCodeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4627
4740
  return !!(code && hasCodeVerifier);
4628
4741
  }
4629
4742
  /**
@@ -4634,7 +4747,7 @@ class AuthService {
4634
4747
  return null;
4635
4748
  }
4636
4749
  try {
4637
- const stored = sessionStorage.getItem('uipath_sdk_oauth_context');
4750
+ const stored = sessionStorage.getItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4638
4751
  if (!stored) {
4639
4752
  return null;
4640
4753
  }
@@ -4642,17 +4755,33 @@ class AuthService {
4642
4755
  // Validate required fields
4643
4756
  if (!context.codeVerifier || !context.clientId || !context.redirectUri ||
4644
4757
  !context.baseUrl || !context.orgName) {
4645
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4758
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4646
4759
  return null;
4647
4760
  }
4648
4761
  return context;
4649
4762
  }
4650
4763
  catch (error) {
4651
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4764
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4652
4765
  console.warn('Failed to parse stored OAuth context from session storage', error);
4653
4766
  return null;
4654
4767
  }
4655
4768
  }
4769
+ /**
4770
+ * Clear stale OAuth context from session storage.
4771
+ * Called when there is no active OAuth callback, meaning any stored context
4772
+ * is left over from a failed or abandoned flow.
4773
+ */
4774
+ static _clearStoredOAuthContext() {
4775
+ if (!isBrowser)
4776
+ return;
4777
+ try {
4778
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4779
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4780
+ }
4781
+ catch {
4782
+ // Ignore storage errors
4783
+ }
4784
+ }
4656
4785
  /**
4657
4786
  * Merges provided config with stored OAuth context, prioritizing stored values
4658
4787
  */
@@ -4723,7 +4852,7 @@ class AuthService {
4723
4852
  throw new Error('OAuth flow is only supported in browser environments');
4724
4853
  }
4725
4854
  // Check if we have a stored code verifier indicating we're in an OAuth flow
4726
- const codeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
4855
+ const codeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4727
4856
  const isInOAuthFlow = codeVerifier !== null;
4728
4857
  const urlParams = new URLSearchParams(window.location.search);
4729
4858
  const code = urlParams.get('code');
@@ -4732,7 +4861,7 @@ class AuthService {
4732
4861
  // We're expecting a callback - validate parameters
4733
4862
  if (!code) {
4734
4863
  // Clear stored state on error
4735
- sessionStorage.removeItem('uipath_sdk_code_verifier');
4864
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4736
4865
  throw new Error('Authorization code missing in OAuth callback');
4737
4866
  }
4738
4867
  // Validate the authorization code format before using it
@@ -4740,7 +4869,7 @@ class AuthService {
4740
4869
  const codePattern = /^[A-Za-z0-9\-._~+/]+=*$/;
4741
4870
  if (!codePattern.test(code)) {
4742
4871
  // Clear stored state on error
4743
- sessionStorage.removeItem('uipath_sdk_code_verifier');
4872
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4744
4873
  throw new Error('Invalid authorization code format');
4745
4874
  }
4746
4875
  // Authorization code is present and validated, so we can exchange it for a token.
@@ -4781,6 +4910,24 @@ class AuthService {
4781
4910
  hasValidToken() {
4782
4911
  return this.tokenManager.hasValidToken();
4783
4912
  }
4913
+ /**
4914
+ * Clears all authentication state including tokens and stored OAuth context.
4915
+ */
4916
+ logout() {
4917
+ this.tokenManager.clearToken();
4918
+ // Clear OAuth context from session storage. These are normally cleaned up in _handleOAuthCallback after a successful
4919
+ // token exchange, but if a user calls logout() while an OAuth flow is
4920
+ // mid-redirect (before callback completes), they'd be left behind.
4921
+ if (isBrowser) {
4922
+ try {
4923
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4924
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4925
+ }
4926
+ catch (error) {
4927
+ console.warn('Failed to clear OAuth context from session storage', error);
4928
+ }
4929
+ }
4930
+ }
4784
4931
  /**
4785
4932
  * Get the current token
4786
4933
  */
@@ -4912,8 +5059,8 @@ class AuthService {
4912
5059
  tenantName: this.config.tenantName,
4913
5060
  scope
4914
5061
  };
4915
- sessionStorage.setItem('uipath_sdk_oauth_context', JSON.stringify(oauthContext));
4916
- sessionStorage.setItem('uipath_sdk_code_verifier', codeVerifier);
5062
+ sessionStorage.setItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT, JSON.stringify(oauthContext));
5063
+ sessionStorage.setItem(AUTH_STORAGE_KEYS.CODE_VERIFIER, codeVerifier);
4917
5064
  const authUrl = this.getAuthorizationUrl({
4918
5065
  clientId,
4919
5066
  redirectUri,
@@ -4923,7 +5070,7 @@ class AuthService {
4923
5070
  window.location.href = authUrl;
4924
5071
  }
4925
5072
  async _handleOAuthCallback(code, clientId, redirectUri) {
4926
- const codeVerifier = sessionStorage.getItem('uipath_sdk_code_verifier');
5073
+ const codeVerifier = sessionStorage.getItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4927
5074
  if (!codeVerifier) {
4928
5075
  throw new Error('Code verifier not found in session storage. Authentication may have been interrupted.');
4929
5076
  }
@@ -4934,8 +5081,8 @@ class AuthService {
4934
5081
  codeVerifier
4935
5082
  });
4936
5083
  // Clear OAuth context and code verifier after successful token exchange
4937
- sessionStorage.removeItem('uipath_sdk_oauth_context');
4938
- sessionStorage.removeItem('uipath_sdk_code_verifier');
5084
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
5085
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4939
5086
  const url = new URL(window.location.href);
4940
5087
  url.searchParams.delete('code');
4941
5088
  url.searchParams.delete('state');
@@ -4943,14 +5090,42 @@ class AuthService {
4943
5090
  }
4944
5091
  }
4945
5092
 
5093
+ /**
5094
+ * Check if config has all required base fields
5095
+ */
5096
+ function hasRequiredBaseFields(config) {
5097
+ return Boolean(config.baseUrl && config.orgName && config.tenantName);
5098
+ }
5099
+ /**
5100
+ * Check if config has exactly one authentication method (secret XOR oauth)
5101
+ * Returns true if exactly one auth method is present, false otherwise
5102
+ */
5103
+ function hasValidAuthConfig(config) {
5104
+ const hasSecret = hasSecretConfig(config);
5105
+ const hasOAuth = hasOAuthConfig(config);
5106
+ // XOR: exactly one auth method, not both, not neither
5107
+ return hasSecret !== hasOAuth;
5108
+ }
4946
5109
  function validateConfig(config) {
4947
- if (!config.baseUrl || !config.orgName || !config.tenantName) {
5110
+ if (!hasRequiredBaseFields(config)) {
4948
5111
  throw new Error('Missing required configuration: baseUrl, orgName, and tenantName are required');
4949
5112
  }
4950
- if (!hasSecretConfig(config) && !hasOAuthConfig(config)) {
4951
- throw new Error('Invalid configuration: must provide either secret or (clientId, redirectUri, and scope)');
5113
+ const hasSecret = hasSecretConfig(config);
5114
+ const hasOAuth = hasOAuthConfig(config);
5115
+ if (hasSecret && hasOAuth) {
5116
+ throw new Error('Invalid configuration: cannot provide both secret and OAuth credentials. Choose one authentication method.');
5117
+ }
5118
+ if (!hasSecret && !hasOAuth) {
5119
+ throw new Error('Invalid configuration: must provide either secret or OAuth credentials (clientId, redirectUri, and scope)');
4952
5120
  }
4953
5121
  }
5122
+ /**
5123
+ * Check if partial config has all required fields for a complete SDK config
5124
+ * Requires base fields and exactly one authentication method (secret XOR oauth)
5125
+ */
5126
+ function isCompleteConfig(config) {
5127
+ return hasRequiredBaseFields(config) && hasValidAuthConfig(config);
5128
+ }
4954
5129
  function normalizeBaseUrl(url) {
4955
5130
  return url.endsWith('/') ? url.slice(0, -1) : url;
4956
5131
  }
@@ -4961,7 +5136,7 @@ function normalizeBaseUrl(url) {
4961
5136
  // Connection string placeholder that will be replaced during build
4962
5137
  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";
4963
5138
  // SDK Version placeholder
4964
- const SDK_VERSION = "1.1.0";
5139
+ const SDK_VERSION = "1.1.2";
4965
5140
  const VERSION = "Version";
4966
5141
  const SERVICE = "Service";
4967
5142
  const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
@@ -5290,19 +5465,71 @@ class SDKInternalsRegistry {
5290
5465
  }
5291
5466
  }
5292
5467
 
5293
- var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5468
+ /**
5469
+ * UiPath meta tag names for runtime configuration.
5470
+ *
5471
+ * These meta tags are injected at deployment time by the Apps Service
5472
+ * to configure SDK authentication and asset resolution in production.
5473
+ */
5474
+ var UiPathMetaTags;
5475
+ (function (UiPathMetaTags) {
5476
+ // SDK/OAuth configuration
5477
+ UiPathMetaTags["CLIENT_ID"] = "uipath:client-id";
5478
+ UiPathMetaTags["SCOPE"] = "uipath:scope";
5479
+ UiPathMetaTags["ORG_NAME"] = "uipath:org-name";
5480
+ UiPathMetaTags["TENANT_NAME"] = "uipath:tenant-name";
5481
+ UiPathMetaTags["BASE_URL"] = "uipath:base-url";
5482
+ UiPathMetaTags["REDIRECT_URI"] = "uipath:redirect-uri";
5483
+ // Asset resolution and routing
5484
+ UiPathMetaTags["CDN_BASE"] = "uipath:cdn-base";
5485
+ UiPathMetaTags["APP_BASE"] = "uipath:app-base";
5486
+ })(UiPathMetaTags || (UiPathMetaTags = {}));
5487
+
5488
+ /**
5489
+ * Get the content of a meta tag by name.
5490
+ * Returns undefined if not in browser environment or meta tag is not found.
5491
+ */
5492
+ function getMetaTagContent(name) {
5493
+ if (!isBrowser)
5494
+ return undefined;
5495
+ return document.querySelector(`meta[name="${name}"]`)?.content;
5496
+ }
5497
+ /**
5498
+ * Load configuration from HTML meta tags injected at runtime.
5499
+ * These meta tags are injected by @uipath/coded-apps during build
5500
+ * or by the Apps service during deployment.
5501
+ *
5502
+ * Returns partial config with values found, or null if no meta tags present.
5503
+ */
5504
+ function loadFromMetaTags() {
5505
+ if (!isBrowser)
5506
+ return null;
5507
+ const config = {
5508
+ clientId: getMetaTagContent(UiPathMetaTags.CLIENT_ID),
5509
+ scope: getMetaTagContent(UiPathMetaTags.SCOPE),
5510
+ orgName: getMetaTagContent(UiPathMetaTags.ORG_NAME),
5511
+ tenantName: getMetaTagContent(UiPathMetaTags.TENANT_NAME),
5512
+ baseUrl: getMetaTagContent(UiPathMetaTags.BASE_URL),
5513
+ redirectUri: getMetaTagContent(UiPathMetaTags.REDIRECT_URI),
5514
+ };
5515
+ const hasAnyValue = Object.values(config).some(Boolean);
5516
+ return hasAnyValue ? config : null;
5517
+ }
5518
+
5519
+ var _UiPath_instances, _UiPath_config, _UiPath_authService, _UiPath_initialized, _UiPath_partialConfig, _UiPath_initializeWithConfig, _UiPath_loadConfig;
5294
5520
  /**
5295
5521
  * UiPath - Core SDK class for authentication and configuration management.
5296
5522
  *
5297
5523
  * Handles authentication, configuration, and provides access to SDK internals
5298
5524
  * for service instantiation in the modular pattern.
5299
5525
  *
5526
+ * Supports two usage patterns:
5527
+ * 1. Full config in constructor — for server-side or explicit configuration
5528
+ * 2. No config / partial config — loads from meta tags injected by @uipath/coded-apps plugin
5529
+ *
5300
5530
  * @example
5301
5531
  * ```typescript
5302
- * // Modular pattern
5303
- * import { UiPath } from '@uipath/uipath-typescript/core';
5304
- * import { Entities } from '@uipath/uipath-typescript/entities';
5305
- *
5532
+ * // Explicit config
5306
5533
  * const sdk = new UiPath({
5307
5534
  * baseUrl: 'https://cloud.uipath.com',
5308
5535
  * orgName: 'myorg',
@@ -5311,70 +5538,47 @@ var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5311
5538
  * redirectUri: 'http://localhost:3000/callback',
5312
5539
  * scope: 'OR.Users OR.Robots'
5313
5540
  * });
5314
- *
5315
5541
  * await sdk.initialize();
5542
+ * ```
5316
5543
  *
5317
- * const entitiesService = new Entities(sdk);
5318
- * const allEntities = await entitiesService.getAll();
5544
+ * @example
5545
+ * ```typescript
5546
+ * // Auto-load from meta tags (coded apps)
5547
+ * const sdk = new UiPath();
5548
+ * await sdk.initialize();
5319
5549
  * ```
5320
5550
  */
5321
5551
  let UiPath$1 = class UiPath {
5322
5552
  constructor(config) {
5553
+ _UiPath_instances.add(this);
5323
5554
  // Private fields - true runtime privacy, not visible via Object.keys()
5324
5555
  _UiPath_config.set(this, void 0);
5325
5556
  _UiPath_authService.set(this, void 0);
5326
5557
  _UiPath_initialized.set(this, false);
5327
- // Validate and normalize the configuration
5328
- validateConfig(config);
5329
- const hasSecretAuth = hasSecretConfig(config);
5330
- const hasOAuthAuth = hasOAuthConfig(config);
5331
- // Initialize core components
5332
- const internalConfig = new UiPathConfig({
5333
- baseUrl: normalizeBaseUrl(config.baseUrl),
5334
- orgName: config.orgName,
5335
- tenantName: config.tenantName,
5336
- secret: hasSecretAuth ? config.secret : undefined,
5337
- clientId: hasOAuthAuth ? config.clientId : undefined,
5338
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5339
- scope: hasOAuthAuth ? config.scope : undefined
5340
- });
5341
- const executionContext = new ExecutionContext();
5342
- __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5343
- __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5344
- // Store internals in SDKInternalsRegistry (not visible on instance)
5345
- SDKInternalsRegistry.set(this, {
5346
- config: internalConfig,
5347
- context: executionContext,
5348
- tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5349
- });
5350
- // Expose read-only config for user convenience
5351
- this.config = {
5352
- baseUrl: internalConfig.baseUrl,
5353
- orgName: internalConfig.orgName,
5354
- tenantName: internalConfig.tenantName
5355
- };
5356
- // Initialize telemetry with SDK configuration
5357
- telemetryClient.initialize({
5358
- baseUrl: config.baseUrl,
5359
- orgName: config.orgName,
5360
- tenantName: config.tenantName,
5361
- clientId: hasOAuthAuth ? config.clientId : undefined,
5362
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5363
- });
5364
- // Track SDK initialization
5365
- trackEvent('Sdk.Auth');
5366
- // Auto-initialize for secret-based auth
5367
- if (hasSecretAuth) {
5368
- __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret);
5369
- __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5558
+ _UiPath_partialConfig.set(this, void 0);
5559
+ // Load configuration from meta tags
5560
+ const configFromMetaTags = loadFromMetaTags();
5561
+ // Merge configuration: constructor config overrides meta tags
5562
+ const mergedConfig = config ? { ...configFromMetaTags, ...config } : configFromMetaTags;
5563
+ if (mergedConfig && isCompleteConfig(mergedConfig)) {
5564
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, mergedConfig);
5565
+ }
5566
+ else if (config) {
5567
+ __classPrivateFieldSet(this, _UiPath_partialConfig, config, "f");
5370
5568
  }
5371
5569
  }
5372
5570
  /**
5373
5571
  * Initialize the SDK based on the provided configuration.
5374
5572
  * This method handles both OAuth flow initiation and completion automatically.
5375
5573
  * For secret-based authentication, initialization is automatic and this returns immediately.
5574
+ * If no config was provided in constructor, loads from meta tags.
5376
5575
  */
5377
5576
  async initialize() {
5577
+ // Load config from meta tags if not provided in constructor
5578
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5579
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5580
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5581
+ }
5378
5582
  // For secret-based auth, it's already initialized in constructor
5379
5583
  if (hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5380
5584
  return;
@@ -5421,6 +5625,11 @@ let UiPath$1 = class UiPath {
5421
5625
  if (!AuthService.isInOAuthCallback()) {
5422
5626
  throw new Error('Not in OAuth callback state. Call initialize() first to start OAuth flow.');
5423
5627
  }
5628
+ // Load config if not yet initialized
5629
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5630
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5631
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5632
+ }
5424
5633
  try {
5425
5634
  const success = await __classPrivateFieldGet(this, _UiPath_authService, "f").authenticate(__classPrivateFieldGet(this, _UiPath_config, "f"));
5426
5635
  if (success && this.isAuthenticated()) {
@@ -5438,16 +5647,85 @@ let UiPath$1 = class UiPath {
5438
5647
  * Check if the user is authenticated (has valid token)
5439
5648
  */
5440
5649
  isAuthenticated() {
5441
- return __classPrivateFieldGet(this, _UiPath_authService, "f").hasValidToken();
5650
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.hasValidToken() ?? false;
5442
5651
  }
5443
5652
  /**
5444
5653
  * Get the current authentication token
5445
5654
  */
5446
5655
  getToken() {
5447
- return __classPrivateFieldGet(this, _UiPath_authService, "f").getToken();
5656
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.getToken();
5657
+ }
5658
+ /**
5659
+ * Logout from the SDK, clearing all authentication state.
5660
+ * After calling this method, the user will need to re-initialize to authenticate again.
5661
+ */
5662
+ logout() {
5663
+ // Secret-based auth has no session to end — skip silently
5664
+ if (__classPrivateFieldGet(this, _UiPath_config, "f") && hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5665
+ return;
5666
+ }
5667
+ __classPrivateFieldGet(this, _UiPath_authService, "f")?.logout();
5668
+ __classPrivateFieldSet(this, _UiPath_initialized, false, "f");
5448
5669
  }
5449
5670
  };
5450
- _UiPath_config = new WeakMap(), _UiPath_authService = new WeakMap(), _UiPath_initialized = new WeakMap();
5671
+ _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) {
5672
+ // Validate and normalize the configuration
5673
+ validateConfig(config);
5674
+ const hasSecretAuth = hasSecretConfig(config);
5675
+ const hasOAuthAuth = hasOAuthConfig(config);
5676
+ // Initialize core components
5677
+ const internalConfig = new UiPathConfig({
5678
+ baseUrl: normalizeBaseUrl(config.baseUrl),
5679
+ orgName: config.orgName,
5680
+ tenantName: config.tenantName,
5681
+ secret: hasSecretAuth ? config.secret : undefined,
5682
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5683
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5684
+ scope: hasOAuthAuth ? config.scope : undefined
5685
+ });
5686
+ const executionContext = new ExecutionContext();
5687
+ __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5688
+ __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5689
+ // Store internals in SDKInternalsRegistry (not visible on instance)
5690
+ SDKInternalsRegistry.set(this, {
5691
+ config: internalConfig,
5692
+ context: executionContext,
5693
+ tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5694
+ });
5695
+ // Expose read-only config for user convenience
5696
+ this.config = {
5697
+ baseUrl: internalConfig.baseUrl,
5698
+ orgName: internalConfig.orgName,
5699
+ tenantName: internalConfig.tenantName
5700
+ };
5701
+ // Initialize telemetry with SDK configuration
5702
+ telemetryClient.initialize({
5703
+ baseUrl: config.baseUrl,
5704
+ orgName: config.orgName,
5705
+ tenantName: config.tenantName,
5706
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5707
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5708
+ });
5709
+ // Track SDK initialization
5710
+ trackEvent('Sdk.Auth');
5711
+ /** Auto-initialize for secret-based auth
5712
+ * When viewed in Action Center, initialize tokenInfo with empty token. When an sdk call is made Action Center passes the token to sdk.
5713
+ */
5714
+ if (hasSecretAuth || isInActionCenter) {
5715
+ __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret ?? '');
5716
+ __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5717
+ }
5718
+ }, _UiPath_loadConfig = function _UiPath_loadConfig() {
5719
+ // Load from meta tags
5720
+ const metaConfig = loadFromMetaTags();
5721
+ // Merge with any partial config from constructor (constructor overrides meta tags)
5722
+ const merged = { ...metaConfig, ...__classPrivateFieldGet(this, _UiPath_partialConfig, "f") };
5723
+ if (!isCompleteConfig(merged)) {
5724
+ throw new Error('UiPath SDK configuration not found. ' +
5725
+ 'Ensure @uipath/coded-apps plugin is set up in your bundler to inject configuration during development and build.');
5726
+ }
5727
+ return merged;
5728
+ };
5451
5729
 
5452
5730
  /**
5453
5731
  * Type guards for error response types
@@ -5726,15 +6004,6 @@ class ApiClient {
5726
6004
  async getDefaultHeaders() {
5727
6005
  // Get headers from execution context first
5728
6006
  const contextHeaders = this.executionContext.getHeaders();
5729
- // If Authorization header is already set in context, use that
5730
- if (contextHeaders['Authorization']) {
5731
- return {
5732
- ...contextHeaders,
5733
- 'Content-Type': CONTENT_TYPES.JSON,
5734
- ...this.defaultHeaders,
5735
- ...this.clientConfig.headers
5736
- };
5737
- }
5738
6007
  const token = await this.getValidToken();
5739
6008
  return {
5740
6009
  ...contextHeaders,
@@ -11078,4 +11347,79 @@ const UserSettingsMap = {
11078
11347
  ...CommonFieldMap
11079
11348
  };
11080
11349
 
11081
- export { APP_NAME, AgentMap, AssetValueScope, AssetValueType, AuthenticationError, AuthorizationError, BucketOptions, CLOUD_CLIENT_ID, CLOUD_ORGANIZATION_NAME, CLOUD_REDIRECT_URI, CLOUD_ROLE_NAME, CLOUD_TENANT_NAME, CLOUD_URL, CONNECTION_STRING, CitationErrorType, ConversationMap, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, DataDirectionType, DebugMode, EntityFieldDataType, EntityType, ErrorType, EscalationActionType, EscalationRecipientScope, EscalationTriggerType, ExchangeMap, FeedbackRating, FieldDisplayType, HttpStatus, InputStreamSpeechSensitivity, InterruptType, JobPriority, JobState, JobType, JoinType, MAX_PAGE_SIZE, MessageMap, MessageRole, NetworkError, NotFoundError, PackageSourceType, PackageType, ProcessIncidentSeverity, ProcessIncidentStatus, ProcessIncidentType, RateLimitError, ReferenceType, RemoteControlAccess, RobotSize, SDK_LOGGER_NAME, SDK_RUN_EVENT, SDK_SERVICE_NAME, SDK_VERSION, SERVICE, SLADurationUnit, ServerError, SortOrder, StageTaskType, StartStrategy, StopStrategy, TargetFramework, TaskActivityType, TaskPriority, TaskSlaCriteria, TaskSlaStatus, TaskSourceName, TaskStatus, TaskType, UNKNOWN$1 as UNKNOWN, UiPath, UiPathError, UserSettingsMap, VERSION, ValidationError, createAgentWithMethods, createCaseInstanceWithMethods, createConversationWithMethods, createEntityWithMethods, createProcessInstanceWithMethods, createProcessWithMethods, createTaskWithMethods, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError, telemetryClient, track, trackEvent };
11350
+ /**
11351
+ * Asset resolution utilities for UiPath Coded Apps
11352
+ *
11353
+ * These helpers enable developers to write code that works identically
11354
+ * in local development and production environments.
11355
+ *
11356
+ * Values are read from meta tags injected at deployment:
11357
+ * - <meta name="uipath:cdn-base" content="https://cdn.example.com/appId/folder">
11358
+ * - <meta name="uipath:app-base" content="/org/apps_/.../public">
11359
+ */
11360
+ /**
11361
+ * Resolves an asset path to the CDN URL (if available)
11362
+ *
11363
+ * In local development: returns path as-is (loads from local dev server)
11364
+ * In production: prepends CDN base URL from meta tag
11365
+ *
11366
+ * @param path - The asset path (e.g., './assets/logo.png' or '/assets/logo.png')
11367
+ * @returns The resolved asset URL
11368
+ *
11369
+ * @example
11370
+ * ```tsx
11371
+ * import { getAsset } from '@uipath/uipath-typescript';
11372
+ * import logoPath from './assets/logo.png';
11373
+ *
11374
+ * function MyComponent() {
11375
+ * return <img src={getAsset(logoPath)} alt="Logo" />;
11376
+ * }
11377
+ * ```
11378
+ */
11379
+ function getAsset(path) {
11380
+ // If path is already an absolute URL, return as-is
11381
+ if (path.startsWith('http://') || path.startsWith('https://')) {
11382
+ return path;
11383
+ }
11384
+ const cdnBase = getMetaTagContent(UiPathMetaTags.CDN_BASE);
11385
+ if (!cdnBase)
11386
+ return path;
11387
+ // Normalize CDN base URL to remove trailing slash
11388
+ const normalizedCdnBase = normalizeBaseUrl(cdnBase);
11389
+ // Normalize path to ensure it starts with /
11390
+ let normalizedPath = path;
11391
+ if (normalizedPath.startsWith('./')) {
11392
+ normalizedPath = normalizedPath.substring(1); // ./assets -> /assets
11393
+ }
11394
+ else if (!normalizedPath.startsWith('/')) {
11395
+ normalizedPath = '/' + normalizedPath; // assets -> /assets
11396
+ }
11397
+ return normalizedCdnBase + normalizedPath;
11398
+ }
11399
+ /**
11400
+ * Returns the app base path for router configuration
11401
+ *
11402
+ * In local development: returns '/'
11403
+ * In production: returns the deployed app path from meta tag
11404
+ *
11405
+ * @returns The app base path
11406
+ *
11407
+ * @example
11408
+ * ```tsx
11409
+ * import { getAppBase } from '@uipath/uipath-typescript';
11410
+ * import { BrowserRouter } from 'react-router-dom';
11411
+ *
11412
+ * function App() {
11413
+ * return (
11414
+ * <BrowserRouter basename={getAppBase()}>
11415
+ * {/* routes *\/}
11416
+ * </BrowserRouter>
11417
+ * );
11418
+ * }
11419
+ * ```
11420
+ */
11421
+ function getAppBase() {
11422
+ return getMetaTagContent(UiPathMetaTags.APP_BASE) || '/';
11423
+ }
11424
+
11425
+ export { APP_NAME, AgentMap, AssetValueScope, AssetValueType, AuthenticationError, AuthorizationError, BucketOptions, CLOUD_CLIENT_ID, CLOUD_ORGANIZATION_NAME, CLOUD_REDIRECT_URI, CLOUD_ROLE_NAME, CLOUD_TENANT_NAME, CLOUD_URL, CONNECTION_STRING, CitationErrorType, ConversationMap, DEFAULT_ITEMS_FIELD, DEFAULT_PAGE_SIZE, DEFAULT_TOTAL_COUNT_FIELD, DataDirectionType, DebugMode, EntityFieldDataType, EntityType, ErrorType, EscalationActionType, EscalationRecipientScope, EscalationTriggerType, ExchangeMap, FeedbackRating, FieldDisplayType, HttpStatus, InputStreamSpeechSensitivity, InterruptType, JobPriority, JobState, JobType, JoinType, MAX_PAGE_SIZE, MessageMap, MessageRole, NetworkError, NotFoundError, PackageSourceType, PackageType, ProcessIncidentSeverity, ProcessIncidentStatus, ProcessIncidentType, RateLimitError, ReferenceType, RemoteControlAccess, RobotSize, SDK_LOGGER_NAME, SDK_RUN_EVENT, SDK_SERVICE_NAME, SDK_VERSION, SERVICE, SLADurationUnit, ServerError, SortOrder, StageTaskType, StartStrategy, StopStrategy, TargetFramework, TaskActivityType, TaskPriority, TaskSlaCriteria, TaskSlaStatus, TaskSourceName, TaskStatus, TaskType, UNKNOWN$1 as UNKNOWN, UiPath, UiPathError, UiPathMetaTags, UserSettingsMap, VERSION, ValidationError, createAgentWithMethods, createCaseInstanceWithMethods, createConversationWithMethods, createEntityWithMethods, createProcessInstanceWithMethods, createProcessWithMethods, createTaskWithMethods, getAppBase, getAsset, getErrorDetails, getLimitedPageSize, isAuthenticationError, isAuthorizationError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isUiPathError, isValidationError, loadFromMetaTags, telemetryClient, track, trackEvent };