Skip to content

Commit 6ec2d7e

Browse files
create indentity client interface
1 parent 7f53b75 commit 6ec2d7e

File tree

6 files changed

+169
-0
lines changed

6 files changed

+169
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {ApplicationToken, IdentityToken} from '../../session/schema.js'
2+
import {ExchangeScopes} from '../../session/exchange.js'
3+
import {API} from '../../api.js'
4+
5+
export abstract class IdentityBaseClient {
6+
abstract requestAndPollForAccessToken(_scopes: string[]): Promise<IdentityToken>
7+
8+
abstract exchangeAccessForApplicationTokens(
9+
identityToken: IdentityToken,
10+
scopes: ExchangeScopes,
11+
store?: string,
12+
): Promise<{[x: string]: ApplicationToken}>
13+
14+
abstract refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken>
15+
16+
clientId(): string {
17+
return ''
18+
}
19+
20+
applicationId(_api: API): string {
21+
return ''
22+
}
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {IdentityBaseClient} from './identity-base-client.js'
2+
import {ApplicationToken, IdentityToken} from '../../session/schema.js'
3+
import {ExchangeScopes} from '../../session/exchange.js'
4+
5+
export class IdentityMockClient extends IdentityBaseClient {
6+
async requestAndPollForAccessToken(_scopes: string[]): Promise<IdentityToken> {
7+
return {} as IdentityToken
8+
}
9+
10+
async exchangeAccessForApplicationTokens(
11+
_identityToken: IdentityToken,
12+
_scopes: ExchangeScopes,
13+
_store?: string,
14+
): Promise<{[x: string]: ApplicationToken}> {
15+
return {}
16+
}
17+
18+
async refreshAccessToken(_currentToken: IdentityToken): Promise<IdentityToken> {
19+
return {} as IdentityToken
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {IdentityBaseClient} from './identity-base-client.js'
2+
import {ApplicationToken, IdentityToken} from '../../session/schema.js'
3+
import {ExchangeScopes} from '../../session/exchange.js'
4+
5+
export class IdentityServiceClient extends IdentityBaseClient {
6+
async requestAndPollForAccessToken(_scopes: string[]): Promise<IdentityToken> {
7+
return {} as IdentityToken
8+
}
9+
10+
async exchangeAccessForApplicationTokens(
11+
_identityToken: IdentityToken,
12+
_scopes: ExchangeScopes,
13+
_store?: string,
14+
): Promise<{[x: string]: ApplicationToken}> {
15+
return {}
16+
}
17+
18+
async refreshAccessToken(_currentToken: IdentityToken): Promise<IdentityToken> {
19+
return {} as IdentityToken
20+
}
21+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {Environment} from '../../context/service.js'
2+
import {describe, expect, test, vi, beforeEach} from 'vitest'
3+
4+
const mockServiceEnvironment = vi.fn()
5+
const mockIsRunning2024 = vi.fn()
6+
7+
vi.mock('../../context/service.js', async () => {
8+
const actual = await vi.importActual('../../context/service.js')
9+
return {
10+
...actual,
11+
serviceEnvironment: (...args: unknown[]) => mockServiceEnvironment(...args),
12+
}
13+
})
14+
15+
vi.mock('../../../../public/node/vendor/dev_server/dev-server-2024.js', async () => {
16+
const actual = await vi.importActual('../../../../public/node/vendor/dev_server/dev-server-2024.js')
17+
return {
18+
...actual,
19+
isRunning2024: (...args: unknown[]) => mockIsRunning2024(...args),
20+
}
21+
})
22+
23+
describe('getIdentityClient', () => {
24+
beforeEach(async () => {
25+
mockServiceEnvironment.mockReset()
26+
mockIsRunning2024.mockReset()
27+
vi.resetModules()
28+
})
29+
30+
test('returns IdentityServiceClient when environment is Production', async () => {
31+
mockServiceEnvironment.mockReturnValue(Environment.Production)
32+
mockIsRunning2024.mockReturnValue(false)
33+
34+
const {getIdentityClient} = await import('./instance.js')
35+
36+
const instance = getIdentityClient()
37+
38+
expect(instance.constructor.name).toBe('IdentityServiceClient')
39+
})
40+
41+
test('returns IdentityServiceClient when environment is Local and identity service is running', async () => {
42+
mockServiceEnvironment.mockReturnValue(Environment.Local)
43+
mockIsRunning2024.mockReturnValue(true)
44+
45+
const {getIdentityClient} = await import('./instance.js')
46+
47+
const instance = getIdentityClient()
48+
49+
expect(instance.constructor.name).toBe('IdentityServiceClient')
50+
expect(mockIsRunning2024).toHaveBeenCalledWith('identity')
51+
})
52+
53+
test('returns IdentityMockClient when environment is Local and identity service is not running', async () => {
54+
mockServiceEnvironment.mockReturnValue(Environment.Local)
55+
mockIsRunning2024.mockReturnValue(false)
56+
57+
const {getIdentityClient} = await import('./instance.js')
58+
59+
const instance = getIdentityClient()
60+
61+
expect(instance.constructor.name).toBe('IdentityMockClient')
62+
expect(mockIsRunning2024).toHaveBeenCalledWith('identity')
63+
})
64+
65+
test('returns the same instance on subsequent calls (singleton pattern)', async () => {
66+
mockServiceEnvironment.mockReturnValue(Environment.Production)
67+
mockIsRunning2024.mockReturnValue(false)
68+
69+
const {getIdentityClient} = await import('./instance.js')
70+
71+
const firstInstance = getIdentityClient()
72+
const secondInstance = getIdentityClient()
73+
74+
expect(firstInstance).toBe(secondInstance)
75+
expect(mockServiceEnvironment).toHaveBeenCalledTimes(1)
76+
})
77+
})
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {IdentityBaseClient} from './identity-base-client.js'
2+
import {IdentityMockClient} from './identity-mock-client.js'
3+
import {IdentityServiceClient} from './identity-service-client.js'
4+
import {Environment, serviceEnvironment} from '../../context/service.js'
5+
import {isRunning2024} from '../../../../public/node/vendor/dev_server/dev-server-2024.js'
6+
7+
let _identityClient: IdentityBaseClient | undefined
8+
9+
export function getIdentityClient() {
10+
if (!_identityClient) {
11+
const isLocal = serviceEnvironment() === Environment.Local
12+
const identityServiceRunning = isRunning2024('identity')
13+
const client = isLocal && !identityServiceRunning ? new IdentityMockClient() : new IdentityServiceClient()
14+
_identityClient = client
15+
}
16+
17+
return _identityClient
18+
}

packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2024.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ function assertRunning2024(projectName: string): void {
4646
})
4747
}
4848

49+
export function isRunning2024(projectName: string) {
50+
try {
51+
assertRunning2024(projectName)
52+
return true
53+
} catch (_) {
54+
return false
55+
}
56+
}
57+
4958
function getBackendIp(projectName: string): string {
5059
try {
5160
const backendIp = resolveBackendHost(projectName)

0 commit comments

Comments
 (0)