@uipath/uipath-typescript 1.1.1 → 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.cjs CHANGED
@@ -3885,6 +3885,7 @@ class ExecutionContext {
3885
3885
  * Checks if code is running in a browser environment
3886
3886
  */
3887
3887
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
3888
+ const isInActionCenter = isBrowser && window.self != window.top && window.location.href.includes('source=ActionCenter');
3888
3889
 
3889
3890
  /**
3890
3891
  * Session storage keys used by the auth module
@@ -4201,6 +4202,102 @@ function getErrorDetails(error) {
4201
4202
  };
4202
4203
  }
4203
4204
 
4205
+ var ActionCenterEventNames;
4206
+ (function (ActionCenterEventNames) {
4207
+ ActionCenterEventNames["TOKENREFRESHED"] = "AC.tokenRefreshed";
4208
+ ActionCenterEventNames["REFRESHTOKEN"] = "AC.refreshToken";
4209
+ })(ActionCenterEventNames || (ActionCenterEventNames = {}));
4210
+
4211
+ const AUTHENTICATION_TIMEOUT = 8000;
4212
+ class ActionCenterTokenManager {
4213
+ constructor(config, onTokenRefreshed) {
4214
+ this.config = config;
4215
+ this.onTokenRefreshed = onTokenRefreshed;
4216
+ this.parentOrigin = new URLSearchParams(window.location.search).get('basedomain');
4217
+ this.refreshPromise = null;
4218
+ }
4219
+ async refreshAccessToken(tokenInfo) {
4220
+ if (!this.isTokenExpired(tokenInfo)) {
4221
+ return tokenInfo.token;
4222
+ }
4223
+ if (this.refreshPromise) {
4224
+ return this.refreshPromise;
4225
+ }
4226
+ this.refreshPromise = new Promise((resolve, reject) => {
4227
+ const content = {
4228
+ clientId: this.config.clientId,
4229
+ scope: this.config.scope,
4230
+ };
4231
+ this.sendMessageToParent(ActionCenterEventNames.REFRESHTOKEN, content);
4232
+ const messageListener = (event) => {
4233
+ if (event.origin !== this.parentOrigin)
4234
+ return;
4235
+ if (event.data?.eventType !== ActionCenterEventNames.TOKENREFRESHED)
4236
+ return;
4237
+ clearTimeout(timer);
4238
+ if (event.data?.content?.token) {
4239
+ const { accessToken, expiresAt } = event.data.content.token;
4240
+ this.onTokenRefreshed({ token: accessToken, type: 'secret', expiresAt });
4241
+ resolve(accessToken);
4242
+ }
4243
+ else {
4244
+ reject(new AuthenticationError({
4245
+ message: 'Failed to fetch access token',
4246
+ statusCode: HttpStatus.UNAUTHORIZED,
4247
+ }));
4248
+ }
4249
+ this.refreshPromise = null;
4250
+ this.cleanup(messageListener);
4251
+ };
4252
+ const timer = setTimeout(() => {
4253
+ reject(new AuthenticationError({
4254
+ message: 'Failed to fetch access token',
4255
+ statusCode: HttpStatus.UNAUTHORIZED,
4256
+ }));
4257
+ this.refreshPromise = null;
4258
+ this.cleanup(messageListener);
4259
+ }, AUTHENTICATION_TIMEOUT);
4260
+ window.addEventListener('message', messageListener);
4261
+ });
4262
+ return this.refreshPromise;
4263
+ }
4264
+ isTokenExpired(tokenInfo) {
4265
+ if (!tokenInfo?.expiresAt) {
4266
+ return true;
4267
+ }
4268
+ return new Date() >= tokenInfo.expiresAt;
4269
+ }
4270
+ sendMessageToParent(eventType, content) {
4271
+ if (window.parent && this.isValidOrigin(this.parentOrigin)) {
4272
+ try {
4273
+ window.parent.postMessage({ eventType, content }, this.parentOrigin);
4274
+ }
4275
+ catch (error) {
4276
+ console.warn('Failed to send message to Action Center', JSON.stringify(error));
4277
+ }
4278
+ }
4279
+ }
4280
+ cleanup(messageListener) {
4281
+ window.removeEventListener('message', messageListener);
4282
+ }
4283
+ isValidOrigin(origin) {
4284
+ const ALLOWED_ORIGINS = ['https://alpha.uipath.com', 'https://staging.uipath.com', 'https://cloud.uipath.com'];
4285
+ if (!origin) {
4286
+ return false;
4287
+ }
4288
+ if (ALLOWED_ORIGINS.includes(origin)) {
4289
+ return true;
4290
+ }
4291
+ try {
4292
+ const url = new URL(origin);
4293
+ return url.hostname === 'localhost';
4294
+ }
4295
+ catch {
4296
+ return false;
4297
+ }
4298
+ }
4299
+ }
4300
+
4204
4301
  /**
4205
4302
  * TokenManager is responsible for managing authentication tokens.
4206
4303
  * It provides token operations for a specific client ID.
@@ -4219,6 +4316,11 @@ class TokenManager {
4219
4316
  this.config = config;
4220
4317
  this.isOAuth = isOAuth;
4221
4318
  this.refreshPromise = null;
4319
+ this.actionCenterTokenManager = null;
4320
+ if (isInActionCenter) {
4321
+ this.actionCenterTokenManager = new ActionCenterTokenManager(config, (tokenInfo) => this.setToken(tokenInfo));
4322
+ this.isOAuth = false;
4323
+ }
4222
4324
  }
4223
4325
  /**
4224
4326
  * Checks if a token is expired
@@ -4246,6 +4348,9 @@ class TokenManager {
4246
4348
  message: 'No authentication token available. Make sure to initialize the SDK first.'
4247
4349
  });
4248
4350
  }
4351
+ if (this.actionCenterTokenManager) {
4352
+ return await this.actionCenterTokenManager.refreshAccessToken(tokenInfo);
4353
+ }
4249
4354
  // For secret-based tokens, they never expire
4250
4355
  if (tokenInfo.type === 'secret') {
4251
4356
  return tokenInfo.token;
@@ -4390,9 +4495,6 @@ class TokenManager {
4390
4495
  clearToken() {
4391
4496
  this.currentToken = undefined;
4392
4497
  this.executionContext.set('tokenInfo', undefined);
4393
- const headers = this.executionContext.getHeaders();
4394
- delete headers['Authorization'];
4395
- this.executionContext.setHeaders(headers);
4396
4498
  // Remove from session storage if this is an OAuth token
4397
4499
  if (isBrowser && this.isOAuth) {
4398
4500
  try {
@@ -4408,10 +4510,6 @@ class TokenManager {
4408
4510
  */
4409
4511
  _updateExecutionContext(tokenInfo) {
4410
4512
  this.executionContext.set('tokenInfo', tokenInfo);
4411
- // Update authorization header
4412
- this.executionContext.setHeaders({
4413
- 'Authorization': `Bearer ${tokenInfo.token}`
4414
- });
4415
4513
  }
4416
4514
  /**
4417
4515
  * Refreshes the access token using the stored refresh token.
@@ -4615,8 +4713,15 @@ const IDENTITY_ENDPOINTS = {
4615
4713
 
4616
4714
  class AuthService {
4617
4715
  constructor(config, executionContext) {
4618
- // Check if we should use stored OAuth context instead of provided config
4619
- const storedContext = AuthService.getStoredOAuthContext();
4716
+ // Only use stored OAuth context when completing an active callback (URL has ?code=).
4717
+ // If stored context exists but we're NOT in a callback, it's stale from a
4718
+ // failed/abandoned flow (e.g. scope mismatch, invalid redirect URI) and must
4719
+ // be cleared so the fresh config takes effect.
4720
+ const isCallback = AuthService.isInOAuthCallback();
4721
+ const storedContext = isCallback ? AuthService.getStoredOAuthContext() : null;
4722
+ if (!isCallback) {
4723
+ AuthService._clearStoredOAuthContext();
4724
+ }
4620
4725
  const effectiveConfig = storedContext ? AuthService._mergeConfigWithContext(config, storedContext) : config;
4621
4726
  this.config = effectiveConfig;
4622
4727
  const isOAuth = hasOAuthConfig(effectiveConfig);
@@ -4663,6 +4768,22 @@ class AuthService {
4663
4768
  return null;
4664
4769
  }
4665
4770
  }
4771
+ /**
4772
+ * Clear stale OAuth context from session storage.
4773
+ * Called when there is no active OAuth callback, meaning any stored context
4774
+ * is left over from a failed or abandoned flow.
4775
+ */
4776
+ static _clearStoredOAuthContext() {
4777
+ if (!isBrowser)
4778
+ return;
4779
+ try {
4780
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.OAUTH_CONTEXT);
4781
+ sessionStorage.removeItem(AUTH_STORAGE_KEYS.CODE_VERIFIER);
4782
+ }
4783
+ catch {
4784
+ // Ignore storage errors
4785
+ }
4786
+ }
4666
4787
  /**
4667
4788
  * Merges provided config with stored OAuth context, prioritizing stored values
4668
4789
  */
@@ -4971,13 +5092,41 @@ class AuthService {
4971
5092
  }
4972
5093
  }
4973
5094
 
5095
+ /**
5096
+ * Check if config has all required base fields
5097
+ */
5098
+ function hasRequiredBaseFields(config) {
5099
+ return Boolean(config.baseUrl && config.orgName && config.tenantName);
5100
+ }
5101
+ /**
5102
+ * Check if config has exactly one authentication method (secret XOR oauth)
5103
+ * Returns true if exactly one auth method is present, false otherwise
5104
+ */
5105
+ function hasValidAuthConfig(config) {
5106
+ const hasSecret = hasSecretConfig(config);
5107
+ const hasOAuth = hasOAuthConfig(config);
5108
+ // XOR: exactly one auth method, not both, not neither
5109
+ return hasSecret !== hasOAuth;
5110
+ }
4974
5111
  function validateConfig(config) {
4975
- if (!config.baseUrl || !config.orgName || !config.tenantName) {
5112
+ if (!hasRequiredBaseFields(config)) {
4976
5113
  throw new Error('Missing required configuration: baseUrl, orgName, and tenantName are required');
4977
5114
  }
4978
- if (!hasSecretConfig(config) && !hasOAuthConfig(config)) {
4979
- throw new Error('Invalid configuration: must provide either secret or (clientId, redirectUri, and scope)');
5115
+ const hasSecret = hasSecretConfig(config);
5116
+ const hasOAuth = hasOAuthConfig(config);
5117
+ if (hasSecret && hasOAuth) {
5118
+ throw new Error('Invalid configuration: cannot provide both secret and OAuth credentials. Choose one authentication method.');
4980
5119
  }
5120
+ if (!hasSecret && !hasOAuth) {
5121
+ throw new Error('Invalid configuration: must provide either secret or OAuth credentials (clientId, redirectUri, and scope)');
5122
+ }
5123
+ }
5124
+ /**
5125
+ * Check if partial config has all required fields for a complete SDK config
5126
+ * Requires base fields and exactly one authentication method (secret XOR oauth)
5127
+ */
5128
+ function isCompleteConfig(config) {
5129
+ return hasRequiredBaseFields(config) && hasValidAuthConfig(config);
4981
5130
  }
4982
5131
  function normalizeBaseUrl(url) {
4983
5132
  return url.endsWith('/') ? url.slice(0, -1) : url;
@@ -4989,7 +5138,7 @@ function normalizeBaseUrl(url) {
4989
5138
  // Connection string placeholder that will be replaced during build
4990
5139
  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";
4991
5140
  // SDK Version placeholder
4992
- const SDK_VERSION = "1.1.1";
5141
+ const SDK_VERSION = "1.1.2";
4993
5142
  const VERSION = "Version";
4994
5143
  const SERVICE = "Service";
4995
5144
  const CLOUD_ORGANIZATION_NAME = "CloudOrganizationName";
@@ -5318,19 +5467,71 @@ class SDKInternalsRegistry {
5318
5467
  }
5319
5468
  }
5320
5469
 
5321
- var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5470
+ /**
5471
+ * UiPath meta tag names for runtime configuration.
5472
+ *
5473
+ * These meta tags are injected at deployment time by the Apps Service
5474
+ * to configure SDK authentication and asset resolution in production.
5475
+ */
5476
+ exports.UiPathMetaTags = void 0;
5477
+ (function (UiPathMetaTags) {
5478
+ // SDK/OAuth configuration
5479
+ UiPathMetaTags["CLIENT_ID"] = "uipath:client-id";
5480
+ UiPathMetaTags["SCOPE"] = "uipath:scope";
5481
+ UiPathMetaTags["ORG_NAME"] = "uipath:org-name";
5482
+ UiPathMetaTags["TENANT_NAME"] = "uipath:tenant-name";
5483
+ UiPathMetaTags["BASE_URL"] = "uipath:base-url";
5484
+ UiPathMetaTags["REDIRECT_URI"] = "uipath:redirect-uri";
5485
+ // Asset resolution and routing
5486
+ UiPathMetaTags["CDN_BASE"] = "uipath:cdn-base";
5487
+ UiPathMetaTags["APP_BASE"] = "uipath:app-base";
5488
+ })(exports.UiPathMetaTags || (exports.UiPathMetaTags = {}));
5489
+
5490
+ /**
5491
+ * Get the content of a meta tag by name.
5492
+ * Returns undefined if not in browser environment or meta tag is not found.
5493
+ */
5494
+ function getMetaTagContent(name) {
5495
+ if (!isBrowser)
5496
+ return undefined;
5497
+ return document.querySelector(`meta[name="${name}"]`)?.content;
5498
+ }
5499
+ /**
5500
+ * Load configuration from HTML meta tags injected at runtime.
5501
+ * These meta tags are injected by @uipath/coded-apps during build
5502
+ * or by the Apps service during deployment.
5503
+ *
5504
+ * Returns partial config with values found, or null if no meta tags present.
5505
+ */
5506
+ function loadFromMetaTags() {
5507
+ if (!isBrowser)
5508
+ return null;
5509
+ const config = {
5510
+ clientId: getMetaTagContent(exports.UiPathMetaTags.CLIENT_ID),
5511
+ scope: getMetaTagContent(exports.UiPathMetaTags.SCOPE),
5512
+ orgName: getMetaTagContent(exports.UiPathMetaTags.ORG_NAME),
5513
+ tenantName: getMetaTagContent(exports.UiPathMetaTags.TENANT_NAME),
5514
+ baseUrl: getMetaTagContent(exports.UiPathMetaTags.BASE_URL),
5515
+ redirectUri: getMetaTagContent(exports.UiPathMetaTags.REDIRECT_URI),
5516
+ };
5517
+ const hasAnyValue = Object.values(config).some(Boolean);
5518
+ return hasAnyValue ? config : null;
5519
+ }
5520
+
5521
+ var _UiPath_instances, _UiPath_config, _UiPath_authService, _UiPath_initialized, _UiPath_partialConfig, _UiPath_initializeWithConfig, _UiPath_loadConfig;
5322
5522
  /**
5323
5523
  * UiPath - Core SDK class for authentication and configuration management.
5324
5524
  *
5325
5525
  * Handles authentication, configuration, and provides access to SDK internals
5326
5526
  * for service instantiation in the modular pattern.
5327
5527
  *
5528
+ * Supports two usage patterns:
5529
+ * 1. Full config in constructor — for server-side or explicit configuration
5530
+ * 2. No config / partial config — loads from meta tags injected by @uipath/coded-apps plugin
5531
+ *
5328
5532
  * @example
5329
5533
  * ```typescript
5330
- * // Modular pattern
5331
- * import { UiPath } from '@uipath/uipath-typescript/core';
5332
- * import { Entities } from '@uipath/uipath-typescript/entities';
5333
- *
5534
+ * // Explicit config
5334
5535
  * const sdk = new UiPath({
5335
5536
  * baseUrl: 'https://cloud.uipath.com',
5336
5537
  * orgName: 'myorg',
@@ -5339,70 +5540,47 @@ var _UiPath_config, _UiPath_authService, _UiPath_initialized;
5339
5540
  * redirectUri: 'http://localhost:3000/callback',
5340
5541
  * scope: 'OR.Users OR.Robots'
5341
5542
  * });
5342
- *
5343
5543
  * await sdk.initialize();
5544
+ * ```
5344
5545
  *
5345
- * const entitiesService = new Entities(sdk);
5346
- * const allEntities = await entitiesService.getAll();
5546
+ * @example
5547
+ * ```typescript
5548
+ * // Auto-load from meta tags (coded apps)
5549
+ * const sdk = new UiPath();
5550
+ * await sdk.initialize();
5347
5551
  * ```
5348
5552
  */
5349
5553
  let UiPath$1 = class UiPath {
5350
5554
  constructor(config) {
5555
+ _UiPath_instances.add(this);
5351
5556
  // Private fields - true runtime privacy, not visible via Object.keys()
5352
5557
  _UiPath_config.set(this, void 0);
5353
5558
  _UiPath_authService.set(this, void 0);
5354
5559
  _UiPath_initialized.set(this, false);
5355
- // Validate and normalize the configuration
5356
- validateConfig(config);
5357
- const hasSecretAuth = hasSecretConfig(config);
5358
- const hasOAuthAuth = hasOAuthConfig(config);
5359
- // Initialize core components
5360
- const internalConfig = new UiPathConfig({
5361
- baseUrl: normalizeBaseUrl(config.baseUrl),
5362
- orgName: config.orgName,
5363
- tenantName: config.tenantName,
5364
- secret: hasSecretAuth ? config.secret : undefined,
5365
- clientId: hasOAuthAuth ? config.clientId : undefined,
5366
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5367
- scope: hasOAuthAuth ? config.scope : undefined
5368
- });
5369
- const executionContext = new ExecutionContext();
5370
- __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5371
- __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5372
- // Store internals in SDKInternalsRegistry (not visible on instance)
5373
- SDKInternalsRegistry.set(this, {
5374
- config: internalConfig,
5375
- context: executionContext,
5376
- tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5377
- });
5378
- // Expose read-only config for user convenience
5379
- this.config = {
5380
- baseUrl: internalConfig.baseUrl,
5381
- orgName: internalConfig.orgName,
5382
- tenantName: internalConfig.tenantName
5383
- };
5384
- // Initialize telemetry with SDK configuration
5385
- telemetryClient.initialize({
5386
- baseUrl: config.baseUrl,
5387
- orgName: config.orgName,
5388
- tenantName: config.tenantName,
5389
- clientId: hasOAuthAuth ? config.clientId : undefined,
5390
- redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5391
- });
5392
- // Track SDK initialization
5393
- trackEvent('Sdk.Auth');
5394
- // Auto-initialize for secret-based auth
5395
- if (hasSecretAuth) {
5396
- __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret);
5397
- __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5560
+ _UiPath_partialConfig.set(this, void 0);
5561
+ // Load configuration from meta tags
5562
+ const configFromMetaTags = loadFromMetaTags();
5563
+ // Merge configuration: constructor config overrides meta tags
5564
+ const mergedConfig = config ? { ...configFromMetaTags, ...config } : configFromMetaTags;
5565
+ if (mergedConfig && isCompleteConfig(mergedConfig)) {
5566
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, mergedConfig);
5567
+ }
5568
+ else if (config) {
5569
+ __classPrivateFieldSet(this, _UiPath_partialConfig, config, "f");
5398
5570
  }
5399
5571
  }
5400
5572
  /**
5401
5573
  * Initialize the SDK based on the provided configuration.
5402
5574
  * This method handles both OAuth flow initiation and completion automatically.
5403
5575
  * For secret-based authentication, initialization is automatic and this returns immediately.
5576
+ * If no config was provided in constructor, loads from meta tags.
5404
5577
  */
5405
5578
  async initialize() {
5579
+ // Load config from meta tags if not provided in constructor
5580
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5581
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5582
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5583
+ }
5406
5584
  // For secret-based auth, it's already initialized in constructor
5407
5585
  if (hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5408
5586
  return;
@@ -5449,6 +5627,11 @@ let UiPath$1 = class UiPath {
5449
5627
  if (!AuthService.isInOAuthCallback()) {
5450
5628
  throw new Error('Not in OAuth callback state. Call initialize() first to start OAuth flow.');
5451
5629
  }
5630
+ // Load config if not yet initialized
5631
+ if (!__classPrivateFieldGet(this, _UiPath_config, "f")) {
5632
+ const loadedConfig = __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_loadConfig).call(this);
5633
+ __classPrivateFieldGet(this, _UiPath_instances, "m", _UiPath_initializeWithConfig).call(this, loadedConfig);
5634
+ }
5452
5635
  try {
5453
5636
  const success = await __classPrivateFieldGet(this, _UiPath_authService, "f").authenticate(__classPrivateFieldGet(this, _UiPath_config, "f"));
5454
5637
  if (success && this.isAuthenticated()) {
@@ -5466,13 +5649,13 @@ let UiPath$1 = class UiPath {
5466
5649
  * Check if the user is authenticated (has valid token)
5467
5650
  */
5468
5651
  isAuthenticated() {
5469
- return __classPrivateFieldGet(this, _UiPath_authService, "f").hasValidToken();
5652
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.hasValidToken() ?? false;
5470
5653
  }
5471
5654
  /**
5472
5655
  * Get the current authentication token
5473
5656
  */
5474
5657
  getToken() {
5475
- return __classPrivateFieldGet(this, _UiPath_authService, "f").getToken();
5658
+ return __classPrivateFieldGet(this, _UiPath_authService, "f")?.getToken();
5476
5659
  }
5477
5660
  /**
5478
5661
  * Logout from the SDK, clearing all authentication state.
@@ -5480,14 +5663,71 @@ let UiPath$1 = class UiPath {
5480
5663
  */
5481
5664
  logout() {
5482
5665
  // Secret-based auth has no session to end — skip silently
5483
- if (hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5666
+ if (__classPrivateFieldGet(this, _UiPath_config, "f") && hasSecretConfig(__classPrivateFieldGet(this, _UiPath_config, "f"))) {
5484
5667
  return;
5485
5668
  }
5486
- __classPrivateFieldGet(this, _UiPath_authService, "f").logout();
5669
+ __classPrivateFieldGet(this, _UiPath_authService, "f")?.logout();
5487
5670
  __classPrivateFieldSet(this, _UiPath_initialized, false, "f");
5488
5671
  }
5489
5672
  };
5490
- _UiPath_config = new WeakMap(), _UiPath_authService = new WeakMap(), _UiPath_initialized = new WeakMap();
5673
+ _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) {
5674
+ // Validate and normalize the configuration
5675
+ validateConfig(config);
5676
+ const hasSecretAuth = hasSecretConfig(config);
5677
+ const hasOAuthAuth = hasOAuthConfig(config);
5678
+ // Initialize core components
5679
+ const internalConfig = new UiPathConfig({
5680
+ baseUrl: normalizeBaseUrl(config.baseUrl),
5681
+ orgName: config.orgName,
5682
+ tenantName: config.tenantName,
5683
+ secret: hasSecretAuth ? config.secret : undefined,
5684
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5685
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined,
5686
+ scope: hasOAuthAuth ? config.scope : undefined
5687
+ });
5688
+ const executionContext = new ExecutionContext();
5689
+ __classPrivateFieldSet(this, _UiPath_authService, new AuthService(internalConfig, executionContext), "f");
5690
+ __classPrivateFieldSet(this, _UiPath_config, internalConfig, "f");
5691
+ // Store internals in SDKInternalsRegistry (not visible on instance)
5692
+ SDKInternalsRegistry.set(this, {
5693
+ config: internalConfig,
5694
+ context: executionContext,
5695
+ tokenManager: __classPrivateFieldGet(this, _UiPath_authService, "f").getTokenManager()
5696
+ });
5697
+ // Expose read-only config for user convenience
5698
+ this.config = {
5699
+ baseUrl: internalConfig.baseUrl,
5700
+ orgName: internalConfig.orgName,
5701
+ tenantName: internalConfig.tenantName
5702
+ };
5703
+ // Initialize telemetry with SDK configuration
5704
+ telemetryClient.initialize({
5705
+ baseUrl: config.baseUrl,
5706
+ orgName: config.orgName,
5707
+ tenantName: config.tenantName,
5708
+ clientId: hasOAuthAuth ? config.clientId : undefined,
5709
+ redirectUri: hasOAuthAuth ? config.redirectUri : undefined
5710
+ });
5711
+ // Track SDK initialization
5712
+ trackEvent('Sdk.Auth');
5713
+ /** Auto-initialize for secret-based auth
5714
+ * When viewed in Action Center, initialize tokenInfo with empty token. When an sdk call is made Action Center passes the token to sdk.
5715
+ */
5716
+ if (hasSecretAuth || isInActionCenter) {
5717
+ __classPrivateFieldGet(this, _UiPath_authService, "f").authenticateWithSecret(config.secret ?? '');
5718
+ __classPrivateFieldSet(this, _UiPath_initialized, true, "f");
5719
+ }
5720
+ }, _UiPath_loadConfig = function _UiPath_loadConfig() {
5721
+ // Load from meta tags
5722
+ const metaConfig = loadFromMetaTags();
5723
+ // Merge with any partial config from constructor (constructor overrides meta tags)
5724
+ const merged = { ...metaConfig, ...__classPrivateFieldGet(this, _UiPath_partialConfig, "f") };
5725
+ if (!isCompleteConfig(merged)) {
5726
+ throw new Error('UiPath SDK configuration not found. ' +
5727
+ 'Ensure @uipath/coded-apps plugin is set up in your bundler to inject configuration during development and build.');
5728
+ }
5729
+ return merged;
5730
+ };
5491
5731
 
5492
5732
  /**
5493
5733
  * Type guards for error response types
@@ -5766,15 +6006,6 @@ class ApiClient {
5766
6006
  async getDefaultHeaders() {
5767
6007
  // Get headers from execution context first
5768
6008
  const contextHeaders = this.executionContext.getHeaders();
5769
- // If Authorization header is already set in context, use that
5770
- if (contextHeaders['Authorization']) {
5771
- return {
5772
- ...contextHeaders,
5773
- 'Content-Type': CONTENT_TYPES.JSON,
5774
- ...this.defaultHeaders,
5775
- ...this.clientConfig.headers
5776
- };
5777
- }
5778
6009
  const token = await this.getValidToken();
5779
6010
  return {
5780
6011
  ...contextHeaders,
@@ -11118,6 +11349,81 @@ const UserSettingsMap = {
11118
11349
  ...CommonFieldMap
11119
11350
  };
11120
11351
 
11352
+ /**
11353
+ * Asset resolution utilities for UiPath Coded Apps
11354
+ *
11355
+ * These helpers enable developers to write code that works identically
11356
+ * in local development and production environments.
11357
+ *
11358
+ * Values are read from meta tags injected at deployment:
11359
+ * - <meta name="uipath:cdn-base" content="https://cdn.example.com/appId/folder">
11360
+ * - <meta name="uipath:app-base" content="/org/apps_/.../public">
11361
+ */
11362
+ /**
11363
+ * Resolves an asset path to the CDN URL (if available)
11364
+ *
11365
+ * In local development: returns path as-is (loads from local dev server)
11366
+ * In production: prepends CDN base URL from meta tag
11367
+ *
11368
+ * @param path - The asset path (e.g., './assets/logo.png' or '/assets/logo.png')
11369
+ * @returns The resolved asset URL
11370
+ *
11371
+ * @example
11372
+ * ```tsx
11373
+ * import { getAsset } from '@uipath/uipath-typescript';
11374
+ * import logoPath from './assets/logo.png';
11375
+ *
11376
+ * function MyComponent() {
11377
+ * return <img src={getAsset(logoPath)} alt="Logo" />;
11378
+ * }
11379
+ * ```
11380
+ */
11381
+ function getAsset(path) {
11382
+ // If path is already an absolute URL, return as-is
11383
+ if (path.startsWith('http://') || path.startsWith('https://')) {
11384
+ return path;
11385
+ }
11386
+ const cdnBase = getMetaTagContent(exports.UiPathMetaTags.CDN_BASE);
11387
+ if (!cdnBase)
11388
+ return path;
11389
+ // Normalize CDN base URL to remove trailing slash
11390
+ const normalizedCdnBase = normalizeBaseUrl(cdnBase);
11391
+ // Normalize path to ensure it starts with /
11392
+ let normalizedPath = path;
11393
+ if (normalizedPath.startsWith('./')) {
11394
+ normalizedPath = normalizedPath.substring(1); // ./assets -> /assets
11395
+ }
11396
+ else if (!normalizedPath.startsWith('/')) {
11397
+ normalizedPath = '/' + normalizedPath; // assets -> /assets
11398
+ }
11399
+ return normalizedCdnBase + normalizedPath;
11400
+ }
11401
+ /**
11402
+ * Returns the app base path for router configuration
11403
+ *
11404
+ * In local development: returns '/'
11405
+ * In production: returns the deployed app path from meta tag
11406
+ *
11407
+ * @returns The app base path
11408
+ *
11409
+ * @example
11410
+ * ```tsx
11411
+ * import { getAppBase } from '@uipath/uipath-typescript';
11412
+ * import { BrowserRouter } from 'react-router-dom';
11413
+ *
11414
+ * function App() {
11415
+ * return (
11416
+ * <BrowserRouter basename={getAppBase()}>
11417
+ * {/* routes *\/}
11418
+ * </BrowserRouter>
11419
+ * );
11420
+ * }
11421
+ * ```
11422
+ */
11423
+ function getAppBase() {
11424
+ return getMetaTagContent(exports.UiPathMetaTags.APP_BASE) || '/';
11425
+ }
11426
+
11121
11427
  exports.APP_NAME = APP_NAME;
11122
11428
  exports.AgentMap = AgentMap;
11123
11429
  exports.AuthenticationError = AuthenticationError;
@@ -11160,6 +11466,8 @@ exports.createEntityWithMethods = createEntityWithMethods;
11160
11466
  exports.createProcessInstanceWithMethods = createProcessInstanceWithMethods;
11161
11467
  exports.createProcessWithMethods = createProcessWithMethods;
11162
11468
  exports.createTaskWithMethods = createTaskWithMethods;
11469
+ exports.getAppBase = getAppBase;
11470
+ exports.getAsset = getAsset;
11163
11471
  exports.getErrorDetails = getErrorDetails;
11164
11472
  exports.getLimitedPageSize = getLimitedPageSize;
11165
11473
  exports.isAuthenticationError = isAuthenticationError;
@@ -11170,6 +11478,7 @@ exports.isRateLimitError = isRateLimitError;
11170
11478
  exports.isServerError = isServerError;
11171
11479
  exports.isUiPathError = isUiPathError;
11172
11480
  exports.isValidationError = isValidationError;
11481
+ exports.loadFromMetaTags = loadFromMetaTags;
11173
11482
  exports.telemetryClient = telemetryClient;
11174
11483
  exports.track = track;
11175
11484
  exports.trackEvent = trackEvent;