@globus/sdk 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,7 @@ The Globus SDK for JavaScript provides first class TypeScript support and makes
9
9
  - [@globus/sdk API Documentation](https://globus.github.io/globus-sdk-javascript/)
10
10
  - [Examples](https://github.com/globus/globus-sdk-javascript/blob/main/examples/README.md)
11
11
  - [Upgrading](https://github.com/globus/globus-sdk-javascript/blob/main/UPGRADING.md)
12
+ - [Migrating from `v4` to `v5`](https://github.com/globus/globus-sdk-javascript/blob/main/UPGRADING.md#migrating-from-v4-to-v5)
12
13
  - [Migrating from `v3` to `v4`](https://github.com/globus/globus-sdk-javascript/blob/main/UPGRADING.md#migrating-from-v3-to-v4)
13
14
 
14
15
  ## Installation
@@ -322,7 +322,7 @@ function toString(info) {
322
322
  }
323
323
 
324
324
  // src/core/info/version.ts
325
- var VERSION = "5.0.0";
325
+ var VERSION = "5.1.0";
326
326
 
327
327
  // src/core/info/index.ts
328
328
  var VERSION2 = VERSION;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/authorization/index.ts", "../../../../src/core/authorization/AuthorizationManager.ts", "../../../../src/services/auth/config.ts", "../../../../src/services/transfer/config.ts", "../../../../src/services/flows/config.ts", "../../../../src/services/timer/config.ts", "../../../../src/services/groups/config.ts", "../../../../src/services/search/config.ts", "../../../../src/services/compute/config.ts", "../../../../src/core/errors.ts", "../../../../src/core/logger.ts", "../../../../src/core/global.ts", "../../../../src/core/url.ts", "../../../../src/services/shared.ts", "../../../../src/core/info/private.ts", "../../../../src/core/info/version.ts", "../../../../src/core/info/index.ts", "../../../../src/services/auth/service/oauth2/index.ts", "../../../../src/services/auth/service/oauth2/token.ts", "../../../../src/services/auth/index.ts", "../../../../src/core/authorization/Event.ts", "../../../../src/core/authorization/pkce.ts", "../../../../src/core/authorization/RedirectTransport.ts", "../../../../src/core/authorization/TokenManager.ts", "../../../../src/core/storage/memory.ts"],
4
- "sourcesContent": ["/**\n * @module Authorization\n * @description Provides modules for interacting with Globus-related authorization contexts in your application.\n * @example\n * import { authorization } from \"globus/sdk\";\n * const manager = authorization.create(...);\n */\nimport {\n AuthorizationManager,\n type AuthorizationManagerConfiguration,\n} from './AuthorizationManager.js';\n\n/**\n * Create an instance of the {@link AuthorizationManager}.\n */\nexport function create(configuration: AuthorizationManagerConfiguration) {\n return new AuthorizationManager(configuration);\n}\n\nexport { AuthorizationManager, AuthorizationManagerConfiguration };\n", "import { jwtDecode } from 'jwt-decode';\n\nimport { isGlobusAuthTokenResponse, isRefreshToken, oauth2 } from '../../services/auth/index.js';\nimport { RESOURCE_SERVERS } from '../../services/auth/config.js';\n\nimport { log } from '../logger.js';\n\nimport { Event } from './Event.js';\nimport {\n RedirectTransportOptions,\n GetTokenOptions,\n RedirectTransport,\n} from './RedirectTransport.js';\nimport { TokenManager } from './TokenManager.js';\n\nimport {\n isConsentRequiredError,\n isAuthorizationRequirementsError,\n AuthorizationRequirementsError,\n ConsentRequiredError,\n toAuthorizationQueryParams,\n} from '../errors.js';\n\nimport type {\n JwtUserInfo,\n Token,\n TokenResponse,\n TokenWithRefresh,\n} from '../../services/auth/types.js';\nimport { MemoryStorage } from '../storage/memory.js';\n// import { PopupTransport } from './PopupTransport.js';\n\nconst TRANSPORTS = {\n redirect: RedirectTransport,\n // popup: PopupTransport,\n};\n\nexport type AuthorizationManagerConfiguration = {\n client: string;\n scopes?: string;\n redirect: string;\n /**\n * The storage system used by the `AuthorizationManager`.\n *\n * By default, the `AuthorizationManager` uses an in-memory storage, this option is secure by default.\n *\n * If you want to persist the state of the `AuthorizationManager`, you can use `localStorage`, or provide your own storage system.\n * **It is important to note that using the `localStorage`, or any persistant storage option will preserve authorization and refresh tokens of users.**\n * Best practices for ensuring the security of your application should be followed to protect this data (e.g., ensuring XSS protection).\n *\n * @default MemoryStorage\n */\n storage?: Storage;\n transport?: keyof typeof TRANSPORTS;\n /**\n * @private\n * @default DEFAULT_CONFIGURATION.useRefreshTokens\n */\n useRefreshTokens?: boolean;\n /**\n * @private\n * @default DEFAULT_CONFIGURATION.defaultScopes\n */\n defaultScopes?: string | false;\n /**\n * Provide an object with event listeners to attach to the instance.\n * This is useful if you need to listen to events that might dispatch immediately\n * after the creation of the instance (constructor), e.g., the `authenticated`.\n */\n events?: Partial<{\n [Event in keyof AuthorizationManager['events']]: Parameters<\n AuthorizationManager['events'][Event]['addListener']\n >[0];\n }>;\n};\n\nconst DEFAULT_CONFIGURATION = {\n useRefreshTokens: false,\n defaultScopes: 'openid profile email',\n transport: 'redirect' as const,\n};\n\nconst DEFAULT_HANDLE_ERROR_OPTIONS = {\n execute: true,\n additionalParams: undefined,\n};\n\n/**\n * Provides management of Globus authorization context for your application.\n * - Handles the OAuth protcol flow (via PKCE)\n * - Token lifecycle management\n * - Common errors (e.g., `ConsentRequired`, `authorization_requirements`)\n *\n * Once you configure your instance, you can determine the authenticated state using `manager.authenticated`.\n *\n * To prompt a user to authenticate, call `manager.login()` on user interaction \u2013 this will initiate the OAuth protocol flow with your configured client and scopes, resulting in an initial redirect to Globus Auth.\n *\n * Once the user authenticates with Globus Auth, they will be redirected to your application using the configured `redirect` URL. On this URL, you will need to call `manager.handleCodeRedirect` (using a manager instance configured in the same manner that initiated the `manager.login()` call) to complete the PKCE flow, exchanging the provided code for a valid token, or tokens.\n *\n * All tokens managed by the `AuthorizationManager` instance can be found on `manager.token`.\n *\n * ### Registering your Globus Application\n *\n * The `AuthorizationManager` expects your Globus Application to be registered as an OAuth public client.\n * In this Globus Web Application, this option is referenced as \"_Register a thick client or script that will be installed and run by users on their devices_\".\n *\n * @example <caption>Creating an AuthorizationManager instance.</caption>\n * import { authorization } from \"globus/sdk\";\n *\n * const manager = authorization.create({\n * // Your registered Globus Application client ID.\n * client: '...',\n * // The redirect URL for your application; Where you will call `manager.handleCodeRedirect()`\n * redirect: 'https://example.com/callback',\n * // Known scopes required by your application.\n * scopes: 'urn:globus:auth:scope:transfer.api.globus.org:all',\n * });\n */\nexport class AuthorizationManager {\n #transport!: RedirectTransport;\n\n configuration: AuthorizationManagerConfiguration;\n\n /**\n * The storage system used by the `AuthorizationManager`.\n * @implements Storage\n */\n storage: Storage;\n\n #authenticated = false;\n\n /**\n * The `AuthorizationManager` is considered `authenticated` if it has a valid Globus Auth token.\n * It does not necessarily mean that it has a valid token for a specific resource server.\n */\n get authenticated() {\n return this.#authenticated;\n }\n\n /**\n * Set the authenticated state and emit the `authenticated` event.\n */\n set authenticated(value: boolean) {\n /**\n * Avoid emitting the event if the value hasn't changed.\n */\n if (value === this.#authenticated) {\n return;\n }\n this.#authenticated = value;\n this.#emitAuthenticatedState();\n }\n\n tokens: TokenManager;\n\n events = {\n /**\n * Emitted when the authenticated state changes.\n * @event AuthorizationManager.events#authenticated\n * @type {object}\n * @property {boolean} isAuthenticated - Whether the `AuthorizationManager` is authenticated.\n * @property {TokenResponse} [token] - The token response if the `AuthorizationManager` is authenticated.\n */\n authenticated: new Event<\n 'authenticated',\n {\n /**\n * Whether the `AuthorizationManager` is authenticated.\n * @see {@link AuthorizationManager.authenticated}\n */\n isAuthenticated: boolean;\n token?: TokenResponse;\n }\n >('authenticated'),\n /**\n * Emitted when the user revokes their authentication.\n * @event AuthorizationManager.events#revoke\n */\n revoke: new Event('revoke'),\n };\n\n constructor(configuration: AuthorizationManagerConfiguration) {\n /**\n * Configure the storage system for the instance, defaulting to an in-memory storage system.\n */\n\n if (!configuration.client) {\n throw new Error('You must provide a `client` for your application.');\n }\n /**\n * Inject the `openid`, `profile`, `email`, and `offline_access` scopes by default unless\n * explicitly opted out of.\n */\n const scopes =\n configuration.defaultScopes === false\n ? ''\n : (configuration.defaultScopes ?? DEFAULT_CONFIGURATION.defaultScopes);\n\n this.configuration = {\n ...DEFAULT_CONFIGURATION,\n ...configuration,\n scopes: [configuration.scopes ? configuration.scopes : '', scopes]\n .filter((s) => s.length)\n .join(' '),\n };\n\n this.storage = configuration.storage || new MemoryStorage();\n\n /**\n * If an `events` object is provided, add the listeners to the instance before\n * any event might be dispatched.\n */\n if (this.configuration.events) {\n Object.entries(this.configuration.events).forEach(([name, callback]) => {\n if (name in this.events) {\n this.events[name as keyof AuthorizationManager['events']].addListener(callback);\n }\n });\n }\n\n this.tokens = new TokenManager({\n manager: this,\n });\n this.#checkAuthorizationState();\n }\n\n get storageKeyPrefix() {\n return `${this.configuration.client}:`;\n }\n\n /**\n * The user information decoded from the `id_token` (JWT) of the current Globus Auth token.\n * This method can be used instead of `auth.oauth2.userinfo` to get the user information without an additional request.\n *\n * **IMPORTANT**: The `id_token` can only be processed if the `openid` scope is requested during the authorization process.\n *\n * Additionally, the `profile` and `email` scopes are required to get the full user information.\n *\n * @see {@link https://docs.globus.org/api/auth/reference/#oidc_userinfo_endpoint}\n */\n get user() {\n const token = this.getGlobusAuthToken();\n return token && token.id_token ? jwtDecode<JwtUserInfo>(token.id_token) : null;\n }\n\n /**\n * Attempt to refresh all of the tokens managed by the instance.\n * This method will only attempt to refresh tokens that have a `refresh_token` attribute.\n */\n async refreshTokens() {\n log('debug', 'AuthorizationManager.refreshTokens');\n const tokens = await Promise.allSettled(\n this.tokens.getAll().map((token) => {\n if (isRefreshToken(token)) {\n return this.refreshToken(token);\n }\n return Promise.resolve(null);\n }),\n );\n this.#checkAuthorizationState();\n return tokens;\n }\n\n /**\n * Use the `refresh_token` attribute of a token to obtain a new access token.\n * @param token The well-formed token with a `refresh_token` attribute.\n */\n async refreshToken(token: TokenWithRefresh) {\n log('debug', `AuthorizationManager.refreshToken | resource_server=${token.resource_server}`);\n try {\n const response = await (\n await oauth2.token.refresh({\n payload: {\n client_id: this.configuration.client,\n refresh_token: token.refresh_token,\n grant_type: 'refresh_token',\n },\n })\n ).json();\n if (isGlobusAuthTokenResponse(response)) {\n this.addTokenResponse(response);\n return response;\n }\n } catch (error) {\n log('error', `AuthorizationManager.refreshToken | resource_server=${token.resource_server}`);\n }\n return null;\n }\n\n /**\n * Whether or not the instance has a reference to a Globus Auth token.\n */\n hasGlobusAuthToken() {\n return this.getGlobusAuthToken() !== null;\n }\n\n /**\n * Retrieve the Globus Auth token managed by the instance.\n */\n getGlobusAuthToken() {\n const entry = this.storage.getItem(`${this.storageKeyPrefix}${RESOURCE_SERVERS.AUTH}`);\n return entry ? JSON.parse(entry) : null;\n }\n\n #checkAuthorizationState() {\n log('debug', 'AuthorizationManager.#checkAuthorizationState');\n if (this.hasGlobusAuthToken()) {\n this.authenticated = true;\n }\n }\n\n async #emitAuthenticatedState() {\n const isAuthenticated = this.authenticated;\n const token = this.getGlobusAuthToken() ?? undefined;\n await this.events.authenticated.dispatch({\n isAuthenticated,\n token,\n });\n }\n\n /**\n * Reset the authenticated state and clear all tokens from storage.\n * This method **does not** emit the `revoke` event. If you need to emit the `revoke` event, use the `AuthorizationManager.revoke` method.\n */\n reset() {\n Object.keys(this.storage).forEach((key) => {\n if (key.startsWith(this.storageKeyPrefix)) {\n this.storage.removeItem(key);\n }\n });\n this.authenticated = false;\n }\n\n /**\n * A private utility method to add the `offline_access` scope to a scope string if the `useRefreshTokens` configuration is set to `true`.\n * @param scopes The scope string to modify.\n */\n #withOfflineAccess(scopes: string) {\n return `${scopes}${this.configuration.useRefreshTokens ? ' offline_access' : ''}`;\n }\n\n #buildTransport(options?: Partial<RedirectTransportOptions>) {\n const { scopes, ...overrides } = options ?? {};\n const TransportFactory = TRANSPORTS[this.configuration.transport || 'redirect'];\n\n let scopesToRequest = this.#withOfflineAccess(scopes ?? (this.configuration.scopes || ''));\n\n if (this.storage instanceof MemoryStorage) {\n /**\n * If the in-memory storage is used, we have to make sure when requesting additional\n * consent the original configured scopes are included in the request.\n *\n * This will ensure we recieve a token for all of resource servers that were originally requested,\n * in addition to any new scopes that are requested.\n */\n scopesToRequest = [\n // Use a Set to deduplicate the scopes.\n ...new Set(\n scopesToRequest.split(' ').concat((this.configuration?.scopes || '').split(' ')),\n ),\n ].join(' ');\n }\n\n return new TransportFactory({\n client: this.configuration.client,\n redirect: this.configuration.redirect,\n scopes: scopesToRequest,\n ...overrides,\n params: {\n // @todo @todo Decide if we want to include the `include_consented_scopes` parameter by default.\n // include_consented_scopes: 'true',\n ...overrides?.params,\n },\n });\n }\n\n /**\n * Initiate the login process by redirecting to the Globus Auth login page.\n *\n * **IMPORTANT**: This method will reset the instance state before initiating the login process,\n * including clearing all tokens from storage. If you need to maintain the current state,\n * use the `AuthorizationManager.prompt` method.\n */\n async login(options = { additionalParams: {} }) {\n log('debug', 'AuthorizationManager.login');\n this.reset();\n /**\n * In the future, it's possible that we may want to support different types of transports.\n */\n const transport = this.#buildTransport({ params: options?.additionalParams });\n await transport.send();\n }\n\n /**\n * Prompt the user to authenticate with Globus Auth.\n */\n async prompt(options?: Partial<RedirectTransportOptions>) {\n log('debug', 'AuthorizationManager.prompt');\n const transport = this.#buildTransport(options);\n await transport.send();\n }\n\n /**\n * This method will attempt to complete the PKCE protocol flow.\n */\n async handleCodeRedirect(\n options: {\n shouldReplace: GetTokenOptions['shouldReplace'];\n additionalParams?: RedirectTransportOptions['params'];\n } = { shouldReplace: true, additionalParams: {} },\n ) {\n log('debug', 'AuthorizationManager.handleCodeRedirect');\n const response = await this.#buildTransport({ params: options?.additionalParams }).getToken({\n shouldReplace: options?.shouldReplace,\n });\n if (isGlobusAuthTokenResponse(response)) {\n log(\n 'debug',\n `AuthorizationManager.handleCodeRedirect | response=${JSON.stringify(response)}`,\n );\n this.addTokenResponse(response);\n }\n return response;\n }\n\n /**\n * Handle an error response from a Globus service in the context of this `AuthorizationManager`.\n * This method will introspect the response and attempt to handle any errors that should result\n * in some additional Globus Auth interaction.\n * @param response The error response from a Globus service.\n * @param {object|boolean} options Options for handling the error response. If a boolean is provided, this will be treated as the `options.execute` value.\n * @param options.execute Whether to execute the handler immediately.\n * @param options.additionalParms Additional query parameters to be included with the transport generated URL.\n */\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?: { execute?: true; additionalParams?: RedirectTransportOptions['params'] } | true,\n ): Promise<void>;\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?: { execute?: false; additionalParams?: RedirectTransportOptions['params'] } | false,\n ): Promise<() => Promise<void>>;\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?:\n | { execute?: boolean; additionalParams?: RedirectTransportOptions['params'] }\n | boolean,\n ) {\n const opts =\n typeof options === 'boolean'\n ? {\n ...DEFAULT_HANDLE_ERROR_OPTIONS,\n execute: options,\n }\n : {\n ...DEFAULT_HANDLE_ERROR_OPTIONS,\n ...options,\n };\n log(\n 'debug',\n `AuthorizationManager.handleErrorResponse | response=${JSON.stringify(response)} execute=${opts.execute}`,\n );\n let handler = async () => {};\n if (isAuthorizationRequirementsError(response)) {\n log(\n 'debug',\n 'AuthorizationManager.handleErrorResponse | error=AuthorizationRequirementsError',\n );\n handler = async () => {\n await this.handleAuthorizationRequirementsError(response, {\n additionalParams: opts.additionalParams,\n });\n };\n }\n if (isConsentRequiredError(response)) {\n log('debug', 'AuthorizationManager.handleErrorResponse | error=ConsentRequiredError');\n handler = async () => {\n await this.handleConsentRequiredError(response, {\n additionalParams: opts.additionalParams,\n });\n };\n }\n if ('code' in response && response['code'] === 'AuthenticationFailed') {\n log('debug', 'AuthorizationManager.handleErrorResponse | error=AuthenticationFailed');\n handler = async () => {\n await this.revoke();\n };\n }\n\n const returnValue = opts.execute === true ? await handler() : handler;\n return returnValue;\n }\n\n /**\n * Process a well-formed Authorization Requirements error response from a Globus service\n * and redirect the user to the Globus Auth login page with the necessary parameters.\n */\n async handleAuthorizationRequirementsError(\n response: AuthorizationRequirementsError,\n options?: { additionalParams?: RedirectTransportOptions['params'] },\n ) {\n this.#transport = this.#buildTransport({\n params: {\n prompt: 'login',\n ...toAuthorizationQueryParams(response),\n ...options?.additionalParams,\n },\n });\n await this.#transport.send();\n }\n\n /**\n * Process a well-formed `ConsentRequired` error response from a Globus service\n * and redirect the user to the Globus Auth login page with the necessary parameters.\n */\n async handleConsentRequiredError(\n response: ConsentRequiredError,\n options?: { additionalParams?: RedirectTransportOptions['params'] },\n ) {\n this.#transport = this.#buildTransport({\n scopes: this.#withOfflineAccess(response.required_scopes.join(' ')),\n params: {\n ...options?.additionalParams,\n },\n });\n await this.#transport.send();\n }\n\n /**\n * Add a Globus Auth token response to storage, if `other_tokens` are present they are also added.\n * This method is mostly used internally by the `AuthorizationManager`, but can be used by downstream\n * consumers to add tokens to storage if necessary.\n */\n addTokenResponse = (token: Token | TokenResponse) => {\n this.tokens.add(token);\n this.#checkAuthorizationState();\n };\n\n /**\n * Call `AuthroizationManager.reset`, revoke all of the available tokns, and emit the `revoke` event.\n * @emits AuthorizationManager.events#revoke\n * @see AuthorizationManager.reset\n */\n async revoke() {\n log('debug', 'AuthorizationManager.revoke');\n const revocation = Promise.all(this.tokens.getAll().map(this.#revokeToken.bind(this)));\n this.reset();\n await revocation;\n await this.events.revoke.dispatch();\n }\n\n /**\n * Revoke a token from a resource server.\n */\n #revokeToken(token: Token) {\n log('debug', `AuthorizationManager.revokeToken | resource_server=${token.resource_server}`);\n return oauth2.token.revoke({\n payload: {\n client_id: this.configuration.client,\n token: token.access_token,\n },\n });\n }\n}\n", "import { ID as TRANSFER } from '../transfer/config.js';\nimport { ID as FLOWS } from '../flows/config.js';\nimport { ID as TIMER } from '../timer/config.js';\nimport { ID as GROUPS } from '../groups/config.js';\nimport { ID as SEARCH } from '../search/config.js';\nimport { ID as COMPUTE } from '../compute/config.js';\n\nimport type { Environment } from '../../core/global.js';\n\nexport const ID = 'AUTH' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n integration: 'auth.integration.globuscs.info',\n sandbox: 'auth.sandbox.globuscs.info',\n production: 'auth.globus.org',\n test: 'auth.test.globuscs.info',\n staging: 'auth.staging.globuscs.info',\n preview: 'auth.preview.globus.org',\n};\n\nexport const SCOPES = {\n VIEW_IDENTITIES: 'urn:globus:auth:scope:auth.globus.org:view_identities',\n};\n\nexport const RESOURCE_SERVERS = {\n [ID]: 'auth.globus.org',\n [TRANSFER]: 'transfer.api.globus.org',\n [FLOWS]: 'flows.globus.org',\n [GROUPS]: 'groups.api.globus.org',\n [SEARCH]: 'search.api.globus.org',\n [TIMER]: '524230d7-ea86-4a52-8312-86065a9e0417',\n [COMPUTE]: 'funcx_service',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'TRANSFER' as const;\n\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:transfer.api.globus.org:all',\n};\n\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'transfer.api.sandbox.globuscs.info',\n production: 'transfer.api.globusonline.org',\n staging: 'transfer.api.staging.globuscs.info',\n integration: 'transfer.api.integration.globuscs.info',\n test: 'transfer.api.test.globuscs.info',\n preview: 'transfer.api.preview.globus.org',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'FLOWS' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'sandbox.flows.automate.globus.org',\n production: 'flows.globus.org',\n staging: 'staging.flows.automate.globus.org',\n integration: 'integration.flows.automate.globus.org',\n test: 'test.flows.automate.globus.org',\n preview: 'preview.flows.automate.globus.org',\n};\n\n/**\n * @see https://docs.globus.org/api/flows/overview/#scopes\n */\nexport const SCOPES = {\n MANAGE_FLOWS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/manage_flows',\n VIEW_FLOWS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/view_flows',\n RUN: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run',\n RUN_STATUS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run_status',\n RUN_MANAGE: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run_manage',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'TIMER' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'sandbox.timer.automate.globus.org',\n production: 'timer.automate.globus.org',\n staging: 'staging.timer.automate.globus.org',\n integration: 'integration.timer.automate.globus.org',\n test: 'test.timer.automate.globus.org',\n preview: 'preview.timer.automate.globus.org',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'GROUPS' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'groups.api.sandbox.globuscs.info',\n production: 'groups.api.globus.org',\n staging: 'groups.api.staging.globuscs.info',\n integration: 'groups.api.integration.globuscs.info',\n test: 'groups.api.test.globuscs.info',\n preview: 'groups.api.preview.globuscs.info',\n};\n\n/**\n * @see https://docs.globus.org/api/groups/#scopes\n */\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:groups.api.globus.org:all',\n VIEW_MY: 'urn:globus:auth:scope:groups.api.globus.org:view_my_groups_and_membership',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'SEARCH' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'search.api.sandbox.globuscs.info',\n production: 'search.api.globus.org',\n staging: 'search.api.staging.globuscs.info',\n integration: 'search.api.integration.globuscs.info',\n test: 'search.api.test.globuscs.info',\n preview: 'search.api.preview.globus.org',\n};\n\n/**\n * @see https://docs.globus.org/api/search/api_usage/#scopes\n */\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:search.api.globus.org:all',\n INGEST: 'urn:globus:auth:scope:search.api.globus.org:ingest',\n SEARCH: 'urn:globus:auth:scope:search.api.globus.org:search',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'COMPUTE' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'compute.api.sandbox.globuscs.info',\n production: 'compute.api.globus.org',\n staging: 'compute.api.staging.globuscs.info',\n integration: 'compute.api.integration.globuscs.info',\n test: 'compute.api.test.globuscs.info',\n preview: 'compute.api.preview.globus.org',\n};\n\nexport const SCOPES = {\n ALL: 'https://auth.globus.org/scopes/facd7ccc-c5f4-42aa-916b-a0e270e2c2a9/all',\n};\n", "/**\n * @module Errors\n * @example\n * import { errors } from \"globus/sdk\";\n * if (errors.isConsentRequiredError(...)) { ... }\n */\nimport type { AuthorizationQueryParameters } from '../services/auth/index.js';\n\nexport class EnvironmentConfigurationError extends Error {\n override name = 'EnvironmentConfigurationError';\n\n constructor(variable: string, value: unknown) {\n super();\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n this.message = `Invalid configuration value provided for ${variable} (${value}).`;\n }\n}\n\nexport type WellFormedError = {\n code: string;\n message: string;\n};\n\nexport function isErrorWellFormed(test: unknown): test is WellFormedError {\n return typeof test === 'object' && test !== null && 'code' in test && 'message' in test;\n}\n\nexport type ConsentRequiredError = {\n code: 'ConsentRequired';\n required_scopes: string[];\n [key: string]: unknown;\n};\n\nexport function isConsentRequiredError(test: unknown): test is ConsentRequiredError {\n return (\n isErrorWellFormed(test) &&\n test.code === 'ConsentRequired' &&\n 'required_scopes' in test &&\n Array.isArray(test.required_scopes)\n );\n}\n\n/**\n * An error that includes an `authorization_parameters` property, a.k.a \"G.A.R.E\".\n *\n * A well-known error shape is provided by services when additional authorization requirements must be met by the session.\n * This object can be converted to parameters accepted by Globus Auth using `sdk.errors.toAuthorizationQueryParams()`.\n */\nexport type AuthorizationRequirementsError = {\n authorization_parameters: {\n session_message?: string;\n session_required_identities?: string[];\n session_required_mfa?: boolean;\n session_required_single_domain?: string[];\n session_required_policies?: string[];\n prompt?: string;\n required_scopes?: string[];\n };\n /**\n * @todo At the moment, most Globus services do not guarentee a `code` property for this error type.\n * Once it becomes more common, this type (and the `isAuthorizationRequirementsError` function) should be updated.\n * @see https://globus-sdk-python.readthedocs.io/en/stable/experimental/auth_requirements_errors.html\n */\n // code: string;\n [key: string]: unknown;\n};\n/**\n * Keys that should not be included in the query string object (not recognized by Globus Auth).\n */\nconst NO_OP_KEYS: (keyof AuthorizationRequirementsError)[] = ['required_scopes'];\n/**\n * Convert an `AuthorizationRequirementsError` to a query string object accepted by Globus Auth.\n */\nexport function toAuthorizationQueryParams(\n error: AuthorizationRequirementsError,\n): AuthorizationQueryParameters {\n return Object.entries(error.authorization_parameters).reduce((acc, [key, v]) => {\n /**\n * Remove keys that are not recognized by Globus Auth and empty values.\n */\n if (NO_OP_KEYS.includes(key) || v === undefined || v === null) {\n return acc;\n }\n /**\n * All other values are converted to strings.\n */\n let value = v;\n if (Array.isArray(value)) {\n value = value.join(',');\n } else if (typeof v === 'boolean') {\n value = value ? 'true' : 'false';\n }\n return { ...acc, [key]: value };\n }, {});\n}\n\n/**\n * Check if an object is an `AuthorizationRequirementsError`.\n * @see {@link AuthorizationRequirementsError}\n */\nexport function isAuthorizationRequirementsError(\n test: unknown,\n): test is AuthorizationRequirementsError {\n return (\n typeof test === 'object' &&\n test !== null &&\n 'authorization_parameters' in test &&\n typeof test.authorization_parameters === 'object' &&\n test.authorization_parameters !== null\n );\n}\n", "const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\ntype LogLevel = (typeof LOG_LEVELS)[number];\n\ntype LogHandler = (...args: unknown[]) => void;\n\ntype Logger = {\n log: LogHandler;\n error?: LogHandler;\n warn?: LogHandler;\n info?: LogHandler;\n debug?: LogHandler;\n};\n/**\n * No logger is set by default.\n */\nlet logger: Logger | undefined;\n/**\n * By default, the logger is set to `error`.\n */\nlet level: number = LOG_LEVELS.indexOf('error');\n/**\n * Set the global logger for the SDK.\n * @param logMechanism The logger to use.\n * @example `log.setLogger(console)`\n */\nexport function setLogger(logMechanism: Logger) {\n logger = logMechanism;\n}\n/**\n * Set the global log level for the logger.\n * @param severity The severity to set the logger to.\n * @example `log.setLogLevel('info')`\n */\nexport function setLogLevel(severity: LogLevel) {\n level = LOG_LEVELS.indexOf(severity);\n}\n/**\n * Log a message to the logger.\n * @param severity The severity of the log entry.\n * @param args The message to log.\n * @private\n */\nexport function log(severity: LogLevel, ...args: unknown[]) {\n if (!logger) return;\n /**\n * If the severity of the entry is less than the logger's configured severity, do not log.\n */\n if (LOG_LEVELS.indexOf(severity) < level) {\n return;\n }\n /**\n * If the logger does not have a handler for the specified severity, use the default `log` handler.\n */\n const handler = logger[severity] ?? logger.log;\n handler(...args);\n}\n", "import * as AUTH from '../services/auth/config.js';\nimport * as TRANSFER from '../services/transfer/config.js';\nimport * as FLOWS from '../services/flows/config.js';\nimport * as GROUPS from '../services/groups/config.js';\nimport * as SEARCH from '../services/search/config.js';\nimport * as TIMER from '../services/timer/config.js';\nimport * as COMPUTE from '../services/compute/config.js';\n\nimport { EnvironmentConfigurationError } from './errors.js';\nimport { SDKOptions } from '../services/types.js';\nimport { log } from './logger.js';\n\nfunction getRuntime() {\n return typeof window !== 'undefined' ? window : process;\n}\n\nfunction isBrowser(runtime: Window | NodeJS.Process): runtime is Window {\n return typeof window === typeof runtime;\n}\n\nfunction env<T>(key: string, fallback: T): T {\n const runtime = getRuntime();\n let envConfiguration;\n if (isBrowser(runtime)) {\n envConfiguration = runtime;\n } else {\n envConfiguration = runtime.env;\n }\n if (key in envConfiguration) {\n return (envConfiguration as Record<typeof key, T>)[key];\n }\n return fallback;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_ENVIRONMENT\n */\nexport const ENVIRONMENTS = {\n PRODUCTION: 'production',\n PREVIEW: 'preview',\n STAGING: 'staging',\n SANDBOX: 'sandbox',\n INTEGRATION: 'integration',\n TEST: 'test',\n} as const;\n\nexport type Environment = (typeof ENVIRONMENTS)[keyof typeof ENVIRONMENTS];\n\nexport const SERVICES = {\n [AUTH.ID]: AUTH.ID,\n [TRANSFER.ID]: TRANSFER.ID,\n [FLOWS.ID]: FLOWS.ID,\n [GROUPS.ID]: GROUPS.ID,\n [SEARCH.ID]: SEARCH.ID,\n [TIMER.ID]: TIMER.ID,\n [COMPUTE.ID]: COMPUTE.ID,\n};\n\nexport type Service = keyof typeof SERVICES;\n\nexport const SERVICE_HOSTS: Record<Service, Partial<Record<Environment, string>>> = {\n [AUTH.ID]: AUTH.HOSTS,\n [TRANSFER.ID]: TRANSFER.HOSTS,\n [FLOWS.ID]: FLOWS.HOSTS,\n [GROUPS.ID]: GROUPS.HOSTS,\n [SEARCH.ID]: SEARCH.HOSTS,\n [TIMER.ID]: TIMER.HOSTS,\n [COMPUTE.ID]: COMPUTE.HOSTS,\n};\n\n/**\n * Get the computed SDK options based on the runtime.\n * This should be used any time we're referencing the SDK options in\n * methods to ensure we're including any global overrides.\n */\nexport function getSDKOptions(options?: SDKOptions) {\n let globalOptions = env<string | SDKOptions>('GLOBUS_SDK_OPTIONS', {});\n if (typeof globalOptions === 'string') {\n globalOptions = JSON.parse(globalOptions) as SDKOptions;\n }\n return {\n ...globalOptions,\n ...options,\n fetch: {\n ...globalOptions?.fetch,\n ...options?.fetch,\n options: {\n ...globalOptions?.fetch?.options,\n ...options?.fetch?.options,\n headers: {\n ...globalOptions?.fetch?.options?.headers,\n ...options?.fetch?.options?.headers,\n },\n },\n },\n };\n}\n\nexport function getEnvironment(): Environment {\n const globalOptions = getSDKOptions();\n const environment = env<Environment>(\n 'GLOBUS_SDK_ENVIRONMENT',\n globalOptions?.environment ?? ENVIRONMENTS.PRODUCTION,\n );\n if (globalOptions?.environment && environment !== globalOptions.environment) {\n log(\n 'debug',\n 'GLOBUS_SDK_ENVIRONMENT and GLOBUS_SDK_OPTIONS.environment are set to different values. GLOBUS_SDK_ENVIRONMENT will take precedence',\n );\n }\n if (!environment || !Object.values(ENVIRONMENTS).includes(environment)) {\n throw new EnvironmentConfigurationError('GLOBUS_SDK_ENVIRONMENT', environment);\n }\n return environment;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_VERIFY_SSL\n * Since disabling SSL is at least not-recommended, we consider\n * this value to always be true, but provide a warning when it set\n * to one of the falsey values for informational purposes.\n *\n * Taking direction from `globus-sdk-python` for possible false values\n * @see https://github.com/globus/globus-sdk-python/blob/18eced9c12e2ec41745d1be183148845198b999c/src/globus_sdk/config/env_vars.py#L20\n */\nexport function getVerifySSL(): boolean {\n const verifySSLTemp = env<string>('GLOBUS_SDK_VERIFY_SSL', 'true').toLowerCase();\n if (['n', 'no', 'f', 'false', 'off', '0'].includes(verifySSLTemp)) {\n log(\n 'warn',\n 'Setting GLOBUS_SDK_VERIFY_SSL to false is disallowed in the Globus JavaScript SDK. It will always true in this context',\n );\n }\n return true;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_HTTP_TIMEOUT\n */\nexport function getHttpTimeout() {\n const timeout = Number(env<string | number>('GLOBUS_SDK_HTTP_TIMEOUT', 60));\n if (timeout === -1) {\n return null;\n }\n return timeout;\n}\n\nexport function getServiceHost(service: Service, environment: Environment = getEnvironment()) {\n return SERVICE_HOSTS[service][environment];\n}\n\nexport function getServiceBaseUrl(service: Service, environment: Environment = getEnvironment()) {\n const host = getServiceHost(service, environment);\n return env(`GLOBUS_SDK_SERVICE_URL_${service}`, host ? `https://${host}` : undefined);\n}\n", "import { getServiceBaseUrl, getEnvironment, Environment, Service } from './global.js';\nimport type { GCSConfiguration } from '../services/globus-connect-server/index.js';\nimport { SDKOptions } from '../services/types.js';\n\n/**\n * An extremely simplified parameter serializer based on our current needs.\n *\n * **This is intended for internal @globus/sdk use only.**\n *\n * @private\n */\nexport function stringifyParameters(parameters: {\n [key: string]:\n | string\n | number\n | boolean\n | Array<string | number | null | undefined>\n | null\n | undefined;\n}) {\n const search = new URLSearchParams();\n\n Array.from(Object.entries(parameters)).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n /**\n * Arrays are converted to comma-separated strings.\n */\n search.set(key, value.join(','));\n } else if (value !== undefined) {\n search.set(key, String(value));\n }\n });\n\n return search.toString();\n}\n\n/**\n * Return the base URL for a service (based on the environment).\n * @param service The service to build the URL for.\n * @param path The path to the resource.\n * @param environment The environment to use.\n */\nexport function getServiceURL(\n service: Service,\n path = '',\n environment: Environment = getEnvironment(),\n): URL {\n const base = getServiceBaseUrl(service, environment);\n return new URL(path, base);\n}\n\n/**\n * Build a URL for a service or GCSConfiguration.\n *\n * @param service The service identifier or GCSConfiguration object to build the URL for.\n * @param path The path to the resource.\n * @param options Additional options for the URL.\n */\nexport function build(\n serviceOrConfiguration: Service | GCSConfiguration,\n path: string,\n options?: {\n search?: Parameters<typeof stringifyParameters>[0];\n },\n sdkOptions?: SDKOptions,\n): string {\n let url;\n if (typeof serviceOrConfiguration === 'object') {\n url = new URL(path, serviceOrConfiguration.host);\n } else {\n url = getServiceURL(serviceOrConfiguration, path, sdkOptions?.environment);\n }\n if (options && options.search) {\n url.search = stringifyParameters(options.search);\n }\n return url.toString();\n}\n", "import _fetch from 'cross-fetch';\nimport { getClientInfoRequestHeaders } from '../core/info/index.js';\nimport { build } from '../core/url.js';\nimport { getSDKOptions, Service } from '../core/global.js';\nimport { isAuthorizationRequirementsError } from '../core/errors.js';\nimport { RESOURCE_SERVERS } from './auth/config.js';\nimport { isRefreshToken } from './auth/index.js';\nimport type { ServiceMethodOptions, SDKOptions } from './types.js';\nimport type { GCSConfiguration } from '../services/globus-connect-server/index.js';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport enum HTTP_METHODS {\n POST = 'POST',\n GET = 'GET',\n DELETE = 'DELETE',\n PUT = 'PUT',\n PATCH = 'PATCH',\n}\n\n/**\n * Our domain-specific language for describing service requests.\n * @private\n */\ntype ServiceRequestDSL = {\n /**\n * The service that the request will be made to.\n */\n service: Service | GCSConfiguration;\n /**\n * A specific scope that is required for the request. If a scope is provided,\n * the `serviceRequest` function will attempt to get a token for the request\n * based on the the `service` => `resource_server` mapping.\n */\n scope?: string;\n /**\n * The resource server that the request will be made to. This can be provided\n * instead of (or addition to) the `scope` property. If this is provided, the\n * `serviceRequest` function will attempt to get a token for the resource server\n * when a `manager` instance is provided in the SDK options.\n */\n resource_server?: string;\n /**\n * The path of the resource (appended to the service's host).\n */\n path: string;\n /**\n * The HTTP method to use for the request.\n */\n method?: HTTP_METHODS;\n /**\n * For some resources, it doesn't make sense for requests to be retried.\n * Setting this to `true` will prevent any retry logic from being applied.\n */\n preventRetry?: boolean;\n};\n\n/**\n * A helper function for making service requests that will handle the arguments\n * of `ServiceMethod` and `ServiceMethodDynamicSegments` functions in a uniform\n * way.\n *\n * @example\n * ```ts\n * export const get = function (flow_id, options?, sdkOptions?) {\n * return serviceRequest({\n * service: FLOWS.ID,\n * scope: SCOPES.VIEW_FLOWS,\n * path: `/flows/${flow_id}`,\n * }, options, sdkOptions);\n * } satisfies ServiceMethodDynamicSegments<string, Record<string, any>>;\n * ```\n *\n * @private\n * @param config The ServiceRequestDSL for the request.\n * @param options The options passed to the service method.\n * @param passedSdkOptions The SDK options passed to the service method.\n * @returns\n */\nexport async function serviceRequest(\n this: unknown,\n config: ServiceRequestDSL,\n options?: ServiceMethodOptions,\n passedSdkOptions?: SDKOptions,\n): Promise<Response> {\n /**\n * Get the SDK options, merging any passed options with the global options.\n */\n const sdkOptions = getSDKOptions(passedSdkOptions);\n const injectedFetchOptions = sdkOptions?.fetch?.options || {};\n\n const headers: Record<string, string> = {\n ...getClientInfoRequestHeaders(),\n ...options?.headers,\n /**\n * Key/value pairs found in the `fetch` options override those found in the\n * service method options.\n */\n ...injectedFetchOptions.headers,\n };\n\n /**\n * The `AuthorizationManager` instance provided with the call.\n */\n const manager = sdkOptions?.manager;\n\n let token;\n /**\n * If a `resource_server` was provided, and the SDK is configured with a `manager`\n * instance, we'll try to get a token for the resource server and use it.\n */\n if (config.resource_server && manager) {\n token = manager.tokens.getByResourceServer(config.resource_server);\n if (token) {\n headers['Authorization'] = `Bearer ${token.access_token}`;\n }\n }\n /**\n * If the `scope` property is provided, and the SDK is configured with a `manager`,\n * we'll try to map the service to a resource server. This is mostly to support\n * backwards compatibility of the `scope` property being used in the `ServiceRequestDSL`.\n */\n if (config.scope && manager) {\n const resourceServer =\n typeof config.service === 'string'\n ? RESOURCE_SERVERS[config.service]\n : // For `GCSConfiguration` objects, the `endpoint_id` is the resource server.\n config.service.endpoint_id;\n\n token = manager.tokens.getByResourceServer(resourceServer);\n if (token) {\n headers['Authorization'] = `Bearer ${token.access_token}`;\n }\n }\n\n /**\n * If a raw body was provided, use that. Otherwise, if a payload was provided, serialize it.\n */\n let body = options?.body;\n if (!body && options?.payload) {\n body = JSON.stringify(options.payload);\n }\n\n /**\n * If `Content-Type` header was not provided, and there is a body, we assume it is JSON.\n */\n if (!headers?.['Content-Type'] && body) {\n headers['Content-Type'] = 'application/json';\n }\n\n const url = build(\n config.service,\n config.path,\n {\n search: options?.query,\n },\n sdkOptions,\n );\n\n const init = {\n method: config.method,\n body,\n ...injectedFetchOptions,\n /**\n * Merge the headers from the options and SDK options.\n */\n headers,\n };\n\n /**\n * The request handler for the fetch call. This can be overridden by providing a\n * `__callable` property in the `fetch` options.\n */\n let handler = _fetch;\n /* eslint-disable no-underscore-dangle */\n if (injectedFetchOptions?.__callable) {\n handler = injectedFetchOptions.__callable.bind(this);\n /**\n * Remove the `__callable` property from the `fetch` options before passing the options along.\n */\n delete init.__callable;\n }\n /* eslint-enable no-underscore-dangle */\n\n /**\n * If the resource is configured to prevent retries, there is no `manager` instance,\n * or token, the request will be made as-is.\n */\n if (config.preventRetry || !manager || !token || !isRefreshToken(token)) {\n return handler(url, init);\n }\n\n /**\n * Automatic Retry Handling\n */\n\n const initialResponse = await handler(url, init);\n /**\n * If the response is \"ok\", we can return it as-is.\n */\n if (initialResponse.ok) {\n return initialResponse;\n }\n /**\n * Do a safe check to see if the response contains any authorization requirements.\n */\n let hasAuthorizationRequirements;\n try {\n hasAuthorizationRequirements = isAuthorizationRequirementsError(\n /**\n * It is important to clone the response before calling `json` avoid\n * `body used already for [...]` errors when the initial response is\n * returned.\n */\n await initialResponse.clone().json(),\n );\n } catch (_e) {\n hasAuthorizationRequirements = false;\n }\n /**\n * We only attempt to refresh the original token supplied with teh request, if the\n * response status is 401 and the response does not contain any authorization requirements.\n */\n const shouldAttemptTokenRefresh = initialResponse.status === 401 && !hasAuthorizationRequirements;\n if (shouldAttemptTokenRefresh) {\n const newToken = await manager.refreshToken(token);\n if (!newToken) {\n return initialResponse;\n }\n /**\n * Retry the request with the new token.\n */\n return handler(url, {\n ...init,\n headers: {\n ...init.headers,\n Authorization: `Bearer ${newToken.access_token}`,\n },\n });\n }\n /**\n * No retry was attempted, return the initial response.\n */\n return initialResponse;\n}\n", "import type { Info } from './index.js';\n\n/**\n * @private\n */\nexport const CLIENT_INFO_HEADER = `X-Globus-Client-Info`;\n\nlet ENABLED = true;\n/**\n * Disable the client information header from being included in requests (enabled by default).\n * @private\n */\nexport function disable() {\n ENABLED = false;\n}\n\n/**\n * Enables the client information header to be included in requests.\n * @private\n */\nexport function enable() {\n ENABLED = true;\n}\n\n/**\n * Whether or not the client information header should be sent with requests.\n * @private\n */\nexport function isEnabled() {\n return ENABLED;\n}\n\nconst INFOS_SEPERATOR = ';';\nconst INFO_ITEM_SEPARATOR = ',';\n\n/**\n * Exported for test purposes only.\n * @private\n */\nexport function toString(info: Info | Info[]) {\n const infos = Array.isArray(info) ? info : [info];\n return infos\n .map((i) =>\n Object.entries(i)\n .map(([key, value]) => `${key}=${value}`)\n .join(INFO_ITEM_SEPARATOR),\n )\n .join(INFOS_SEPERATOR);\n}\n", "// x-release-please-start-version\nexport const VERSION = '5.0.0';\n// x-release-please-end\n", "/**\n * @module Information\n * @description This module is mostly intended for internal use, but can be helpful\n * identifying information about the SDK package you are using at runtime.\n */\nimport { toString, isEnabled, CLIENT_INFO_HEADER } from './private.js';\nimport { VERSION as _VERSION } from './version.js';\n\nexport type Version = string;\n\n/**\n * The version of the `@globus/sdk` package that is in use.\n */\nexport const VERSION: Version = _VERSION;\n\nexport type Info = {\n product: string;\n version: Version;\n};\n\n/**\n * The client information identifier for this package.\n */\nexport const CLIENT_INFO: Info = {\n product: 'javascript-sdk',\n version: VERSION,\n};\n\nlet INFOS: Info[] = [CLIENT_INFO];\n\n/**\n * Add a client information identifier to the existing SDK information.\n */\nexport function addClientInfo(info: Info) {\n INFOS = INFOS.concat(info);\n}\n/**\n * Get the current client information as a string.\n */\nexport function getClientInfo(): string {\n return toString(INFOS);\n}\n\nexport function getClientInfoRequestHeaders(): Record<string, string> {\n if (!isEnabled()) {\n return {};\n }\n return {\n [CLIENT_INFO_HEADER]: getClientInfo(),\n };\n}\n", "import { ID } from '../../config.js';\nimport { HTTP_METHODS, serviceRequest } from '../../../../services/shared.js';\n\nimport type { ServiceMethod } from '../../../types.js';\n\nexport const userinfo = function (options?, sdkOptions?) {\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/userinfo`,\n method: HTTP_METHODS.GET,\n },\n options,\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: never;\n}>;\n\nexport * as token from './token.js';\n", "import { ID } from '../../config.js';\nimport { HTTP_METHODS, serviceRequest } from '../../../../services/shared.js';\n\nimport type { ServiceMethod, ServiceMethodOptions } from '../../../types.js';\n\ntype IntrospectPayload = {\n token: string;\n include?: string;\n};\n\ntype RevokePayload = {\n token: string;\n /**\n * This is an undocumented property that is required for the request to be successful.\n */\n client_id: string;\n};\n\ntype ValidatePayload = {\n token: string;\n client_id: string;\n};\n\ntype RefreshPayload = {\n refresh_token: string;\n grant_type: 'refresh_token';\n /**\n * This is an undocumented property that is required for the request to be successful.\n */\n client_id: string;\n};\n\ntype ExchangePayload = {\n grant_type: 'authorization_code';\n code: string;\n client_id: string;\n code_verifier: string;\n redirect_uri: string;\n};\n\ntype SupportedPayloads =\n | IntrospectPayload\n | RevokePayload\n | ValidatePayload\n | RefreshPayload\n | ExchangePayload;\n\nfunction serialize(payload?: SupportedPayloads) {\n return new URLSearchParams(payload);\n}\n\n/**\n * Format and inject properties that are specific to the `/token` resources.\n */\nfunction injectServiceOptions(\n options: ServiceMethodOptions & {\n payload?: SupportedPayloads;\n },\n): ServiceMethodOptions {\n return {\n ...options,\n /**\n * The `token` service methods always expect a form-encoded body. We still allow\n * end-consumers to pass a raw body, but if `payload` is provided it is serialized.\n */\n body: options.payload ? serialize(options.payload) : undefined,\n headers: {\n ...(options?.headers || {}),\n Accept: 'application/json',\n /**\n * Force the `Content-Type` header to be `application/x-www-form-urlencoded` and `charset=UTF-8`.\n */\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n },\n };\n}\n\n/**\n * @see https://docs.globus.org/api/auth/reference/#dependent_token_grant_post_v2oauth2token\n */\nexport const token = function (options = {}, sdkOptions?) {\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload?: ExchangePayload;\n}>;\n\n/**\n * @see https://docs.globus.org/api/auth/developer-guide/#obtaining-authorization\n */\nexport const exchange = token;\n\n/**\n * Token Introspection\n * @see https://docs.globus.org/api/auth/reference/#token-introspect\n */\nexport const introspect = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for introspect`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/introspect`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: IntrospectPayload;\n}>;\n\n/**\n * Token Revocation\n * @see https://docs.globus.org/api/auth/reference/#token-revoke\n */\nexport const revoke = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for revoke`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/revoke`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: RevokePayload;\n}>;\n\n/**\n * Token Refresh\n * @see https://docs.globus.org/api/auth/reference/#refresh_token_grant\n */\nexport const refresh = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for revoke`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: RefreshPayload;\n}>;\n\n/**\n * @private\n * @deprecated Rather than using `validate` to check if a token is valid, it is recommended to make a request to the resource server with the token and handle the error response.\n */\nexport const validate = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for validate`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/validate`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: ValidatePayload;\n}>;\n", "/**\n * @description A wrapper around the Globus Auth service.\n * @group Service\n * @see [Globus Auth API Documentation](https://docs.globus.org/api/auth/)\n * @module\n */\nimport { build } from '../../core/url.js';\n\nimport * as AUTH from './config.js';\n\nimport type { Token, TokenWithRefresh, TokenResponse } from './types.js';\n\n/**\n * @private\n * @internal\n */\nexport const CONFIG = AUTH;\n\n/**\n * Query parameters that can be passed to the authorization endpoint.\n * @see https://docs.globus.org/api/auth/reference/#authorization_code_grant_preferred\n * @see https://docs.globus.org/api/auth/sessions/#client-initiated-authns\n */\nexport type AuthorizationQueryParameters = {\n prompt?: string;\n session_message?: string;\n session_required_identities?: string;\n session_required_single_domain?: string;\n session_required_mfa?: 'true' | 'false';\n session_required_policies?: string;\n};\n\nexport function getAuthorizationEndpoint() {\n return build(AUTH.ID, '/v2/oauth2/authorize');\n}\n\nexport function getTokenEndpoint() {\n return build(AUTH.ID, '/v2/oauth2/token');\n}\n\nexport * as identities from './service/identities.js';\nexport * as oauth2 from './service/oauth2/index.js';\n\nexport function isToken(check: unknown): check is Token {\n return typeof check === 'object' && check !== null && 'access_token' in check;\n}\n\nexport function isRefreshToken(check: unknown): check is TokenWithRefresh {\n return isToken(check) && check !== null && 'refresh_token' in check;\n}\n\nexport function isGlobusAuthTokenResponse(check: unknown): check is TokenResponse {\n /**\n * @todo This could be made more robust by checking whether the `resource_server` is a well-known value.\n */\n return isToken(check) && check !== null && 'resource_server' in check;\n}\n", "/**\n * @todo It would be nice to not `| any` here, but ideally callers do not need to\n * fully type the payload to attach listeners.\n */\ntype ListenerCallback<P> = (payload?: P | any) => Promise<void> | void;\n\nexport class Event<EventName extends string, Payload extends unknown> {\n #callbacks: ListenerCallback<Payload>[] = [];\n\n constructor(readonly name: EventName) {}\n\n addListener(callback: ListenerCallback<Payload>) {\n this.#callbacks.push(callback);\n return () => this.removeListener(callback);\n }\n\n removeListener(callback: ListenerCallback<Payload>) {\n this.#callbacks = this.#callbacks.filter((cb) => cb !== callback);\n }\n\n clearListeners() {\n this.#callbacks = [];\n }\n\n async dispatch(payload?: Payload) {\n await Promise.all(this.#callbacks.map((callback) => callback(payload)));\n }\n}\n", "export function isSupported() {\n return 'crypto' in globalThis;\n}\n\nfunction getCrypto(): Crypto {\n return 'webcrypto' in globalThis.crypto\n ? (globalThis.crypto.webcrypto as unknown as Crypto)\n : globalThis.crypto;\n}\n\n/**\n * Base64 URL encode a string.\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\nconst encode = (value: string) =>\n btoa(value).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\nasync function sha256(input: string) {\n const hashBuffer = await getCrypto().subtle.digest('SHA-256', new TextEncoder().encode(input));\n return String.fromCharCode(...new Uint8Array(hashBuffer));\n}\n\n/**\n * Character set for generating random alpha-numeric strings.\n */\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Character set allowed to be used in the PKCE `code_verifier`\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.1\n */\nconst PKCE_SAFE_CHARSET = `${CHARSET}-._~`;\n/**\n * Create a Code Verifier for PKCE\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.1\n */\nexport function generateCodeVerifier() {\n /**\n * @todo Make length random between 43 and 128 characters\n */\n return Array.from(getCrypto().getRandomValues(new Uint8Array(43)))\n .map((v) => PKCE_SAFE_CHARSET[v % PKCE_SAFE_CHARSET.length])\n .join('');\n}\n\n/**\n * Create a Code Challenge from a provided Code Verifier (assumes S256 `code_challenge_method`).\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.2\n */\nexport async function generateCodeChallenge(verifier: string) {\n const hashed = await sha256(verifier);\n return encode(hashed);\n}\n\nexport function generateState() {\n return Array.from(getCrypto().getRandomValues(new Uint8Array(16)))\n .map((v) => CHARSET[v % CHARSET.length])\n .join('');\n}\n\n/**\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-code-exchange/\n */\nexport type AuthorizationCodeExchangeParameters = {\n code: string;\n code_verifier: string;\n client_id: string;\n client_secret?: string;\n redirect_uri: string;\n grant_type: 'authorization_code';\n};\n\n/**\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\nexport type AuthorizationRequestParameters = {\n client_id: string;\n redirect_uri: string;\n response_type: 'code';\n scope: string;\n state: string;\n code_challenge: string;\n code_challenge_method: 'S256' | 'plain';\n};\n", "import { getAuthorizationEndpoint, oauth2 } from '../../services/auth/index.js';\nimport {\n generateCodeChallenge,\n generateCodeVerifier,\n generateState,\n AuthorizationRequestParameters,\n AuthorizationCodeExchangeParameters,\n isSupported,\n} from './pkce.js';\n\nimport type { AuthorizationManagerConfiguration } from './AuthorizationManager';\n\nexport type GetTokenOptions = {\n /**\n * Whether or not the URL should be replaced after processing the token.\n * @default true\n */\n shouldReplace?: boolean;\n};\n\nexport type RedirectTransportOptions = Pick<\n AuthorizationManagerConfiguration,\n 'client' | 'redirect' | 'scopes'\n> & {\n /**\n * Query parameters to include in the authorization request.\n *\n * The `RedirectTransport` will include all parameters required for a default OAuth PKCE flow, but\n * these parameters can be overridden or extended with this option.\n */\n params?: {\n [key: string]: string;\n };\n};\n\n/**\n * @private\n */\nexport const KEYS = {\n PKCE_STATE: 'pkce_state',\n PKCE_CODE_VERIFIER: 'pkce_code_verifier',\n};\n\nfunction resetPKCE() {\n sessionStorage.removeItem(KEYS.PKCE_STATE);\n sessionStorage.removeItem(KEYS.PKCE_CODE_VERIFIER);\n}\n\nexport class RedirectTransport {\n #options: RedirectTransportOptions;\n\n constructor(options: RedirectTransportOptions) {\n this.#options = options;\n if (RedirectTransport.supported === false) {\n throw new Error('RedirectTransport is not supported in this environment.');\n }\n }\n\n static supported = isSupported();\n\n /**\n * For the redirect transport, sending the request will redirect the user to the authorization endpoint, initiating the OAuth flow.\n */\n async send() {\n /**\n * Since we'll be using PKCE, we need to generate a code verifier and challenge\n * for the OAuth handshake.\n */\n const verifier = generateCodeVerifier();\n const challenge = await generateCodeChallenge(verifier);\n /**\n * If there is caller-provided `state`, use it; Otherwise, generate a state parameter.\n */\n const state = this.#options.params?.['state'] ?? generateState();\n /**\n * The verifier and state are stored in session storage so that we can validate\n * the response when we receive it.\n */\n sessionStorage.setItem(KEYS.PKCE_CODE_VERIFIER, verifier);\n sessionStorage.setItem(KEYS.PKCE_STATE, state);\n\n const params: AuthorizationRequestParameters = {\n response_type: 'code',\n client_id: this.#options.client,\n scope: this.#options.scopes || '',\n redirect_uri: this.#options.redirect,\n state,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n ...(this.#options.params || {}),\n };\n\n const url = new URL(getAuthorizationEndpoint());\n url.search = new URLSearchParams(params).toString();\n\n window.location.assign(url.toString());\n }\n\n /**\n * Parse the current URL for the authorization code (`?code=...`) and exchange it for an access token when available.\n * - When the URL is processed and exchanged for an access token, the page is redirected to the current URL without the `?code=...&state=...` parameters.\n */\n async getToken(options: GetTokenOptions = { shouldReplace: true }) {\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.search);\n /**\n * Check for an error in the OAuth flow.\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\n if (params.get('error')) {\n throw new Error(\n params.get('error_description') || 'An error occurred during the authorization process.',\n );\n }\n\n const code = params.get('code');\n\n /**\n * If we don't have a `code` parameter, we can't exchange it for an access token.\n */\n if (!code) return undefined;\n\n /**\n * Grab the PKCE information from session storage.\n */\n const state = sessionStorage.getItem(KEYS.PKCE_STATE);\n const verifier = sessionStorage.getItem(KEYS.PKCE_CODE_VERIFIER);\n /**\n * Now that we have the values in memory, we can remove them from session storage.\n */\n resetPKCE();\n\n /**\n * Validate the `state` parameter matches the preserved state (to prevent CSRF attacks).\n */\n if (params.get('state') !== state) {\n throw new Error(\n 'Invalid State. The received \"state\" parameter does not match the expected state.',\n );\n }\n /**\n * Ensure we have a valid code verifier.\n */\n if (!verifier) {\n throw new Error('Invalid Code Verifier');\n }\n\n /**\n * Prepare the payload for the PKCE token exchange.\n */\n const payload: AuthorizationCodeExchangeParameters = {\n code,\n client_id: this.#options.client,\n /**\n * Retrieve the code verifier from session storage.\n */\n code_verifier: verifier,\n redirect_uri: this.#options.redirect,\n grant_type: 'authorization_code',\n };\n\n const response = await (\n await oauth2.token.exchange({\n payload,\n })\n ).json();\n\n if (options.shouldReplace) {\n /**\n * Remove the `code` and `state` parameters from the URL.\n */\n params.delete('code');\n params.delete('state');\n /**\n * Update the URL with the new query string.\n */\n url.search = params.toString();\n /**\n * Redirect the page to the new URL (without the `code` and `state` parameters)/\n */\n window.location.replace(url);\n }\n return response;\n }\n}\n", "import { CONFIG, isToken } from '../../services/auth/index.js';\n\nimport { SERVICES, type Service } from '../global.js';\nimport { AuthorizationManager } from './AuthorizationManager.js';\n\nimport type { Token, TokenResponse } from '../../services/auth/types.js';\n\nexport type StoredToken = Token & {\n /**\n * Tokens stored before the introduction of the `__metadata` field will be missing this property.\n * @since 4.3.0\n */\n __metadata?: {\n /**\n * The timestamp when the token was added to the storage as a number of milliseconds since the Unix epoch.\n *\n * **IMPORTANT**: This value might **not** represent the time when the token was created by the authorization server.\n */\n created: number;\n /**\n * The timestamp when the token will expire as a number of milliseconds since the Unix epoch, based\n * on the `expires_in` value from the token response and the time when the token was stored.\n */\n expires: number | null;\n };\n};\n\nexport class TokenManager {\n #manager: AuthorizationManager;\n\n constructor(options: { manager: AuthorizationManager }) {\n this.#manager = options.manager;\n }\n\n /**\n * Retrieve and parse an item from the storage.\n */\n #getTokenFromStorage(key: string) {\n const raw = this.#manager.storage.getItem(key) || 'null';\n let token: StoredToken | null = null;\n try {\n const parsed = JSON.parse(raw);\n if (isToken(parsed)) {\n token = parsed;\n }\n } catch (e) {\n // no-op\n }\n return token;\n }\n\n #getTokenForService(service: Service) {\n const resourceServer = CONFIG.RESOURCE_SERVERS?.[service];\n return this.getByResourceServer(resourceServer);\n }\n\n getByResourceServer(resourceServer: string): StoredToken | null {\n return this.#getTokenFromStorage(`${this.#manager.storageKeyPrefix}${resourceServer}`);\n }\n\n get auth(): StoredToken | null {\n return this.#getTokenForService(SERVICES.AUTH);\n }\n\n get transfer(): StoredToken | null {\n return this.#getTokenForService(SERVICES.TRANSFER);\n }\n\n get flows(): StoredToken | null {\n return this.#getTokenForService(SERVICES.FLOWS);\n }\n\n get groups(): StoredToken | null {\n return this.#getTokenForService(SERVICES.GROUPS);\n }\n\n get search(): StoredToken | null {\n return this.#getTokenForService(SERVICES.SEARCH);\n }\n\n get timer(): StoredToken | null {\n return this.#getTokenForService(SERVICES.TIMER);\n }\n\n get compute(): StoredToken | null {\n return this.#getTokenForService(SERVICES.COMPUTE);\n }\n\n gcs(endpoint: string): StoredToken | null {\n return this.getByResourceServer(endpoint);\n }\n\n getAll(): StoredToken[] {\n const entries = Object.keys(this.#manager.storage).reduce(\n (acc: (StoredToken | null)[], key) => {\n if (key.startsWith(this.#manager.storageKeyPrefix)) {\n acc.push(this.#getTokenFromStorage(key));\n }\n return acc;\n },\n [],\n );\n return entries.filter(isToken);\n }\n\n /**\n * Add a token to the storage.\n */\n add(token: Token | TokenResponse) {\n const created = Date.now();\n const expires = created + token.expires_in * 1000;\n this.#manager.storage.setItem(\n `${this.#manager.storageKeyPrefix}${token.resource_server}`,\n JSON.stringify({\n ...token,\n /**\n * Add metadata to the token to track when it was created and when it expires.\n */\n __metadata: {\n created,\n expires,\n },\n }),\n );\n if ('other_tokens' in token) {\n token.other_tokens?.forEach((t) => {\n this.add(t);\n });\n }\n }\n\n /**\n * Determines whether or not a stored token is expired.\n * @param token The token to check.\n * @param augment An optional number of milliseconds to add to the current time when checking the expiration.\n * @returns `true` if the token is expired, `false` if it is not expired, and `undefined` if the expiration status cannot be determined\n * based on the token's metadata. This can happen if the token is missing the `__metadata` field or the `expires` field.\n */\n static isTokenExpired(token: StoredToken | null, augment: number = 0): boolean | undefined {\n /* eslint-disable no-underscore-dangle */\n if (!token || !token.__metadata || typeof token.__metadata.expires !== 'number') {\n return undefined;\n }\n return Date.now() + augment >= token.__metadata.expires;\n /* eslint-enable no-underscore-dangle */\n }\n}\n", "/**\n * An in-memory implementation of the `Storage` interface.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Storage\n */\nexport class MemoryStorage implements Storage {\n #storage: Record<string, string | null> = {};\n\n getItem(key: string) {\n return this.#storage[key] !== undefined ? this.#storage[key] : null;\n }\n\n setItem(key: string, value: string) {\n this.#storage[key] = value;\n }\n\n removeItem(key: string) {\n delete this.#storage[key];\n }\n\n key(index: number) {\n return Object.keys(this.#storage)[index];\n }\n\n clear() {\n this.#storage = {};\n }\n\n get length() {\n return Object.keys(this.#storage).length;\n }\n}\n"],
4
+ "sourcesContent": ["/**\n * @module Authorization\n * @description Provides modules for interacting with Globus-related authorization contexts in your application.\n * @example\n * import { authorization } from \"globus/sdk\";\n * const manager = authorization.create(...);\n */\nimport {\n AuthorizationManager,\n type AuthorizationManagerConfiguration,\n} from './AuthorizationManager.js';\n\n/**\n * Create an instance of the {@link AuthorizationManager}.\n */\nexport function create(configuration: AuthorizationManagerConfiguration) {\n return new AuthorizationManager(configuration);\n}\n\nexport { AuthorizationManager, AuthorizationManagerConfiguration };\n", "import { jwtDecode } from 'jwt-decode';\n\nimport { isGlobusAuthTokenResponse, isRefreshToken, oauth2 } from '../../services/auth/index.js';\nimport { RESOURCE_SERVERS } from '../../services/auth/config.js';\n\nimport { log } from '../logger.js';\n\nimport { Event } from './Event.js';\nimport {\n RedirectTransportOptions,\n GetTokenOptions,\n RedirectTransport,\n} from './RedirectTransport.js';\nimport { TokenManager } from './TokenManager.js';\n\nimport {\n isConsentRequiredError,\n isAuthorizationRequirementsError,\n AuthorizationRequirementsError,\n ConsentRequiredError,\n toAuthorizationQueryParams,\n} from '../errors.js';\n\nimport type {\n JwtUserInfo,\n Token,\n TokenResponse,\n TokenWithRefresh,\n} from '../../services/auth/types.js';\nimport { MemoryStorage } from '../storage/memory.js';\n// import { PopupTransport } from './PopupTransport.js';\n\nconst TRANSPORTS = {\n redirect: RedirectTransport,\n // popup: PopupTransport,\n};\n\nexport type AuthorizationManagerConfiguration = {\n client: string;\n scopes?: string;\n redirect: string;\n /**\n * The storage system used by the `AuthorizationManager`.\n *\n * By default, the `AuthorizationManager` uses an in-memory storage, this option is secure by default.\n *\n * If you want to persist the state of the `AuthorizationManager`, you can use `localStorage`, or provide your own storage system.\n * **It is important to note that using the `localStorage`, or any persistant storage option will preserve authorization and refresh tokens of users.**\n * Best practices for ensuring the security of your application should be followed to protect this data (e.g., ensuring XSS protection).\n *\n * @default MemoryStorage\n */\n storage?: Storage;\n transport?: keyof typeof TRANSPORTS;\n /**\n * @private\n * @default DEFAULT_CONFIGURATION.useRefreshTokens\n */\n useRefreshTokens?: boolean;\n /**\n * @private\n * @default DEFAULT_CONFIGURATION.defaultScopes\n */\n defaultScopes?: string | false;\n /**\n * Provide an object with event listeners to attach to the instance.\n * This is useful if you need to listen to events that might dispatch immediately\n * after the creation of the instance (constructor), e.g., the `authenticated`.\n */\n events?: Partial<{\n [Event in keyof AuthorizationManager['events']]: Parameters<\n AuthorizationManager['events'][Event]['addListener']\n >[0];\n }>;\n};\n\nconst DEFAULT_CONFIGURATION = {\n useRefreshTokens: false,\n defaultScopes: 'openid profile email',\n transport: 'redirect' as const,\n};\n\nconst DEFAULT_HANDLE_ERROR_OPTIONS = {\n execute: true,\n additionalParams: undefined,\n};\n\n/**\n * Provides management of Globus authorization context for your application.\n * - Handles the OAuth protcol flow (via PKCE)\n * - Token lifecycle management\n * - Common errors (e.g., `ConsentRequired`, `authorization_requirements`)\n *\n * Once you configure your instance, you can determine the authenticated state using `manager.authenticated`.\n *\n * To prompt a user to authenticate, call `manager.login()` on user interaction \u2013 this will initiate the OAuth protocol flow with your configured client and scopes, resulting in an initial redirect to Globus Auth.\n *\n * Once the user authenticates with Globus Auth, they will be redirected to your application using the configured `redirect` URL. On this URL, you will need to call `manager.handleCodeRedirect` (using a manager instance configured in the same manner that initiated the `manager.login()` call) to complete the PKCE flow, exchanging the provided code for a valid token, or tokens.\n *\n * All tokens managed by the `AuthorizationManager` instance can be found on `manager.token`.\n *\n * ### Registering your Globus Application\n *\n * The `AuthorizationManager` expects your Globus Application to be registered as an OAuth public client.\n * In this Globus Web Application, this option is referenced as \"_Register a thick client or script that will be installed and run by users on their devices_\".\n *\n * @example <caption>Creating an AuthorizationManager instance.</caption>\n * import { authorization } from \"globus/sdk\";\n *\n * const manager = authorization.create({\n * // Your registered Globus Application client ID.\n * client: '...',\n * // The redirect URL for your application; Where you will call `manager.handleCodeRedirect()`\n * redirect: 'https://example.com/callback',\n * // Known scopes required by your application.\n * scopes: 'urn:globus:auth:scope:transfer.api.globus.org:all',\n * });\n */\nexport class AuthorizationManager {\n #transport!: RedirectTransport;\n\n configuration: AuthorizationManagerConfiguration;\n\n /**\n * The storage system used by the `AuthorizationManager`.\n * @implements Storage\n */\n storage: Storage;\n\n #authenticated = false;\n\n /**\n * The `AuthorizationManager` is considered `authenticated` if it has a valid Globus Auth token.\n * It does not necessarily mean that it has a valid token for a specific resource server.\n */\n get authenticated() {\n return this.#authenticated;\n }\n\n /**\n * Set the authenticated state and emit the `authenticated` event.\n */\n set authenticated(value: boolean) {\n /**\n * Avoid emitting the event if the value hasn't changed.\n */\n if (value === this.#authenticated) {\n return;\n }\n this.#authenticated = value;\n this.#emitAuthenticatedState();\n }\n\n tokens: TokenManager;\n\n events = {\n /**\n * Emitted when the authenticated state changes.\n * @event AuthorizationManager.events#authenticated\n * @type {object}\n * @property {boolean} isAuthenticated - Whether the `AuthorizationManager` is authenticated.\n * @property {TokenResponse} [token] - The token response if the `AuthorizationManager` is authenticated.\n */\n authenticated: new Event<\n 'authenticated',\n {\n /**\n * Whether the `AuthorizationManager` is authenticated.\n * @see {@link AuthorizationManager.authenticated}\n */\n isAuthenticated: boolean;\n token?: TokenResponse;\n }\n >('authenticated'),\n /**\n * Emitted when the user revokes their authentication.\n * @event AuthorizationManager.events#revoke\n */\n revoke: new Event('revoke'),\n };\n\n constructor(configuration: AuthorizationManagerConfiguration) {\n /**\n * Configure the storage system for the instance, defaulting to an in-memory storage system.\n */\n\n if (!configuration.client) {\n throw new Error('You must provide a `client` for your application.');\n }\n /**\n * Inject the `openid`, `profile`, `email`, and `offline_access` scopes by default unless\n * explicitly opted out of.\n */\n const scopes =\n configuration.defaultScopes === false\n ? ''\n : (configuration.defaultScopes ?? DEFAULT_CONFIGURATION.defaultScopes);\n\n this.configuration = {\n ...DEFAULT_CONFIGURATION,\n ...configuration,\n scopes: [configuration.scopes ? configuration.scopes : '', scopes]\n .filter((s) => s.length)\n .join(' '),\n };\n\n this.storage = configuration.storage || new MemoryStorage();\n\n /**\n * If an `events` object is provided, add the listeners to the instance before\n * any event might be dispatched.\n */\n if (this.configuration.events) {\n Object.entries(this.configuration.events).forEach(([name, callback]) => {\n if (name in this.events) {\n this.events[name as keyof AuthorizationManager['events']].addListener(callback);\n }\n });\n }\n\n this.tokens = new TokenManager({\n manager: this,\n });\n this.#checkAuthorizationState();\n }\n\n get storageKeyPrefix() {\n return `${this.configuration.client}:`;\n }\n\n /**\n * The user information decoded from the `id_token` (JWT) of the current Globus Auth token.\n * This method can be used instead of `auth.oauth2.userinfo` to get the user information without an additional request.\n *\n * **IMPORTANT**: The `id_token` can only be processed if the `openid` scope is requested during the authorization process.\n *\n * Additionally, the `profile` and `email` scopes are required to get the full user information.\n *\n * @see {@link https://docs.globus.org/api/auth/reference/#oidc_userinfo_endpoint}\n */\n get user() {\n const token = this.getGlobusAuthToken();\n return token && token.id_token ? jwtDecode<JwtUserInfo>(token.id_token) : null;\n }\n\n /**\n * Attempt to refresh all of the tokens managed by the instance.\n * This method will only attempt to refresh tokens that have a `refresh_token` attribute.\n */\n async refreshTokens() {\n log('debug', 'AuthorizationManager.refreshTokens');\n const tokens = await Promise.allSettled(\n this.tokens.getAll().map((token) => {\n if (isRefreshToken(token)) {\n return this.refreshToken(token);\n }\n return Promise.resolve(null);\n }),\n );\n this.#checkAuthorizationState();\n return tokens;\n }\n\n /**\n * Use the `refresh_token` attribute of a token to obtain a new access token.\n * @param token The well-formed token with a `refresh_token` attribute.\n */\n async refreshToken(token: TokenWithRefresh) {\n log('debug', `AuthorizationManager.refreshToken | resource_server=${token.resource_server}`);\n try {\n const response = await (\n await oauth2.token.refresh({\n payload: {\n client_id: this.configuration.client,\n refresh_token: token.refresh_token,\n grant_type: 'refresh_token',\n },\n })\n ).json();\n if (isGlobusAuthTokenResponse(response)) {\n this.addTokenResponse(response);\n return response;\n }\n } catch (error) {\n log('error', `AuthorizationManager.refreshToken | resource_server=${token.resource_server}`);\n }\n return null;\n }\n\n /**\n * Whether or not the instance has a reference to a Globus Auth token.\n */\n hasGlobusAuthToken() {\n return this.getGlobusAuthToken() !== null;\n }\n\n /**\n * Retrieve the Globus Auth token managed by the instance.\n */\n getGlobusAuthToken() {\n const entry = this.storage.getItem(`${this.storageKeyPrefix}${RESOURCE_SERVERS.AUTH}`);\n return entry ? JSON.parse(entry) : null;\n }\n\n #checkAuthorizationState() {\n log('debug', 'AuthorizationManager.#checkAuthorizationState');\n if (this.hasGlobusAuthToken()) {\n this.authenticated = true;\n }\n }\n\n async #emitAuthenticatedState() {\n const isAuthenticated = this.authenticated;\n const token = this.getGlobusAuthToken() ?? undefined;\n await this.events.authenticated.dispatch({\n isAuthenticated,\n token,\n });\n }\n\n /**\n * Reset the authenticated state and clear all tokens from storage.\n * This method **does not** emit the `revoke` event. If you need to emit the `revoke` event, use the `AuthorizationManager.revoke` method.\n */\n reset() {\n Object.keys(this.storage).forEach((key) => {\n if (key.startsWith(this.storageKeyPrefix)) {\n this.storage.removeItem(key);\n }\n });\n this.authenticated = false;\n }\n\n /**\n * A private utility method to add the `offline_access` scope to a scope string if the `useRefreshTokens` configuration is set to `true`.\n * @param scopes The scope string to modify.\n */\n #withOfflineAccess(scopes: string) {\n return `${scopes}${this.configuration.useRefreshTokens ? ' offline_access' : ''}`;\n }\n\n #buildTransport(options?: Partial<RedirectTransportOptions>) {\n const { scopes, ...overrides } = options ?? {};\n const TransportFactory = TRANSPORTS[this.configuration.transport || 'redirect'];\n\n let scopesToRequest = this.#withOfflineAccess(scopes ?? (this.configuration.scopes || ''));\n\n if (this.storage instanceof MemoryStorage) {\n /**\n * If the in-memory storage is used, we have to make sure when requesting additional\n * consent the original configured scopes are included in the request.\n *\n * This will ensure we recieve a token for all of resource servers that were originally requested,\n * in addition to any new scopes that are requested.\n */\n scopesToRequest = [\n // Use a Set to deduplicate the scopes.\n ...new Set(\n scopesToRequest.split(' ').concat((this.configuration?.scopes || '').split(' ')),\n ),\n ].join(' ');\n }\n\n return new TransportFactory({\n client: this.configuration.client,\n redirect: this.configuration.redirect,\n scopes: scopesToRequest,\n ...overrides,\n params: {\n // @todo @todo Decide if we want to include the `include_consented_scopes` parameter by default.\n // include_consented_scopes: 'true',\n ...overrides?.params,\n },\n });\n }\n\n /**\n * Initiate the login process by redirecting to the Globus Auth login page.\n *\n * **IMPORTANT**: This method will reset the instance state before initiating the login process,\n * including clearing all tokens from storage. If you need to maintain the current state,\n * use the `AuthorizationManager.prompt` method.\n */\n async login(options = { additionalParams: {} }) {\n log('debug', 'AuthorizationManager.login');\n this.reset();\n /**\n * In the future, it's possible that we may want to support different types of transports.\n */\n const transport = this.#buildTransport({ params: options?.additionalParams });\n await transport.send();\n }\n\n /**\n * Prompt the user to authenticate with Globus Auth.\n */\n async prompt(options?: Partial<RedirectTransportOptions>) {\n log('debug', 'AuthorizationManager.prompt');\n const transport = this.#buildTransport(options);\n await transport.send();\n }\n\n /**\n * This method will attempt to complete the PKCE protocol flow.\n */\n async handleCodeRedirect(\n options: {\n shouldReplace: GetTokenOptions['shouldReplace'];\n additionalParams?: RedirectTransportOptions['params'];\n } = { shouldReplace: true, additionalParams: {} },\n ) {\n log('debug', 'AuthorizationManager.handleCodeRedirect');\n const response = await this.#buildTransport({ params: options?.additionalParams }).getToken({\n shouldReplace: options?.shouldReplace,\n });\n if (isGlobusAuthTokenResponse(response)) {\n log(\n 'debug',\n `AuthorizationManager.handleCodeRedirect | response=${JSON.stringify(response)}`,\n );\n this.addTokenResponse(response);\n }\n return response;\n }\n\n /**\n * Handle an error response from a Globus service in the context of this `AuthorizationManager`.\n * This method will introspect the response and attempt to handle any errors that should result\n * in some additional Globus Auth interaction.\n * @param response The error response from a Globus service.\n * @param {object|boolean} options Options for handling the error response. If a boolean is provided, this will be treated as the `options.execute` value.\n * @param options.execute Whether to execute the handler immediately.\n * @param options.additionalParms Additional query parameters to be included with the transport generated URL.\n */\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?: { execute?: true; additionalParams?: RedirectTransportOptions['params'] } | true,\n ): Promise<void>;\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?: { execute?: false; additionalParams?: RedirectTransportOptions['params'] } | false,\n ): Promise<() => Promise<void>>;\n async handleErrorResponse(\n response: Record<string, unknown>,\n options?:\n | { execute?: boolean; additionalParams?: RedirectTransportOptions['params'] }\n | boolean,\n ) {\n const opts =\n typeof options === 'boolean'\n ? {\n ...DEFAULT_HANDLE_ERROR_OPTIONS,\n execute: options,\n }\n : {\n ...DEFAULT_HANDLE_ERROR_OPTIONS,\n ...options,\n };\n log(\n 'debug',\n `AuthorizationManager.handleErrorResponse | response=${JSON.stringify(response)} execute=${opts.execute}`,\n );\n let handler = async () => {};\n if (isAuthorizationRequirementsError(response)) {\n log(\n 'debug',\n 'AuthorizationManager.handleErrorResponse | error=AuthorizationRequirementsError',\n );\n handler = async () => {\n await this.handleAuthorizationRequirementsError(response, {\n additionalParams: opts.additionalParams,\n });\n };\n }\n if (isConsentRequiredError(response)) {\n log('debug', 'AuthorizationManager.handleErrorResponse | error=ConsentRequiredError');\n handler = async () => {\n await this.handleConsentRequiredError(response, {\n additionalParams: opts.additionalParams,\n });\n };\n }\n if ('code' in response && response['code'] === 'AuthenticationFailed') {\n log('debug', 'AuthorizationManager.handleErrorResponse | error=AuthenticationFailed');\n handler = async () => {\n await this.revoke();\n };\n }\n\n const returnValue = opts.execute === true ? await handler() : handler;\n return returnValue;\n }\n\n /**\n * Process a well-formed Authorization Requirements error response from a Globus service\n * and redirect the user to the Globus Auth login page with the necessary parameters.\n */\n async handleAuthorizationRequirementsError(\n response: AuthorizationRequirementsError,\n options?: { additionalParams?: RedirectTransportOptions['params'] },\n ) {\n this.#transport = this.#buildTransport({\n params: {\n prompt: 'login',\n ...toAuthorizationQueryParams(response),\n ...options?.additionalParams,\n },\n });\n await this.#transport.send();\n }\n\n /**\n * Process a well-formed `ConsentRequired` error response from a Globus service\n * and redirect the user to the Globus Auth login page with the necessary parameters.\n */\n async handleConsentRequiredError(\n response: ConsentRequiredError,\n options?: { additionalParams?: RedirectTransportOptions['params'] },\n ) {\n this.#transport = this.#buildTransport({\n scopes: this.#withOfflineAccess(response.required_scopes.join(' ')),\n params: {\n ...options?.additionalParams,\n },\n });\n await this.#transport.send();\n }\n\n /**\n * Add a Globus Auth token response to storage, if `other_tokens` are present they are also added.\n * This method is mostly used internally by the `AuthorizationManager`, but can be used by downstream\n * consumers to add tokens to storage if necessary.\n */\n addTokenResponse = (token: Token | TokenResponse) => {\n this.tokens.add(token);\n this.#checkAuthorizationState();\n };\n\n /**\n * Call `AuthroizationManager.reset`, revoke all of the available tokns, and emit the `revoke` event.\n * @emits AuthorizationManager.events#revoke\n * @see AuthorizationManager.reset\n */\n async revoke() {\n log('debug', 'AuthorizationManager.revoke');\n const revocation = Promise.all(this.tokens.getAll().map(this.#revokeToken.bind(this)));\n this.reset();\n await revocation;\n await this.events.revoke.dispatch();\n }\n\n /**\n * Revoke a token from a resource server.\n */\n #revokeToken(token: Token) {\n log('debug', `AuthorizationManager.revokeToken | resource_server=${token.resource_server}`);\n return oauth2.token.revoke({\n payload: {\n client_id: this.configuration.client,\n token: token.access_token,\n },\n });\n }\n}\n", "import { ID as TRANSFER } from '../transfer/config.js';\nimport { ID as FLOWS } from '../flows/config.js';\nimport { ID as TIMER } from '../timer/config.js';\nimport { ID as GROUPS } from '../groups/config.js';\nimport { ID as SEARCH } from '../search/config.js';\nimport { ID as COMPUTE } from '../compute/config.js';\n\nimport type { Environment } from '../../core/global.js';\n\nexport const ID = 'AUTH' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n integration: 'auth.integration.globuscs.info',\n sandbox: 'auth.sandbox.globuscs.info',\n production: 'auth.globus.org',\n test: 'auth.test.globuscs.info',\n staging: 'auth.staging.globuscs.info',\n preview: 'auth.preview.globus.org',\n};\n\nexport const SCOPES = {\n VIEW_IDENTITIES: 'urn:globus:auth:scope:auth.globus.org:view_identities',\n};\n\nexport const RESOURCE_SERVERS = {\n [ID]: 'auth.globus.org',\n [TRANSFER]: 'transfer.api.globus.org',\n [FLOWS]: 'flows.globus.org',\n [GROUPS]: 'groups.api.globus.org',\n [SEARCH]: 'search.api.globus.org',\n [TIMER]: '524230d7-ea86-4a52-8312-86065a9e0417',\n [COMPUTE]: 'funcx_service',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'TRANSFER' as const;\n\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:transfer.api.globus.org:all',\n};\n\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'transfer.api.sandbox.globuscs.info',\n production: 'transfer.api.globusonline.org',\n staging: 'transfer.api.staging.globuscs.info',\n integration: 'transfer.api.integration.globuscs.info',\n test: 'transfer.api.test.globuscs.info',\n preview: 'transfer.api.preview.globus.org',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'FLOWS' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'sandbox.flows.automate.globus.org',\n production: 'flows.globus.org',\n staging: 'staging.flows.automate.globus.org',\n integration: 'integration.flows.automate.globus.org',\n test: 'test.flows.automate.globus.org',\n preview: 'preview.flows.automate.globus.org',\n};\n\n/**\n * @see https://docs.globus.org/api/flows/overview/#scopes\n */\nexport const SCOPES = {\n MANAGE_FLOWS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/manage_flows',\n VIEW_FLOWS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/view_flows',\n RUN: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run',\n RUN_STATUS: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run_status',\n RUN_MANAGE: 'https://auth.globus.org/scopes/eec9b274-0c81-4334-bdc2-54e90e689b9a/run_manage',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'TIMER' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'sandbox.timer.automate.globus.org',\n production: 'timer.automate.globus.org',\n staging: 'staging.timer.automate.globus.org',\n integration: 'integration.timer.automate.globus.org',\n test: 'test.timer.automate.globus.org',\n preview: 'preview.timer.automate.globus.org',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'GROUPS' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'groups.api.sandbox.globuscs.info',\n production: 'groups.api.globus.org',\n staging: 'groups.api.staging.globuscs.info',\n integration: 'groups.api.integration.globuscs.info',\n test: 'groups.api.test.globuscs.info',\n preview: 'groups.api.preview.globuscs.info',\n};\n\n/**\n * @see https://docs.globus.org/api/groups/#scopes\n */\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:groups.api.globus.org:all',\n VIEW_MY: 'urn:globus:auth:scope:groups.api.globus.org:view_my_groups_and_membership',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'SEARCH' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'search.api.sandbox.globuscs.info',\n production: 'search.api.globus.org',\n staging: 'search.api.staging.globuscs.info',\n integration: 'search.api.integration.globuscs.info',\n test: 'search.api.test.globuscs.info',\n preview: 'search.api.preview.globus.org',\n};\n\n/**\n * @see https://docs.globus.org/api/search/api_usage/#scopes\n */\nexport const SCOPES = {\n ALL: 'urn:globus:auth:scope:search.api.globus.org:all',\n INGEST: 'urn:globus:auth:scope:search.api.globus.org:ingest',\n SEARCH: 'urn:globus:auth:scope:search.api.globus.org:search',\n};\n", "import type { Environment } from '../../core/global.js';\n\nexport const ID = 'COMPUTE' as const;\nexport const HOSTS: Partial<Record<Environment, string>> = {\n sandbox: 'compute.api.sandbox.globuscs.info',\n production: 'compute.api.globus.org',\n staging: 'compute.api.staging.globuscs.info',\n integration: 'compute.api.integration.globuscs.info',\n test: 'compute.api.test.globuscs.info',\n preview: 'compute.api.preview.globus.org',\n};\n\nexport const SCOPES = {\n ALL: 'https://auth.globus.org/scopes/facd7ccc-c5f4-42aa-916b-a0e270e2c2a9/all',\n};\n", "/**\n * @module Errors\n * @example\n * import { errors } from \"globus/sdk\";\n * if (errors.isConsentRequiredError(...)) { ... }\n */\nimport type { AuthorizationQueryParameters } from '../services/auth/index.js';\n\nexport class EnvironmentConfigurationError extends Error {\n override name = 'EnvironmentConfigurationError';\n\n constructor(variable: string, value: unknown) {\n super();\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n this.message = `Invalid configuration value provided for ${variable} (${value}).`;\n }\n}\n\nexport type WellFormedError = {\n code: string;\n message: string;\n};\n\nexport function isErrorWellFormed(test: unknown): test is WellFormedError {\n return typeof test === 'object' && test !== null && 'code' in test && 'message' in test;\n}\n\nexport type ConsentRequiredError = {\n code: 'ConsentRequired';\n required_scopes: string[];\n [key: string]: unknown;\n};\n\nexport function isConsentRequiredError(test: unknown): test is ConsentRequiredError {\n return (\n isErrorWellFormed(test) &&\n test.code === 'ConsentRequired' &&\n 'required_scopes' in test &&\n Array.isArray(test.required_scopes)\n );\n}\n\n/**\n * An error that includes an `authorization_parameters` property, a.k.a \"G.A.R.E\".\n *\n * A well-known error shape is provided by services when additional authorization requirements must be met by the session.\n * This object can be converted to parameters accepted by Globus Auth using `sdk.errors.toAuthorizationQueryParams()`.\n */\nexport type AuthorizationRequirementsError = {\n authorization_parameters: {\n session_message?: string;\n session_required_identities?: string[];\n session_required_mfa?: boolean;\n session_required_single_domain?: string[];\n session_required_policies?: string[];\n prompt?: string;\n required_scopes?: string[];\n };\n /**\n * @todo At the moment, most Globus services do not guarentee a `code` property for this error type.\n * Once it becomes more common, this type (and the `isAuthorizationRequirementsError` function) should be updated.\n * @see https://globus-sdk-python.readthedocs.io/en/stable/experimental/auth_requirements_errors.html\n */\n // code: string;\n [key: string]: unknown;\n};\n/**\n * Keys that should not be included in the query string object (not recognized by Globus Auth).\n */\nconst NO_OP_KEYS: (keyof AuthorizationRequirementsError)[] = ['required_scopes'];\n/**\n * Convert an `AuthorizationRequirementsError` to a query string object accepted by Globus Auth.\n */\nexport function toAuthorizationQueryParams(\n error: AuthorizationRequirementsError,\n): AuthorizationQueryParameters {\n return Object.entries(error.authorization_parameters).reduce((acc, [key, v]) => {\n /**\n * Remove keys that are not recognized by Globus Auth and empty values.\n */\n if (NO_OP_KEYS.includes(key) || v === undefined || v === null) {\n return acc;\n }\n /**\n * All other values are converted to strings.\n */\n let value = v;\n if (Array.isArray(value)) {\n value = value.join(',');\n } else if (typeof v === 'boolean') {\n value = value ? 'true' : 'false';\n }\n return { ...acc, [key]: value };\n }, {});\n}\n\n/**\n * Check if an object is an `AuthorizationRequirementsError`.\n * @see {@link AuthorizationRequirementsError}\n */\nexport function isAuthorizationRequirementsError(\n test: unknown,\n): test is AuthorizationRequirementsError {\n return (\n typeof test === 'object' &&\n test !== null &&\n 'authorization_parameters' in test &&\n typeof test.authorization_parameters === 'object' &&\n test.authorization_parameters !== null\n );\n}\n", "const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\ntype LogLevel = (typeof LOG_LEVELS)[number];\n\ntype LogHandler = (...args: unknown[]) => void;\n\ntype Logger = {\n log: LogHandler;\n error?: LogHandler;\n warn?: LogHandler;\n info?: LogHandler;\n debug?: LogHandler;\n};\n/**\n * No logger is set by default.\n */\nlet logger: Logger | undefined;\n/**\n * By default, the logger is set to `error`.\n */\nlet level: number = LOG_LEVELS.indexOf('error');\n/**\n * Set the global logger for the SDK.\n * @param logMechanism The logger to use.\n * @example `log.setLogger(console)`\n */\nexport function setLogger(logMechanism: Logger) {\n logger = logMechanism;\n}\n/**\n * Set the global log level for the logger.\n * @param severity The severity to set the logger to.\n * @example `log.setLogLevel('info')`\n */\nexport function setLogLevel(severity: LogLevel) {\n level = LOG_LEVELS.indexOf(severity);\n}\n/**\n * Log a message to the logger.\n * @param severity The severity of the log entry.\n * @param args The message to log.\n * @private\n */\nexport function log(severity: LogLevel, ...args: unknown[]) {\n if (!logger) return;\n /**\n * If the severity of the entry is less than the logger's configured severity, do not log.\n */\n if (LOG_LEVELS.indexOf(severity) < level) {\n return;\n }\n /**\n * If the logger does not have a handler for the specified severity, use the default `log` handler.\n */\n const handler = logger[severity] ?? logger.log;\n handler(...args);\n}\n", "import * as AUTH from '../services/auth/config.js';\nimport * as TRANSFER from '../services/transfer/config.js';\nimport * as FLOWS from '../services/flows/config.js';\nimport * as GROUPS from '../services/groups/config.js';\nimport * as SEARCH from '../services/search/config.js';\nimport * as TIMER from '../services/timer/config.js';\nimport * as COMPUTE from '../services/compute/config.js';\n\nimport { EnvironmentConfigurationError } from './errors.js';\nimport { SDKOptions } from '../services/types.js';\nimport { log } from './logger.js';\n\nfunction getRuntime() {\n return typeof window !== 'undefined' ? window : process;\n}\n\nfunction isBrowser(runtime: Window | NodeJS.Process): runtime is Window {\n return typeof window === typeof runtime;\n}\n\nfunction env<T>(key: string, fallback: T): T {\n const runtime = getRuntime();\n let envConfiguration;\n if (isBrowser(runtime)) {\n envConfiguration = runtime;\n } else {\n envConfiguration = runtime.env;\n }\n if (key in envConfiguration) {\n return (envConfiguration as Record<typeof key, T>)[key];\n }\n return fallback;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_ENVIRONMENT\n */\nexport const ENVIRONMENTS = {\n PRODUCTION: 'production',\n PREVIEW: 'preview',\n STAGING: 'staging',\n SANDBOX: 'sandbox',\n INTEGRATION: 'integration',\n TEST: 'test',\n} as const;\n\nexport type Environment = (typeof ENVIRONMENTS)[keyof typeof ENVIRONMENTS];\n\nexport const SERVICES = {\n [AUTH.ID]: AUTH.ID,\n [TRANSFER.ID]: TRANSFER.ID,\n [FLOWS.ID]: FLOWS.ID,\n [GROUPS.ID]: GROUPS.ID,\n [SEARCH.ID]: SEARCH.ID,\n [TIMER.ID]: TIMER.ID,\n [COMPUTE.ID]: COMPUTE.ID,\n};\n\nexport type Service = keyof typeof SERVICES;\n\nexport const SERVICE_HOSTS: Record<Service, Partial<Record<Environment, string>>> = {\n [AUTH.ID]: AUTH.HOSTS,\n [TRANSFER.ID]: TRANSFER.HOSTS,\n [FLOWS.ID]: FLOWS.HOSTS,\n [GROUPS.ID]: GROUPS.HOSTS,\n [SEARCH.ID]: SEARCH.HOSTS,\n [TIMER.ID]: TIMER.HOSTS,\n [COMPUTE.ID]: COMPUTE.HOSTS,\n};\n\n/**\n * Get the computed SDK options based on the runtime.\n * This should be used any time we're referencing the SDK options in\n * methods to ensure we're including any global overrides.\n */\nexport function getSDKOptions(options?: SDKOptions) {\n let globalOptions = env<string | SDKOptions>('GLOBUS_SDK_OPTIONS', {});\n if (typeof globalOptions === 'string') {\n globalOptions = JSON.parse(globalOptions) as SDKOptions;\n }\n return {\n ...globalOptions,\n ...options,\n fetch: {\n ...globalOptions?.fetch,\n ...options?.fetch,\n options: {\n ...globalOptions?.fetch?.options,\n ...options?.fetch?.options,\n headers: {\n ...globalOptions?.fetch?.options?.headers,\n ...options?.fetch?.options?.headers,\n },\n },\n },\n };\n}\n\nexport function getEnvironment(): Environment {\n const globalOptions = getSDKOptions();\n const environment = env<Environment>(\n 'GLOBUS_SDK_ENVIRONMENT',\n globalOptions?.environment ?? ENVIRONMENTS.PRODUCTION,\n );\n if (globalOptions?.environment && environment !== globalOptions.environment) {\n log(\n 'debug',\n 'GLOBUS_SDK_ENVIRONMENT and GLOBUS_SDK_OPTIONS.environment are set to different values. GLOBUS_SDK_ENVIRONMENT will take precedence',\n );\n }\n if (!environment || !Object.values(ENVIRONMENTS).includes(environment)) {\n throw new EnvironmentConfigurationError('GLOBUS_SDK_ENVIRONMENT', environment);\n }\n return environment;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_VERIFY_SSL\n * Since disabling SSL is at least not-recommended, we consider\n * this value to always be true, but provide a warning when it set\n * to one of the falsey values for informational purposes.\n *\n * Taking direction from `globus-sdk-python` for possible false values\n * @see https://github.com/globus/globus-sdk-python/blob/18eced9c12e2ec41745d1be183148845198b999c/src/globus_sdk/config/env_vars.py#L20\n */\nexport function getVerifySSL(): boolean {\n const verifySSLTemp = env<string>('GLOBUS_SDK_VERIFY_SSL', 'true').toLowerCase();\n if (['n', 'no', 'f', 'false', 'off', '0'].includes(verifySSLTemp)) {\n log(\n 'warn',\n 'Setting GLOBUS_SDK_VERIFY_SSL to false is disallowed in the Globus JavaScript SDK. It will always true in this context',\n );\n }\n return true;\n}\n\n/**\n * Handlers for: GLOBUS_SDK_HTTP_TIMEOUT\n */\nexport function getHttpTimeout() {\n const timeout = Number(env<string | number>('GLOBUS_SDK_HTTP_TIMEOUT', 60));\n if (timeout === -1) {\n return null;\n }\n return timeout;\n}\n\nexport function getServiceHost(service: Service, environment: Environment = getEnvironment()) {\n return SERVICE_HOSTS[service][environment];\n}\n\nexport function getServiceBaseUrl(service: Service, environment: Environment = getEnvironment()) {\n const host = getServiceHost(service, environment);\n return env(`GLOBUS_SDK_SERVICE_URL_${service}`, host ? `https://${host}` : undefined);\n}\n", "import { getServiceBaseUrl, getEnvironment, Environment, Service } from './global.js';\nimport type { GCSConfiguration } from '../services/globus-connect-server/index.js';\nimport { SDKOptions } from '../services/types.js';\n\n/**\n * An extremely simplified parameter serializer based on our current needs.\n *\n * **This is intended for internal @globus/sdk use only.**\n *\n * @private\n */\nexport function stringifyParameters(parameters: {\n [key: string]:\n | string\n | number\n | boolean\n | Array<string | number | null | undefined>\n | null\n | undefined;\n}) {\n const search = new URLSearchParams();\n\n Array.from(Object.entries(parameters)).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n /**\n * Arrays are converted to comma-separated strings.\n */\n search.set(key, value.join(','));\n } else if (value !== undefined) {\n search.set(key, String(value));\n }\n });\n\n return search.toString();\n}\n\n/**\n * Return the base URL for a service (based on the environment).\n * @param service The service to build the URL for.\n * @param path The path to the resource.\n * @param environment The environment to use.\n */\nexport function getServiceURL(\n service: Service,\n path = '',\n environment: Environment = getEnvironment(),\n): URL {\n const base = getServiceBaseUrl(service, environment);\n return new URL(path, base);\n}\n\n/**\n * Build a URL for a service or GCSConfiguration.\n *\n * @param service The service identifier or GCSConfiguration object to build the URL for.\n * @param path The path to the resource.\n * @param options Additional options for the URL.\n */\nexport function build(\n serviceOrConfiguration: Service | GCSConfiguration,\n path: string,\n options?: {\n search?: Parameters<typeof stringifyParameters>[0];\n },\n sdkOptions?: SDKOptions,\n): string {\n let url;\n if (typeof serviceOrConfiguration === 'object') {\n url = new URL(path, serviceOrConfiguration.host);\n } else {\n url = getServiceURL(serviceOrConfiguration, path, sdkOptions?.environment);\n }\n if (options && options.search) {\n url.search = stringifyParameters(options.search);\n }\n return url.toString();\n}\n", "import _fetch from 'cross-fetch';\nimport { getClientInfoRequestHeaders } from '../core/info/index.js';\nimport { build } from '../core/url.js';\nimport { getSDKOptions, Service } from '../core/global.js';\nimport { isAuthorizationRequirementsError } from '../core/errors.js';\nimport { RESOURCE_SERVERS } from './auth/config.js';\nimport { isRefreshToken } from './auth/index.js';\nimport type { ServiceMethodOptions, SDKOptions } from './types.js';\nimport type { GCSConfiguration } from '../services/globus-connect-server/index.js';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport enum HTTP_METHODS {\n POST = 'POST',\n GET = 'GET',\n DELETE = 'DELETE',\n PUT = 'PUT',\n PATCH = 'PATCH',\n}\n\n/**\n * Our domain-specific language for describing service requests.\n * @private\n */\ntype ServiceRequestDSL = {\n /**\n * The service that the request will be made to.\n */\n service: Service | GCSConfiguration;\n /**\n * A specific scope that is required for the request. If a scope is provided,\n * the `serviceRequest` function will attempt to get a token for the request\n * based on the the `service` => `resource_server` mapping.\n */\n scope?: string;\n /**\n * The resource server that the request will be made to. This can be provided\n * instead of (or addition to) the `scope` property. If this is provided, the\n * `serviceRequest` function will attempt to get a token for the resource server\n * when a `manager` instance is provided in the SDK options.\n */\n resource_server?: string;\n /**\n * The path of the resource (appended to the service's host).\n */\n path: string;\n /**\n * The HTTP method to use for the request.\n */\n method?: HTTP_METHODS;\n /**\n * For some resources, it doesn't make sense for requests to be retried.\n * Setting this to `true` will prevent any retry logic from being applied.\n */\n preventRetry?: boolean;\n};\n\n/**\n * A helper function for making service requests that will handle the arguments\n * of `ServiceMethod` and `ServiceMethodDynamicSegments` functions in a uniform\n * way.\n *\n * @example\n * ```ts\n * export const get = function (flow_id, options?, sdkOptions?) {\n * return serviceRequest({\n * service: FLOWS.ID,\n * scope: SCOPES.VIEW_FLOWS,\n * path: `/flows/${flow_id}`,\n * }, options, sdkOptions);\n * } satisfies ServiceMethodDynamicSegments<string, Record<string, any>>;\n * ```\n *\n * @private\n * @param config The ServiceRequestDSL for the request.\n * @param options The options passed to the service method.\n * @param passedSdkOptions The SDK options passed to the service method.\n * @returns\n */\nexport async function serviceRequest(\n this: unknown,\n config: ServiceRequestDSL,\n options?: ServiceMethodOptions,\n passedSdkOptions?: SDKOptions,\n): Promise<Response> {\n /**\n * Get the SDK options, merging any passed options with the global options.\n */\n const sdkOptions = getSDKOptions(passedSdkOptions);\n const injectedFetchOptions = sdkOptions?.fetch?.options || {};\n\n const headers: Record<string, string> = {\n ...getClientInfoRequestHeaders(),\n ...options?.headers,\n /**\n * Key/value pairs found in the `fetch` options override those found in the\n * service method options.\n */\n ...injectedFetchOptions.headers,\n };\n\n /**\n * The `AuthorizationManager` instance provided with the call.\n */\n const manager = sdkOptions?.manager;\n\n let token;\n /**\n * If a `resource_server` was provided, and the SDK is configured with a `manager`\n * instance, we'll try to get a token for the resource server and use it.\n */\n if (config.resource_server && manager) {\n token = manager.tokens.getByResourceServer(config.resource_server);\n if (token) {\n headers['Authorization'] = `Bearer ${token.access_token}`;\n }\n }\n /**\n * If the `scope` property is provided, and the SDK is configured with a `manager`,\n * we'll try to map the service to a resource server. This is mostly to support\n * backwards compatibility of the `scope` property being used in the `ServiceRequestDSL`.\n */\n if (config.scope && manager) {\n const resourceServer =\n typeof config.service === 'string'\n ? RESOURCE_SERVERS[config.service]\n : // For `GCSConfiguration` objects, the `endpoint_id` is the resource server.\n config.service.endpoint_id;\n\n token = manager.tokens.getByResourceServer(resourceServer);\n if (token) {\n headers['Authorization'] = `Bearer ${token.access_token}`;\n }\n }\n\n /**\n * If a raw body was provided, use that. Otherwise, if a payload was provided, serialize it.\n */\n let body = options?.body;\n if (!body && options?.payload) {\n body = JSON.stringify(options.payload);\n }\n\n /**\n * If `Content-Type` header was not provided, and there is a body, we assume it is JSON.\n */\n if (!headers?.['Content-Type'] && body) {\n headers['Content-Type'] = 'application/json';\n }\n\n const url = build(\n config.service,\n config.path,\n {\n search: options?.query,\n },\n sdkOptions,\n );\n\n const init = {\n method: config.method,\n body,\n ...injectedFetchOptions,\n /**\n * Merge the headers from the options and SDK options.\n */\n headers,\n };\n\n /**\n * The request handler for the fetch call. This can be overridden by providing a\n * `__callable` property in the `fetch` options.\n */\n let handler = _fetch;\n /* eslint-disable no-underscore-dangle */\n if (injectedFetchOptions?.__callable) {\n handler = injectedFetchOptions.__callable.bind(this);\n /**\n * Remove the `__callable` property from the `fetch` options before passing the options along.\n */\n delete init.__callable;\n }\n /* eslint-enable no-underscore-dangle */\n\n /**\n * If the resource is configured to prevent retries, there is no `manager` instance,\n * or token, the request will be made as-is.\n */\n if (config.preventRetry || !manager || !token || !isRefreshToken(token)) {\n return handler(url, init);\n }\n\n /**\n * Automatic Retry Handling\n */\n\n const initialResponse = await handler(url, init);\n /**\n * If the response is \"ok\", we can return it as-is.\n */\n if (initialResponse.ok) {\n return initialResponse;\n }\n /**\n * Do a safe check to see if the response contains any authorization requirements.\n */\n let hasAuthorizationRequirements;\n try {\n hasAuthorizationRequirements = isAuthorizationRequirementsError(\n /**\n * It is important to clone the response before calling `json` avoid\n * `body used already for [...]` errors when the initial response is\n * returned.\n */\n await initialResponse.clone().json(),\n );\n } catch (_e) {\n hasAuthorizationRequirements = false;\n }\n /**\n * We only attempt to refresh the original token supplied with teh request, if the\n * response status is 401 and the response does not contain any authorization requirements.\n */\n const shouldAttemptTokenRefresh = initialResponse.status === 401 && !hasAuthorizationRequirements;\n if (shouldAttemptTokenRefresh) {\n const newToken = await manager.refreshToken(token);\n if (!newToken) {\n return initialResponse;\n }\n /**\n * Retry the request with the new token.\n */\n return handler(url, {\n ...init,\n headers: {\n ...init.headers,\n Authorization: `Bearer ${newToken.access_token}`,\n },\n });\n }\n /**\n * No retry was attempted, return the initial response.\n */\n return initialResponse;\n}\n", "import type { Info } from './index.js';\n\n/**\n * @private\n */\nexport const CLIENT_INFO_HEADER = `X-Globus-Client-Info`;\n\nlet ENABLED = true;\n/**\n * Disable the client information header from being included in requests (enabled by default).\n * @private\n */\nexport function disable() {\n ENABLED = false;\n}\n\n/**\n * Enables the client information header to be included in requests.\n * @private\n */\nexport function enable() {\n ENABLED = true;\n}\n\n/**\n * Whether or not the client information header should be sent with requests.\n * @private\n */\nexport function isEnabled() {\n return ENABLED;\n}\n\nconst INFOS_SEPERATOR = ';';\nconst INFO_ITEM_SEPARATOR = ',';\n\n/**\n * Exported for test purposes only.\n * @private\n */\nexport function toString(info: Info | Info[]) {\n const infos = Array.isArray(info) ? info : [info];\n return infos\n .map((i) =>\n Object.entries(i)\n .map(([key, value]) => `${key}=${value}`)\n .join(INFO_ITEM_SEPARATOR),\n )\n .join(INFOS_SEPERATOR);\n}\n", "// x-release-please-start-version\nexport const VERSION = '5.1.0';\n// x-release-please-end\n", "/**\n * @module Information\n * @description This module is mostly intended for internal use, but can be helpful\n * identifying information about the SDK package you are using at runtime.\n */\nimport { toString, isEnabled, CLIENT_INFO_HEADER } from './private.js';\nimport { VERSION as _VERSION } from './version.js';\n\nexport type Version = string;\n\n/**\n * The version of the `@globus/sdk` package that is in use.\n */\nexport const VERSION: Version = _VERSION;\n\nexport type Info = {\n product: string;\n version: Version;\n};\n\n/**\n * The client information identifier for this package.\n */\nexport const CLIENT_INFO: Info = {\n product: 'javascript-sdk',\n version: VERSION,\n};\n\nlet INFOS: Info[] = [CLIENT_INFO];\n\n/**\n * Add a client information identifier to the existing SDK information.\n */\nexport function addClientInfo(info: Info) {\n INFOS = INFOS.concat(info);\n}\n/**\n * Get the current client information as a string.\n */\nexport function getClientInfo(): string {\n return toString(INFOS);\n}\n\nexport function getClientInfoRequestHeaders(): Record<string, string> {\n if (!isEnabled()) {\n return {};\n }\n return {\n [CLIENT_INFO_HEADER]: getClientInfo(),\n };\n}\n", "import { ID } from '../../config.js';\nimport { HTTP_METHODS, serviceRequest } from '../../../../services/shared.js';\n\nimport type { ServiceMethod } from '../../../types.js';\n\nexport const userinfo = function (options?, sdkOptions?) {\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/userinfo`,\n method: HTTP_METHODS.GET,\n },\n options,\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: never;\n}>;\n\nexport * as token from './token.js';\n", "import { ID } from '../../config.js';\nimport { HTTP_METHODS, serviceRequest } from '../../../../services/shared.js';\n\nimport type { ServiceMethod, ServiceMethodOptions } from '../../../types.js';\n\ntype IntrospectPayload = {\n token: string;\n include?: string;\n};\n\ntype RevokePayload = {\n token: string;\n /**\n * This is an undocumented property that is required for the request to be successful.\n */\n client_id: string;\n};\n\ntype ValidatePayload = {\n token: string;\n client_id: string;\n};\n\ntype RefreshPayload = {\n refresh_token: string;\n grant_type: 'refresh_token';\n /**\n * This is an undocumented property that is required for the request to be successful.\n */\n client_id: string;\n};\n\ntype ExchangePayload = {\n grant_type: 'authorization_code';\n code: string;\n client_id: string;\n code_verifier: string;\n redirect_uri: string;\n};\n\ntype SupportedPayloads =\n | IntrospectPayload\n | RevokePayload\n | ValidatePayload\n | RefreshPayload\n | ExchangePayload;\n\nfunction serialize(payload?: SupportedPayloads) {\n return new URLSearchParams(payload);\n}\n\n/**\n * Format and inject properties that are specific to the `/token` resources.\n */\nfunction injectServiceOptions(\n options: ServiceMethodOptions & {\n payload?: SupportedPayloads;\n },\n): ServiceMethodOptions {\n return {\n ...options,\n /**\n * The `token` service methods always expect a form-encoded body. We still allow\n * end-consumers to pass a raw body, but if `payload` is provided it is serialized.\n */\n body: options.payload ? serialize(options.payload) : undefined,\n headers: {\n ...(options?.headers || {}),\n Accept: 'application/json',\n /**\n * Force the `Content-Type` header to be `application/x-www-form-urlencoded` and `charset=UTF-8`.\n */\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n },\n };\n}\n\n/**\n * @see https://docs.globus.org/api/auth/reference/#dependent_token_grant_post_v2oauth2token\n */\nexport const token = function (options = {}, sdkOptions?) {\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload?: ExchangePayload;\n}>;\n\n/**\n * @see https://docs.globus.org/api/auth/developer-guide/#obtaining-authorization\n */\nexport const exchange = token;\n\n/**\n * Token Introspection\n * @see https://docs.globus.org/api/auth/reference/#token-introspect\n */\nexport const introspect = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for introspect`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/introspect`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: IntrospectPayload;\n}>;\n\n/**\n * Token Revocation\n * @see https://docs.globus.org/api/auth/reference/#token-revoke\n */\nexport const revoke = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for revoke`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/revoke`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: RevokePayload;\n}>;\n\n/**\n * Token Refresh\n * @see https://docs.globus.org/api/auth/reference/#refresh_token_grant\n */\nexport const refresh = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for revoke`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: RefreshPayload;\n}>;\n\n/**\n * @private\n * @deprecated Rather than using `validate` to check if a token is valid, it is recommended to make a request to the resource server with the token and handle the error response.\n */\nexport const validate = function (options, sdkOptions?) {\n if (!options?.payload) {\n throw new Error(`'payload' is required for validate`);\n }\n return serviceRequest(\n {\n service: ID,\n scope: undefined,\n path: `/v2/oauth2/token/validate`,\n method: HTTP_METHODS.POST,\n preventRetry: true,\n },\n injectServiceOptions(options),\n sdkOptions,\n );\n} satisfies ServiceMethod<{\n payload: ValidatePayload;\n}>;\n", "/**\n * @description A wrapper around the Globus Auth service.\n * @group Service\n * @see [Globus Auth API Documentation](https://docs.globus.org/api/auth/)\n * @module\n */\nimport { build } from '../../core/url.js';\n\nimport * as AUTH from './config.js';\n\nimport type { Token, TokenWithRefresh, TokenResponse } from './types.js';\n\n/**\n * @private\n * @internal\n */\nexport const CONFIG = AUTH;\n\n/**\n * Query parameters that can be passed to the authorization endpoint.\n * @see https://docs.globus.org/api/auth/reference/#authorization_code_grant_preferred\n * @see https://docs.globus.org/api/auth/sessions/#client-initiated-authns\n */\nexport type AuthorizationQueryParameters = {\n prompt?: string;\n session_message?: string;\n session_required_identities?: string;\n session_required_single_domain?: string;\n session_required_mfa?: 'true' | 'false';\n session_required_policies?: string;\n};\n\nexport function getAuthorizationEndpoint() {\n return build(AUTH.ID, '/v2/oauth2/authorize');\n}\n\nexport function getTokenEndpoint() {\n return build(AUTH.ID, '/v2/oauth2/token');\n}\n\nexport * as identities from './service/identities.js';\nexport * as oauth2 from './service/oauth2/index.js';\n\nexport function isToken(check: unknown): check is Token {\n return typeof check === 'object' && check !== null && 'access_token' in check;\n}\n\nexport function isRefreshToken(check: unknown): check is TokenWithRefresh {\n return isToken(check) && check !== null && 'refresh_token' in check;\n}\n\nexport function isGlobusAuthTokenResponse(check: unknown): check is TokenResponse {\n /**\n * @todo This could be made more robust by checking whether the `resource_server` is a well-known value.\n */\n return isToken(check) && check !== null && 'resource_server' in check;\n}\n", "/**\n * @todo It would be nice to not `| any` here, but ideally callers do not need to\n * fully type the payload to attach listeners.\n */\ntype ListenerCallback<P> = (payload?: P | any) => Promise<void> | void;\n\nexport class Event<EventName extends string, Payload extends unknown> {\n #callbacks: ListenerCallback<Payload>[] = [];\n\n constructor(readonly name: EventName) {}\n\n addListener(callback: ListenerCallback<Payload>) {\n this.#callbacks.push(callback);\n return () => this.removeListener(callback);\n }\n\n removeListener(callback: ListenerCallback<Payload>) {\n this.#callbacks = this.#callbacks.filter((cb) => cb !== callback);\n }\n\n clearListeners() {\n this.#callbacks = [];\n }\n\n async dispatch(payload?: Payload) {\n await Promise.all(this.#callbacks.map((callback) => callback(payload)));\n }\n}\n", "export function isSupported() {\n return 'crypto' in globalThis;\n}\n\nfunction getCrypto(): Crypto {\n return 'webcrypto' in globalThis.crypto\n ? (globalThis.crypto.webcrypto as unknown as Crypto)\n : globalThis.crypto;\n}\n\n/**\n * Base64 URL encode a string.\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\nconst encode = (value: string) =>\n btoa(value).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\nasync function sha256(input: string) {\n const hashBuffer = await getCrypto().subtle.digest('SHA-256', new TextEncoder().encode(input));\n return String.fromCharCode(...new Uint8Array(hashBuffer));\n}\n\n/**\n * Character set for generating random alpha-numeric strings.\n */\nconst CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Character set allowed to be used in the PKCE `code_verifier`\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.1\n */\nconst PKCE_SAFE_CHARSET = `${CHARSET}-._~`;\n/**\n * Create a Code Verifier for PKCE\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.1\n */\nexport function generateCodeVerifier() {\n /**\n * @todo Make length random between 43 and 128 characters\n */\n return Array.from(getCrypto().getRandomValues(new Uint8Array(43)))\n .map((v) => PKCE_SAFE_CHARSET[v % PKCE_SAFE_CHARSET.length])\n .join('');\n}\n\n/**\n * Create a Code Challenge from a provided Code Verifier (assumes S256 `code_challenge_method`).\n * @see https://www.rfc-editor.org/rfc/rfc7636#section-4.2\n */\nexport async function generateCodeChallenge(verifier: string) {\n const hashed = await sha256(verifier);\n return encode(hashed);\n}\n\nexport function generateState() {\n return Array.from(getCrypto().getRandomValues(new Uint8Array(16)))\n .map((v) => CHARSET[v % CHARSET.length])\n .join('');\n}\n\n/**\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-code-exchange/\n */\nexport type AuthorizationCodeExchangeParameters = {\n code: string;\n code_verifier: string;\n client_id: string;\n client_secret?: string;\n redirect_uri: string;\n grant_type: 'authorization_code';\n};\n\n/**\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\nexport type AuthorizationRequestParameters = {\n client_id: string;\n redirect_uri: string;\n response_type: 'code';\n scope: string;\n state: string;\n code_challenge: string;\n code_challenge_method: 'S256' | 'plain';\n};\n", "import { getAuthorizationEndpoint, oauth2 } from '../../services/auth/index.js';\nimport {\n generateCodeChallenge,\n generateCodeVerifier,\n generateState,\n AuthorizationRequestParameters,\n AuthorizationCodeExchangeParameters,\n isSupported,\n} from './pkce.js';\n\nimport type { AuthorizationManagerConfiguration } from './AuthorizationManager';\n\nexport type GetTokenOptions = {\n /**\n * Whether or not the URL should be replaced after processing the token.\n * @default true\n */\n shouldReplace?: boolean;\n};\n\nexport type RedirectTransportOptions = Pick<\n AuthorizationManagerConfiguration,\n 'client' | 'redirect' | 'scopes'\n> & {\n /**\n * Query parameters to include in the authorization request.\n *\n * The `RedirectTransport` will include all parameters required for a default OAuth PKCE flow, but\n * these parameters can be overridden or extended with this option.\n */\n params?: {\n [key: string]: string;\n };\n};\n\n/**\n * @private\n */\nexport const KEYS = {\n PKCE_STATE: 'pkce_state',\n PKCE_CODE_VERIFIER: 'pkce_code_verifier',\n};\n\nfunction resetPKCE() {\n sessionStorage.removeItem(KEYS.PKCE_STATE);\n sessionStorage.removeItem(KEYS.PKCE_CODE_VERIFIER);\n}\n\nexport class RedirectTransport {\n #options: RedirectTransportOptions;\n\n constructor(options: RedirectTransportOptions) {\n this.#options = options;\n if (RedirectTransport.supported === false) {\n throw new Error('RedirectTransport is not supported in this environment.');\n }\n }\n\n static supported = isSupported();\n\n /**\n * For the redirect transport, sending the request will redirect the user to the authorization endpoint, initiating the OAuth flow.\n */\n async send() {\n /**\n * Since we'll be using PKCE, we need to generate a code verifier and challenge\n * for the OAuth handshake.\n */\n const verifier = generateCodeVerifier();\n const challenge = await generateCodeChallenge(verifier);\n /**\n * If there is caller-provided `state`, use it; Otherwise, generate a state parameter.\n */\n const state = this.#options.params?.['state'] ?? generateState();\n /**\n * The verifier and state are stored in session storage so that we can validate\n * the response when we receive it.\n */\n sessionStorage.setItem(KEYS.PKCE_CODE_VERIFIER, verifier);\n sessionStorage.setItem(KEYS.PKCE_STATE, state);\n\n const params: AuthorizationRequestParameters = {\n response_type: 'code',\n client_id: this.#options.client,\n scope: this.#options.scopes || '',\n redirect_uri: this.#options.redirect,\n state,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n ...(this.#options.params || {}),\n };\n\n const url = new URL(getAuthorizationEndpoint());\n url.search = new URLSearchParams(params).toString();\n\n window.location.assign(url.toString());\n }\n\n /**\n * Parse the current URL for the authorization code (`?code=...`) and exchange it for an access token when available.\n * - When the URL is processed and exchanged for an access token, the page is redirected to the current URL without the `?code=...&state=...` parameters.\n */\n async getToken(options: GetTokenOptions = { shouldReplace: true }) {\n const url = new URL(window.location.href);\n const params = new URLSearchParams(url.search);\n /**\n * Check for an error in the OAuth flow.\n * @see https://www.oauth.com/oauth2-servers/pkce/authorization-request/\n */\n if (params.get('error')) {\n throw new Error(\n params.get('error_description') || 'An error occurred during the authorization process.',\n );\n }\n\n const code = params.get('code');\n\n /**\n * If we don't have a `code` parameter, we can't exchange it for an access token.\n */\n if (!code) return undefined;\n\n /**\n * Grab the PKCE information from session storage.\n */\n const state = sessionStorage.getItem(KEYS.PKCE_STATE);\n const verifier = sessionStorage.getItem(KEYS.PKCE_CODE_VERIFIER);\n /**\n * Now that we have the values in memory, we can remove them from session storage.\n */\n resetPKCE();\n\n /**\n * Validate the `state` parameter matches the preserved state (to prevent CSRF attacks).\n */\n if (params.get('state') !== state) {\n throw new Error(\n 'Invalid State. The received \"state\" parameter does not match the expected state.',\n );\n }\n /**\n * Ensure we have a valid code verifier.\n */\n if (!verifier) {\n throw new Error('Invalid Code Verifier');\n }\n\n /**\n * Prepare the payload for the PKCE token exchange.\n */\n const payload: AuthorizationCodeExchangeParameters = {\n code,\n client_id: this.#options.client,\n /**\n * Retrieve the code verifier from session storage.\n */\n code_verifier: verifier,\n redirect_uri: this.#options.redirect,\n grant_type: 'authorization_code',\n };\n\n const response = await (\n await oauth2.token.exchange({\n payload,\n })\n ).json();\n\n if (options.shouldReplace) {\n /**\n * Remove the `code` and `state` parameters from the URL.\n */\n params.delete('code');\n params.delete('state');\n /**\n * Update the URL with the new query string.\n */\n url.search = params.toString();\n /**\n * Redirect the page to the new URL (without the `code` and `state` parameters)/\n */\n window.location.replace(url);\n }\n return response;\n }\n}\n", "import { CONFIG, isToken } from '../../services/auth/index.js';\n\nimport { SERVICES, type Service } from '../global.js';\nimport { AuthorizationManager } from './AuthorizationManager.js';\n\nimport type { Token, TokenResponse } from '../../services/auth/types.js';\n\nexport type StoredToken = Token & {\n /**\n * Tokens stored before the introduction of the `__metadata` field will be missing this property.\n * @since 4.3.0\n */\n __metadata?: {\n /**\n * The timestamp when the token was added to the storage as a number of milliseconds since the Unix epoch.\n *\n * **IMPORTANT**: This value might **not** represent the time when the token was created by the authorization server.\n */\n created: number;\n /**\n * The timestamp when the token will expire as a number of milliseconds since the Unix epoch, based\n * on the `expires_in` value from the token response and the time when the token was stored.\n */\n expires: number | null;\n };\n};\n\nexport class TokenManager {\n #manager: AuthorizationManager;\n\n constructor(options: { manager: AuthorizationManager }) {\n this.#manager = options.manager;\n }\n\n /**\n * Retrieve and parse an item from the storage.\n */\n #getTokenFromStorage(key: string) {\n const raw = this.#manager.storage.getItem(key) || 'null';\n let token: StoredToken | null = null;\n try {\n const parsed = JSON.parse(raw);\n if (isToken(parsed)) {\n token = parsed;\n }\n } catch (e) {\n // no-op\n }\n return token;\n }\n\n #getTokenForService(service: Service) {\n const resourceServer = CONFIG.RESOURCE_SERVERS?.[service];\n return this.getByResourceServer(resourceServer);\n }\n\n getByResourceServer(resourceServer: string): StoredToken | null {\n return this.#getTokenFromStorage(`${this.#manager.storageKeyPrefix}${resourceServer}`);\n }\n\n get auth(): StoredToken | null {\n return this.#getTokenForService(SERVICES.AUTH);\n }\n\n get transfer(): StoredToken | null {\n return this.#getTokenForService(SERVICES.TRANSFER);\n }\n\n get flows(): StoredToken | null {\n return this.#getTokenForService(SERVICES.FLOWS);\n }\n\n get groups(): StoredToken | null {\n return this.#getTokenForService(SERVICES.GROUPS);\n }\n\n get search(): StoredToken | null {\n return this.#getTokenForService(SERVICES.SEARCH);\n }\n\n get timer(): StoredToken | null {\n return this.#getTokenForService(SERVICES.TIMER);\n }\n\n get compute(): StoredToken | null {\n return this.#getTokenForService(SERVICES.COMPUTE);\n }\n\n gcs(endpoint: string): StoredToken | null {\n return this.getByResourceServer(endpoint);\n }\n\n getAll(): StoredToken[] {\n const entries = Object.keys(this.#manager.storage).reduce(\n (acc: (StoredToken | null)[], key) => {\n if (key.startsWith(this.#manager.storageKeyPrefix)) {\n acc.push(this.#getTokenFromStorage(key));\n }\n return acc;\n },\n [],\n );\n return entries.filter(isToken);\n }\n\n /**\n * Add a token to the storage.\n */\n add(token: Token | TokenResponse) {\n const created = Date.now();\n const expires = created + token.expires_in * 1000;\n this.#manager.storage.setItem(\n `${this.#manager.storageKeyPrefix}${token.resource_server}`,\n JSON.stringify({\n ...token,\n /**\n * Add metadata to the token to track when it was created and when it expires.\n */\n __metadata: {\n created,\n expires,\n },\n }),\n );\n if ('other_tokens' in token) {\n token.other_tokens?.forEach((t) => {\n this.add(t);\n });\n }\n }\n\n /**\n * Determines whether or not a stored token is expired.\n * @param token The token to check.\n * @param augment An optional number of milliseconds to add to the current time when checking the expiration.\n * @returns `true` if the token is expired, `false` if it is not expired, and `undefined` if the expiration status cannot be determined\n * based on the token's metadata. This can happen if the token is missing the `__metadata` field or the `expires` field.\n */\n static isTokenExpired(token: StoredToken | null, augment: number = 0): boolean | undefined {\n /* eslint-disable no-underscore-dangle */\n if (!token || !token.__metadata || typeof token.__metadata.expires !== 'number') {\n return undefined;\n }\n return Date.now() + augment >= token.__metadata.expires;\n /* eslint-enable no-underscore-dangle */\n }\n}\n", "/**\n * An in-memory implementation of the `Storage` interface.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Storage\n */\nexport class MemoryStorage implements Storage {\n #storage: Record<string, string | null> = {};\n\n getItem(key: string) {\n return this.#storage[key] !== undefined ? this.#storage[key] : null;\n }\n\n setItem(key: string, value: string) {\n this.#storage[key] = value;\n }\n\n removeItem(key: string) {\n delete this.#storage[key];\n }\n\n key(index: number) {\n return Object.keys(this.#storage)[index];\n }\n\n clear() {\n this.#storage = {};\n }\n\n get length() {\n return Object.keys(this.#storage).length;\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["HOSTS", "ID", "ID", "HOSTS", "ID", "HOSTS", "ID", "HOSTS", "ID", "HOSTS", "ID", "HOSTS", "ID", "HOSTS", "ID", "HOSTS", "VERSION", "token", "_fetch", "ID", "ID", "ID", "token", "token"]
7
7
  }
@@ -43,7 +43,7 @@ function toString(info) {
43
43
  }
44
44
 
45
45
  // src/core/info/version.ts
46
- var VERSION = "5.0.0";
46
+ var VERSION = "5.1.0";
47
47
 
48
48
  // src/core/info/index.ts
49
49
  var VERSION2 = VERSION;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/info/index.ts", "../../../../src/core/info/private.ts", "../../../../src/core/info/version.ts"],
4
- "sourcesContent": ["/**\n * @module Information\n * @description This module is mostly intended for internal use, but can be helpful\n * identifying information about the SDK package you are using at runtime.\n */\nimport { toString, isEnabled, CLIENT_INFO_HEADER } from './private.js';\nimport { VERSION as _VERSION } from './version.js';\n\nexport type Version = string;\n\n/**\n * The version of the `@globus/sdk` package that is in use.\n */\nexport const VERSION: Version = _VERSION;\n\nexport type Info = {\n product: string;\n version: Version;\n};\n\n/**\n * The client information identifier for this package.\n */\nexport const CLIENT_INFO: Info = {\n product: 'javascript-sdk',\n version: VERSION,\n};\n\nlet INFOS: Info[] = [CLIENT_INFO];\n\n/**\n * Add a client information identifier to the existing SDK information.\n */\nexport function addClientInfo(info: Info) {\n INFOS = INFOS.concat(info);\n}\n/**\n * Get the current client information as a string.\n */\nexport function getClientInfo(): string {\n return toString(INFOS);\n}\n\nexport function getClientInfoRequestHeaders(): Record<string, string> {\n if (!isEnabled()) {\n return {};\n }\n return {\n [CLIENT_INFO_HEADER]: getClientInfo(),\n };\n}\n", "import type { Info } from './index.js';\n\n/**\n * @private\n */\nexport const CLIENT_INFO_HEADER = `X-Globus-Client-Info`;\n\nlet ENABLED = true;\n/**\n * Disable the client information header from being included in requests (enabled by default).\n * @private\n */\nexport function disable() {\n ENABLED = false;\n}\n\n/**\n * Enables the client information header to be included in requests.\n * @private\n */\nexport function enable() {\n ENABLED = true;\n}\n\n/**\n * Whether or not the client information header should be sent with requests.\n * @private\n */\nexport function isEnabled() {\n return ENABLED;\n}\n\nconst INFOS_SEPERATOR = ';';\nconst INFO_ITEM_SEPARATOR = ',';\n\n/**\n * Exported for test purposes only.\n * @private\n */\nexport function toString(info: Info | Info[]) {\n const infos = Array.isArray(info) ? info : [info];\n return infos\n .map((i) =>\n Object.entries(i)\n .map(([key, value]) => `${key}=${value}`)\n .join(INFO_ITEM_SEPARATOR),\n )\n .join(INFOS_SEPERATOR);\n}\n", "// x-release-please-start-version\nexport const VERSION = '5.0.0';\n// x-release-please-end\n"],
4
+ "sourcesContent": ["/**\n * @module Information\n * @description This module is mostly intended for internal use, but can be helpful\n * identifying information about the SDK package you are using at runtime.\n */\nimport { toString, isEnabled, CLIENT_INFO_HEADER } from './private.js';\nimport { VERSION as _VERSION } from './version.js';\n\nexport type Version = string;\n\n/**\n * The version of the `@globus/sdk` package that is in use.\n */\nexport const VERSION: Version = _VERSION;\n\nexport type Info = {\n product: string;\n version: Version;\n};\n\n/**\n * The client information identifier for this package.\n */\nexport const CLIENT_INFO: Info = {\n product: 'javascript-sdk',\n version: VERSION,\n};\n\nlet INFOS: Info[] = [CLIENT_INFO];\n\n/**\n * Add a client information identifier to the existing SDK information.\n */\nexport function addClientInfo(info: Info) {\n INFOS = INFOS.concat(info);\n}\n/**\n * Get the current client information as a string.\n */\nexport function getClientInfo(): string {\n return toString(INFOS);\n}\n\nexport function getClientInfoRequestHeaders(): Record<string, string> {\n if (!isEnabled()) {\n return {};\n }\n return {\n [CLIENT_INFO_HEADER]: getClientInfo(),\n };\n}\n", "import type { Info } from './index.js';\n\n/**\n * @private\n */\nexport const CLIENT_INFO_HEADER = `X-Globus-Client-Info`;\n\nlet ENABLED = true;\n/**\n * Disable the client information header from being included in requests (enabled by default).\n * @private\n */\nexport function disable() {\n ENABLED = false;\n}\n\n/**\n * Enables the client information header to be included in requests.\n * @private\n */\nexport function enable() {\n ENABLED = true;\n}\n\n/**\n * Whether or not the client information header should be sent with requests.\n * @private\n */\nexport function isEnabled() {\n return ENABLED;\n}\n\nconst INFOS_SEPERATOR = ';';\nconst INFO_ITEM_SEPARATOR = ',';\n\n/**\n * Exported for test purposes only.\n * @private\n */\nexport function toString(info: Info | Info[]) {\n const infos = Array.isArray(info) ? info : [info];\n return infos\n .map((i) =>\n Object.entries(i)\n .map(([key, value]) => `${key}=${value}`)\n .join(INFO_ITEM_SEPARATOR),\n )\n .join(INFOS_SEPERATOR);\n}\n", "// x-release-please-start-version\nexport const VERSION = '5.1.0';\n// x-release-please-end\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,iBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,qBAAqB;AAElC,IAAI,UAAU;AAqBP,SAAS,YAAY;AAC1B,SAAO;AACT;AAEA,IAAM,kBAAkB;AACxB,IAAM,sBAAsB;AAMrB,SAAS,SAAS,MAAqB;AAC5C,QAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAChD,SAAO,MACJ;AAAA,IAAI,CAAC,MACJ,OAAO,QAAQ,CAAC,EACb,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,EACvC,KAAK,mBAAmB;AAAA,EAC7B,EACC,KAAK,eAAe;AACzB;;;AC/CO,IAAM,UAAU;;;AFYhB,IAAMC,WAAmB;AAUzB,IAAM,cAAoB;AAAA,EAC/B,SAAS;AAAA,EACT,SAASA;AACX;AAEA,IAAI,QAAgB,CAAC,WAAW;AAKzB,SAAS,cAAc,MAAY;AACxC,UAAQ,MAAM,OAAO,IAAI;AAC3B;AAIO,SAAS,gBAAwB;AACtC,SAAO,SAAS,KAAK;AACvB;AAEO,SAAS,8BAAsD;AACpE,MAAI,CAAC,UAAU,GAAG;AAChB,WAAO,CAAC;AAAA,EACV;AACA,SAAO;AAAA,IACL,CAAC,kBAAkB,GAAG,cAAc;AAAA,EACtC;AACF;",
6
6
  "names": ["VERSION", "VERSION"]
7
7
  }
package/dist/cjs/index.js CHANGED
@@ -71,7 +71,7 @@ function toString(info2) {
71
71
  }
72
72
 
73
73
  // src/core/info/version.ts
74
- var VERSION = "5.0.0";
74
+ var VERSION = "5.1.0";
75
75
 
76
76
  // src/core/info/index.ts
77
77
  var VERSION2 = VERSION;
@@ -2448,6 +2448,8 @@ __export(flows_exports2, {
2448
2448
  // src/services/flows/service/flows.ts
2449
2449
  var flows_exports = {};
2450
2450
  __export(flows_exports, {
2451
+ create: () => create7,
2452
+ deploy: () => deploy,
2451
2453
  get: () => get15,
2452
2454
  getAll: () => getAll8,
2453
2455
  remove: () => remove7,
@@ -2512,6 +2514,19 @@ var validate2 = function(options, sdkOptions) {
2512
2514
  sdkOptions
2513
2515
  );
2514
2516
  };
2517
+ var create7 = function(options, sdkOptions) {
2518
+ return serviceRequest(
2519
+ {
2520
+ service: ID2,
2521
+ scope: SCOPES2.MANAGE_FLOWS,
2522
+ path: `/flows`,
2523
+ method: "POST" /* POST */
2524
+ },
2525
+ options,
2526
+ sdkOptions
2527
+ );
2528
+ };
2529
+ var deploy = create7;
2515
2530
 
2516
2531
  // src/services/flows/service/runs.ts
2517
2532
  var runs_exports = {};
@@ -2575,7 +2590,7 @@ __export(globus_connect_server_exports, {
2575
2590
  // src/services/globus-connect-server/service/collections.ts
2576
2591
  var collections_exports = {};
2577
2592
  __export(collections_exports, {
2578
- create: () => create7,
2593
+ create: () => create8,
2579
2594
  get: () => get16,
2580
2595
  getAll: () => getAll10,
2581
2596
  patch: () => patch,
@@ -2618,7 +2633,7 @@ var remove8 = function(configuration, collection_id, options, sdkOptions) {
2618
2633
  sdkOptions
2619
2634
  );
2620
2635
  };
2621
- var create7 = function(configuration, options, sdkOptions) {
2636
+ var create8 = function(configuration, options, sdkOptions) {
2622
2637
  return serviceRequest(
2623
2638
  {
2624
2639
  service: configuration,
@@ -2820,7 +2835,7 @@ var update8 = function(configuration, path, options, sdkOptions) {
2820
2835
  // src/services/globus-connect-server/service/nodes.ts
2821
2836
  var nodes_exports = {};
2822
2837
  __export(nodes_exports, {
2823
- create: () => create8,
2838
+ create: () => create9,
2824
2839
  get: () => get19,
2825
2840
  getAll: () => getAll11,
2826
2841
  patch: () => patch3,
@@ -2861,7 +2876,7 @@ var remove10 = function(configuration, node_id, options, sdkOptions) {
2861
2876
  sdkOptions
2862
2877
  );
2863
2878
  };
2864
- var create8 = function(configuration, options, sdkOptions) {
2879
+ var create9 = function(configuration, options, sdkOptions) {
2865
2880
  return serviceRequest(
2866
2881
  {
2867
2882
  service: configuration,
@@ -2901,7 +2916,7 @@ var patch3 = function(configuration, node_id, options, sdkOptions) {
2901
2916
  // src/services/globus-connect-server/service/roles.ts
2902
2917
  var roles_exports = {};
2903
2918
  __export(roles_exports, {
2904
- create: () => create9,
2919
+ create: () => create10,
2905
2920
  get: () => get20,
2906
2921
  getAll: () => getAll12,
2907
2922
  remove: () => remove11
@@ -2940,7 +2955,7 @@ var remove11 = function(configuration, role_id, options, sdkOptions) {
2940
2955
  sdkOptions
2941
2956
  );
2942
2957
  };
2943
- var create9 = function(configuration, options, sdkOptions) {
2958
+ var create10 = function(configuration, options, sdkOptions) {
2944
2959
  return serviceRequest(
2945
2960
  {
2946
2961
  service: configuration,
@@ -2956,7 +2971,7 @@ var create9 = function(configuration, options, sdkOptions) {
2956
2971
  // src/services/globus-connect-server/service/storage-gateways.ts
2957
2972
  var storage_gateways_exports = {};
2958
2973
  __export(storage_gateways_exports, {
2959
- create: () => create10,
2974
+ create: () => create11,
2960
2975
  get: () => get21,
2961
2976
  getAll: () => getAll13,
2962
2977
  patch: () => patch4,
@@ -2997,7 +3012,7 @@ var remove12 = function(configuration, storage_gateway_id, options, sdkOptions)
2997
3012
  sdkOptions
2998
3013
  );
2999
3014
  };
3000
- var create10 = function(configuration, options, sdkOptions) {
3015
+ var create11 = function(configuration, options, sdkOptions) {
3001
3016
  return serviceRequest(
3002
3017
  {
3003
3018
  service: configuration,
@@ -3037,7 +3052,7 @@ var patch4 = function(configuration, storage_gateway_id, options, sdkOptions) {
3037
3052
  // src/services/globus-connect-server/service/user-credentials.ts
3038
3053
  var user_credentials_exports = {};
3039
3054
  __export(user_credentials_exports, {
3040
- create: () => create11,
3055
+ create: () => create12,
3041
3056
  get: () => get22,
3042
3057
  getAll: () => getAll14,
3043
3058
  patch: () => patch5,
@@ -3078,7 +3093,7 @@ var remove13 = function(configuration, user_credential_id, options, sdkOptions)
3078
3093
  sdkOptions
3079
3094
  );
3080
3095
  };
3081
- var create11 = function(configuration, options, sdkOptions) {
3096
+ var create12 = function(configuration, options, sdkOptions) {
3082
3097
  return serviceRequest(
3083
3098
  {
3084
3099
  service: configuration,
@@ -3145,11 +3160,11 @@ function getRequiredScopes(configuration) {
3145
3160
  var timer_exports = {};
3146
3161
  __export(timer_exports, {
3147
3162
  CONFIG: () => CONFIG6,
3148
- create: () => create12
3163
+ create: () => create13
3149
3164
  });
3150
3165
 
3151
3166
  // src/services/timer/service/timer.ts
3152
- var create12 = function(options, sdkOptions) {
3167
+ var create13 = function(options, sdkOptions) {
3153
3168
  return serviceRequest(
3154
3169
  {
3155
3170
  service: ID3,