Skip to content

Commit 06eaa06

Browse files
Make types a little more explicit
Previously the options passed to generateFrontendURL were an object with a bunch of optional properties. But if noTunnelUseLocalhost is true then port is mandatory and it's alwasy passed. By switching options to a union typescriot understands this and we no longer need to have get an available TCP port for localhost... it would alwasy be passed
1 parent a5833ff commit 06eaa06

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

packages/app/src/cli/services/dev.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
ApplicationURLs,
3+
FrontendURLOptions,
34
generateApplicationURLs,
45
generateFrontendURL,
56
getURLs,
@@ -48,7 +49,7 @@ import {OutputProcess, formatPackageManagerCommand, outputDebug} from '@shopify/
4849
import {hashString} from '@shopify/cli-kit/node/crypto'
4950
import {AbortError} from '@shopify/cli-kit/node/error'
5051

51-
interface NoTunnel {
52+
export interface NoTunnel {
5253
mode: 'use-localhost'
5354
port: number
5455
provideCertificate: (appDirectory: string) => Promise<{keyContent: string; certContent: string; certPath: string}>
@@ -321,15 +322,22 @@ async function setupNetworkingOptions(
321322

322323
await validateCustomPorts(webs, graphiqlPort)
323324

325+
const frontendUrlOptions: FrontendURLOptions =
326+
tunnelOptions.mode === 'use-localhost'
327+
? {
328+
noTunnelUseLocalhost: true,
329+
port: tunnelOptions.port,
330+
}
331+
: {
332+
noTunnelUseLocalhost: false,
333+
tunnelUrl: tunnelOptions.mode === 'custom' ? tunnelOptions.url : undefined,
334+
tunnelClient,
335+
}
336+
324337
// generateFrontendURL still uses the old naming of frontendUrl and frontendPort,
325338
// we can rename them to proxyUrl and proxyPort when we delete dev.ts
326339
const [{frontendUrl, frontendPort: proxyPort, usingLocalhost}, backendPort, currentUrls] = await Promise.all([
327-
generateFrontendURL({
328-
noTunnelUseLocalhost: tunnelOptions.mode === 'use-localhost',
329-
tunnelUrl: tunnelOptions.mode === 'custom' ? tunnelOptions.url : undefined,
330-
tunnelClient,
331-
port: tunnelOptions.mode === 'use-localhost' ? tunnelOptions.port : undefined,
332-
}),
340+
generateFrontendURL(frontendUrlOptions),
333341
getBackendPort() ?? backendConfig?.configuration.port ?? getAvailableTCPPort(),
334342
getURLs(remoteAppConfig),
335343
])

packages/app/src/cli/services/dev/urls.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,13 @@ describe('generateFrontendURL', () => {
450450

451451
test('returns localhost if noTunnelUseLocalhost is true', async () => {
452452
// Given
453-
const options = {...defaultOptions, noTunnelUseLocalhost: true}
453+
const options: FrontendURLOptions = {noTunnelUseLocalhost: true, port: 1234}
454454

455455
// When
456456
const got = await generateFrontendURL(options)
457457

458458
// Then
459-
expect(got).toEqual({frontendUrl: 'https://localhost', frontendPort: 3042, usingLocalhost: true})
459+
expect(got).toEqual({frontendUrl: 'https://localhost', frontendPort: 1234, usingLocalhost: true})
460460
expect(renderSelectPrompt).not.toBeCalled()
461461
})
462462

packages/app/src/cli/services/dev/urls.ts

+15-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {DeveloperPlatformClient} from '../../utilities/developer-platform-client
77
import {patchAppConfigurationFile} from '../app/patch-app-configuration-file.js'
88
import {AbortError, BugError} from '@shopify/cli-kit/node/error'
99
import {Config} from '@oclif/core'
10-
import {checkPortAvailability, getAvailableTCPPort} from '@shopify/cli-kit/node/tcp'
10+
import {checkPortAvailability} from '@shopify/cli-kit/node/tcp'
1111
import {isValidURL} from '@shopify/cli-kit/common/url'
1212
import {appHost, appPort, fetchSpinPort, isSpin, spinFqdn, spinVariables} from '@shopify/cli-kit/node/context/spin'
1313
import {codespaceURL, codespacePortForwardingDomain, gitpodURL} from '@shopify/cli-kit/node/context/local'
@@ -28,11 +28,19 @@ export interface ApplicationURLs {
2828
appProxy?: AppProxy
2929
}
3030

31-
export interface FrontendURLOptions {
32-
noTunnelUseLocalhost: boolean
31+
export type FrontendURLOptions = UseLocalhostFrontendUrlOptions | UseTunnelFrontendUrlOptions
32+
33+
interface UseLocalhostFrontendUrlOptions {
34+
noTunnelUseLocalhost: true
35+
port: number
36+
tunnelUrl?: undefined
37+
tunnelClient?: undefined
38+
}
39+
40+
interface UseTunnelFrontendUrlOptions {
41+
noTunnelUseLocalhost: false
3342
tunnelUrl?: string
3443
tunnelClient: TunnelClient | undefined
35-
port?: number
3644
}
3745

3846
interface FrontendURLResult {
@@ -43,7 +51,7 @@ interface FrontendURLResult {
4351

4452
/**
4553
* The tunnel creation logic depends on 7 variables:
46-
* - If a Codespaces environment is deteced, then the URL is built using the codespaces hostname. No need for tunnel
54+
* - If a Codespaces environment is detected, then the URL is built using the codespaces hostname. No need for tunnel
4755
* - If a Gitpod environment is detected, then the URL is built using the gitpod hostname. No need for tunnel
4856
* - If a Spin environment is detected, then the URL is built using the cli + fqdn hostname as configured in nginx.
4957
* No need for tunnel. In case problems with that configuration, the flags Tunnel or Custom Tunnel url could be used
@@ -100,12 +108,11 @@ export async function generateFrontendURL(options: FrontendURLOptions): Promise<
100108
}
101109

102110
if (options.noTunnelUseLocalhost) {
103-
frontendPort = options.port ?? (await getAvailableTCPPort())
111+
frontendPort = options.port
104112
frontendUrl = 'https://localhost'
105113
} else if (options.tunnelClient) {
106-
const url = await pollTunnelURL(options.tunnelClient)
107114
frontendPort = options.tunnelClient.port
108-
frontendUrl = url
115+
frontendUrl = await pollTunnelURL(options.tunnelClient)
109116
}
110117

111118
return {frontendUrl, frontendPort, usingLocalhost}

0 commit comments

Comments
 (0)