@shopify/cli-kit 4.5.1 → 4.6.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.
Files changed (64) hide show
  1. package/dist/private/node/analytics/error-grouping.d.ts +57 -0
  2. package/dist/private/node/analytics/error-grouping.js +191 -0
  3. package/dist/private/node/analytics/error-grouping.js.map +1 -0
  4. package/dist/private/node/analytics/graphql-error-codes.d.ts +39 -0
  5. package/dist/private/node/analytics/graphql-error-codes.js +73 -0
  6. package/dist/private/node/analytics/graphql-error-codes.js.map +1 -0
  7. package/dist/private/node/api/headers.js +1 -2
  8. package/dist/private/node/api/headers.js.map +1 -1
  9. package/dist/private/node/constants.d.ts +0 -2
  10. package/dist/private/node/constants.js +0 -2
  11. package/dist/private/node/constants.js.map +1 -1
  12. package/dist/private/node/content-tokens.js +2 -4
  13. package/dist/private/node/content-tokens.js.map +1 -1
  14. package/dist/private/node/session/scopes.js +6 -5
  15. package/dist/private/node/session/scopes.js.map +1 -1
  16. package/dist/private/node/session/validate.js +1 -2
  17. package/dist/private/node/session/validate.js.map +1 -1
  18. package/dist/private/node/session.d.ts +1 -0
  19. package/dist/private/node/session.js +9 -8
  20. package/dist/private/node/session.js.map +1 -1
  21. package/dist/public/common/object.d.ts +8 -0
  22. package/dist/public/common/object.js +24 -0
  23. package/dist/public/common/object.js.map +1 -1
  24. package/dist/public/common/version.d.ts +1 -1
  25. package/dist/public/common/version.js +1 -1
  26. package/dist/public/common/version.js.map +1 -1
  27. package/dist/public/node/analytics.js +4 -1
  28. package/dist/public/node/analytics.js.map +1 -1
  29. package/dist/public/node/api/partners.d.ts +0 -17
  30. package/dist/public/node/api/partners.js +1 -48
  31. package/dist/public/node/api/partners.js.map +1 -1
  32. package/dist/public/node/base-command.d.ts +1 -0
  33. package/dist/public/node/base-command.js +2 -0
  34. package/dist/public/node/base-command.js.map +1 -1
  35. package/dist/public/node/cli.d.ts +3 -0
  36. package/dist/public/node/cli.js +6 -0
  37. package/dist/public/node/cli.js.map +1 -1
  38. package/dist/public/node/context/local.d.ts +0 -7
  39. package/dist/public/node/context/local.js +0 -9
  40. package/dist/public/node/context/local.js.map +1 -1
  41. package/dist/public/node/environment.d.ts +0 -6
  42. package/dist/public/node/environment.js +0 -8
  43. package/dist/public/node/environment.js.map +1 -1
  44. package/dist/public/node/error-handler.js +35 -14
  45. package/dist/public/node/error-handler.js.map +1 -1
  46. package/dist/public/node/error.js +34 -0
  47. package/dist/public/node/error.js.map +1 -1
  48. package/dist/public/node/graphiql/server.js +2 -2
  49. package/dist/public/node/graphiql/server.js.map +1 -1
  50. package/dist/public/node/local-storage.js +10 -1
  51. package/dist/public/node/local-storage.js.map +1 -1
  52. package/dist/public/node/node-package-manager.js +2 -13
  53. package/dist/public/node/node-package-manager.js.map +1 -1
  54. package/dist/public/node/session.d.ts +13 -0
  55. package/dist/public/node/session.js +26 -1
  56. package/dist/public/node/session.js.map +1 -1
  57. package/dist/public/node/system.js +2 -3
  58. package/dist/public/node/system.js.map +1 -1
  59. package/dist/public/node/themes/api.js +9 -2
  60. package/dist/public/node/themes/api.js.map +1 -1
  61. package/dist/public/node/tree-kill.js +12 -25
  62. package/dist/public/node/tree-kill.js.map +1 -1
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +4 -4
@@ -1,14 +1,13 @@
1
1
  import { validateCachedIdentityTokenStructure } from './schema.js';
2
2
  import { applicationId } from './identity.js';
3
3
  import { sessionConstants } from '../constants.js';
4
- import { firstPartyDev } from '../../../public/node/context/local.js';
5
4
  import { outputDebug } from '../../../public/node/output.js';
6
5
  /**
7
6
  * Validate if an identity token is valid for the requested scopes
8
7
  */
9
8
  function validateScopes(requestedScopes, identity) {
10
9
  const currentScopes = identity.scopes;
11
- if (firstPartyDev() !== currentScopes.includes('employee'))
10
+ if (currentScopes.includes('employee'))
12
11
  return false;
13
12
  return requestedScopes.every((scope) => currentScopes.includes(scope));
14
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/private/node/session/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApplicationToken, IdentityToken, Session, validateCachedIdentityTokenStructure} from './schema.js'\n\nimport {applicationId} from './identity.js'\nimport {sessionConstants} from '../constants.js'\nimport {firstPartyDev} from '../../../public/node/context/local.js'\nimport {OAuthApplications} from '../session.js'\nimport {outputDebug} from '../../../public/node/output.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes - requested scopes to validate\n * @param applications - requested applications\n * @param session - current session with identity and application tokens\n * @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: Session | undefined,\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n outputDebug(`- Token validation -> It's expired: ${tokensAreExpired}`)\n\n if (!validateCachedIdentityTokenStructure(session.identity)) {\n return 'needs_full_auth'\n }\n\n if (tokensAreExpired) return 'needs_refresh'\n\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + sessionConstants.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/private/node/session/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApplicationToken, IdentityToken, Session, validateCachedIdentityTokenStructure} from './schema.js'\n\nimport {applicationId} from './identity.js'\nimport {sessionConstants} from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {outputDebug} from '../../../public/node/output.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes - requested scopes to validate\n * @param applications - requested applications\n * @param session - current session with identity and application tokens\n * @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: Session | undefined,\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n outputDebug(`- Token validation -> It's expired: ${tokensAreExpired}`)\n\n if (!validateCachedIdentityTokenStructure(session.identity)) {\n return 'needs_full_auth'\n }\n\n if (tokensAreExpired) return 'needs_refresh'\n\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + sessionConstants.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
@@ -90,6 +90,7 @@ export declare function setLastSeenUserIdAfterAuth(id: string): void;
90
90
  */
91
91
  export declare function getLastSeenAuthMethod(): Promise<AuthMethod>;
92
92
  export declare function setLastSeenAuthMethod(method: AuthMethod): void;
93
+ export declare function setCommandSessionId(sessionId: string | undefined): void;
93
94
  export interface EnsureAuthenticatedAdditionalOptions {
94
95
  noPrompt?: boolean;
95
96
  forceRefresh?: boolean;
@@ -8,7 +8,7 @@ import { isThemeAccessSession } from './api/rest.js';
8
8
  import { getCurrentSessionId, setCurrentSessionId } from './conf-store.js';
9
9
  import { UserEmailQueryString } from './api/graphql/business-platform-destinations/user-email.js';
10
10
  import { outputContent, outputToken, outputDebug, outputCompleted } from '../../public/node/output.js';
11
- import { firstPartyDev, themeToken } from '../../public/node/context/local.js';
11
+ import { themeToken } from '../../public/node/context/local.js';
12
12
  import { AbortError } from '../../public/node/error.js';
13
13
  import { normalizeStoreFqdn, identityFqdn } from '../../public/node/context/fqdn.js';
14
14
  import { getIdentityTokenInformation, getAppAutomationToken } from '../../public/node/environment.js';
@@ -36,6 +36,7 @@ async function fetchEmail(businessPlatformToken) {
36
36
  }
37
37
  let userId;
38
38
  let authMethod = 'none';
39
+ let commandSessionId;
39
40
  /**
40
41
  * Retrieves a stable user identifier for analytics, or `'unknown'` if none applies.
41
42
  *
@@ -91,6 +92,9 @@ export async function getLastSeenAuthMethod() {
91
92
  export function setLastSeenAuthMethod(method) {
92
93
  authMethod = method;
93
94
  }
95
+ export function setCommandSessionId(sessionId) {
96
+ commandSessionId = sessionId;
97
+ }
94
98
  /**
95
99
  * This method ensures that we have a valid session to authenticate against the given applications using the provided scopes.
96
100
  *
@@ -109,8 +113,8 @@ export async function ensureAuthenticated(applications, _env, { forceRefresh = f
109
113
  }
110
114
  }
111
115
  const sessions = (await sessionStore.fetch()) ?? {};
112
- let currentSessionId = getCurrentSessionId();
113
- if (!currentSessionId) {
116
+ let currentSessionId = forceNewSession ? undefined : (commandSessionId ?? getCurrentSessionId());
117
+ if (!currentSessionId && !commandSessionId) {
114
118
  const userIds = Object.keys(sessions[fqdn] ?? {});
115
119
  if (userIds.length > 0)
116
120
  currentSessionId = userIds[0];
@@ -157,7 +161,8 @@ ${outputToken.json(applications)}
157
161
  // Save the new session info if it has changed
158
162
  if (!isEmpty(newSession)) {
159
163
  await sessionStore.store(updatedSessions);
160
- setCurrentSessionId(newSessionId);
164
+ if (!commandSessionId)
165
+ setCurrentSessionId(newSessionId);
161
166
  }
162
167
  const tokens = await tokensFor(applications, completeSession);
163
168
  const envToken = getAppAutomationToken();
@@ -186,10 +191,6 @@ async function executeCompleteFlow(applications, existingAlias) {
186
191
  const scopes = getFlattenScopes(applications);
187
192
  const exchangeScopes = getExchangeScopes(applications);
188
193
  const store = applications.adminApi?.storeFqdn;
189
- if (firstPartyDev()) {
190
- outputDebug(outputContent `Authenticating as Shopify Employee...`);
191
- scopes.push('employee');
192
- }
193
194
  let identityToken;
194
195
  const identityTokenInformation = getIdentityTokenInformation();
195
196
  if (identityTokenInformation) {
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/private/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {applicationId} from './session/identity.js'\nimport {validateSession} from './session/validate.js'\nimport {allDefaultScopes, apiScopes} from './session/scopes.js'\nimport {\n exchangeAccessForApplicationTokens,\n exchangeCustomPartnerToken,\n ExchangeScopes,\n refreshAccessToken,\n InvalidGrantError,\n InvalidRequestError,\n} from './session/exchange.js'\nimport {IdentityToken, Session, Sessions} from './session/schema.js'\nimport * as sessionStore from './session/store.js'\nimport {pollForDeviceAuthorization, requestDeviceAuthorization} from './session/device-authorization.js'\nimport {isThemeAccessSession} from './api/rest.js'\nimport {getCurrentSessionId, setCurrentSessionId} from './conf-store.js'\nimport {UserEmailQueryString, UserEmailQuery} from './api/graphql/business-platform-destinations/user-email.js'\nimport {outputContent, outputToken, outputDebug, outputCompleted} from '../../public/node/output.js'\nimport {firstPartyDev, themeToken} from '../../public/node/context/local.js'\nimport {AbortError} from '../../public/node/error.js'\nimport {normalizeStoreFqdn, identityFqdn} from '../../public/node/context/fqdn.js'\nimport {getIdentityTokenInformation, getAppAutomationToken} from '../../public/node/environment.js'\nimport {AdminSession, logout} from '../../public/node/session.js'\nimport {nonRandomUUID} from '../../public/node/crypto.js'\nimport {isEmpty} from '../../public/common/object.js'\nimport {businessPlatformRequest} from '../../public/node/api/business-platform.js'\n\n/**\n * Fetches the user's email from the Business Platform API\n * @param businessPlatformToken - The business platform token\n * @returns The user's email address or undefined if not found\n */\nasync function fetchEmail(businessPlatformToken: string | undefined): Promise<string | undefined> {\n if (!businessPlatformToken) return undefined\n\n try {\n const userEmailResult = await businessPlatformRequest<UserEmailQuery>(UserEmailQueryString, businessPlatformToken)\n return userEmailResult.currentUserAccount?.email ?? undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n outputDebug(outputContent`Failed to fetch user email: ${(error as Error).message ?? String(error)}`)\n return undefined\n }\n}\n\n/**\n * A scope supported by the Shopify Admin API.\n */\nexport type AdminAPIScope = 'graphql' | 'themes' | 'collaborator'\n\n/**\n * It represents the options to authenticate against the Shopify Admin API.\n */\n\ninterface AdminAPIOAuthOptions {\n /** Store to request permissions for. */\n storeFqdn: string\n /** List of scopes to request permissions for. */\n scopes: AdminAPIScope[]\n}\n\n/**\n * A scope supported by the Partners API.\n */\nexport type PartnersAPIScope = 'cli'\ninterface PartnersAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: PartnersAPIScope[]\n}\n\n/**\n * A scope supported by the Developer Platform API.\n */\nexport type AppManagementAPIScope = 'https://api.shopify.com/auth/organization.apps.manage'\ninterface AppManagementAPIOauthOptions {\n /** List of scopes to request permissions for. */\n scopes: AppManagementAPIScope[]\n}\n\n/**\n * A scope supported by the Storefront Renderer API.\n */\nexport type StorefrontRendererScope = 'devtools' | 'graphql'\ninterface StorefrontRendererAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: StorefrontRendererScope[]\n}\n\nexport type BusinessPlatformScope = 'destinations'\ninterface BusinessPlatformAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: BusinessPlatformScope[]\n}\n\n/**\n * It represents the authentication requirements and\n * is the input necessary to trigger the authentication\n * flow.\n */\nexport interface OAuthApplications {\n adminApi?: AdminAPIOAuthOptions\n storefrontRendererApi?: StorefrontRendererAPIOAuthOptions\n partnersApi?: PartnersAPIOAuthOptions\n businessPlatformApi?: BusinessPlatformAPIOAuthOptions\n appManagementApi?: AppManagementAPIOauthOptions\n}\n\nexport interface OAuthSession {\n admin?: AdminSession\n partners?: string\n storefront?: string\n businessPlatform?: string\n appManagement?: string\n userId: string\n}\n\ntype AuthMethod = 'partners_token' | 'device_auth' | 'theme_access_token' | 'custom_app_token' | 'none'\n\nlet userId: undefined | string\nlet authMethod: AuthMethod = 'none'\n\n/**\n * Retrieves a stable user identifier for analytics, or `'unknown'` if none applies.\n *\n * Evaluation order:\n * 1. If an app automation token or theme token is used, returns a deterministic UUID\n * derived from that secret.\n * 2. Otherwise, if `setLastSeenUserIdAfterAuth` was called (e.g. after OAuth), returns that value.\n * 3. Otherwise, if a persisted CLI session id is available, returns it.\n * 4. Otherwise returns `'unknown'`.\n *\n * @returns A Promise that resolves to the user ID as a string.\n */\nexport async function getLastSeenUserIdAfterAuth(): Promise<string> {\n const customToken = getAppAutomationToken() ?? themeToken()\n if (customToken) return nonRandomUUID(customToken)\n\n if (userId) return userId\n\n const currentSessionId = getCurrentSessionId()\n if (currentSessionId) return currentSessionId\n\n return 'unknown'\n}\n\nexport function setLastSeenUserIdAfterAuth(id: string) {\n userId = id\n}\n\n/**\n * Retrieves the last seen authentication method used in the current session.\n *\n * This function checks for the authentication method in the following order:\n * 1. Returns the cached auth method if it's not 'none'.\n * 2. Checks for a cached session, which implies 'device_auth' was used.\n * 3. Checks for a partners token in the environment.\n * 4. Checks for a theme password in the environment.\n * 5. If none of the above are true, returns 'none'.\n *\n * @returns A Promise that resolves to the last seen authentication method as an AuthMethod type.\n */\nexport async function getLastSeenAuthMethod(): Promise<AuthMethod> {\n if (authMethod !== 'none') return authMethod\n\n if (getCurrentSessionId()) return 'device_auth'\n\n const appAutomationToken = getAppAutomationToken()\n if (appAutomationToken) return 'partners_token'\n\n const themePassword = themeToken()\n if (themePassword) {\n return isThemeAccessSession({token: themePassword, storeFqdn: ''}) ? 'theme_access_token' : 'custom_app_token'\n }\n\n return 'none'\n}\n\nexport function setLastSeenAuthMethod(method: AuthMethod) {\n authMethod = method\n}\n\nexport interface EnsureAuthenticatedAdditionalOptions {\n noPrompt?: boolean\n forceRefresh?: boolean\n forceNewSession?: boolean\n}\n\n/**\n * This method ensures that we have a valid session to authenticate against the given applications using the provided scopes.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param _env - Optional environment variables to use.\n * @param options - Optional extra options to use.\n * @returns An instance with the access tokens organized by application.\n */\nexport async function ensureAuthenticated(\n applications: OAuthApplications,\n _env?: NodeJS.ProcessEnv,\n {forceRefresh = false, noPrompt = false, forceNewSession = false}: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<OAuthSession> {\n const fqdn = await identityFqdn()\n\n const previousStoreFqdn = applications.adminApi?.storeFqdn\n if (previousStoreFqdn) {\n const normalizedStoreName = normalizeStoreFqdn(previousStoreFqdn)\n if (previousStoreFqdn === applications.adminApi?.storeFqdn) {\n applications.adminApi.storeFqdn = normalizedStoreName\n }\n }\n\n const sessions = (await sessionStore.fetch()) ?? {}\n\n let currentSessionId = getCurrentSessionId()\n if (!currentSessionId) {\n const userIds = Object.keys(sessions[fqdn] ?? {})\n if (userIds.length > 0) currentSessionId = userIds[0]\n }\n const currentSession: Session | undefined =\n currentSessionId && !forceNewSession ? sessions[fqdn]?.[currentSessionId] : undefined\n const scopes = getFlattenScopes(applications)\n\n outputDebug(outputContent`Validating existing session against the scopes:\n${outputToken.json(scopes)}\nFor applications:\n${outputToken.json(applications)}\n`)\n\n const validationResult = await validateSession(scopes, applications, currentSession)\n\n let newSession = {}\n\n if (validationResult === 'needs_full_auth') {\n await throwOnNoPrompt(noPrompt)\n outputDebug(outputContent`Initiating the full authentication flow...`)\n newSession = await executeCompleteFlow(applications, currentSession?.identity.alias)\n } else if (validationResult === 'needs_refresh' || forceRefresh) {\n outputDebug(outputContent`The current session is valid but needs refresh. Refreshing...`)\n try {\n newSession = await refreshTokens(currentSession!, applications)\n } catch (error) {\n if (error instanceof InvalidGrantError) {\n await throwOnNoPrompt(noPrompt)\n newSession = await executeCompleteFlow(applications, currentSession?.identity.alias)\n } else if (error instanceof InvalidRequestError) {\n await sessionStore.remove()\n throw new AbortError('\\nError validating auth session', \"We've cleared the current session, please try again\")\n } else {\n throw error\n }\n }\n }\n\n const completeSession = {...currentSession, ...newSession} as Session\n const newSessionId = completeSession.identity.userId\n const updatedSessions: Sessions = {\n ...sessions,\n [fqdn]: {...sessions[fqdn], [newSessionId]: completeSession},\n }\n\n // Save the new session info if it has changed\n if (!isEmpty(newSession)) {\n await sessionStore.store(updatedSessions)\n setCurrentSessionId(newSessionId)\n }\n\n const tokens = await tokensFor(applications, completeSession)\n\n const envToken = getAppAutomationToken()\n if (envToken && applications.partnersApi) {\n tokens.partners = (await exchangeCustomPartnerToken(envToken)).accessToken\n }\n\n setLastSeenAuthMethod(envToken ? 'partners_token' : 'device_auth')\n setLastSeenUserIdAfterAuth(tokens.userId)\n return tokens\n}\n\nasync function throwOnNoPrompt(noPrompt: boolean) {\n if (!noPrompt) return\n await logout()\n throw new AbortError(\n `The currently available CLI credentials are invalid.\n\nThe CLI is currently unable to prompt for reauthentication.`,\n 'Restart the CLI process you were running. If in an interactive terminal, you will be prompted to reauthenticate. If in a non-interactive terminal, ensure the correct credentials are available in the program environment.',\n )\n}\n\n/**\n * Execute the full authentication flow.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param existingAlias - Optional alias from a previous session to preserve if the email fetch fails.\n */\nasync function executeCompleteFlow(applications: OAuthApplications, existingAlias?: string): Promise<Session> {\n const scopes = getFlattenScopes(applications)\n const exchangeScopes = getExchangeScopes(applications)\n const store = applications.adminApi?.storeFqdn\n if (firstPartyDev()) {\n outputDebug(outputContent`Authenticating as Shopify Employee...`)\n scopes.push('employee')\n }\n\n let identityToken: IdentityToken\n const identityTokenInformation = getIdentityTokenInformation()\n if (identityTokenInformation) {\n identityToken = buildIdentityTokenFromEnv(scopes, identityTokenInformation)\n } else {\n // Request a device code to authorize without a browser redirect.\n outputDebug(outputContent`Requesting device authorization code...`)\n const deviceAuth = await requestDeviceAuthorization(scopes)\n\n // Poll for the identity token\n outputDebug(outputContent`Starting polling for the identity token...`)\n identityToken = await pollForDeviceAuthorization(deviceAuth.deviceCode, deviceAuth.interval)\n }\n\n // Exchange identity token for application tokens\n outputDebug(outputContent`CLI token received. Exchanging it for application tokens...`)\n const result = await exchangeAccessForApplicationTokens(identityToken, exchangeScopes, store)\n\n // Preserve existing alias if available, otherwise try fetching email\n const businessPlatformToken = result[applicationId('business-platform')]?.accessToken\n const alias = existingAlias ?? (await fetchEmail(businessPlatformToken)) ?? identityToken.userId\n\n const session: Session = {\n identity: {\n ...identityToken,\n alias,\n },\n applications: result,\n }\n\n outputCompleted(`Logged in.`)\n\n return session\n}\n\n/**\n * Refresh the tokens for a given session.\n *\n * @param session - The session to refresh.\n */\nasync function refreshTokens(session: Session, applications: OAuthApplications): Promise<Session> {\n // Refresh Identity Token\n const identityToken = await refreshAccessToken(session.identity)\n // Exchange new identity token for application tokens\n const exchangeScopes = getExchangeScopes(applications)\n const applicationTokens = await exchangeAccessForApplicationTokens(\n identityToken,\n exchangeScopes,\n applications.adminApi?.storeFqdn,\n )\n\n return {\n identity: {...identityToken, alias: session.identity.alias},\n applications: applicationTokens,\n }\n}\n\n/**\n * Get the application tokens for a given session.\n *\n * @param applications - An object containing the applications we need the tokens for.\n * @param session - The current session.\n * @param fqdn - The identity FQDN.\n */\nasync function tokensFor(applications: OAuthApplications, session: Session): Promise<OAuthSession> {\n const tokens: OAuthSession = {\n userId: session.identity.userId,\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]?.accessToken\n if (token) {\n tokens.admin = {token, storeFqdn: applications.adminApi.storeFqdn}\n }\n }\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n tokens.partners = session.applications[appId]?.accessToken\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n tokens.storefront = session.applications[appId]?.accessToken\n }\n\n if (applications.businessPlatformApi) {\n const appId = applicationId('business-platform')\n tokens.businessPlatform = session.applications[appId]?.accessToken\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n tokens.appManagement = session.applications[appId]?.accessToken\n }\n\n return tokens\n}\n\n// Scope Helpers\n/**\n * Get a flattened array of scopes for the given applications.\n *\n * @param apps - An object containing the applications we need the scopes for.\n * @returns A flattened array of scopes.\n */\nfunction getFlattenScopes(apps: OAuthApplications): string[] {\n const admin = apps.adminApi?.scopes ?? []\n const partner = apps.partnersApi?.scopes ?? []\n const storefront = apps.storefrontRendererApi?.scopes ?? []\n const businessPlatform = apps.businessPlatformApi?.scopes ?? []\n const appManagement = apps.appManagementApi?.scopes ?? []\n const requestedScopes = [...admin, ...partner, ...storefront, ...businessPlatform, ...appManagement]\n return allDefaultScopes(requestedScopes)\n}\n\n/**\n * Get the scopes for the given applications.\n *\n * @param apps - An object containing the applications we need the scopes for.\n * @returns An object containing the scopes for each application.\n */\nfunction getExchangeScopes(apps: OAuthApplications): ExchangeScopes {\n const adminScope = apps.adminApi?.scopes ?? []\n const partnerScope = apps.partnersApi?.scopes ?? []\n const storefrontScopes = apps.storefrontRendererApi?.scopes ?? []\n const businessPlatformScopes = apps.businessPlatformApi?.scopes ?? []\n const appManagementScopes = apps.appManagementApi?.scopes ?? []\n return {\n admin: apiScopes('admin', adminScope),\n partners: apiScopes('partners', partnerScope),\n storefront: apiScopes('storefront-renderer', storefrontScopes),\n businessPlatform: apiScopes('business-platform', businessPlatformScopes),\n appManagement: apiScopes('app-management', appManagementScopes),\n }\n}\n\nfunction buildIdentityTokenFromEnv(\n scopes: string[],\n identityTokenInformation: {accessToken: string; refreshToken: string; userId: string},\n) {\n return {\n ...identityTokenInformation,\n expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),\n scopes,\n alias: undefined,\n }\n}\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/private/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {applicationId} from './session/identity.js'\nimport {validateSession} from './session/validate.js'\nimport {allDefaultScopes, apiScopes} from './session/scopes.js'\nimport {\n exchangeAccessForApplicationTokens,\n exchangeCustomPartnerToken,\n ExchangeScopes,\n refreshAccessToken,\n InvalidGrantError,\n InvalidRequestError,\n} from './session/exchange.js'\nimport {IdentityToken, Session, Sessions} from './session/schema.js'\nimport * as sessionStore from './session/store.js'\nimport {pollForDeviceAuthorization, requestDeviceAuthorization} from './session/device-authorization.js'\nimport {isThemeAccessSession} from './api/rest.js'\nimport {getCurrentSessionId, setCurrentSessionId} from './conf-store.js'\nimport {UserEmailQueryString, UserEmailQuery} from './api/graphql/business-platform-destinations/user-email.js'\nimport {outputContent, outputToken, outputDebug, outputCompleted} from '../../public/node/output.js'\nimport {themeToken} from '../../public/node/context/local.js'\nimport {AbortError} from '../../public/node/error.js'\nimport {normalizeStoreFqdn, identityFqdn} from '../../public/node/context/fqdn.js'\nimport {getIdentityTokenInformation, getAppAutomationToken} from '../../public/node/environment.js'\nimport {AdminSession, logout} from '../../public/node/session.js'\nimport {nonRandomUUID} from '../../public/node/crypto.js'\nimport {isEmpty} from '../../public/common/object.js'\nimport {businessPlatformRequest} from '../../public/node/api/business-platform.js'\n\n/**\n * Fetches the user's email from the Business Platform API\n * @param businessPlatformToken - The business platform token\n * @returns The user's email address or undefined if not found\n */\nasync function fetchEmail(businessPlatformToken: string | undefined): Promise<string | undefined> {\n if (!businessPlatformToken) return undefined\n\n try {\n const userEmailResult = await businessPlatformRequest<UserEmailQuery>(UserEmailQueryString, businessPlatformToken)\n return userEmailResult.currentUserAccount?.email ?? undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n outputDebug(outputContent`Failed to fetch user email: ${(error as Error).message ?? String(error)}`)\n return undefined\n }\n}\n\n/**\n * A scope supported by the Shopify Admin API.\n */\nexport type AdminAPIScope = 'graphql' | 'themes' | 'collaborator'\n\n/**\n * It represents the options to authenticate against the Shopify Admin API.\n */\n\ninterface AdminAPIOAuthOptions {\n /** Store to request permissions for. */\n storeFqdn: string\n /** List of scopes to request permissions for. */\n scopes: AdminAPIScope[]\n}\n\n/**\n * A scope supported by the Partners API.\n */\nexport type PartnersAPIScope = 'cli'\ninterface PartnersAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: PartnersAPIScope[]\n}\n\n/**\n * A scope supported by the Developer Platform API.\n */\nexport type AppManagementAPIScope = 'https://api.shopify.com/auth/organization.apps.manage'\ninterface AppManagementAPIOauthOptions {\n /** List of scopes to request permissions for. */\n scopes: AppManagementAPIScope[]\n}\n\n/**\n * A scope supported by the Storefront Renderer API.\n */\nexport type StorefrontRendererScope = 'devtools' | 'graphql'\ninterface StorefrontRendererAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: StorefrontRendererScope[]\n}\n\nexport type BusinessPlatformScope = 'destinations'\ninterface BusinessPlatformAPIOAuthOptions {\n /** List of scopes to request permissions for. */\n scopes: BusinessPlatformScope[]\n}\n\n/**\n * It represents the authentication requirements and\n * is the input necessary to trigger the authentication\n * flow.\n */\nexport interface OAuthApplications {\n adminApi?: AdminAPIOAuthOptions\n storefrontRendererApi?: StorefrontRendererAPIOAuthOptions\n partnersApi?: PartnersAPIOAuthOptions\n businessPlatformApi?: BusinessPlatformAPIOAuthOptions\n appManagementApi?: AppManagementAPIOauthOptions\n}\n\nexport interface OAuthSession {\n admin?: AdminSession\n partners?: string\n storefront?: string\n businessPlatform?: string\n appManagement?: string\n userId: string\n}\n\ntype AuthMethod = 'partners_token' | 'device_auth' | 'theme_access_token' | 'custom_app_token' | 'none'\n\nlet userId: undefined | string\nlet authMethod: AuthMethod = 'none'\nlet commandSessionId: string | undefined\n\n/**\n * Retrieves a stable user identifier for analytics, or `'unknown'` if none applies.\n *\n * Evaluation order:\n * 1. If an app automation token or theme token is used, returns a deterministic UUID\n * derived from that secret.\n * 2. Otherwise, if `setLastSeenUserIdAfterAuth` was called (e.g. after OAuth), returns that value.\n * 3. Otherwise, if a persisted CLI session id is available, returns it.\n * 4. Otherwise returns `'unknown'`.\n *\n * @returns A Promise that resolves to the user ID as a string.\n */\nexport async function getLastSeenUserIdAfterAuth(): Promise<string> {\n const customToken = getAppAutomationToken() ?? themeToken()\n if (customToken) return nonRandomUUID(customToken)\n\n if (userId) return userId\n\n const currentSessionId = getCurrentSessionId()\n if (currentSessionId) return currentSessionId\n\n return 'unknown'\n}\n\nexport function setLastSeenUserIdAfterAuth(id: string) {\n userId = id\n}\n\n/**\n * Retrieves the last seen authentication method used in the current session.\n *\n * This function checks for the authentication method in the following order:\n * 1. Returns the cached auth method if it's not 'none'.\n * 2. Checks for a cached session, which implies 'device_auth' was used.\n * 3. Checks for a partners token in the environment.\n * 4. Checks for a theme password in the environment.\n * 5. If none of the above are true, returns 'none'.\n *\n * @returns A Promise that resolves to the last seen authentication method as an AuthMethod type.\n */\nexport async function getLastSeenAuthMethod(): Promise<AuthMethod> {\n if (authMethod !== 'none') return authMethod\n\n if (getCurrentSessionId()) return 'device_auth'\n\n const appAutomationToken = getAppAutomationToken()\n if (appAutomationToken) return 'partners_token'\n\n const themePassword = themeToken()\n if (themePassword) {\n return isThemeAccessSession({token: themePassword, storeFqdn: ''}) ? 'theme_access_token' : 'custom_app_token'\n }\n\n return 'none'\n}\n\nexport function setLastSeenAuthMethod(method: AuthMethod) {\n authMethod = method\n}\n\nexport function setCommandSessionId(sessionId: string | undefined) {\n commandSessionId = sessionId\n}\n\nexport interface EnsureAuthenticatedAdditionalOptions {\n noPrompt?: boolean\n forceRefresh?: boolean\n forceNewSession?: boolean\n}\n\n/**\n * This method ensures that we have a valid session to authenticate against the given applications using the provided scopes.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param _env - Optional environment variables to use.\n * @param options - Optional extra options to use.\n * @returns An instance with the access tokens organized by application.\n */\nexport async function ensureAuthenticated(\n applications: OAuthApplications,\n _env?: NodeJS.ProcessEnv,\n {forceRefresh = false, noPrompt = false, forceNewSession = false}: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<OAuthSession> {\n const fqdn = await identityFqdn()\n\n const previousStoreFqdn = applications.adminApi?.storeFqdn\n if (previousStoreFqdn) {\n const normalizedStoreName = normalizeStoreFqdn(previousStoreFqdn)\n if (previousStoreFqdn === applications.adminApi?.storeFqdn) {\n applications.adminApi.storeFqdn = normalizedStoreName\n }\n }\n\n const sessions = (await sessionStore.fetch()) ?? {}\n\n let currentSessionId = forceNewSession ? undefined : (commandSessionId ?? getCurrentSessionId())\n if (!currentSessionId && !commandSessionId) {\n const userIds = Object.keys(sessions[fqdn] ?? {})\n if (userIds.length > 0) currentSessionId = userIds[0]\n }\n const currentSession: Session | undefined =\n currentSessionId && !forceNewSession ? sessions[fqdn]?.[currentSessionId] : undefined\n const scopes = getFlattenScopes(applications)\n\n outputDebug(outputContent`Validating existing session against the scopes:\n${outputToken.json(scopes)}\nFor applications:\n${outputToken.json(applications)}\n`)\n\n const validationResult = await validateSession(scopes, applications, currentSession)\n\n let newSession = {}\n\n if (validationResult === 'needs_full_auth') {\n await throwOnNoPrompt(noPrompt)\n outputDebug(outputContent`Initiating the full authentication flow...`)\n newSession = await executeCompleteFlow(applications, currentSession?.identity.alias)\n } else if (validationResult === 'needs_refresh' || forceRefresh) {\n outputDebug(outputContent`The current session is valid but needs refresh. Refreshing...`)\n try {\n newSession = await refreshTokens(currentSession!, applications)\n } catch (error) {\n if (error instanceof InvalidGrantError) {\n await throwOnNoPrompt(noPrompt)\n newSession = await executeCompleteFlow(applications, currentSession?.identity.alias)\n } else if (error instanceof InvalidRequestError) {\n await sessionStore.remove()\n throw new AbortError('\\nError validating auth session', \"We've cleared the current session, please try again\")\n } else {\n throw error\n }\n }\n }\n\n const completeSession = {...currentSession, ...newSession} as Session\n const newSessionId = completeSession.identity.userId\n const updatedSessions: Sessions = {\n ...sessions,\n [fqdn]: {...sessions[fqdn], [newSessionId]: completeSession},\n }\n\n // Save the new session info if it has changed\n if (!isEmpty(newSession)) {\n await sessionStore.store(updatedSessions)\n if (!commandSessionId) setCurrentSessionId(newSessionId)\n }\n\n const tokens = await tokensFor(applications, completeSession)\n\n const envToken = getAppAutomationToken()\n if (envToken && applications.partnersApi) {\n tokens.partners = (await exchangeCustomPartnerToken(envToken)).accessToken\n }\n\n setLastSeenAuthMethod(envToken ? 'partners_token' : 'device_auth')\n setLastSeenUserIdAfterAuth(tokens.userId)\n return tokens\n}\n\nasync function throwOnNoPrompt(noPrompt: boolean) {\n if (!noPrompt) return\n await logout()\n throw new AbortError(\n `The currently available CLI credentials are invalid.\n\nThe CLI is currently unable to prompt for reauthentication.`,\n 'Restart the CLI process you were running. If in an interactive terminal, you will be prompted to reauthenticate. If in a non-interactive terminal, ensure the correct credentials are available in the program environment.',\n )\n}\n\n/**\n * Execute the full authentication flow.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param existingAlias - Optional alias from a previous session to preserve if the email fetch fails.\n */\nasync function executeCompleteFlow(applications: OAuthApplications, existingAlias?: string): Promise<Session> {\n const scopes = getFlattenScopes(applications)\n const exchangeScopes = getExchangeScopes(applications)\n const store = applications.adminApi?.storeFqdn\n\n let identityToken: IdentityToken\n const identityTokenInformation = getIdentityTokenInformation()\n if (identityTokenInformation) {\n identityToken = buildIdentityTokenFromEnv(scopes, identityTokenInformation)\n } else {\n // Request a device code to authorize without a browser redirect.\n outputDebug(outputContent`Requesting device authorization code...`)\n const deviceAuth = await requestDeviceAuthorization(scopes)\n\n // Poll for the identity token\n outputDebug(outputContent`Starting polling for the identity token...`)\n identityToken = await pollForDeviceAuthorization(deviceAuth.deviceCode, deviceAuth.interval)\n }\n\n // Exchange identity token for application tokens\n outputDebug(outputContent`CLI token received. Exchanging it for application tokens...`)\n const result = await exchangeAccessForApplicationTokens(identityToken, exchangeScopes, store)\n\n // Preserve existing alias if available, otherwise try fetching email\n const businessPlatformToken = result[applicationId('business-platform')]?.accessToken\n const alias = existingAlias ?? (await fetchEmail(businessPlatformToken)) ?? identityToken.userId\n\n const session: Session = {\n identity: {\n ...identityToken,\n alias,\n },\n applications: result,\n }\n\n outputCompleted(`Logged in.`)\n\n return session\n}\n\n/**\n * Refresh the tokens for a given session.\n *\n * @param session - The session to refresh.\n */\nasync function refreshTokens(session: Session, applications: OAuthApplications): Promise<Session> {\n // Refresh Identity Token\n const identityToken = await refreshAccessToken(session.identity)\n // Exchange new identity token for application tokens\n const exchangeScopes = getExchangeScopes(applications)\n const applicationTokens = await exchangeAccessForApplicationTokens(\n identityToken,\n exchangeScopes,\n applications.adminApi?.storeFqdn,\n )\n\n return {\n identity: {...identityToken, alias: session.identity.alias},\n applications: applicationTokens,\n }\n}\n\n/**\n * Get the application tokens for a given session.\n *\n * @param applications - An object containing the applications we need the tokens for.\n * @param session - The current session.\n * @param fqdn - The identity FQDN.\n */\nasync function tokensFor(applications: OAuthApplications, session: Session): Promise<OAuthSession> {\n const tokens: OAuthSession = {\n userId: session.identity.userId,\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]?.accessToken\n if (token) {\n tokens.admin = {token, storeFqdn: applications.adminApi.storeFqdn}\n }\n }\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n tokens.partners = session.applications[appId]?.accessToken\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n tokens.storefront = session.applications[appId]?.accessToken\n }\n\n if (applications.businessPlatformApi) {\n const appId = applicationId('business-platform')\n tokens.businessPlatform = session.applications[appId]?.accessToken\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n tokens.appManagement = session.applications[appId]?.accessToken\n }\n\n return tokens\n}\n\n// Scope Helpers\n/**\n * Get a flattened array of scopes for the given applications.\n *\n * @param apps - An object containing the applications we need the scopes for.\n * @returns A flattened array of scopes.\n */\nfunction getFlattenScopes(apps: OAuthApplications): string[] {\n const admin = apps.adminApi?.scopes ?? []\n const partner = apps.partnersApi?.scopes ?? []\n const storefront = apps.storefrontRendererApi?.scopes ?? []\n const businessPlatform = apps.businessPlatformApi?.scopes ?? []\n const appManagement = apps.appManagementApi?.scopes ?? []\n const requestedScopes = [...admin, ...partner, ...storefront, ...businessPlatform, ...appManagement]\n return allDefaultScopes(requestedScopes)\n}\n\n/**\n * Get the scopes for the given applications.\n *\n * @param apps - An object containing the applications we need the scopes for.\n * @returns An object containing the scopes for each application.\n */\nfunction getExchangeScopes(apps: OAuthApplications): ExchangeScopes {\n const adminScope = apps.adminApi?.scopes ?? []\n const partnerScope = apps.partnersApi?.scopes ?? []\n const storefrontScopes = apps.storefrontRendererApi?.scopes ?? []\n const businessPlatformScopes = apps.businessPlatformApi?.scopes ?? []\n const appManagementScopes = apps.appManagementApi?.scopes ?? []\n return {\n admin: apiScopes('admin', adminScope),\n partners: apiScopes('partners', partnerScope),\n storefront: apiScopes('storefront-renderer', storefrontScopes),\n businessPlatform: apiScopes('business-platform', businessPlatformScopes),\n appManagement: apiScopes('app-management', appManagementScopes),\n }\n}\n\nfunction buildIdentityTokenFromEnv(\n scopes: string[],\n identityTokenInformation: {accessToken: string; refreshToken: string; userId: string},\n) {\n return {\n ...identityTokenInformation,\n expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),\n scopes,\n alias: undefined,\n }\n}\n"]}
@@ -38,6 +38,14 @@ export declare function mapValues<T extends object, TResult>(source: T | null |
38
38
  * @returns True if the objects are equal, false otherwise.
39
39
  */
40
40
  export declare function deepCompare(one: object, two: object): boolean;
41
+ /**
42
+ * Deeply compares two values and treats arrays as order-insensitive.
43
+ *
44
+ * @param one - The first value to be compared.
45
+ * @param two - The second value to be compared.
46
+ * @returns True if the normalized values are equal, false otherwise.
47
+ */
48
+ export declare function deepCompareWithOrderInsensitiveArrays(one: unknown, two: unknown): boolean;
41
49
  /**
42
50
  * Return the difference between two nested objects.
43
51
  *
@@ -55,6 +55,30 @@ export function mapValues(source, callback) {
55
55
  export function deepCompare(one, two) {
56
56
  return lodashIsEqual(one, two);
57
57
  }
58
+ /**
59
+ * Deeply compares two values and treats arrays as order-insensitive.
60
+ *
61
+ * @param one - The first value to be compared.
62
+ * @param two - The second value to be compared.
63
+ * @returns True if the normalized values are equal, false otherwise.
64
+ */
65
+ export function deepCompareWithOrderInsensitiveArrays(one, two) {
66
+ return lodashIsEqual(normalizeOrderInsensitiveArrays(one), normalizeOrderInsensitiveArrays(two));
67
+ }
68
+ function normalizeOrderInsensitiveArrays(value) {
69
+ if (Array.isArray(value)) {
70
+ return value.map(normalizeOrderInsensitiveArrays).sort(compareNormalizedValues);
71
+ }
72
+ if (value && typeof value === 'object') {
73
+ return Object.fromEntries(Object.entries(value)
74
+ .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
75
+ .map(([key, nestedValue]) => [key, normalizeOrderInsensitiveArrays(nestedValue)]));
76
+ }
77
+ return value ?? {};
78
+ }
79
+ function compareNormalizedValues(left, right) {
80
+ return JSON.stringify(left).localeCompare(JSON.stringify(right));
81
+ }
58
82
  /**
59
83
  * Return the difference between two nested objects.
60
84
  *
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/public/common/object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,+BAA+B,CAAA;AAChE,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAC3C,OAAO,eAAe,MAAM,qBAAqB,CAAA;AACjD,OAAO,aAAa,MAAM,mBAAmB,CAAA;AAC7C,OAAO,cAAc,MAAM,0BAA0B,CAAA;AACrD,OAAO,SAAS,MAAM,qBAAqB,CAAA;AAC3C,OAAO,OAAO,MAAM,mBAAmB,CAAA;AACvC,OAAO,GAAG,MAAM,eAAe,CAAA;AAC/B,OAAO,GAAG,MAAM,eAAe,CAAA;AAC/B,OAAO,KAAK,MAAM,iBAAiB,CAAA;AACnC,OAAO,aAAa,MAAM,mBAAmB,CAAA;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAgB,EAChB,GAAgB,EAChB,qBAAyF,kBAAkB;IAE3G,OAAO,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAI,MAAwC,EAAE,SAA8B;IAChG,OAAO,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AACxC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,MAA4B,EAC5B,QAAoC;IAEpC,OAAO,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,GAAW;IAClD,OAAO,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,GAAW;IACrD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAA;IACvE,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAA;IACxE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAa,MAAc,EAAE,IAAkB;IACzE,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAO,CAAA;AAC/E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAkB,EAAE,KAAe;IAC9E,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,IAAkB;IAC/D,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,OAAO,aAAa,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAA;AACzF,CAAC","sourcesContent":["import {unionArrayStrategy} from '../../private/common/array.js'\nimport deepMerge from 'deepmerge'\nimport {Dictionary, ObjectIterator, PropertyPath, ValueKeyIteratee} from 'lodash'\nimport lodashPickBy from 'lodash/pickBy.js'\nimport lodashMapValues from 'lodash/mapValues.js'\nimport lodashIsEqual from 'lodash/isEqual.js'\nimport differenceWith from 'lodash/differenceWith.js'\nimport fromPairs from 'lodash/fromPairs.js'\nimport toPairs from 'lodash/toPairs.js'\nimport get from 'lodash/get.js'\nimport set from 'lodash/set.js'\nimport unset from 'lodash/unset.js'\nimport lodashIsEmpty from 'lodash/isEmpty.js'\n\n/**\n * Deep merges the two objects and returns a new object with the merge result.\n *\n * @param lhs - One of the objects to be merged.\n * @param rhs - Another object to be merged.\n * @param arrayMergeStrategy - Strategy used to merge the array typed fields. Union strategy is used by default to avoid\n * duplicated elements.\n * @returns A Javascrip tobject with th emerged objects.\n */\nexport function deepMergeObjects<T1, T2>(\n lhs: Partial<T1>,\n rhs: Partial<T2>,\n arrayMergeStrategy: (destinationArray: unknown[], sourceArray: unknown[]) => unknown[] = unionArrayStrategy,\n): T1 & T2 {\n return deepMerge(lhs, rhs, {arrayMerge: arrayMergeStrategy})\n}\n\n/**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @param object - The source object.\n * @param predicate - The function invoked per property.\n * @returns Returns the new object.\n */\nexport function pickBy<T>(object: Dictionary<T> | null | undefined, predicate: ValueKeyIteratee<T>): Dictionary<T> {\n return lodashPickBy(object, predicate)\n}\n\n/**\n * Creates an object with the same keys as object and values generated by running each own\n * enumerable property of object through iteratee. The iteratee function is\n * invoked with three arguments: (value, key, object).\n *\n * @param source - The object to iterate over.\n * @param callback - The function invoked per iteration.\n * @returns Returns the new mapped object.\n */\nexport function mapValues<T extends object, TResult>(\n source: T | null | undefined,\n callback: ObjectIterator<T, TResult>,\n): {[P in keyof T]: TResult} {\n return lodashMapValues(source, callback)\n}\n\n/**\n * Deeply compares two objects and returns true if they are equal.\n *\n * @param one - The first object to be compared.\n * @param two - The second object to be compared.\n * @returns True if the objects are equal, false otherwise.\n */\nexport function deepCompare(one: object, two: object): boolean {\n return lodashIsEqual(one, two)\n}\n\n/**\n * Return the difference between two nested objects.\n *\n * @param one - The first object to be compared.\n * @param two - The second object to be compared.\n * @returns Two objects containing the fields that are different, each one with the values of one object.\n */\nexport function deepDifference(one: object, two: object): [object, object] {\n const changes = differenceWith(toPairs(one), toPairs(two), deepCompare)\n const changes2 = differenceWith(toPairs(two), toPairs(one), deepCompare)\n return [fromPairs(changes), fromPairs(changes2)]\n}\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns - Returns the resolved value.\n */\nexport function getPathValue<T = object>(object: object, path: PropertyPath): T | undefined {\n return get(object, path) === undefined ? undefined : (get(object, path) as T)\n}\n\n/**\n * Sets the value at path of object. If a portion of path doesn't exist, it's create.\n *\n * @param object - The object to modify.\n * @param path - The path of the property to set.\n * @param value - The value to set.\n * @returns - Returns object.\n */\nexport function setPathValue(object: object, path: PropertyPath, value?: unknown): object {\n return set(object, path, value)\n}\n\n/**\n * Removes the property at path of object.\n *\n * @param object - The object to modify.\n * @param path - The path of the property to unset.\n * @returns - Returns true if the property is deleted or not found, else false.\n */\nexport function unsetPathValue(object: object, path: PropertyPath): boolean {\n return unset(object, path)\n}\n\n/**\n * Checks if value is an empty object, collection, map, or set.\n *\n * @param object - The value to check.\n * @returns - Returns true if value is empty, else false.\n */\nexport function isEmpty(object: object): boolean {\n return lodashIsEmpty(object)\n}\n\n/**\n * Removes the undefined elements.\n *\n * @param object - The object whose undefined will be deleted.\n * @returns A copy of the object with the undefined elements deleted.\n */\nexport function compact(object: object): object {\n return Object.fromEntries(Object.entries(object).filter(([_, value]) => value != null))\n}\n"]}
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/public/common/object.ts"],"names":[],"mappings":"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","sourcesContent":["import {unionArrayStrategy} from '../../private/common/array.js'\nimport deepMerge from 'deepmerge'\nimport {Dictionary, ObjectIterator, PropertyPath, ValueKeyIteratee} from 'lodash'\nimport lodashPickBy from 'lodash/pickBy.js'\nimport lodashMapValues from 'lodash/mapValues.js'\nimport lodashIsEqual from 'lodash/isEqual.js'\nimport differenceWith from 'lodash/differenceWith.js'\nimport fromPairs from 'lodash/fromPairs.js'\nimport toPairs from 'lodash/toPairs.js'\nimport get from 'lodash/get.js'\nimport set from 'lodash/set.js'\nimport unset from 'lodash/unset.js'\nimport lodashIsEmpty from 'lodash/isEmpty.js'\n\n/**\n * Deep merges the two objects and returns a new object with the merge result.\n *\n * @param lhs - One of the objects to be merged.\n * @param rhs - Another object to be merged.\n * @param arrayMergeStrategy - Strategy used to merge the array typed fields. Union strategy is used by default to avoid\n * duplicated elements.\n * @returns A Javascrip tobject with th emerged objects.\n */\nexport function deepMergeObjects<T1, T2>(\n lhs: Partial<T1>,\n rhs: Partial<T2>,\n arrayMergeStrategy: (destinationArray: unknown[], sourceArray: unknown[]) => unknown[] = unionArrayStrategy,\n): T1 & T2 {\n return deepMerge(lhs, rhs, {arrayMerge: arrayMergeStrategy})\n}\n\n/**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @param object - The source object.\n * @param predicate - The function invoked per property.\n * @returns Returns the new object.\n */\nexport function pickBy<T>(object: Dictionary<T> | null | undefined, predicate: ValueKeyIteratee<T>): Dictionary<T> {\n return lodashPickBy(object, predicate)\n}\n\n/**\n * Creates an object with the same keys as object and values generated by running each own\n * enumerable property of object through iteratee. The iteratee function is\n * invoked with three arguments: (value, key, object).\n *\n * @param source - The object to iterate over.\n * @param callback - The function invoked per iteration.\n * @returns Returns the new mapped object.\n */\nexport function mapValues<T extends object, TResult>(\n source: T | null | undefined,\n callback: ObjectIterator<T, TResult>,\n): {[P in keyof T]: TResult} {\n return lodashMapValues(source, callback)\n}\n\n/**\n * Deeply compares two objects and returns true if they are equal.\n *\n * @param one - The first object to be compared.\n * @param two - The second object to be compared.\n * @returns True if the objects are equal, false otherwise.\n */\nexport function deepCompare(one: object, two: object): boolean {\n return lodashIsEqual(one, two)\n}\n\n/**\n * Deeply compares two values and treats arrays as order-insensitive.\n *\n * @param one - The first value to be compared.\n * @param two - The second value to be compared.\n * @returns True if the normalized values are equal, false otherwise.\n */\nexport function deepCompareWithOrderInsensitiveArrays(one: unknown, two: unknown): boolean {\n return lodashIsEqual(normalizeOrderInsensitiveArrays(one), normalizeOrderInsensitiveArrays(two))\n}\n\nfunction normalizeOrderInsensitiveArrays(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(normalizeOrderInsensitiveArrays).sort(compareNormalizedValues)\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value)\n .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))\n .map(([key, nestedValue]) => [key, normalizeOrderInsensitiveArrays(nestedValue)]),\n )\n }\n\n return value ?? {}\n}\n\nfunction compareNormalizedValues(left: unknown, right: unknown) {\n return JSON.stringify(left).localeCompare(JSON.stringify(right))\n}\n\n/**\n * Return the difference between two nested objects.\n *\n * @param one - The first object to be compared.\n * @param two - The second object to be compared.\n * @returns Two objects containing the fields that are different, each one with the values of one object.\n */\nexport function deepDifference(one: object, two: object): [object, object] {\n const changes = differenceWith(toPairs(one), toPairs(two), deepCompare)\n const changes2 = differenceWith(toPairs(two), toPairs(one), deepCompare)\n return [fromPairs(changes), fromPairs(changes2)]\n}\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns - Returns the resolved value.\n */\nexport function getPathValue<T = object>(object: object, path: PropertyPath): T | undefined {\n return get(object, path) === undefined ? undefined : (get(object, path) as T)\n}\n\n/**\n * Sets the value at path of object. If a portion of path doesn't exist, it's create.\n *\n * @param object - The object to modify.\n * @param path - The path of the property to set.\n * @param value - The value to set.\n * @returns - Returns object.\n */\nexport function setPathValue(object: object, path: PropertyPath, value?: unknown): object {\n return set(object, path, value)\n}\n\n/**\n * Removes the property at path of object.\n *\n * @param object - The object to modify.\n * @param path - The path of the property to unset.\n * @returns - Returns true if the property is deleted or not found, else false.\n */\nexport function unsetPathValue(object: object, path: PropertyPath): boolean {\n return unset(object, path)\n}\n\n/**\n * Checks if value is an empty object, collection, map, or set.\n *\n * @param object - The value to check.\n * @returns - Returns true if value is empty, else false.\n */\nexport function isEmpty(object: object): boolean {\n return lodashIsEmpty(object)\n}\n\n/**\n * Removes the undefined elements.\n *\n * @param object - The object whose undefined will be deleted.\n * @returns A copy of the object with the undefined elements deleted.\n */\nexport function compact(object: object): object {\n return Object.fromEntries(Object.entries(object).filter(([_, value]) => value != null))\n}\n"]}
@@ -1 +1 @@
1
- export declare const CLI_KIT_VERSION = "4.5.1";
1
+ export declare const CLI_KIT_VERSION = "4.6.0";
@@ -1,2 +1,2 @@
1
- export const CLI_KIT_VERSION = '4.5.1';
1
+ export const CLI_KIT_VERSION = '4.6.0';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '4.5.1'\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '4.6.0'\n"]}
@@ -151,7 +151,10 @@ async function buildPayload({ config, errorMessage, exitMode }) {
151
151
  function sanitizePayload(payload) {
152
152
  const payloadString = JSON.stringify(payload);
153
153
  // Remove Theme Access passwords from the payload
154
- const sanitizedPayloadString = payloadString.replace(/shptka_\w*/g, '*****');
154
+ const sanitizedPayloadString = payloadString
155
+ .replace(/shptka_\w*/g, '*****')
156
+ .replace(/(--store-password(?:=|\s+))(?:"[^"]*"|'[^']*'|[^\s"]+)/g, '$1*****')
157
+ .replace(/((?:store-password|SHOPIFY_FLAG_STORE_PASSWORD)\\?":\\?")[^"\\]*/g, '$1*****');
155
158
  return JSON.parse(sanitizedPayloadString);
156
159
  }
157
160
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/public/node/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import {alwaysLogAnalytics, alwaysLogMetrics, analyticsDisabled, isShopify} from './context/local.js'\nimport * as metadata from './metadata.js'\nimport {publishMonorailEvent, MONORAIL_COMMAND_TOPIC} from './monorail.js'\nimport {fanoutHooks} from './plugins.js'\nimport {sendErrorToBugsnag} from './error-handler.js'\nimport {outputContent, outputDebug, outputToken} from './output.js'\nimport {\n recordTiming as storageRecordTiming,\n recordError as storageRecordError,\n recordRetry as storageRecordRetry,\n recordEvent as storageRecordEvent,\n compileData as storageCompileData,\n RuntimeData,\n} from '../../private/node/analytics/storage.js'\nimport {getEnvironmentData, getSensitiveEnvironmentData} from '../../private/node/analytics.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {recordMetrics} from '../../private/node/otel-metrics.js'\nimport {runWithRateLimit} from '../../private/node/conf-store.js'\nimport {reportingRateLimit} from '../../private/node/constants.js'\nimport {getLastSeenUserIdAfterAuth} from '../../private/node/session.js'\nimport {requestIdsCollection} from '../../private/node/request-ids.js'\n\nimport {Interfaces} from '@oclif/core'\n\nexport type CommandExitMode =\n // The command completed successfully\n | 'ok'\n // The command exited for some unexpected reason -- i.e. a bug\n | 'unexpected_error'\n // The command exited with an error, but its one we expect and doesn't point to a bug -- i.e. malformed config files\n | 'expected_error'\n\ninterface ReportAnalyticsEventOptions {\n config: Interfaces.Config\n errorMessage?: string\n exitMode: CommandExitMode\n}\n\n/**\n * Report an analytics event, sending it off to Monorail -- Shopify's internal analytics service.\n *\n * The payload for an event includes both generic data, and data gathered from installed plug-ins.\n *\n */\nexport async function reportAnalyticsEvent(options: ReportAnalyticsEventOptions): Promise<void> {\n try {\n const payload = await buildPayload(options)\n if (payload === undefined) {\n // Nothing to log\n return\n }\n\n let withinRateLimit = false\n await runWithRateLimit({\n key: 'report-analytics-event',\n ...reportingRateLimit,\n task: async () => {\n withinRateLimit = true\n },\n })\n if (!withinRateLimit) {\n outputDebug(outputContent`Skipping command analytics due to rate limiting, payload: ${outputToken.json(payload)}`)\n return\n }\n\n const skipMonorailAnalytics = !alwaysLogAnalytics() && analyticsDisabled()\n const skipMetricAnalytics = !alwaysLogMetrics() && analyticsDisabled()\n if (skipMonorailAnalytics || skipMetricAnalytics) {\n outputDebug(outputContent`Skipping command analytics, payload: ${outputToken.json(payload)}`)\n }\n\n const doMonorail = async () => {\n if (skipMonorailAnalytics) {\n return\n }\n const response = await publishMonorailEvent(MONORAIL_COMMAND_TOPIC, payload.public, payload.sensitive)\n if (response.type === 'error') {\n outputDebug(response.message)\n }\n }\n const doOpenTelemetry = async () => {\n const active = payload.public.cmd_all_timing_active_ms ?? 0\n const network = payload.public.cmd_all_timing_network_ms ?? 0\n const prompt = payload.public.cmd_all_timing_prompts_ms ?? 0\n\n return recordMetrics(\n {\n skipMetricAnalytics,\n cliVersion: payload.public.cli_version,\n owningPlugin: payload.public.cmd_all_plugin ?? '@shopify/cli',\n command: payload.public.command,\n exitMode: options.exitMode,\n },\n {\n active,\n network,\n prompt,\n },\n )\n }\n await Promise.all([doMonorail(), doOpenTelemetry()])\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n outputDebug(message)\n await sendErrorToBugsnag(error, 'expected_error')\n }\n}\n\nasync function buildPayload({config, errorMessage, exitMode}: ReportAnalyticsEventOptions) {\n const {commandStartOptions, environmentFlags, ...sensitiveMetadata} = metadata.getAllSensitiveMetadata()\n if (commandStartOptions === undefined) {\n outputDebug('Unable to log analytics event - no information on executed command')\n return\n }\n const {startCommand, startArgs, startTime, endTime} = commandStartOptions\n const currentTime = endTime ?? new Date().getTime()\n\n // All bundled plugins appear as `@shopify/cli` in the payload\n const {'@shopify/cli': internalPluginsPublic, ...externalPluginsPublic} = await fanoutHooks(\n config,\n 'public_command_metadata',\n {},\n )\n const {'@shopify/cli': internalPluginsSensitive, ...externalPluginsSensitive} = await fanoutHooks(\n config,\n 'sensitive_command_metadata',\n {},\n )\n\n const environmentData = await getEnvironmentData(config)\n const sensitiveEnvironmentData = await getSensitiveEnvironmentData(config)\n const publicMetadata = metadata.getAllPublicMetadata()\n\n // Automatically calculate the total time spent in the command, excluding time spent in subtimers.\n const subTimers = ['cmd_all_timing_network_ms', 'cmd_all_timing_prompts_ms'] as const\n const totalTimeFromSubtimers = subTimers.reduce((total, timer) => {\n const value = publicMetadata[timer]\n if (value !== undefined) {\n return total + value\n }\n return total\n }, 0)\n const wallClockElapsed = currentTime - startTime\n const totalTimeWithoutSubtimers = wallClockElapsed - totalTimeFromSubtimers\n\n const payload = {\n public: {\n command: startCommand,\n time_start: startTime,\n time_end: currentTime,\n total_time: wallClockElapsed,\n success: exitMode === 'ok' && errorMessage === undefined,\n cli_version: CLI_KIT_VERSION,\n ruby_version: '',\n node_version: process.version.replace('v', ''),\n is_employee: await isShopify(),\n ...environmentData,\n ...internalPluginsPublic,\n ...publicMetadata,\n cmd_all_timing_active_ms: totalTimeWithoutSubtimers,\n cmd_all_exit: exitMode,\n user_id: await getLastSeenUserIdAfterAuth(),\n request_ids: requestIdsCollection.getRequestIds(),\n },\n sensitive: {\n args: startArgs.join(' '),\n cmd_all_environment_flags: environmentFlags,\n error_message: errorMessage,\n ...internalPluginsSensitive,\n ...sensitiveEnvironmentData,\n metadata: JSON.stringify({\n ...sensitiveMetadata,\n extraPublic: {\n ...externalPluginsPublic,\n },\n extraSensitive: {...externalPluginsSensitive},\n }),\n },\n }\n\n // round down timing metrics\n const timingMetrics = ['cmd_all_timing_active_ms', 'cmd_all_timing_network_ms', 'cmd_all_timing_prompts_ms'] as const\n timingMetrics.forEach((metric) => {\n const current = payload.public[metric]\n if (current !== undefined) {\n payload.public[metric] = Math.floor(current)\n }\n })\n\n return sanitizePayload(payload)\n}\n\nfunction sanitizePayload<T>(payload: T): T {\n const payloadString = JSON.stringify(payload)\n // Remove Theme Access passwords from the payload\n const sanitizedPayloadString = payloadString.replace(/shptka_\\w*/g, '*****')\n return JSON.parse(sanitizedPayloadString)\n}\n\n/**\n * Records timing data for performance monitoring. Call twice with the same\n * event name to start and stop timing. First call starts the timer, second\n * call stops it and records the duration.\n *\n * @example\n * ```ts\n * recordTiming('theme-upload') // Start timing\n * // ... do work ...\n * recordTiming('theme-upload') // Stop timing and record duration\n * ```\n *\n * @param eventName - Unique identifier for the timing event\n */\nexport function recordTiming(eventName: string): void {\n storageRecordTiming(eventName)\n}\n\n/**\n * Records error information for debugging and monitoring. Use this to track\n * any exceptions or error conditions that occur during theme operations.\n * Errors are automatically categorized for easier analysis.\n *\n * @example\n * ```ts\n * try {\n * // ... risky operation ...\n * } catch (error) {\n * recordError(error)\n * }\n * ```\n *\n * @param error - Error object or message to record\n */\nexport function recordError<T>(error: T): T {\n storageRecordError(error)\n return error\n}\n\n/**\n * Records retry attempts for network operations. Use this to track when\n * operations are retried due to transient failures. Helps identify\n * problematic endpoints or operations that frequently fail.\n *\n * @example\n * ```ts\n * recordRetry('https://api.shopify.com/themes', 'upload')\n * ```\n *\n * @param url - The URL or endpoint being retried\n * @param operation - Description of the operation being retried\n */\nexport function recordRetry(url: string, operation: string): void {\n storageRecordRetry(url, operation)\n}\n\n/**\n * Records custom events for tracking specific user actions or system events.\n * Use this for important milestones, user interactions, or significant\n * state changes in the application.\n *\n * @example\n * ```ts\n * recordEvent('theme-dev-started')\n * recordEvent('file-watcher-connected')\n * ```\n *\n * @param eventName - Descriptive name for the event\n */\nexport function recordEvent(eventName: string): void {\n storageRecordEvent(eventName)\n}\n\n/**\n * Compiles and returns all runtime analytics data collected during the session.\n * This includes timing measurements, error records, retry attempts, and custom\n * events. Use this to retrieve a complete snapshot of analytics data for\n * reporting or debugging purposes.\n *\n * @example\n * ```ts\n * const analyticsData = compileData()\n * console.log(`Recorded ${analyticsData.timings.length} timing events`)\n * console.log(`Recorded ${analyticsData.errors.length} errors`)\n * ```\n *\n * @returns Object containing all collected analytics data including timings, errors, retries, and events\n */\nexport function compileData(): RuntimeData {\n return storageCompileData()\n}\n"]}
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/public/node/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import {alwaysLogAnalytics, alwaysLogMetrics, analyticsDisabled, isShopify} from './context/local.js'\nimport * as metadata from './metadata.js'\nimport {publishMonorailEvent, MONORAIL_COMMAND_TOPIC} from './monorail.js'\nimport {fanoutHooks} from './plugins.js'\nimport {sendErrorToBugsnag} from './error-handler.js'\nimport {outputContent, outputDebug, outputToken} from './output.js'\nimport {\n recordTiming as storageRecordTiming,\n recordError as storageRecordError,\n recordRetry as storageRecordRetry,\n recordEvent as storageRecordEvent,\n compileData as storageCompileData,\n RuntimeData,\n} from '../../private/node/analytics/storage.js'\nimport {getEnvironmentData, getSensitiveEnvironmentData} from '../../private/node/analytics.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {recordMetrics} from '../../private/node/otel-metrics.js'\nimport {runWithRateLimit} from '../../private/node/conf-store.js'\nimport {reportingRateLimit} from '../../private/node/constants.js'\nimport {getLastSeenUserIdAfterAuth} from '../../private/node/session.js'\nimport {requestIdsCollection} from '../../private/node/request-ids.js'\n\nimport {Interfaces} from '@oclif/core'\n\nexport type CommandExitMode =\n // The command completed successfully\n | 'ok'\n // The command exited for some unexpected reason -- i.e. a bug\n | 'unexpected_error'\n // The command exited with an error, but its one we expect and doesn't point to a bug -- i.e. malformed config files\n | 'expected_error'\n\ninterface ReportAnalyticsEventOptions {\n config: Interfaces.Config\n errorMessage?: string\n exitMode: CommandExitMode\n}\n\n/**\n * Report an analytics event, sending it off to Monorail -- Shopify's internal analytics service.\n *\n * The payload for an event includes both generic data, and data gathered from installed plug-ins.\n *\n */\nexport async function reportAnalyticsEvent(options: ReportAnalyticsEventOptions): Promise<void> {\n try {\n const payload = await buildPayload(options)\n if (payload === undefined) {\n // Nothing to log\n return\n }\n\n let withinRateLimit = false\n await runWithRateLimit({\n key: 'report-analytics-event',\n ...reportingRateLimit,\n task: async () => {\n withinRateLimit = true\n },\n })\n if (!withinRateLimit) {\n outputDebug(outputContent`Skipping command analytics due to rate limiting, payload: ${outputToken.json(payload)}`)\n return\n }\n\n const skipMonorailAnalytics = !alwaysLogAnalytics() && analyticsDisabled()\n const skipMetricAnalytics = !alwaysLogMetrics() && analyticsDisabled()\n if (skipMonorailAnalytics || skipMetricAnalytics) {\n outputDebug(outputContent`Skipping command analytics, payload: ${outputToken.json(payload)}`)\n }\n\n const doMonorail = async () => {\n if (skipMonorailAnalytics) {\n return\n }\n const response = await publishMonorailEvent(MONORAIL_COMMAND_TOPIC, payload.public, payload.sensitive)\n if (response.type === 'error') {\n outputDebug(response.message)\n }\n }\n const doOpenTelemetry = async () => {\n const active = payload.public.cmd_all_timing_active_ms ?? 0\n const network = payload.public.cmd_all_timing_network_ms ?? 0\n const prompt = payload.public.cmd_all_timing_prompts_ms ?? 0\n\n return recordMetrics(\n {\n skipMetricAnalytics,\n cliVersion: payload.public.cli_version,\n owningPlugin: payload.public.cmd_all_plugin ?? '@shopify/cli',\n command: payload.public.command,\n exitMode: options.exitMode,\n },\n {\n active,\n network,\n prompt,\n },\n )\n }\n await Promise.all([doMonorail(), doOpenTelemetry()])\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n outputDebug(message)\n await sendErrorToBugsnag(error, 'expected_error')\n }\n}\n\nasync function buildPayload({config, errorMessage, exitMode}: ReportAnalyticsEventOptions) {\n const {commandStartOptions, environmentFlags, ...sensitiveMetadata} = metadata.getAllSensitiveMetadata()\n if (commandStartOptions === undefined) {\n outputDebug('Unable to log analytics event - no information on executed command')\n return\n }\n const {startCommand, startArgs, startTime, endTime} = commandStartOptions\n const currentTime = endTime ?? new Date().getTime()\n\n // All bundled plugins appear as `@shopify/cli` in the payload\n const {'@shopify/cli': internalPluginsPublic, ...externalPluginsPublic} = await fanoutHooks(\n config,\n 'public_command_metadata',\n {},\n )\n const {'@shopify/cli': internalPluginsSensitive, ...externalPluginsSensitive} = await fanoutHooks(\n config,\n 'sensitive_command_metadata',\n {},\n )\n\n const environmentData = await getEnvironmentData(config)\n const sensitiveEnvironmentData = await getSensitiveEnvironmentData(config)\n const publicMetadata = metadata.getAllPublicMetadata()\n\n // Automatically calculate the total time spent in the command, excluding time spent in subtimers.\n const subTimers = ['cmd_all_timing_network_ms', 'cmd_all_timing_prompts_ms'] as const\n const totalTimeFromSubtimers = subTimers.reduce((total, timer) => {\n const value = publicMetadata[timer]\n if (value !== undefined) {\n return total + value\n }\n return total\n }, 0)\n const wallClockElapsed = currentTime - startTime\n const totalTimeWithoutSubtimers = wallClockElapsed - totalTimeFromSubtimers\n\n const payload = {\n public: {\n command: startCommand,\n time_start: startTime,\n time_end: currentTime,\n total_time: wallClockElapsed,\n success: exitMode === 'ok' && errorMessage === undefined,\n cli_version: CLI_KIT_VERSION,\n ruby_version: '',\n node_version: process.version.replace('v', ''),\n is_employee: await isShopify(),\n ...environmentData,\n ...internalPluginsPublic,\n ...publicMetadata,\n cmd_all_timing_active_ms: totalTimeWithoutSubtimers,\n cmd_all_exit: exitMode,\n user_id: await getLastSeenUserIdAfterAuth(),\n request_ids: requestIdsCollection.getRequestIds(),\n },\n sensitive: {\n args: startArgs.join(' '),\n cmd_all_environment_flags: environmentFlags,\n error_message: errorMessage,\n ...internalPluginsSensitive,\n ...sensitiveEnvironmentData,\n metadata: JSON.stringify({\n ...sensitiveMetadata,\n extraPublic: {\n ...externalPluginsPublic,\n },\n extraSensitive: {...externalPluginsSensitive},\n }),\n },\n }\n\n // round down timing metrics\n const timingMetrics = ['cmd_all_timing_active_ms', 'cmd_all_timing_network_ms', 'cmd_all_timing_prompts_ms'] as const\n timingMetrics.forEach((metric) => {\n const current = payload.public[metric]\n if (current !== undefined) {\n payload.public[metric] = Math.floor(current)\n }\n })\n\n return sanitizePayload(payload)\n}\n\nfunction sanitizePayload<T>(payload: T): T {\n const payloadString = JSON.stringify(payload)\n // Remove Theme Access passwords from the payload\n const sanitizedPayloadString = payloadString\n .replace(/shptka_\\w*/g, '*****')\n .replace(/(--store-password(?:=|\\s+))(?:\"[^\"]*\"|'[^']*'|[^\\s\"]+)/g, '$1*****')\n .replace(/((?:store-password|SHOPIFY_FLAG_STORE_PASSWORD)\\\\?\":\\\\?\")[^\"\\\\]*/g, '$1*****')\n return JSON.parse(sanitizedPayloadString)\n}\n\n/**\n * Records timing data for performance monitoring. Call twice with the same\n * event name to start and stop timing. First call starts the timer, second\n * call stops it and records the duration.\n *\n * @example\n * ```ts\n * recordTiming('theme-upload') // Start timing\n * // ... do work ...\n * recordTiming('theme-upload') // Stop timing and record duration\n * ```\n *\n * @param eventName - Unique identifier for the timing event\n */\nexport function recordTiming(eventName: string): void {\n storageRecordTiming(eventName)\n}\n\n/**\n * Records error information for debugging and monitoring. Use this to track\n * any exceptions or error conditions that occur during theme operations.\n * Errors are automatically categorized for easier analysis.\n *\n * @example\n * ```ts\n * try {\n * // ... risky operation ...\n * } catch (error) {\n * recordError(error)\n * }\n * ```\n *\n * @param error - Error object or message to record\n */\nexport function recordError<T>(error: T): T {\n storageRecordError(error)\n return error\n}\n\n/**\n * Records retry attempts for network operations. Use this to track when\n * operations are retried due to transient failures. Helps identify\n * problematic endpoints or operations that frequently fail.\n *\n * @example\n * ```ts\n * recordRetry('https://api.shopify.com/themes', 'upload')\n * ```\n *\n * @param url - The URL or endpoint being retried\n * @param operation - Description of the operation being retried\n */\nexport function recordRetry(url: string, operation: string): void {\n storageRecordRetry(url, operation)\n}\n\n/**\n * Records custom events for tracking specific user actions or system events.\n * Use this for important milestones, user interactions, or significant\n * state changes in the application.\n *\n * @example\n * ```ts\n * recordEvent('theme-dev-started')\n * recordEvent('file-watcher-connected')\n * ```\n *\n * @param eventName - Descriptive name for the event\n */\nexport function recordEvent(eventName: string): void {\n storageRecordEvent(eventName)\n}\n\n/**\n * Compiles and returns all runtime analytics data collected during the session.\n * This includes timing measurements, error records, retry attempts, and custom\n * events. Use this to retrieve a complete snapshot of analytics data for\n * reporting or debugging purposes.\n *\n * @example\n * ```ts\n * const analyticsData = compileData()\n * console.log(`Recorded ${analyticsData.timings.length} timing events`)\n * console.log(`Recorded ${analyticsData.errors.length} errors`)\n * ```\n *\n * @returns Object containing all collected analytics data including timings, errors, retries, and events\n */\nexport function compileData(): RuntimeData {\n return storageCompileData()\n}\n"]}
@@ -1,7 +1,5 @@
1
1
  import { GraphQLVariables, GraphQLResponse, CacheOptions, UnauthorizedHandler } from './graphql.js';
2
2
  import { RequestModeInput } from '../http.js';
3
- import { Variables } from 'graphql-request';
4
- import { TypedDocumentNode } from '@graphql-typed-document-node/core';
5
3
  /**
6
4
  * Executes a GraphQL query against the Partners API.
7
5
  *
@@ -14,21 +12,6 @@ import { TypedDocumentNode } from '@graphql-typed-document-node/core';
14
12
  * @returns The response of the query of generic type <T>.
15
13
  */
16
14
  export declare function partnersRequest<T>(query: string, token: string, variables?: GraphQLVariables, cacheOptions?: CacheOptions, preferredBehaviour?: RequestModeInput, unauthorizedHandler?: UnauthorizedHandler): Promise<T>;
17
- export declare const generateFetchAppLogUrl: (cursor?: string, filters?: {
18
- status?: string;
19
- source?: string;
20
- }) => Promise<string>;
21
- /**
22
- * Executes a GraphQL query against the Partners API. Uses typed documents.
23
- *
24
- * @param query - GraphQL query to execute.
25
- * @param token - Partners token.
26
- * @param variables - GraphQL variables to pass to the query.
27
- * @param preferredBehaviour - Preferred behaviour for the request.
28
- * @param unauthorizedHandler - Optional handler for unauthorized requests.
29
- * @returns The response of the query of generic type <TResult>.
30
- */
31
- export declare function partnersRequestDoc<TResult, TVariables extends Variables>(query: TypedDocumentNode<TResult, TVariables>, token: string, variables?: TVariables, preferredBehaviour?: RequestModeInput, unauthorizedHandler?: UnauthorizedHandler): Promise<TResult>;
32
15
  /**
33
16
  * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)
34
17
  * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).
@@ -1,12 +1,6 @@
1
- import { addCursorAndFiltersToAppLogsUrl } from './utilities.js';
2
- import { graphqlRequest, graphqlRequestDoc, } from './graphql.js';
1
+ import { graphqlRequest } from './graphql.js';
3
2
  import { partnersFqdn } from '../context/fqdn.js';
4
3
  import { setNextDeprecationDate } from '../../../private/node/context/deprecations-store.js';
5
- import { getPackageManager } from '../node-package-manager.js';
6
- import { cwd } from '../path.js';
7
- import { AbortError, BugError } from '../error.js';
8
- import { formatPackageManagerCommand } from '../output.js';
9
- import { blockPartnersAccess } from '../environment.js';
10
4
  import Bottleneck from 'bottleneck';
11
5
  // API Rate limiter for partners API (Limit is 10 requests per second)
12
6
  // Jobs are launched every 150ms to add an extra 50ms margin per request.
@@ -21,9 +15,6 @@ const limiter = new Bottleneck({
21
15
  * @param token - Partners token.
22
16
  */
23
17
  async function setupRequest(token) {
24
- if (blockPartnersAccess()) {
25
- throw new BugError('Partners API is no longer available.');
26
- }
27
18
  const api = 'Partners';
28
19
  const fqdn = await partnersFqdn();
29
20
  const url = `https://${fqdn}/api/cli/graphql`;
@@ -57,44 +48,6 @@ export async function partnersRequest(query, token, variables, cacheOptions, pre
57
48
  }));
58
49
  return result;
59
50
  }
60
- export const generateFetchAppLogUrl = async (cursor, filters) => {
61
- const fqdn = await partnersFqdn();
62
- const url = `https://${fqdn}/app_logs/poll`;
63
- return addCursorAndFiltersToAppLogsUrl(url, cursor, filters);
64
- };
65
- /**
66
- * Executes a GraphQL query against the Partners API. Uses typed documents.
67
- *
68
- * @param query - GraphQL query to execute.
69
- * @param token - Partners token.
70
- * @param variables - GraphQL variables to pass to the query.
71
- * @param preferredBehaviour - Preferred behaviour for the request.
72
- * @param unauthorizedHandler - Optional handler for unauthorized requests.
73
- * @returns The response of the query of generic type <TResult>.
74
- */
75
- export async function partnersRequestDoc(query, token, variables, preferredBehaviour, unauthorizedHandler) {
76
- try {
77
- const opts = await setupRequest(token);
78
- const result = limiter.schedule(() => graphqlRequestDoc({
79
- ...opts,
80
- query,
81
- variables,
82
- preferredBehaviour,
83
- unauthorizedHandler,
84
- }));
85
- return result;
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- }
88
- catch (error) {
89
- if (error.errors?.[0]?.extensions?.type === 'unsupported_client_version') {
90
- const packageManager = await getPackageManager(cwd());
91
- throw new AbortError(['Upgrade your CLI version to run this command.'], null, [
92
- ['Run', { command: formatPackageManagerCommand(packageManager, 'shopify upgrade') }],
93
- ]);
94
- }
95
- throw error;
96
- }
97
- }
98
51
  /**
99
52
  * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)
100
53
  * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).
@@ -1 +1 @@
1
- {"version":3,"file":"partners.js","sourceRoot":"","sources":["../../../../src/public/node/api/partners.ts"],"names":[],"mappings":"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","sourcesContent":["import {addCursorAndFiltersToAppLogsUrl} from './utilities.js'\nimport {\n graphqlRequest,\n GraphQLVariables,\n GraphQLResponse,\n graphqlRequestDoc,\n CacheOptions,\n UnauthorizedHandler,\n} from './graphql.js'\nimport {partnersFqdn} from '../context/fqdn.js'\nimport {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js'\nimport {getPackageManager} from '../node-package-manager.js'\nimport {cwd} from '../path.js'\nimport {AbortError, BugError} from '../error.js'\nimport {formatPackageManagerCommand} from '../output.js'\nimport {RequestModeInput} from '../http.js'\nimport {blockPartnersAccess} from '../environment.js'\nimport Bottleneck from 'bottleneck'\n\nimport {Variables} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\n// API Rate limiter for partners API (Limit is 10 requests per second)\n// Jobs are launched every 150ms to add an extra 50ms margin per request.\n// Only 10 requests can be executed concurrently.\nconst limiter = new Bottleneck({\n minTime: 150,\n maxConcurrent: 10,\n})\n\n/**\n * Sets up the request to the Partners API.\n *\n * @param token - Partners token.\n */\nasync function setupRequest(token: string) {\n if (blockPartnersAccess()) {\n throw new BugError('Partners API is no longer available.')\n }\n\n const api = 'Partners'\n const fqdn = await partnersFqdn()\n const url = `https://${fqdn}/api/cli/graphql`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes a GraphQL query against the Partners API.\n *\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options.\n * @param preferredBehaviour - Preferred behaviour for the request.\n * @param unauthorizedHandler - Optional handler for unauthorized requests.\n * @returns The response of the query of generic type <T>.\n */\nexport async function partnersRequest<T>(\n query: string,\n token: string,\n variables?: GraphQLVariables,\n cacheOptions?: CacheOptions,\n preferredBehaviour?: RequestModeInput,\n unauthorizedHandler?: UnauthorizedHandler,\n): Promise<T> {\n const opts = await setupRequest(token)\n const result = limiter.schedule(() =>\n graphqlRequest<T>({\n ...opts,\n query,\n variables,\n cacheOptions,\n preferredBehaviour,\n unauthorizedHandler,\n }),\n )\n\n return result\n}\n\nexport const generateFetchAppLogUrl = async (\n cursor?: string,\n filters?: {\n status?: string\n source?: string\n },\n): Promise<string> => {\n const fqdn = await partnersFqdn()\n const url = `https://${fqdn}/app_logs/poll`\n return addCursorAndFiltersToAppLogsUrl(url, cursor, filters)\n}\n\n/**\n * Executes a GraphQL query against the Partners API. Uses typed documents.\n *\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @param preferredBehaviour - Preferred behaviour for the request.\n * @param unauthorizedHandler - Optional handler for unauthorized requests.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function partnersRequestDoc<TResult, TVariables extends Variables>(\n query: TypedDocumentNode<TResult, TVariables>,\n token: string,\n variables?: TVariables,\n preferredBehaviour?: RequestModeInput,\n unauthorizedHandler?: UnauthorizedHandler,\n): Promise<TResult> {\n try {\n const opts = await setupRequest(token)\n const result = limiter.schedule(() =>\n graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n preferredBehaviour,\n unauthorizedHandler,\n }),\n )\n\n return result\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.errors?.[0]?.extensions?.type === 'unsupported_client_version') {\n const packageManager = await getPackageManager(cwd())\n\n throw new AbortError(['Upgrade your CLI version to run this command.'], null, [\n ['Run', {command: formatPackageManagerCommand(packageManager, 'shopify upgrade')}],\n ])\n }\n\n throw error\n }\n}\n\ninterface Deprecation {\n supportedUntilDate?: string\n}\n\ninterface WithDeprecations {\n deprecations: Deprecation[]\n}\n\n/**\n * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)\n * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).\n *\n * @param response - The response of the query.\n */\nexport function handleDeprecations<T>(response: GraphQLResponse<T>): void {\n if (!response.extensions) return\n\n const deprecationDates: Date[] = []\n for (const deprecation of (response.extensions as WithDeprecations).deprecations) {\n if (deprecation.supportedUntilDate) {\n deprecationDates.push(new Date(deprecation.supportedUntilDate))\n }\n }\n\n setNextDeprecationDate(deprecationDates)\n}\n"]}
1
+ {"version":3,"file":"partners.js","sourceRoot":"","sources":["../../../../src/public/node/api/partners.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAuE,MAAM,cAAc,CAAA;AACjH,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,sBAAsB,EAAC,MAAM,qDAAqD,CAAA;AAE1F,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AACjD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;IAC7B,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,EAAE;CAClB,CAAC,CAAA;AAEF;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,KAAa;IACvC,MAAM,GAAG,GAAG,UAAU,CAAA;IACtB,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,WAAW,IAAI,kBAAkB,CAAA;IAC7C,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,KAAa,EACb,SAA4B,EAC5B,YAA2B,EAC3B,kBAAqC,EACrC,mBAAyC;IAEzC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CACnC,cAAc,CAAI;QAChB,GAAG,IAAI;QACP,KAAK;QACL,SAAS;QACT,YAAY;QACZ,kBAAkB;QAClB,mBAAmB;KACpB,CAAC,CACH,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAI,QAA4B;IAChE,IAAI,CAAC,QAAQ,CAAC,UAAU;QAAE,OAAM;IAEhC,MAAM,gBAAgB,GAAW,EAAE,CAAA;IACnC,KAAK,MAAM,WAAW,IAAK,QAAQ,CAAC,UAA+B,CAAC,YAAY,EAAE,CAAC;QACjF,IAAI,WAAW,CAAC,kBAAkB,EAAE,CAAC;YACnC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAED,sBAAsB,CAAC,gBAAgB,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {graphqlRequest, GraphQLVariables, GraphQLResponse, CacheOptions, UnauthorizedHandler} from './graphql.js'\nimport {partnersFqdn} from '../context/fqdn.js'\nimport {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js'\nimport {RequestModeInput} from '../http.js'\nimport Bottleneck from 'bottleneck'\n\n// API Rate limiter for partners API (Limit is 10 requests per second)\n// Jobs are launched every 150ms to add an extra 50ms margin per request.\n// Only 10 requests can be executed concurrently.\nconst limiter = new Bottleneck({\n minTime: 150,\n maxConcurrent: 10,\n})\n\n/**\n * Sets up the request to the Partners API.\n *\n * @param token - Partners token.\n */\nasync function setupRequest(token: string) {\n const api = 'Partners'\n const fqdn = await partnersFqdn()\n const url = `https://${fqdn}/api/cli/graphql`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes a GraphQL query against the Partners API.\n *\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options.\n * @param preferredBehaviour - Preferred behaviour for the request.\n * @param unauthorizedHandler - Optional handler for unauthorized requests.\n * @returns The response of the query of generic type <T>.\n */\nexport async function partnersRequest<T>(\n query: string,\n token: string,\n variables?: GraphQLVariables,\n cacheOptions?: CacheOptions,\n preferredBehaviour?: RequestModeInput,\n unauthorizedHandler?: UnauthorizedHandler,\n): Promise<T> {\n const opts = await setupRequest(token)\n const result = limiter.schedule(() =>\n graphqlRequest<T>({\n ...opts,\n query,\n variables,\n cacheOptions,\n preferredBehaviour,\n unauthorizedHandler,\n }),\n )\n\n return result\n}\n\ninterface Deprecation {\n supportedUntilDate?: string\n}\n\ninterface WithDeprecations {\n deprecations: Deprecation[]\n}\n\n/**\n * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)\n * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).\n *\n * @param response - The response of the query.\n */\nexport function handleDeprecations<T>(response: GraphQLResponse<T>): void {\n if (!response.extensions) return\n\n const deprecationDates: Date[] = []\n for (const deprecation of (response.extensions as WithDeprecations).deprecations) {\n if (deprecation.supportedUntilDate) {\n deprecationDates.push(new Date(deprecation.supportedUntilDate))\n }\n }\n\n setNextDeprecationDate(deprecationDates)\n}\n"]}
@@ -16,6 +16,7 @@ declare abstract class BaseCommand extends Command {
16
16
  protected parse<TFlags extends FlagOutput & {
17
17
  path?: string;
18
18
  verbose?: boolean;
19
+ 'auth-alias'?: string;
19
20
  }, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(options?: Input<TFlags, TGlobalFlags, TArgs>, argv?: string[]): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs> & {
20
21
  argv: string[];
21
22
  }>;
@@ -2,6 +2,7 @@ import { isDevelopment } from './context/local.js';
2
2
  import { addPublicMetadata } from './metadata.js';
3
3
  import { AbortError } from './error.js';
4
4
  import { outputContent, outputResult, outputToken } from './output.js';
5
+ import { setCurrentSessionAlias } from './session.js';
5
6
  import { terminalSupportsPrompting } from './system.js';
6
7
  import { hashString } from './crypto.js';
7
8
  import { isTruthy } from './context/utilities.js';
@@ -74,6 +75,7 @@ class BaseCommand extends Command {
74
75
  async parse(options, argv) {
75
76
  let result = await super.parse(options, argv);
76
77
  result = await this.resultWithEnvironment(result, options, argv);
78
+ await setCurrentSessionAlias(result.flags['auth-alias']);
77
79
  await addFromParsedFlags(result.flags);
78
80
  return { ...result, ...{ argv: result.argv } };
79
81
  }