Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connect: use the public /v1/content/{guid}/environment endpoints #40

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 26 additions & 23 deletions __tests__/EnvironmentUpdater.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ import * as rsconnect from '../src/main'

describe('EnvironmentUpdater', () => {
let eu: rsconnect.EnvironmentUpdater
let client: FakeAPIClient

beforeEach(() => {
eu = new rsconnect.EnvironmentUpdater(new FakeAPIClient())
client = new FakeAPIClient()
eu = new rsconnect.EnvironmentUpdater(client)
process.chdir = jest.fn()
})

describe('updateAppEnvironment', () => {
it('works', async () => {
process.env.CONNECT_ENV_SET_SECRET = 'eye of newt'
const env = await eu.updateAppEnvironment(42, './somewhar/up/er')
expect(env.get('MODE')).toBe('ludicrous')
expect(env.get('SECRET')).toBe('eye of newt')
const vars = await eu.updateAppEnvironment('the-content-guid', './somewhar/up/er')
expect(vars.sort((a, b) => a.localeCompare(b))).toStrictEqual(['MODE', 'SECRET'])
expect(client.fakeState).toStrictEqual({
'the-content-guid': {
MODE: 'ludicrous',
SECRET: 'eye of newt'
}
})
})
})
})
Expand All @@ -27,31 +34,27 @@ class FakeAPIClient extends rsconnect.APIClient {
apiKey: 'notAsEcRet'
})
this.fakeState = {
42: {
appId: 42,
version: 4,
values: {
MODE: 'ludicrous'
}
'the-content-guid': {
MODE: 'ludicrous'
}
}
}

public async getAppEnvironment (appID: number): Promise<any> {
return this.fakeState[appID]
public async getAppEnvironment (appGUID: string): Promise<any> {
const state = this.fakeState[appGUID] !== undefined ? this.fakeState[appGUID] : {}
return Object.keys(state)
}

public async updateAppEnvironment (appID: number, version: number, env: rsconnect.Environment): Promise<any> {
const origState = this.fakeState[appID] !== undefined ? this.fakeState[appID] : { values: {} }
this.fakeState[appID] = {
...origState,
appId: appID,
version,
values: {
...origState.values,
...Object.fromEntries(env.entries())
public async updateAppEnvironment (appGUID: string, env: rsconnect.Environment): Promise<any> {
const state = this.fakeState[appGUID] !== undefined ? this.fakeState[appGUID] : {}
Array.from(env.keys()).forEach(key => {
const value = env.get(key)
if (value === null || value === undefined) {
state.delete(key)
} else {
state[key] = value
}
}
return {}
})
this.fakeState[appGUID] = state
}
}
21 changes: 9 additions & 12 deletions src/APIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import qs from 'qs'
import { debugLog, debugEnabled } from './debugLog'
import {
Application,
AppEnvironmentResponse,
ClientTaskResponse,
ExtendedBundleResponse,
ListApplicationsParams,
Expand Down Expand Up @@ -139,19 +138,17 @@ export class APIClient {
})
}

public async getAppEnvironment (appID: number): Promise<AppEnvironmentResponse> {
return await this.client.get(`applications/${appID}/environment`)
.then((resp: AxiosResponse) => {
const camelized = keysToCamel(resp.data)
camelized.values = resp.data.values
return camelized
})
public async getAppEnvironment (appGUID: string): Promise<string[]> {
return await this.client.get(`v1/content/${appGUID}/environment`)
.then((resp: AxiosResponse) => resp.data)
}

public async updateAppEnvironment (appID: number, version: number, env: Environment): Promise<AxiosResponse> {
return await this.client.post(
`applications/${appID}/environment`,
{ app_id: appID, version, values: Object.fromEntries(env.entries()) }
public async updateAppEnvironment (appGUID: string, env: Environment): Promise<AxiosResponse> {
return await this.client.patch(
`v1/content/${appGUID}/environment`,
Array.from(env.keys()).map(key => {
return { name: key, value: env.get(key) }
})
)
}

Expand Down
41 changes: 17 additions & 24 deletions src/EnvironmentUpdater.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { APIClient } from './APIClient'
import { Environment } from './Environment'
import { AppEnvironmentResponse } from './api-types'
import { debugLog } from './debugLog'

export class EnvironmentUpdater {
Expand All @@ -10,14 +9,13 @@ export class EnvironmentUpdater {
this.client = client
}

public async updateAppEnvironment (appID: number, dir: string = '.'): Promise<Environment> {
public async updateAppEnvironment (appGUID: string, dir: string = '.'): Promise<string[]> {
debugLog(() => [
'EnvironmentUpdater: updating environment for',
`app=${appID}`,
'EnvironmentUpdater: loading environment for',
`app=${appGUID}`,
`dir=${dir}`
].join(' '))

const { version } = await this.client.getAppEnvironment(appID)
const curDir = process.cwd()
const env = new Environment()

Expand All @@ -31,33 +29,28 @@ export class EnvironmentUpdater {
if (env.size === 0) {
debugLog(() => [
'EnvironmentUpdater: no environment variables found for',
`app=${appID}`,
`app=${appGUID}`,
`dir=${dir}`
].join(' '))
} else {
debugLog(() => [
'EnvironmentUpdater: updating environment for',
`app=${appGUID}`,
`dir=${dir}`
].join(' '))
return env
}

debugLog(() => [
'EnvironmentUpdater: updating environment based on',
`version=${version}`,
'for',
`app=${appID}`,
`dir=${dir}`
].join(' '))
await this.client.updateAppEnvironment(appGUID, env)
}

await this.client.updateAppEnvironment(appID, version, env)
return await this.client.getAppEnvironment(appID)
.then((resp: AppEnvironmentResponse) => {
return await this.client.getAppEnvironment(appGUID)
.then((resp: string[]) => {
debugLog(() => [
'EnvironmentUpdater: converting env object to map',
'EnvironmentUpdater: active environment variables for',
`app=${appGUID}`,
`resp=${JSON.stringify(resp)}`
].join(' '))

const newEnv = new Environment()
for (const key in resp.values) {
newEnv.set(key, resp.values[key])
}
return newEnv
return resp
})
}
}
7 changes: 0 additions & 7 deletions src/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ export interface AppGitRecord {
lastError: string
}

export interface AppEnvironmentResponse {
appId: number
appGuid: string
version: number
values: any
}

export interface Application {
id: number
guid: string
Expand Down