@shopify/cli-kit 3.80.7 → 3.81.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/private/node/analytics.js +4 -4
- package/dist/private/node/analytics.js.map +1 -1
- package/dist/private/node/api/rest.d.ts +1 -1
- package/dist/private/node/api/rest.js.map +1 -1
- package/dist/private/node/api.d.ts +1 -1
- package/dist/private/node/api.js +3 -9
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/conf-store.js +1 -1
- package/dist/private/node/conf-store.js.map +1 -1
- package/dist/private/node/constants.d.ts +0 -2
- package/dist/private/node/constants.js +0 -2
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/output.d.ts +22 -0
- package/dist/private/node/output.js +47 -0
- package/dist/private/node/output.js.map +1 -0
- package/dist/private/node/session/exchange.js +1 -1
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/scopes.js +3 -1
- package/dist/private/node/session/scopes.js.map +1 -1
- package/dist/private/node/session/validate.js +1 -1
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/session.d.ts +1 -1
- package/dist/private/node/session.js +3 -4
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/sleep-with-backoff.js +1 -1
- package/dist/private/node/sleep-with-backoff.js.map +1 -1
- package/dist/private/node/ui/alert.js +1 -8
- package/dist/private/node/ui/alert.js.map +1 -1
- package/dist/private/node/ui/components/Banner.test.js +1 -1
- package/dist/private/node/ui/components/Banner.test.js.map +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
- package/dist/private/node/ui.d.ts +1 -1
- package/dist/private/node/ui.js +6 -8
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/ts/json-narrowing.js +1 -1
- package/dist/public/common/ts/json-narrowing.js.map +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/api/admin.js +2 -2
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/app-dev.d.ts +16 -4
- package/dist/public/node/api/app-dev.js +7 -9
- package/dist/public/node/api/app-dev.js.map +1 -1
- package/dist/public/node/api/app-management.d.ts +17 -4
- package/dist/public/node/api/app-management.js +9 -13
- package/dist/public/node/api/app-management.js.map +1 -1
- package/dist/public/node/api/business-platform.d.ts +28 -16
- package/dist/public/node/api/business-platform.js +19 -25
- package/dist/public/node/api/business-platform.js.map +1 -1
- package/dist/public/node/api/functions.d.ts +16 -3
- package/dist/public/node/api/functions.js +6 -9
- package/dist/public/node/api/functions.js.map +1 -1
- package/dist/public/node/api/graphql.d.ts +10 -2
- package/dist/public/node/api/graphql.js +52 -10
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/api/partners.d.ts +5 -3
- package/dist/public/node/api/partners.js +7 -3
- package/dist/public/node/api/partners.js.map +1 -1
- package/dist/public/node/api/rest-api-throttler.js +1 -1
- package/dist/public/node/api/rest-api-throttler.js.map +1 -1
- package/dist/public/node/api/webhooks.d.ts +13 -5
- package/dist/public/node/api/webhooks.js +7 -9
- package/dist/public/node/api/webhooks.js.map +1 -1
- package/dist/public/node/archiver.js +1 -2
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.d.ts +5 -0
- package/dist/public/node/base-command.js +27 -10
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/context/local.d.ts +0 -14
- package/dist/public/node/context/local.js +0 -18
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/environments.d.ts +2 -0
- package/dist/public/node/environments.js +26 -11
- package/dist/public/node/environments.js.map +1 -1
- package/dist/public/node/git.d.ts +8 -0
- package/dist/public/node/git.js +22 -0
- package/dist/public/node/git.js.map +1 -1
- package/dist/public/node/hooks/deprecations.js +1 -1
- package/dist/public/node/hooks/deprecations.js.map +1 -1
- package/dist/public/node/json-schema.js +30 -11
- package/dist/public/node/json-schema.js.map +1 -1
- package/dist/public/node/logs.js +2 -2
- package/dist/public/node/logs.js.map +1 -1
- package/dist/public/node/node-package-manager.js +12 -4
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/notifications-system.js +1 -1
- package/dist/public/node/notifications-system.js.map +1 -1
- package/dist/public/node/output.d.ts +16 -26
- package/dist/public/node/output.js +24 -55
- package/dist/public/node/output.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +2 -2
- package/dist/public/node/themes/api.js +8 -5
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/conf.d.ts +2 -2
- package/dist/public/node/themes/conf.js +2 -2
- package/dist/public/node/themes/conf.js.map +1 -1
- package/dist/public/node/themes/factories.d.ts +1 -1
- package/dist/public/node/themes/factories.js.map +1 -1
- package/dist/public/node/themes/theme-manager.d.ts +3 -3
- package/dist/public/node/themes/theme-manager.js +2 -2
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/public/node/themes/urls.d.ts +2 -2
- package/dist/public/node/themes/urls.js.map +1 -1
- package/dist/public/node/themes/utils.d.ts +1 -1
- package/dist/public/node/themes/utils.js +1 -1
- package/dist/public/node/themes/utils.js.map +1 -1
- package/dist/public/node/ui.d.ts +0 -13
- package/dist/public/node/ui.js +2 -18
- package/dist/public/node/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/private/node/session/validate.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAkC,oCAAoC,EAAC,MAAM,aAAa,CAAA;AACjG,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,aAAa,EAAC,MAAM,uCAAuC,CAAA;AAEnE,OAAO,EAAC,WAAW,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/private/node/session/validate.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken, validateCachedIdentityTokenStructure} from './schema.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: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\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"]}
|
|
@@ -5,14 +5,13 @@ import { exchangeAccessForApplicationTokens, exchangeCustomPartnerToken, refresh
|
|
|
5
5
|
import * as secureStore from './session/store.js';
|
|
6
6
|
import { pollForDeviceAuthorization, requestDeviceAuthorization } from './session/device-authorization.js';
|
|
7
7
|
import { isThemeAccessSession } from './api/rest.js';
|
|
8
|
-
import { outputContent, outputToken, outputDebug } from '../../public/node/output.js';
|
|
8
|
+
import { outputContent, outputToken, outputDebug, outputCompleted } from '../../public/node/output.js';
|
|
9
9
|
import { firstPartyDev, themeToken } from '../../public/node/context/local.js';
|
|
10
10
|
import { AbortError, BugError } from '../../public/node/error.js';
|
|
11
11
|
import { normalizeStoreFqdn, identityFqdn } from '../../public/node/context/fqdn.js';
|
|
12
12
|
import { getIdentityTokenInformation, getPartnersToken } from '../../public/node/environment.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { nonRandomUUID } from '@shopify/cli-kit/node/crypto';
|
|
13
|
+
import { isSpin } from '../../public/node/context/spin.js';
|
|
14
|
+
import { nonRandomUUID } from '../../public/node/crypto.js';
|
|
16
15
|
let userId;
|
|
17
16
|
let authMethod = 'none';
|
|
18
17
|
/**
|
|
@@ -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} from './session/schema.js'\nimport * as secureStore from './session/store.js'\nimport {pollForDeviceAuthorization, requestDeviceAuthorization} from './session/device-authorization.js'\nimport {isThemeAccessSession} from './api/rest.js'\nimport {outputContent, outputToken, outputDebug} from '../../public/node/output.js'\nimport {firstPartyDev, themeToken} from '../../public/node/context/local.js'\nimport {AbortError, BugError} from '../../public/node/error.js'\nimport {normalizeStoreFqdn, identityFqdn} from '../../public/node/context/fqdn.js'\nimport {getIdentityTokenInformation, getPartnersToken} from '../../public/node/environment.js'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\nimport {outputCompleted} from '@shopify/cli-kit/node/output'\nimport {isSpin} from '@shopify/cli-kit/node/context/spin'\nimport {nonRandomUUID} from '@shopify/cli-kit/node/crypto'\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'\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 the user ID from the current session or returns 'unknown' if not found.\n *\n * This function performs the following steps:\n * 1. Checks for a cached user ID in memory (obtained in the current run).\n * 2. Attempts to fetch it from the secure store (from a previous auth session).\n * 3. Checks if a custom token was used (either as a theme password or partners token).\n * 4. If a custom token is present in the environment, generates a UUID and uses it as userId.\n * 5. If after all this we don't have a userId, then reports as 'unknown'.\n *\n * @returns A Promise that resolves to the user ID as a string.\n */\nexport async function getLastSeenUserIdAfterAuth(): Promise<string> {\n if (userId) return userId\n\n const currentSession = (await secureStore.fetch()) || {}\n const fqdn = await identityFqdn()\n const cachedUserId = currentSession[fqdn]?.identity.userId\n if (cachedUserId) return cachedUserId\n\n const customToken = getPartnersToken() ?? themeToken()\n return customToken ? nonRandomUUID(customToken) : '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 const currentSession = (await secureStore.fetch()) || {}\n const fqdn = await identityFqdn()\n const cachedUserId = currentSession[fqdn]?.identity.userId\n if (cachedUserId) return 'device_auth'\n\n const partnersToken = getPartnersToken()\n if (partnersToken) 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\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 forceRefresh - Optional flag to force a refresh of the token.\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}: {forceRefresh?: boolean; noPrompt?: boolean} = {},\n): Promise<OAuthSession> {\n const fqdn = await identityFqdn()\n\n const previousStoreFqdn = applications.adminApi?.storeFqdn\n if (previousStoreFqdn) {\n const normalizedStoreName = await normalizeStoreFqdn(previousStoreFqdn)\n if (previousStoreFqdn === applications.adminApi?.storeFqdn) {\n applications.adminApi.storeFqdn = normalizedStoreName\n }\n }\n\n const currentSession = (await secureStore.fetch()) || {}\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const fqdnSession = currentSession[fqdn]!\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 const validationResult = await validateSession(scopes, applications, fqdnSession)\n\n let newSession = {}\n\n function throwOnNoPrompt() {\n if (!noPrompt || (isSpin() && firstPartyDev())) return\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 if (validationResult === 'needs_full_auth') {\n throwOnNoPrompt()\n outputDebug(outputContent`Initiating the full authentication flow...`)\n newSession = await executeCompleteFlow(applications, fqdn)\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(fqdnSession.identity, applications, fqdn)\n } catch (error) {\n if (error instanceof InvalidGrantError) {\n throwOnNoPrompt()\n newSession = await executeCompleteFlow(applications, fqdn)\n } else if (error instanceof InvalidRequestError) {\n await secureStore.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: Session = {...currentSession, ...newSession}\n\n // Save the new session info if it has changed\n if (Object.keys(newSession).length > 0) await secureStore.store(completeSession)\n const tokens = await tokensFor(applications, completeSession, fqdn)\n\n // Overwrite partners token if using a custom CLI Token\n const envToken = getPartnersToken()\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\n/**\n * Execute the full authentication flow.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param identityFqdn - The identity FQDN.\n */\nasync function executeCompleteFlow(applications: OAuthApplications, identityFqdn: 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 const session: Session = {\n [identityFqdn]: {\n identity: identityToken,\n applications: result,\n },\n }\n\n outputCompleted('Logged in.')\n\n return session\n}\n\n/**\n * Refresh the tokens for a given session.\n *\n * @param token - Identity token.\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param fqdn - The identity FQDN.\n */\nasync function refreshTokens(token: IdentityToken, applications: OAuthApplications, fqdn: string): Promise<Session> {\n // Refresh Identity Token\n const identityToken = await refreshAccessToken(token)\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 [fqdn]: {\n identity: identityToken,\n applications: applicationTokens,\n },\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, fqdn: string): Promise<OAuthSession> {\n const fqdnSession = session[fqdn]\n if (!fqdnSession) {\n throw new BugError('No session found after ensuring authenticated')\n }\n const tokens: OAuthSession = {\n userId: fqdnSession.identity.userId,\n }\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = fqdnSession.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 = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n tokens.storefront = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.businessPlatformApi) {\n const appId = applicationId('business-platform')\n tokens.businessPlatform = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n tokens.appManagement = fqdnSession.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 }\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} from './session/schema.js'\nimport * as secureStore from './session/store.js'\nimport {pollForDeviceAuthorization, requestDeviceAuthorization} from './session/device-authorization.js'\nimport {isThemeAccessSession} from './api/rest.js'\nimport {outputContent, outputToken, outputDebug, outputCompleted} from '../../public/node/output.js'\nimport {firstPartyDev, themeToken} from '../../public/node/context/local.js'\nimport {AbortError, BugError} from '../../public/node/error.js'\nimport {normalizeStoreFqdn, identityFqdn} from '../../public/node/context/fqdn.js'\nimport {getIdentityTokenInformation, getPartnersToken} from '../../public/node/environment.js'\nimport {AdminSession} from '../../public/node/session.js'\nimport {isSpin} from '../../public/node/context/spin.js'\nimport {nonRandomUUID} from '../../public/node/crypto.js'\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'\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 the user ID from the current session or returns 'unknown' if not found.\n *\n * This function performs the following steps:\n * 1. Checks for a cached user ID in memory (obtained in the current run).\n * 2. Attempts to fetch it from the secure store (from a previous auth session).\n * 3. Checks if a custom token was used (either as a theme password or partners token).\n * 4. If a custom token is present in the environment, generates a UUID and uses it as userId.\n * 5. If after all this we don't have a userId, then reports as 'unknown'.\n *\n * @returns A Promise that resolves to the user ID as a string.\n */\nexport async function getLastSeenUserIdAfterAuth(): Promise<string> {\n if (userId) return userId\n\n const currentSession = (await secureStore.fetch()) || {}\n const fqdn = await identityFqdn()\n const cachedUserId = currentSession[fqdn]?.identity.userId\n if (cachedUserId) return cachedUserId\n\n const customToken = getPartnersToken() ?? themeToken()\n return customToken ? nonRandomUUID(customToken) : '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 const currentSession = (await secureStore.fetch()) || {}\n const fqdn = await identityFqdn()\n const cachedUserId = currentSession[fqdn]?.identity.userId\n if (cachedUserId) return 'device_auth'\n\n const partnersToken = getPartnersToken()\n if (partnersToken) 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\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 forceRefresh - Optional flag to force a refresh of the token.\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}: {forceRefresh?: boolean; noPrompt?: boolean} = {},\n): Promise<OAuthSession> {\n const fqdn = await identityFqdn()\n\n const previousStoreFqdn = applications.adminApi?.storeFqdn\n if (previousStoreFqdn) {\n const normalizedStoreName = await normalizeStoreFqdn(previousStoreFqdn)\n if (previousStoreFqdn === applications.adminApi?.storeFqdn) {\n applications.adminApi.storeFqdn = normalizedStoreName\n }\n }\n\n const currentSession = (await secureStore.fetch()) || {}\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const fqdnSession = currentSession[fqdn]!\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 const validationResult = await validateSession(scopes, applications, fqdnSession)\n\n let newSession = {}\n\n function throwOnNoPrompt() {\n if (!noPrompt || (isSpin() && firstPartyDev())) return\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 if (validationResult === 'needs_full_auth') {\n throwOnNoPrompt()\n outputDebug(outputContent`Initiating the full authentication flow...`)\n newSession = await executeCompleteFlow(applications, fqdn)\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(fqdnSession.identity, applications, fqdn)\n } catch (error) {\n if (error instanceof InvalidGrantError) {\n throwOnNoPrompt()\n newSession = await executeCompleteFlow(applications, fqdn)\n } else if (error instanceof InvalidRequestError) {\n await secureStore.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: Session = {...currentSession, ...newSession}\n\n // Save the new session info if it has changed\n if (Object.keys(newSession).length > 0) await secureStore.store(completeSession)\n const tokens = await tokensFor(applications, completeSession, fqdn)\n\n // Overwrite partners token if using a custom CLI Token\n const envToken = getPartnersToken()\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\n/**\n * Execute the full authentication flow.\n *\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param identityFqdn - The identity FQDN.\n */\nasync function executeCompleteFlow(applications: OAuthApplications, identityFqdn: 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 const session: Session = {\n [identityFqdn]: {\n identity: identityToken,\n applications: result,\n },\n }\n\n outputCompleted('Logged in.')\n\n return session\n}\n\n/**\n * Refresh the tokens for a given session.\n *\n * @param token - Identity token.\n * @param applications - An object containing the applications we need to be authenticated with.\n * @param fqdn - The identity FQDN.\n */\nasync function refreshTokens(token: IdentityToken, applications: OAuthApplications, fqdn: string): Promise<Session> {\n // Refresh Identity Token\n const identityToken = await refreshAccessToken(token)\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 [fqdn]: {\n identity: identityToken,\n applications: applicationTokens,\n },\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, fqdn: string): Promise<OAuthSession> {\n const fqdnSession = session[fqdn]\n if (!fqdnSession) {\n throw new BugError('No session found after ensuring authenticated')\n }\n const tokens: OAuthSession = {\n userId: fqdnSession.identity.userId,\n }\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = fqdnSession.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 = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n tokens.storefront = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.businessPlatformApi) {\n const appId = applicationId('business-platform')\n tokens.businessPlatform = fqdnSession.applications[appId]?.accessToken\n }\n\n if (applications.appManagementApi) {\n const appId = applicationId('app-management')\n tokens.appManagement = fqdnSession.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 }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep-with-backoff.js","sourceRoot":"","sources":["../../../src/private/node/sleep-with-backoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"sleep-with-backoff.js","sourceRoot":"","sources":["../../../src/private/node/sleep-with-backoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,6BAA6B,CAAA;AAEjD,MAAM,sBAAsB,GAAG,GAAG,CAAA;AAClC,qBAAqB;AACrB,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAA;AAOxC;;;;;;GAMG;AACH,SAAS,qBAAqB,CAC5B,OAAe,EACf,YAAoB,EACpB,iBAAyB,mBAAmB,GAAG,CAAC;IAEhD,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,eAAe,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,eAAe,EAAE,cAAc,CAAC,CAAA;AACjE,CAAC;AAED;;GAEG;AACH,KAAK,SAAS,CAAC,CAAC,gBAAgB,CAC9B,cAA8C,EAC9C,YAAoB;IAEpB,IAAI,OAAO,GAAG,CAAC,CAAA;IAEf,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;QAChE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,OAAO,EAAC,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAC,CAAA;QAC9C,CAAC;QAED,4CAA4C;QAC5C,MAAM,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;QAC/B,MAAM,WAAW,CAAA;QACjB,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,qBAAqB,CAC1C,YAAoB,mBAAmB,EACvC,eAAuB,sBAAsB;IAE7C,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,EAAC,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAC,CAAA;IACxC,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;QAC1C,OAAO,WAAW,GAAG,SAAS,IAAI,SAAS,CAAA;IAC7C,CAAC,EAAE,YAAY,CAAC,CAAA;IAEhB,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QACtC,MAAM,OAAO,CAAA;QACb,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IAC1C,OAAO;QACL,WAAW,EAAE,SAAS,GAAG,WAAW;QACpC,UAAU,EAAE,OAAO;KACpB,CAAA;AACH,CAAC","sourcesContent":["import {sleep} from '../../public/node/system.js'\n\nconst DEFAULT_RETRY_DELAY_MS = 300\n// 10 seconds default\nexport const DEFAULT_MAX_TIME_MS = 10000\n\ninterface BackoffResult {\n remainingMs: number\n iterations: number\n}\n\n/**\n * Calculates the delay for a given attempt in exponential backoff\n *\n * First result is zero, second result is firstDelayMs, third result is firstDelay * 2, then * 4, then * 8, etc.\n *\n * Delays are capped by a maximum value.\n */\nfunction calculateBackoffDelay(\n attempt: number,\n firstDelayMs: number,\n maximumDelayMs: number = DEFAULT_MAX_TIME_MS / 3,\n): number {\n if (attempt === 0) {\n return 0\n }\n const delayMultiplier = 2 ** (attempt - 1)\n return Math.min(firstDelayMs * delayMultiplier, maximumDelayMs)\n}\n\n/**\n * Common generator function for backoff implementations\n */\nasync function* backoffGenerator(\n shouldContinue: (nextDelay: number) => boolean,\n firstDelayMs: number,\n): AsyncGenerator<number, BackoffResult, unknown> {\n let attempt = 0\n\n while (true) {\n const nextDelayMs = calculateBackoffDelay(attempt, firstDelayMs)\n if (!shouldContinue(nextDelayMs)) {\n return {remainingMs: 0, iterations: attempt}\n }\n\n // eslint-disable-next-line no-await-in-loop\n await sleep(nextDelayMs / 1000)\n yield nextDelayMs\n attempt++\n }\n}\n\n/**\n * Generator that sleeps with exponential backoff between yields, stopping before exceeding a time limit\n *\n * Yields the amount of time slept in milliseconds.\n *\n * @param maxTimeMs - Maximum total time in milliseconds before stopping\n * @param firstDelayMs - First delay in milliseconds\n * @returns Information about the backoff sequence: remaining time and iteration count\n */\nexport async function* sleepWithBackoffUntil(\n maxTimeMs: number = DEFAULT_MAX_TIME_MS,\n firstDelayMs: number = DEFAULT_RETRY_DELAY_MS,\n): AsyncGenerator<number, BackoffResult, unknown> {\n if (maxTimeMs <= 0) {\n return {remainingMs: 0, iterations: 0}\n }\n\n const startTime = Date.now()\n const generator = backoffGenerator((nextDelay) => {\n const elapsedTime = Date.now() - startTime\n return elapsedTime + nextDelay <= maxTimeMs\n }, firstDelayMs)\n\n let attempt = 0\n for await (const delayMs of generator) {\n yield delayMs\n attempt++\n }\n\n const elapsedTime = Date.now() - startTime\n return {\n remainingMs: maxTimeMs - elapsedTime,\n iterations: attempt,\n }\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Alert } from './components/Alert.js';
|
|
2
2
|
import { renderOnce } from '../ui.js';
|
|
3
|
-
import { consoleError, consoleLog, consoleWarn } from '../../../public/node/output.js';
|
|
4
3
|
import React from 'react';
|
|
5
4
|
const typeToLogLevel = {
|
|
6
5
|
info: 'info',
|
|
@@ -8,15 +7,9 @@ const typeToLogLevel = {
|
|
|
8
7
|
success: 'info',
|
|
9
8
|
error: 'error',
|
|
10
9
|
};
|
|
11
|
-
const typeToLogger = {
|
|
12
|
-
info: consoleLog,
|
|
13
|
-
warning: consoleWarn,
|
|
14
|
-
success: consoleLog,
|
|
15
|
-
error: consoleError,
|
|
16
|
-
};
|
|
17
10
|
export function alert({ type, headline, body, nextSteps, reference, link, customSections, orderedNextSteps = false, renderOptions, }) {
|
|
18
11
|
// eslint-disable-next-line prefer-rest-params
|
|
19
12
|
const { type: alertType, ..._eventProps } = arguments[0];
|
|
20
|
-
return renderOnce(React.createElement(Alert, { type: type, headline: headline, body: body, nextSteps: nextSteps, reference: reference, link: link, orderedNextSteps: orderedNextSteps, customSections: customSections }), { logLevel: typeToLogLevel[type],
|
|
13
|
+
return renderOnce(React.createElement(Alert, { type: type, headline: headline, body: body, nextSteps: nextSteps, reference: reference, link: link, orderedNextSteps: orderedNextSteps, customSections: customSections }), { logLevel: typeToLogLevel[type], renderOptions });
|
|
21
14
|
}
|
|
22
15
|
//# sourceMappingURL=alert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../../src/private/node/ui/alert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAa,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../../src/private/node/ui/alert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAa,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAA;AAEnC,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,cAAc,GAA4C;IAC9D,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,OAAO;CACf,CAAA;AAMD,MAAM,UAAU,KAAK,CAAC,EACpB,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,SAAS,EACT,IAAI,EACJ,cAAc,EACd,gBAAgB,GAAG,KAAK,EACxB,aAAa,GACA;IACb,8CAA8C;IAC9C,MAAM,EAAC,IAAI,EAAE,SAAS,EAAE,GAAG,WAAW,EAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IAEtD,OAAO,UAAU,CACf,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,cAAc,GAC9B,EACF,EAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,aAAa,EAAC,CAChD,CAAA;AACH,CAAC","sourcesContent":["import {Alert, AlertProps} from './components/Alert.js'\nimport {renderOnce} from '../ui.js'\nimport {LogLevel} from '../../../public/node/output.js'\nimport React from 'react'\nimport {RenderOptions} from 'ink'\n\nconst typeToLogLevel: {[key in AlertProps['type']]: LogLevel} = {\n info: 'info',\n warning: 'warn',\n success: 'info',\n error: 'error',\n}\n\nexport interface AlertOptions extends AlertProps {\n renderOptions?: RenderOptions\n}\n\nexport function alert({\n type,\n headline,\n body,\n nextSteps,\n reference,\n link,\n customSections,\n orderedNextSteps = false,\n renderOptions,\n}: AlertOptions) {\n // eslint-disable-next-line prefer-rest-params\n const {type: alertType, ..._eventProps} = arguments[0]\n\n return renderOnce(\n <Alert\n type={type}\n headline={headline}\n body={body}\n nextSteps={nextSteps}\n reference={reference}\n link={link}\n orderedNextSteps={orderedNextSteps}\n customSections={customSections}\n />,\n {logLevel: typeToLogLevel[type], renderOptions},\n )\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Banner } from './Banner.js';
|
|
2
2
|
import { List } from './List.js';
|
|
3
3
|
import { render } from '../../testing/ui.js';
|
|
4
|
+
import { unstyled } from '../../../../public/node/output.js';
|
|
4
5
|
import { describe, expect, test } from 'vitest';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
import { Text } from 'ink';
|
|
7
|
-
import { unstyled } from '@shopify/cli-kit/node/output';
|
|
8
8
|
describe('Banner', async () => {
|
|
9
9
|
test('renders with a border for success with proper wrapping', async () => {
|
|
10
10
|
const { lastFrame } = render(React.createElement(Banner, { type: "success" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Banner.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"Banner.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Banner.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AAExB,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC5B,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CACxB,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS;YACpB,oBAAC,IAAI,IACH,KAAK,EAAE;oBACL,yOAAyO;oBACzO,uNAAuN;iBACxN,GACD,CACK,CACV,CAAA;QAED,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;KAcpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CACxB,oBAAC,MAAM,IAAC,IAAI,EAAC,MAAM;YACjB,oBAAC,IAAI,kPAIE,CACA,CACV,CAAA;QACD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAUpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CACxB,oBAAC,MAAM,IAAC,IAAI,EAAC,SAAS;YACpB,oBAAC,IAAI,kPAIE,CACA,CACV,CAAA;QACD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAUpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CACxB,oBAAC,MAAM,IAAC,IAAI,EAAC,OAAO;YAClB,oBAAC,IAAI,kPAIE,CACA,CACV,CAAA;QACD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAUpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CACxB,oBAAC,MAAM,IAAC,IAAI,EAAC,gBAAgB;YAC3B,oBAAC,IAAI,kPAIE,CACA,CACV,CAAA;QAED,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;KASpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Banner} from './Banner.js'\nimport {List} from './List.js'\nimport {render} from '../../testing/ui.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {Text} from 'ink'\n\ndescribe('Banner', async () => {\n test('renders with a border for success with proper wrapping', async () => {\n const {lastFrame} = render(\n <Banner type=\"success\">\n <List\n items={[\n 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',\n ]}\n />\n </Banner>,\n )\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ success ────────────────────────────────────────────────────────────────────╮\n │ │\n │ • Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod │\n │ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim │\n │ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea │\n │ commodo consequat. │\n │ • Duis aute irure dolor in reprehenderit in voluptate velit esse cillum │\n │ dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non │\n │ proident, sunt in culpa qui officia deserunt mollit anim id est │\n │ laborum. │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders with a border for info', async () => {\n const {lastFrame} = render(\n <Banner type=\"info\">\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore\n magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n consequat.\n </Text>\n </Banner>,\n )\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ info ───────────────────────────────────────────────────────────────────────╮\n │ │\n │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod │\n │ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim │\n │ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea │\n │ commodo consequat. │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders with a border for warning', async () => {\n const {lastFrame} = render(\n <Banner type=\"warning\">\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore\n magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n consequat.\n </Text>\n </Banner>,\n )\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ warning ────────────────────────────────────────────────────────────────────╮\n │ │\n │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod │\n │ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim │\n │ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea │\n │ commodo consequat. │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders with a border for error', async () => {\n const {lastFrame} = render(\n <Banner type=\"error\">\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore\n magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n consequat.\n </Text>\n </Banner>,\n )\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod │\n │ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim │\n │ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea │\n │ commodo consequat. │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders with a top and bottom lines only for external errors', async () => {\n const {lastFrame} = render(\n <Banner type=\"external_error\">\n <Text>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore\n magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n consequat.\n </Text>\n </Banner>,\n )\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"── external error ──────────────────────────────────────────────────────────────\n\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore\n et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n aliquip ex ea commodo consequat.\n\n ────────────────────────────────────────────────────────────────────────────────\n \"\n `)\n })\n})\n"]}
|
|
@@ -2,9 +2,9 @@ import { TextPrompt } from './TextPrompt.js';
|
|
|
2
2
|
import { getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady, render } from '../../testing/ui.js';
|
|
3
3
|
import { unstyled } from '../../../../public/node/output.js';
|
|
4
4
|
import { AbortController } from '../../../../public/node/abort.js';
|
|
5
|
+
import colors from '../../../../public/node/colors.js';
|
|
5
6
|
import React from 'react';
|
|
6
7
|
import { describe, expect, test, vi } from 'vitest';
|
|
7
|
-
import colors from '@shopify/cli-kit/node/colors';
|
|
8
8
|
const ENTER = '\r';
|
|
9
9
|
describe('TextPrompt', () => {
|
|
10
10
|
test('default state', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextPrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextPrompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {TextPrompt} from './TextPrompt.js'\nimport {getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady, render} from '../../testing/ui.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {AbortController} from '../../../../public/node/abort.js'\nimport React from 'react'\nimport {describe, expect, test, vi} from 'vitest'\nimport colors from '@shopify/cli-kit/node/colors'\n\nconst ENTER = '\\r'\n\ndescribe('TextPrompt', () => {\n test('default state', () => {\n const {lastFrame} = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" defaultValue=\"Placeholder\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question:\n > Placeholder\n ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\n \"\n `)\n })\n\n test('default validation error', async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n // testing with styles because the color changes to red\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[31m>\u001b[39m \u001b[31m\u001b[41m█\u001b[49m\u001b[39m\n \u001b[31m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \u001b[31mType an answer to the prompt.\u001b[39m\n \"\n `)\n await sendInputAndWaitForChange(renderInstance, 'A')\n // color changes back to valid color\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36mA\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test('custom validation error', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"Test question\"\n validate={(value) => (value.includes('shopify') ? \"App name can't include the word shopify\" : undefined)}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'this-test-includes-shopify')\n await sendInputAndWaitForChange(renderInstance, ENTER)\n // testing with styles because the color changes to red\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[31m>\u001b[39m \u001b[31mthis-test-includes-shopify\u001b[41m█\u001b[49m\u001b[39m\n \u001b[31m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \u001b[31mApp name can't include the word shopify\u001b[39m\n \"\n `)\n })\n\n test('submitting the value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(<TextPrompt onSubmit={onSubmit} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'A')\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('submitting the default value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(<TextPrompt onSubmit={onSubmit} message=\"Test question\" defaultValue=\"A\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('display the empty value when no input is entered and there is no default value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(\n <TextPrompt onSubmit={onSubmit} message=\"Test question\" allowEmpty emptyDisplayedValue=\"empty\" />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ empty\n \"\n `)\n })\n\n test(\"display the default value when allow empty is enabled but the user don't modify it\", async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(\n <TextPrompt\n onSubmit={onSubmit}\n message=\"Test question\"\n allowEmpty\n emptyDisplayedValue=\"empty\"\n defaultValue=\"A\"\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('text wrapping', async () => {\n // component width is 80 characters wide in tests but because of the question mark and\n // spaces before the question, we only have 77 characters to work with\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'A'.repeat(77))\n await sendInputAndWaitForChange(renderInstance, 'B'.repeat(6))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\u001b[39m\n \u001b[36mBBBBBB\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test(\"masking the input if it's a password\", async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" password />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'ABC')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36m***\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ ***\n \"\n `)\n })\n\n test(\"doesn't append a colon to the message if it ends with a question mark\", async () => {\n const {lastFrame} = render(<TextPrompt onSubmit={() => {}} message=\"Test question?\" />)\n\n expect(lastFrame()!).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m>\u001b[39m \u001b[36m\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test(\"doesn't allow to pass defaultValue and password at the same time\", async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" password defaultValue=\"A\" />)\n\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toContain(\"ERROR Can't use defaultValue with password\")\n })\n\n test('abortController can be used to exit the prompt from outside', async () => {\n const abortController = new AbortController()\n\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"Test question\"\n defaultValue=\"Placeholder\"\n abortSignal={abortController.signal}\n />,\n )\n const promise = renderInstance.waitUntilExit()\n\n abortController.abort()\n\n // wait for the onAbort promise to resolve\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n expect(getLastFrameAfterUnmount(renderInstance)).toEqual('')\n await expect(promise).resolves.toEqual(undefined)\n })\n\n test('shows a preview footer when provided', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"How tall are you in cm?\"\n preview={(value) => `You are ${colors.cyan(String(Number(value) / 100))}m tall.`}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, '180')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? How tall are you in cm?\n \u001b[36m>\u001b[39m \u001b[36m180\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n You are \u001b[36m1.8\u001b[39mm tall.\n \"\n `)\n })\n\n test('the preview footer wraps when the value is very long', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"How tall are you?\"\n preview={(value) =>\n `You are ${colors.cyan(\n `incredibly humongously savagely unnaturally monstrously pathetically arrogantly ${value}`,\n )} tall.`\n }\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'uber')\n\n expect(renderInstance.lastFrame()!).toMatchInlineSnapshot(`\n \"? How tall are you?\n \u001b[36m>\u001b[39m \u001b[36muber\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n You are \u001b[36mincredibly humongously savagely unnaturally monstrously pathetically \u001b[39m\n \u001b[36marrogantly uber\u001b[39m tall.\n \"\n `)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"TextPrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextPrompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {TextPrompt} from './TextPrompt.js'\nimport {getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady, render} from '../../testing/ui.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {AbortController} from '../../../../public/node/abort.js'\nimport colors from '../../../../public/node/colors.js'\nimport React from 'react'\nimport {describe, expect, test, vi} from 'vitest'\n\nconst ENTER = '\\r'\n\ndescribe('TextPrompt', () => {\n test('default state', () => {\n const {lastFrame} = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" defaultValue=\"Placeholder\" />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question:\n > Placeholder\n ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\n \"\n `)\n })\n\n test('default validation error', async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n // testing with styles because the color changes to red\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[31m>\u001b[39m \u001b[31m\u001b[41m█\u001b[49m\u001b[39m\n \u001b[31m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \u001b[31mType an answer to the prompt.\u001b[39m\n \"\n `)\n await sendInputAndWaitForChange(renderInstance, 'A')\n // color changes back to valid color\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36mA\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test('custom validation error', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"Test question\"\n validate={(value) => (value.includes('shopify') ? \"App name can't include the word shopify\" : undefined)}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'this-test-includes-shopify')\n await sendInputAndWaitForChange(renderInstance, ENTER)\n // testing with styles because the color changes to red\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[31m>\u001b[39m \u001b[31mthis-test-includes-shopify\u001b[41m█\u001b[49m\u001b[39m\n \u001b[31m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \u001b[31mApp name can't include the word shopify\u001b[39m\n \"\n `)\n })\n\n test('submitting the value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(<TextPrompt onSubmit={onSubmit} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'A')\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('submitting the default value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(<TextPrompt onSubmit={onSubmit} message=\"Test question\" defaultValue=\"A\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('display the empty value when no input is entered and there is no default value', async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(\n <TextPrompt onSubmit={onSubmit} message=\"Test question\" allowEmpty emptyDisplayedValue=\"empty\" />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ empty\n \"\n `)\n })\n\n test(\"display the default value when allow empty is enabled but the user don't modify it\", async () => {\n const onSubmit = vi.fn()\n const renderInstance = render(\n <TextPrompt\n onSubmit={onSubmit}\n message=\"Test question\"\n allowEmpty\n emptyDisplayedValue=\"empty\"\n defaultValue=\"A\"\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(onSubmit).toHaveBeenCalledWith('A')\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ A\n \"\n `)\n })\n\n test('text wrapping', async () => {\n // component width is 80 characters wide in tests but because of the question mark and\n // spaces before the question, we only have 77 characters to work with\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'A'.repeat(77))\n await sendInputAndWaitForChange(renderInstance, 'B'.repeat(6))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\u001b[39m\n \u001b[36mBBBBBB\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test(\"masking the input if it's a password\", async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" password />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'ABC')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Test question:\n \u001b[36m>\u001b[39m \u001b[36m***\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n\n await sendInputAndWaitForChange(renderInstance, ENTER)\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toMatchInlineSnapshot(`\n \"? Test question:\n ✔ ***\n \"\n `)\n })\n\n test(\"doesn't append a colon to the message if it ends with a question mark\", async () => {\n const {lastFrame} = render(<TextPrompt onSubmit={() => {}} message=\"Test question?\" />)\n\n expect(lastFrame()!).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m>\u001b[39m \u001b[36m\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n \"\n `)\n })\n\n test(\"doesn't allow to pass defaultValue and password at the same time\", async () => {\n const renderInstance = render(<TextPrompt onSubmit={() => {}} message=\"Test question\" password defaultValue=\"A\" />)\n\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toContain(\"ERROR Can't use defaultValue with password\")\n })\n\n test('abortController can be used to exit the prompt from outside', async () => {\n const abortController = new AbortController()\n\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"Test question\"\n defaultValue=\"Placeholder\"\n abortSignal={abortController.signal}\n />,\n )\n const promise = renderInstance.waitUntilExit()\n\n abortController.abort()\n\n // wait for the onAbort promise to resolve\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n expect(getLastFrameAfterUnmount(renderInstance)).toEqual('')\n await expect(promise).resolves.toEqual(undefined)\n })\n\n test('shows a preview footer when provided', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"How tall are you in cm?\"\n preview={(value) => `You are ${colors.cyan(String(Number(value) / 100))}m tall.`}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, '180')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? How tall are you in cm?\n \u001b[36m>\u001b[39m \u001b[36m180\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n You are \u001b[36m1.8\u001b[39mm tall.\n \"\n `)\n })\n\n test('the preview footer wraps when the value is very long', async () => {\n const renderInstance = render(\n <TextPrompt\n onSubmit={() => {}}\n message=\"How tall are you?\"\n preview={(value) =>\n `You are ${colors.cyan(\n `incredibly humongously savagely unnaturally monstrously pathetically arrogantly ${value}`,\n )} tall.`\n }\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'uber')\n\n expect(renderInstance.lastFrame()!).toMatchInlineSnapshot(`\n \"? How tall are you?\n \u001b[36m>\u001b[39m \u001b[36muber\u001b[46m█\u001b[49m\u001b[39m\n \u001b[36m▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\u001b[39m\n You are \u001b[36mincredibly humongously savagely unnaturally monstrously pathetically \u001b[39m\n \u001b[36marrogantly uber\u001b[39m tall.\n \"\n `)\n })\n})\n"]}
|
|
@@ -6,7 +6,7 @@ interface RenderOnceOptions {
|
|
|
6
6
|
logger?: Logger;
|
|
7
7
|
renderOptions?: RenderOptions;
|
|
8
8
|
}
|
|
9
|
-
export declare function renderOnce(element: JSX.Element, { logLevel,
|
|
9
|
+
export declare function renderOnce(element: JSX.Element, { logLevel, renderOptions }: RenderOnceOptions): string | undefined;
|
|
10
10
|
export declare function render(element: JSX.Element, options?: RenderOptions): Promise<unknown>;
|
|
11
11
|
export declare class Stdout extends EventEmitter {
|
|
12
12
|
columns: number;
|
package/dist/private/node/ui.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { output } from './output.js';
|
|
2
2
|
import { isUnitTest } from '../../public/node/context/local.js';
|
|
3
3
|
import { treeKill } from '../../public/node/tree-kill.js';
|
|
4
4
|
import { render as inkRender } from 'ink';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
|
-
export function renderOnce(element, { logLevel = 'info',
|
|
7
|
-
const { output, unmount } = renderString(element, renderOptions);
|
|
8
|
-
if (
|
|
9
|
-
|
|
10
|
-
collectLog(logLevel, output);
|
|
11
|
-
outputWhereAppropriate(logLevel, logger, output);
|
|
6
|
+
export function renderOnce(element, { logLevel = 'info', renderOptions }) {
|
|
7
|
+
const { output: renderedString, unmount } = renderString(element, renderOptions);
|
|
8
|
+
if (renderedString) {
|
|
9
|
+
output(renderedString, logLevel);
|
|
12
10
|
}
|
|
13
11
|
unmount();
|
|
14
|
-
return
|
|
12
|
+
return renderedString;
|
|
15
13
|
}
|
|
16
14
|
export async function render(element, options) {
|
|
17
15
|
const { waitUntilExit } = inkRender(element, options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/private/node/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/private/node/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,OAAO,EAAC,UAAU,EAAC,MAAM,oCAAoC,CAAA;AAC7D,OAAO,EAAC,QAAQ,EAAC,MAAM,gCAAgC,CAAA;AAEvD,OAAO,EAAM,MAAM,IAAI,SAAS,EAAgB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAC,YAAY,EAAC,MAAM,QAAQ,CAAA;AAQnC,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,EAAC,QAAQ,GAAG,MAAM,EAAE,aAAa,EAAoB;IACpG,MAAM,EAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAC,GAAG,YAAY,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;IAE9E,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED,OAAO,EAAE,CAAA;IAET,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAoB,EAAE,OAAuB;IACxE,MAAM,EAAC,aAAa,EAAC,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACnD,MAAM,aAAa,EAAE,CAAA;IACrB,4FAA4F;IAC5F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;AACxD,CAAC;AAOD,MAAM,OAAO,MAAO,SAAQ,YAAY;IAMtC,YAAY,OAA0C;QACpD,KAAK,EAAE,CAAA;QAJA,WAAM,GAAa,EAAE,CAAA;QAS9B,UAAK,GAAG,CAAC,KAAa,EAAE,EAAE;YACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAA;QACzB,CAAC,CAAA;QAED,cAAS,GAAG,GAAG,EAAE;YACf,OAAO,IAAI,CAAC,UAAU,CAAA;QACxB,CAAC,CAAA;QAXC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAA;QACpC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA;IAChC,CAAC;CAUF;AAED,MAAM,YAAY,GAAG,CAAC,OAAqB,EAAE,aAA6B,EAAY,EAAE;IACtF,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAA;IAC1D,8DAA8D;IAC9D,MAAM,MAAM,GAAI,aAAa,EAAE,MAAc,IAAI,IAAI,MAAM,CAAC,EAAC,OAAO,EAAC,CAAC,CAAA;IAEtE,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE;QAClC,MAAM;QACN,KAAK,EAAE,IAAI;QACX,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,KAAK;KACpB,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE;QAC1B,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,WAAW,CACzB,KAAa,EACb,GAAQ,EACR,IAAI,GAAG,GAAG,EAAE;IACV,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;AACjC,CAAC;IAED,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,gEAAgE;QAChE,IAAI,EAAE,CAAA;IACR,CAAC;AACH,CAAC","sourcesContent":["import {output} from './output.js'\nimport {Logger, LogLevel} from '../../public/node/output.js'\nimport {isUnitTest} from '../../public/node/context/local.js'\nimport {treeKill} from '../../public/node/tree-kill.js'\nimport {ReactElement} from 'react'\nimport {Key, render as inkRender, RenderOptions} from 'ink'\nimport {EventEmitter} from 'events'\n\ninterface RenderOnceOptions {\n logLevel?: LogLevel\n logger?: Logger\n renderOptions?: RenderOptions\n}\n\nexport function renderOnce(element: JSX.Element, {logLevel = 'info', renderOptions}: RenderOnceOptions) {\n const {output: renderedString, unmount} = renderString(element, renderOptions)\n\n if (renderedString) {\n output(renderedString, logLevel)\n }\n\n unmount()\n\n return renderedString\n}\n\nexport async function render(element: JSX.Element, options?: RenderOptions) {\n const {waitUntilExit} = inkRender(element, options)\n await waitUntilExit()\n // We need to wait for other pending tasks -- unmounting of the ink component -- to complete\n return new Promise((resolve) => setImmediate(resolve))\n}\n\ninterface Instance {\n output: string | undefined\n unmount: () => void\n}\n\nexport class Stdout extends EventEmitter {\n columns: number\n rows: number\n readonly frames: string[] = []\n private _lastFrame?: string\n\n constructor(options: {columns?: number; rows?: number}) {\n super()\n this.columns = options.columns ?? 80\n this.rows = options.rows ?? 80\n }\n\n write = (frame: string) => {\n this.frames.push(frame)\n this._lastFrame = frame\n }\n\n lastFrame = () => {\n return this._lastFrame\n }\n}\n\nconst renderString = (element: ReactElement, renderOptions?: RenderOptions): Instance => {\n const columns = isUnitTest() ? 80 : process.stdout.columns\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const stdout = (renderOptions?.stdout as any) ?? new Stdout({columns})\n\n const instance = inkRender(element, {\n stdout,\n debug: true,\n exitOnCtrlC: false,\n patchConsole: false,\n })\n\n return {\n output: stdout.lastFrame(),\n unmount: instance.unmount,\n }\n}\n\nexport function handleCtrlC(\n input: string,\n key: Key,\n exit = () => {\n treeKill(process.pid, 'SIGINT')\n },\n) {\n if (input === 'c' && key.ctrl) {\n // Exceptions thrown in hooks aren't caught by our errorHandler.\n exit()\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-narrowing.js","sourceRoot":"","sources":["../../../../src/public/common/ts/json-narrowing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"json-narrowing.js","sourceRoot":"","sources":["../../../../src/public/common/ts/json-narrowing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAE5C;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,WAAoB;IAClD,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QAC5D,MAAM,IAAI,QAAQ,CAAC,qBAAqB,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC","sourcesContent":["import {BugError} from '../../node/error.js'\n\n/**\n * Asserts that the unknownBlob is a string map. Used to validate JSON objects received over the wire.\n *\n * @param unknownBlob - The unknown object to validate.\n * @throws BugError - Thrown if the unknownBlob is not a string map.\n */\nexport function assertStringMap(unknownBlob: unknown): asserts unknownBlob is {[key: string]: string} {\n if (typeof unknownBlob !== 'object' || unknownBlob === null) {\n throw new BugError('Expected an object.')\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CLI_KIT_VERSION = "3.
|
|
1
|
+
export declare const CLI_KIT_VERSION = "3.81.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const CLI_KIT_VERSION = '3.
|
|
1
|
+
export const CLI_KIT_VERSION = '3.81.1';
|
|
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,QAAQ,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '3.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '3.81.1'\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { graphqlRequest, graphqlRequestDoc } from './graphql.js';
|
|
1
|
+
import { graphqlRequest, graphqlRequestDoc, } from './graphql.js';
|
|
2
2
|
import { outputContent, outputToken } from '../../../public/node/output.js';
|
|
3
3
|
import { AbortError, BugError } from '../error.js';
|
|
4
4
|
import { restRequestBody, restRequestHeaders, restRequestUrl, isThemeAccessSession, } from '../../../private/node/api/rest.js';
|
|
@@ -46,7 +46,7 @@ export async function adminRequestDoc(options) {
|
|
|
46
46
|
};
|
|
47
47
|
let unauthorizedHandler;
|
|
48
48
|
if ('refresh' in session) {
|
|
49
|
-
unauthorizedHandler = session.refresh;
|
|
49
|
+
unauthorizedHandler = { type: 'token_refresh', handler: session.refresh };
|
|
50
50
|
}
|
|
51
51
|
const result = graphqlRequestDoc({
|
|
52
52
|
...opts,
|