From 7ba8b9408ca85a5458a7f3206db43132d6b9d38a Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 17 Apr 2024 12:22:45 -0700 Subject: [PATCH 01/23] update cross-fetch dependency to v4, bump version and add publish command --- package-lock.json | 24 ++++++++++++------------ package.json | 10 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69c689b..6b92835 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { - "name": "fly-admin", - "version": "0.0.0-automated", + "name": "@triplit/fly-admin", + "version": "1.6.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "fly-admin", - "version": "0.0.0-automated", + "name": "@triplit/fly-admin", + "version": "1.6.2", "license": "MIT", "dependencies": { - "cross-fetch": "^3.1.5" + "cross-fetch": "^4.0.0" }, "devDependencies": { "@types/node": "^18.15.0", @@ -2130,11 +2130,11 @@ "dev": true }, "node_modules/cross-fetch": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", - "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dependencies": { - "node-fetch": "^2.6.11" + "node-fetch": "^2.6.12" } }, "node_modules/cross-spawn": { @@ -4827,9 +4827,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, diff --git a/package.json b/package.json index 6f7beb8..91bf99f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "fly-admin", - "version": "0.0.0-automated", + "name": "@triplit/fly-admin", + "version": "1.6.2", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -14,7 +14,8 @@ "lint": "eslint src/**/*.ts", "test": "jest", "gen:types": "npx swagger-typescript-api -p https://docs.machines.dev/swagger/doc.json -o ./src/lib --extract-enums --extract-request-params --no-client -n types.ts", - "all": "npm run build && npm run format && npm run lint && npm test" + "all": "npm run build && npm run format && npm run lint && npm test", + "publish": "npm run build && npm publish --access public" }, "repository": { "type": "git", @@ -25,10 +26,9 @@ "api", "client" ], - "author": "Supabase", "license": "MIT", "dependencies": { - "cross-fetch": "^3.1.5" + "cross-fetch": "^4.0.0" }, "devDependencies": { "@types/node": "^18.15.0", From eebd2563aa0ea441f7500c3f02b302ceadd423f5 Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 17 Apr 2024 12:25:09 -0700 Subject: [PATCH 02/23] update return type of API methods to {data, error} --- src/client.ts | 79 ++++++++++++++++++++++++++++++++ src/lib/app.ts | 45 +++++++++++++------ src/lib/machine.ts | 99 +++++++++++++++++++++++++++-------------- src/lib/network.ts | 9 ++-- src/lib/organization.ts | 5 ++- src/lib/regions.ts | 5 ++- src/lib/secret.ts | 13 ++++-- src/lib/utils.ts | 3 ++ src/lib/volume.ts | 33 +++++++++----- 9 files changed, 219 insertions(+), 72 deletions(-) create mode 100644 src/lib/utils.ts diff --git a/src/client.ts b/src/client.ts index ed1a6cf..82e5156 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6,6 +6,7 @@ import { Organization } from './lib/organization' import { Secret } from './lib/secret' import { Volume } from './lib/volume' import { Regions } from './lib/regions' +import { APIResponse } from './lib/utils' export const FLY_API_GRAPHQL = 'https://api.fly.io' export const FLY_API_HOSTNAME = 'https://api.machines.dev' @@ -92,6 +93,47 @@ class Client { return data } + // TODO: make sure these methods using this method are using return values correctly + async safeGqlPost(payload: GraphQLRequest): Promise> { + try { + const token = this.apiKey + const resp = await crossFetch(`${this.graphqlUrl}/graphql`, { + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }) + if (!resp.ok) { + const text = await resp.text() + return { + data: undefined, + error: { status: resp.status, message: text }, + } + } + const { data, errors }: GraphQLResponse = await resp.json() + if (errors) { + return { + data: undefined, + error: { status: 500, message: JSON.stringify(errors) }, + } + } + return { data, error: undefined } + } catch (e) { + if (e instanceof Error) { + return { data: undefined, error: { status: 500, message: e.message } } + } + if (typeof e === 'string') { + return { data: undefined, error: { status: 500, message: e } } + } + return { + data: undefined, + error: { status: 500, message: 'An unknown error occurred.' }, + } + } + } + async restOrThrow( path: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET', @@ -111,6 +153,43 @@ class Client { } return text ? JSON.parse(text) : undefined } + + async safeRest( + path: string, + method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET', + body?: U + ): Promise> { + try { + const resp = await crossFetch(`${this.apiUrl}/v1/${path}`, { + method, + headers: { + Authorization: `Bearer ${this.apiKey}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }) + if (!resp.ok) { + const text = await resp.text() + return { + data: undefined, + error: { status: resp.status, message: text }, + } + } + const data = await resp.json() + return { data, error: undefined } + } catch (e) { + if (e instanceof Error) { + return { data: undefined, error: { status: 500, message: e.message } } + } + if (typeof e === 'string') { + return { data: undefined, error: { status: 500, message: e } } + } + return { + data: undefined, + error: { status: 500, message: 'An unknown error occurred.' }, + } + } + } } export default Client diff --git a/src/lib/app.ts b/src/lib/app.ts index a94136a..ca53f8c 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -1,4 +1,5 @@ import Client from '../client' +import { APIResponse } from './utils' export type ListAppRequest = string @@ -67,37 +68,53 @@ export class App { this.client = client } - async listApps(org_slug: ListAppRequest): Promise { + async listApps( + org_slug: ListAppRequest + ): Promise> { const path = `apps?org_slug=${org_slug}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async getApp(app_name: GetAppRequest): Promise { + async getApp(app_name: GetAppRequest): Promise> { const path = `apps/${app_name}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async getAppDetailed(app_name: GetAppRequest): Promise { - const { app } = await this.client.gqlPostOrThrow({ + async getAppDetailed( + app_name: GetAppRequest + ): Promise> { + const response = await this.client.safeGqlPost< + string, + { app: AppResponse } + >({ query: getAppQuery, variables: { name: app_name }, - }) as { app: AppResponse } + }) - const ipAddresses = app.ipAddresses as unknown as { nodes: IPAddress[] } + if (response.error) { + return response + } + + const ipAddresses = response.data.app.ipAddresses as unknown as { + nodes: IPAddress[] + } return { - ...app, - ipAddresses: ipAddresses.nodes, + data: { + ...response.data.app, + ipAddresses: ipAddresses.nodes, + }, + error: undefined, } } - async createApp(payload: CreateAppRequest): Promise { + async createApp(payload: CreateAppRequest): Promise> { const path = 'apps' - return await this.client.restOrThrow(path, 'POST', payload) + return await this.client.safeRest(path, 'POST', payload) } - async deleteApp(app_name: DeleteAppRequest): Promise { + async deleteApp(app_name: DeleteAppRequest): Promise> { const path = `apps/${app_name}` - return await this.client.restOrThrow(path, 'DELETE') + return await this.client.safeRest(path, 'DELETE') } } diff --git a/src/lib/machine.ts b/src/lib/machine.ts index 1e009de..d8a9f0b 100644 --- a/src/lib/machine.ts +++ b/src/lib/machine.ts @@ -15,6 +15,7 @@ import { StateEnum as ApiMachineState, SignalRequestSignalEnum as ApiMachineSignal, } from './types' +import { APIResponse } from './utils' // We override the generated types from openapi spec to mark fields as non-optional export interface MachineConfig extends ApiMachineConfig { @@ -302,7 +303,9 @@ export class Machine { this.client = client } - async listMachines(app_name: ListMachineRequest): Promise { + async listMachines( + app_name: ListMachineRequest + ): Promise> { let path: string if (typeof app_name === 'string') { path = `apps/${app_name}/machines` @@ -312,116 +315,144 @@ export class Machine { const query = new URLSearchParams(params).toString() if (query) path += `?${query}` } - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async getMachine(payload: GetMachineRequest): Promise { + async getMachine( + payload: GetMachineRequest + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async createMachine(payload: CreateMachineRequest): Promise { + async createMachine( + payload: CreateMachineRequest + ): Promise> { const { app_name, ...body } = payload const path = `apps/${app_name}/machines` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } - async updateMachine(payload: UpdateMachineRequest): Promise { + async updateMachine( + payload: UpdateMachineRequest + ): Promise> { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } - async deleteMachine(payload: DeleteMachineRequest): Promise { + async deleteMachine( + payload: DeleteMachineRequest + ): Promise> { const { app_name, machine_id, force } = payload const query = force ? '?kill=true' : '' const path = `apps/${app_name}/machines/${machine_id}${query}` - return await this.client.restOrThrow(path, 'DELETE') + return await this.client.safeRest(path, 'DELETE') } - async startMachine(payload: StartMachineRequest): Promise { + async startMachine( + payload: StartMachineRequest + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/start` - return await this.client.restOrThrow(path, 'POST') + return await this.client.safeRest(path, 'POST') } - async stopMachine(payload: StopMachineRequest): Promise { + async stopMachine( + payload: StopMachineRequest + ): Promise> { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}/stop` - return await this.client.restOrThrow(path, 'POST', { + return await this.client.safeRest(path, 'POST', { signal: ApiMachineSignal.SIGTERM, ...body, }) } - async restartMachine(payload: RestartMachineRequest): Promise { + async restartMachine( + payload: RestartMachineRequest + ): Promise> { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}/restart` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } - async signalMachine(payload: SignalMachineRequest): Promise { + async signalMachine( + payload: SignalMachineRequest + ): Promise> { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}/signal` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } async listEvents( payload: ListEventsRequest - ): Promise { + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/events` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } async listVersions( payload: ListVersionsRequest - ): Promise { + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/versions` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async listProcesses(payload: ListProcessesRequest): Promise { + async listProcesses( + payload: ListProcessesRequest + ): Promise> { const { app_name, machine_id, ...params } = payload let path = `apps/${app_name}/machines/${machine_id}/ps` const query = new URLSearchParams(params).toString() if (query) path += `?${query}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async waitMachine(payload: WaitMachineRequest): Promise { + async waitMachine( + payload: WaitMachineRequest + ): Promise> { const { app_name, machine_id, ...params } = payload let path = `apps/${app_name}/machines/${machine_id}/wait` if (params.timeout?.endsWith('s')) params.timeout = params.timeout.slice(0, -1) const query = new URLSearchParams(params).toString() if (query) path += `?${query}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async getLease(payload: GetLeaseRequest): Promise { + async getLease( + payload: GetLeaseRequest + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/lease` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async acquireLease(payload: AcquireLeaseRequest): Promise { + async acquireLease( + payload: AcquireLeaseRequest + ): Promise> { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}/lease` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } - async cordonMachine(payload: CordonMachineRequest): Promise { + async cordonMachine( + payload: CordonMachineRequest + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/cordon` - return await this.client.restOrThrow(path, 'POST') + return await this.client.safeRest(path, 'POST') } - async uncordonMachine(payload: UncordonMachineRequest): Promise { + async uncordonMachine( + payload: UncordonMachineRequest + ): Promise> { const { app_name, machine_id } = payload const path = `apps/${app_name}/machines/${machine_id}/uncordon` - return await this.client.restOrThrow(path, 'POST') + return await this.client.safeRest(path, 'POST') } } diff --git a/src/lib/network.ts b/src/lib/network.ts index fafb668..17f8774 100644 --- a/src/lib/network.ts +++ b/src/lib/network.ts @@ -1,4 +1,5 @@ import Client from '../client' +import { APIResponse } from './utils' export enum AddressType { v4 = 'v4', @@ -71,8 +72,8 @@ export class Network { // Ref: https://github.com/superfly/flyctl/blob/master/api/resource_ip_addresses.go#L79 async allocateIpAddress( input: AllocateIPAddressInput - ): Promise { - return this.client.gqlPostOrThrow({ + ): Promise> { + return this.client.safeGqlPost({ query: allocateIpAddressQuery, variables: { input }, }) @@ -80,8 +81,8 @@ export class Network { async releaseIpAddress( input: ReleaseIPAddressInput - ): Promise { - return this.client.gqlPostOrThrow({ + ): Promise> { + return this.client.safeGqlPost({ query: releaseIpAddressQuery, variables: { input }, }) diff --git a/src/lib/organization.ts b/src/lib/organization.ts index 8954f3c..5e42356 100644 --- a/src/lib/organization.ts +++ b/src/lib/organization.ts @@ -1,4 +1,5 @@ import Client from '../client' +import { APIResponse } from './utils' export type GetOrganizationInput = string @@ -33,8 +34,8 @@ export class Organization { async getOrganization( slug: GetOrganizationInput - ): Promise { - return this.client.gqlPostOrThrow({ + ): Promise> { + return this.client.safeGqlPost({ query: getOrganizationQuery, variables: { slug }, }) diff --git a/src/lib/regions.ts b/src/lib/regions.ts index b8caaf3..d9d8817 100644 --- a/src/lib/regions.ts +++ b/src/lib/regions.ts @@ -1,4 +1,5 @@ import Client from '../client' +import { APIResponse } from './utils' interface RegionResponse { name: string @@ -40,8 +41,8 @@ export class Regions { this.client = client } - async getRegions(): Promise { - return this.client.gqlPostOrThrow({ + async getRegions(): Promise> { + return this.client.safeGqlPost({ query: getRegionsQuery, variables: {}, }) diff --git a/src/lib/secret.ts b/src/lib/secret.ts index 70d4f60..a39098f 100644 --- a/src/lib/secret.ts +++ b/src/lib/secret.ts @@ -1,4 +1,5 @@ import Client from '../client' +import { APIResponse } from './utils' export interface SetSecretsInput { appId: string @@ -90,15 +91,19 @@ export class Secret { this.client = client } - async setSecrets(input: SetSecretsInput): Promise { - return await this.client.gqlPostOrThrow({ + async setSecrets( + input: SetSecretsInput + ): Promise> { + return await this.client.safeGqlPost({ query: setSecretsQuery, variables: { input }, }) } - async unsetSecrets(input: UnsetSecretsInput): Promise { - return await this.client.gqlPostOrThrow({ + async unsetSecrets( + input: UnsetSecretsInput + ): Promise> { + return await this.client.safeGqlPost({ query: unsetSecretsQuery, variables: { input }, }) diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..bf21e8d --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,3 @@ +export type APIResponse = + | { data: V; error: undefined } + | { data: undefined; error: { status: number; message: string } } diff --git a/src/lib/volume.ts b/src/lib/volume.ts index 4b449f5..f13be4a 100644 --- a/src/lib/volume.ts +++ b/src/lib/volume.ts @@ -1,5 +1,6 @@ import Client from '../client' import { CreateVolumeRequest as ApiCreateVolumeRequest } from './types' +import { APIResponse } from './utils' export type ListVolumesRequest = string @@ -62,42 +63,50 @@ export class Volume { this.client = client } - async listVolumes(app_name: ListVolumesRequest): Promise { + async listVolumes( + app_name: ListVolumesRequest + ): Promise> { const path = `apps/${app_name}/volumes` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async getVolume(payload: GetVolumeRequest): Promise { + async getVolume( + payload: GetVolumeRequest + ): Promise> { const { app_name, volume_id } = payload const path = `apps/${app_name}/volumes/${volume_id}` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } - async createVolume(payload: CreateVolumeRequest): Promise { + async createVolume( + payload: CreateVolumeRequest + ): Promise> { const { app_name, ...body } = payload const path = `apps/${app_name}/volumes` - return await this.client.restOrThrow(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body) } - async deleteVolume(payload: DeleteVolumeRequest): Promise { + async deleteVolume( + payload: DeleteVolumeRequest + ): Promise> { const { app_name, volume_id } = payload const path = `apps/${app_name}/volumes/${volume_id}` - return await this.client.restOrThrow(path, 'DELETE') + return await this.client.safeRest(path, 'DELETE') } async extendVolume( payload: ExtendVolumeRequest - ): Promise { + ): Promise> { const { app_name, volume_id, ...body } = payload const path = `apps/${app_name}/volumes/${volume_id}/extend` - return await this.client.restOrThrow(path, 'PUT', body) + return await this.client.safeRest(path, 'PUT', body) } async listSnapshots( payload: ListSnapshotsRequest - ): Promise { + ): Promise> { const { app_name, volume_id } = payload const path = `apps/${app_name}/volumes/${volume_id}/snapshots` - return await this.client.restOrThrow(path) + return await this.client.safeRest(path) } } From ff62db3c9edf380721d84d40ef7c099329dab9fa Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 17 Apr 2024 12:26:56 -0700 Subject: [PATCH 03/23] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 91bf99f..4acf31f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.6.2", + "version": "1.6.3", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From da06f915d1d7dfde8d97219880a3682712a4df13 Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Thu, 2 May 2024 13:32:18 -0700 Subject: [PATCH 04/23] add machines to app detail response --- src/lib/app.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/lib/app.ts b/src/lib/app.ts index ca53f8c..1bffac4 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -29,6 +29,14 @@ const getAppQuery = `query($name: String!) { address } } + machines { + nodes { + id + name + state + region + } + } } }` @@ -46,6 +54,14 @@ export interface AppResponse { slug: string } ipAddresses: IPAddress[] + machines: AppMachine[] +} + +interface AppMachine { + id: string + name: string + state: string + region: string } export interface IPAddress { @@ -99,10 +115,15 @@ export class App { nodes: IPAddress[] } + const machines = response.data.app.machines as unknown as { + nodes: AppMachine[] + } + return { data: { ...response.data.app, ipAddresses: ipAddresses.nodes, + machines: machines.nodes, }, error: undefined, } From a909f95a997dbda8d0b1c59f7aa85dfe7db0e351 Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Thu, 2 May 2024 13:32:58 -0700 Subject: [PATCH 05/23] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4acf31f..ccd4eb9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.6.3", + "version": "1.6.4", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From 1751462c43702d407e30a97d303ba9fd01b5d4e5 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:39:43 -0500 Subject: [PATCH 06/23] Add lease deletion and using lease for updates --- package-lock.json | 4 ++-- src/client.ts | 4 +++- src/lib/machine.ts | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b92835..13aa1d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triplit/fly-admin", - "version": "1.6.2", + "version": "1.6.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triplit/fly-admin", - "version": "1.6.2", + "version": "1.6.4", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/src/client.ts b/src/client.ts index 82e5156..ef15ce5 100644 --- a/src/client.ts +++ b/src/client.ts @@ -157,7 +157,8 @@ class Client { async safeRest( path: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET', - body?: U + body?: U, + headers?: Record ): Promise> { try { const resp = await crossFetch(`${this.apiUrl}/v1/${path}`, { @@ -165,6 +166,7 @@ class Client { headers: { Authorization: `Bearer ${this.apiKey}`, 'Content-Type': 'application/json', + ...headers, }, body: JSON.stringify(body), }) diff --git a/src/lib/machine.ts b/src/lib/machine.ts index d8a9f0b..8d3e598 100644 --- a/src/lib/machine.ts +++ b/src/lib/machine.ts @@ -227,6 +227,7 @@ export type StartMachineRequest = GetMachineRequest export interface UpdateMachineRequest extends GetMachineRequest { config: MachineConfig + lease_nonce: string } export type ListEventsRequest = GetMachineRequest @@ -337,9 +338,11 @@ export class Machine { async updateMachine( payload: UpdateMachineRequest ): Promise> { - const { app_name, machine_id, ...body } = payload + const { app_name, machine_id, lease_nonce, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}` - return await this.client.safeRest(path, 'POST', body) + return await this.client.safeRest(path, 'POST', body, { + 'fly-machine-lease-nonce': lease_nonce, + }) } async deleteMachine( @@ -440,6 +443,16 @@ export class Machine { return await this.client.safeRest(path, 'POST', body) } + async deleteLease( + payload: DeleteLeaseRequest + ): Promise> { + const { app_name, machine_id, nonce } = payload + const path = `apps/${app_name}/machines/${machine_id}/lease/${nonce}` + return await this.client.safeRest(path, 'DELETE', { + 'fly-machine-lease-nonce': nonce, + }) + } + async cordonMachine( payload: CordonMachineRequest ): Promise> { From ae0853a7bc82693f65e1e37f4d96359d0b41afe1 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:43:03 -0500 Subject: [PATCH 07/23] Update types --- src/lib/machine.ts | 55 +++++------ src/lib/types.ts | 227 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 202 insertions(+), 80 deletions(-) diff --git a/src/lib/machine.ts b/src/lib/machine.ts index 8d3e598..06baf1f 100644 --- a/src/lib/machine.ts +++ b/src/lib/machine.ts @@ -1,24 +1,25 @@ import Client from '../client' import { - ApiMachineConfig, - ApiMachineInit, - ApiMachineService, - ApiMachineMount, - ApiMachinePort, - ApiMachineCheck, - ApiMachineRestart, - ApiMachineGuest, + FlyMachineConfig, + FlyMachineInit, + FlyMachineService, + FlyMachineMount, + FlyMachinePort, + FlyMachineCheck, + FlyMachineRestart, + FlyMachineGuest, CheckStatus as ApiCheckStatus, CreateMachineRequest as ApiCreateMachineRequest, ImageRef as ApiImageRef, - Machine as ApiMachine, - StateEnum as ApiMachineState, - SignalRequestSignalEnum as ApiMachineSignal, + Machine as FlyMachine, + StateEnum as FlyMachineState, + SignalRequestSignalEnum as FlyMachineSignal, + FlyDuration, } from './types' import { APIResponse } from './utils' // We override the generated types from openapi spec to mark fields as non-optional -export interface MachineConfig extends ApiMachineConfig { +export interface MachineConfig extends FlyMachineConfig { // The Docker image to run image: string // Optionally one of hourly, daily, weekly, monthly. Runs machine at the given interval. Interval starts at time of machine creation @@ -98,7 +99,7 @@ export enum MachineState { Destroyed = 'destroyed', } -interface MachineMount extends ApiMachineMount { +interface MachineMount extends FlyMachineMount { encrypted: boolean // Absolute path on the VM where the volume should be mounted. i.e. /data path: string @@ -119,14 +120,14 @@ export enum ConnectionHandler { PROXY_PROTO = 'proxy_proto', } -interface MachinePort extends ApiMachinePort { +interface MachinePort extends FlyMachinePort { // Public-facing port number port: number // Array of connection handlers for TCP-based services. handlers?: ConnectionHandler[] } -interface MachineService extends ApiMachineService { +interface MachineService extends FlyMachineService { protocol: 'tcp' | 'udp' internal_port: number ports: MachinePort[] @@ -141,18 +142,18 @@ interface MachineService extends ApiMachineService { } } -interface MachineCheck extends ApiMachineCheck { +interface MachineCheck extends FlyMachineCheck { // tcp or http type: 'tcp' | 'http' // The port to connect to, likely should be the same as internal_port port: number // The time between connectivity checks - interval: string + interval: FlyDuration // The maximum time a connection can take before being reported as failing its healthcheck - timeout: string + timeout: FlyDuration } -interface MachineGuest extends ApiMachineGuest { +interface MachineGuest extends FlyMachineGuest { cpu_kind: 'shared' | 'performance' cpus: number memory_mb: number @@ -173,7 +174,7 @@ interface MachineImageRef extends Omit { labels: Record | null } -export interface MachineResponse extends Omit { +export interface MachineResponse extends Omit { id: string name: string state: MachineState @@ -182,11 +183,11 @@ export interface MachineResponse extends Omit { private_ip: string config: { env: Record - init: ApiMachineInit + init: FlyMachineInit mounts: MachineMount[] services: MachineService[] checks: Record - restart: ApiMachineRestart + restart: FlyMachineRestart guest: MachineGuest size: 'shared-cpu-1x' | 'shared-cpu-2x' | 'shared-cpu-4x' } & MachineConfig @@ -216,11 +217,11 @@ export interface RestartMachineRequest extends GetMachineRequest { } export interface SignalMachineRequest extends GetMachineRequest { - signal: ApiMachineSignal + signal: FlyMachineSignal } export interface StopMachineRequest extends RestartMachineRequest { - signal?: ApiMachineSignal + signal?: FlyMachineSignal } export type StartMachineRequest = GetMachineRequest @@ -259,12 +260,12 @@ export interface WaitMachineRequest extends GetMachineRequest { instance_id?: string // Default timeout is 60 (seconds) timeout?: string - state?: ApiMachineState + state?: FlyMachineState } export interface WaitMachineStopRequest extends WaitMachineRequest { instance_id: string - state?: ApiMachineState.Stopped + state?: FlyMachineState.Stopped } export interface MachineVersionResponse { @@ -368,7 +369,7 @@ export class Machine { const { app_name, machine_id, ...body } = payload const path = `apps/${app_name}/machines/${machine_id}/stop` return await this.client.safeRest(path, 'POST', { - signal: ApiMachineSignal.SIGTERM, + signal: FlyMachineSignal.SIGTERM, ...body, }) } diff --git a/src/lib/types.ts b/src/lib/types.ts index 6311438..10a2307 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -25,19 +25,20 @@ export interface CheckStatus { export interface CreateAppRequest { app_name?: string - app_role_id?: string + enable_subdomains?: boolean network?: string org_slug?: string } export interface CreateLeaseRequest { description?: string + /** seconds lease will be valid */ ttl?: number } export interface CreateMachineRequest { /** An object defining the Machine configuration */ - config?: ApiMachineConfig + config?: FlyMachineConfig lease_ttl?: number lsvd?: boolean /** Unique name for this Machine. If omitted, one is generated for you */ @@ -48,8 +49,13 @@ export interface CreateMachineRequest { skip_service_registration?: boolean } +export interface CreateOIDCTokenRequest { + aud?: string +} + export interface CreateVolumeRequest { - compute?: ApiMachineGuest + compute?: FlyMachineGuest + compute_image?: string encrypted?: boolean fstype?: string machines_only?: boolean @@ -120,9 +126,10 @@ export interface ListenSocket { export interface Machine { checks?: CheckStatus[] - config?: ApiMachineConfig + config?: FlyMachineConfig created_at?: string events?: MachineEvent[] + host_status?: MachineHostStatusEnum id?: string image_ref?: ImageRef /** InstanceID is unique for each version of the machine */ @@ -154,7 +161,7 @@ export interface MachineExecRequest { } export interface MachineVersion { - user_config?: ApiMachineConfig + user_config?: FlyMachineConfig version?: string } @@ -180,12 +187,12 @@ export interface SignalRequest { export interface StopRequest { signal?: string - timeout?: string + timeout?: FlyDuration } export interface UpdateMachineRequest { /** An object defining the Machine configuration */ - config?: ApiMachineConfig + config?: FlyMachineConfig current_version?: string lease_ttl?: number lsvd?: boolean @@ -198,12 +205,14 @@ export interface UpdateMachineRequest { } export interface UpdateVolumeRequest { + auto_backup_enabled?: boolean snapshot_retention?: number } export interface Volume { attached_alloc_id?: string attached_machine_id?: string + auto_backup_enabled?: boolean block_size?: number blocks?: number blocks_avail?: number @@ -211,6 +220,7 @@ export interface Volume { created_at?: string encrypted?: boolean fstype?: string + host_status?: VolumeHostStatusEnum id?: string name?: string region?: string @@ -228,12 +238,31 @@ export interface VolumeSnapshot { status?: string } -export interface ApiDNSConfig { +export interface FlyDNSConfig { + dns_forward_rules?: FlyDnsForwardRule[] + nameservers?: string[] + options?: FlyDnsOption[] + searches?: string[] skip_registration?: boolean } +export interface FlyDuration { + 'time.Duration'?: FlyDurationTimeDurationEnum +} + +/** EnvVar defines an environment variable to be populated from a machine field, env_var */ +export interface FlyEnvFrom { + /** + * EnvVar is required and is the name of the environment variable that will be set from the + * secret. It must be a valid environment variable name. + */ + env_var?: string + /** FieldRef selects a field of the Machine: supports id, version, app_name, private_ip, region, image. */ + field_ref?: FlyEnvFromFieldRefEnum +} + /** A file that will be written to the Machine. One of RawValue or SecretName must be set. */ -export interface ApiFile { +export interface FlyFile { /** * GuestPath is the path on the machine where the file will be written and must be an absolute path. * For example: /full/path/to/file.json @@ -245,23 +274,24 @@ export interface ApiFile { secret_name?: string } -export interface ApiHTTPOptions { +export interface FlyHTTPOptions { compress?: boolean h2_backend?: boolean - response?: ApiHTTPResponseOptions + response?: FlyHTTPResponseOptions } -export interface ApiHTTPResponseOptions { +export interface FlyHTTPResponseOptions { headers?: Record + pristine?: boolean } /** An optional object that defines one or more named checks. The key for each check is the check name. */ -export interface ApiMachineCheck { +export interface FlyMachineCheck { /** The time to wait after a VM starts before checking its health */ - grace_period?: string - headers?: ApiMachineHTTPHeader[] + grace_period?: FlyDuration + headers?: FlyMachineHTTPHeader[] /** The time between connectivity checks */ - interval?: string + interval?: FlyDuration /** For http checks, the HTTP method to use to when making the request */ method?: string /** For http checks, the path to send the request to */ @@ -271,7 +301,7 @@ export interface ApiMachineCheck { /** For http checks, whether to use http or https */ protocol?: string /** The maximum time a connection can take before being reported as failing its health check */ - timeout?: string + timeout?: FlyDuration /** If the protocol is https, the hostname to use for TLS certificate validation */ tls_server_name?: string /** For http checks with https protocol, whether or not to verify the TLS certificate */ @@ -280,28 +310,28 @@ export interface ApiMachineCheck { type?: string } -export interface ApiMachineConfig { +export interface FlyMachineConfig { /** Optional boolean telling the Machine to destroy itself once it’s complete (default false) */ auto_destroy?: boolean - checks?: Record + checks?: Record /** Deprecated: use Service.Autostart instead */ disable_machine_autostart?: boolean - dns?: ApiDNSConfig + dns?: FlyDNSConfig /** An object filled with key/value pairs to be set as environment variables */ env?: Record - files?: ApiFile[] - guest?: ApiMachineGuest + files?: FlyFile[] + guest?: FlyMachineGuest /** The docker image to run */ image?: string - init?: ApiMachineInit + init?: FlyMachineInit metadata?: Record - metrics?: ApiMachineMetrics - mounts?: ApiMachineMount[] - processes?: ApiMachineProcess[] + metrics?: FlyMachineMetrics + mounts?: FlyMachineMount[] + processes?: FlyMachineProcess[] /** The Machine restart policy defines whether and how flyd restarts a Machine after its main process exits. See https://fly.io/docs/machines/guides-examples/machine-restart-policy/. */ - restart?: ApiMachineRestart + restart?: FlyMachineRestart schedule?: string - services?: ApiMachineService[] + services?: FlyMachineService[] /** Deprecated: use Guest instead */ size?: string /** @@ -309,28 +339,29 @@ export interface ApiMachineConfig { * the standby machine will be started. */ standbys?: string[] - statics?: ApiStatic[] - stop_config?: ApiStopConfig + statics?: FlyStatic[] + stop_config?: FlyStopConfig } -export interface ApiMachineGuest { +export interface FlyMachineGuest { cpu_kind?: string cpus?: number gpu_kind?: string + gpus?: number host_dedication_id?: string kernel_args?: string[] memory_mb?: number } /** For http checks, an array of objects with string field Name and array of strings field Values. The key/value pairs specify header and header values that will get passed with the check call. */ -export interface ApiMachineHTTPHeader { +export interface FlyMachineHTTPHeader { /** The header name */ name?: string /** The header value */ values?: string[] } -export interface ApiMachineInit { +export interface FlyMachineInit { cmd?: string[] entrypoint?: string[] exec?: string[] @@ -339,12 +370,12 @@ export interface ApiMachineInit { tty?: boolean } -export interface ApiMachineMetrics { +export interface FlyMachineMetrics { path?: string port?: number } -export interface ApiMachineMount { +export interface FlyMachineMount { add_size_gb?: number encrypted?: boolean extend_threshold_percent?: number @@ -355,27 +386,40 @@ export interface ApiMachineMount { volume?: string } -export interface ApiMachinePort { +export interface FlyMachinePort { end_port?: number force_https?: boolean handlers?: string[] - http_options?: ApiHTTPOptions + http_options?: FlyHTTPOptions port?: number - proxy_proto_options?: ApiProxyProtoOptions + proxy_proto_options?: FlyProxyProtoOptions start_port?: number - tls_options?: ApiTLSOptions + tls_options?: FlyTLSOptions } -export interface ApiMachineProcess { +export interface FlyMachineProcess { cmd?: string[] entrypoint?: string[] env?: Record + /** EnvFrom can be provided to set environment variables from machine fields. */ + env_from?: FlyEnvFrom[] exec?: string[] + /** + * IgnoreAppSecrets can be set to true to ignore the secrets for the App the Machine belongs to + * and only use the secrets provided at the process level. The default/legacy behavior is to use + * the secrets provided at the App level. + */ + ignore_app_secrets?: boolean + /** + * Secrets can be provided at the process level to explicitly indicate which secrets should be + * used for the process. If not provided, the secrets provided at the machine level will be used. + */ + secrets?: FlyMachineSecret[] user?: string } /** The Machine restart policy defines whether and how flyd restarts a Machine after its main process exits. See https://fly.io/docs/machines/guides-examples/machine-restart-policy/. */ -export interface ApiMachineRestart { +export interface FlyMachineRestart { /** When policy is on-failure, the maximum number of times to attempt to restart the Machine before letting it stop. */ max_retries?: number /** @@ -383,53 +427,84 @@ export interface ApiMachineRestart { * * always - Always restart a Machine automatically and never let it enter a stopped state, even when the main process exits cleanly. * * on-failure - Try up to MaxRetries times to automatically restart the Machine if it exits with a non-zero exit code. Default when no explicit policy is set, and for Machines with schedules. */ - policy?: ApiMachineRestartPolicyEnum + policy?: FlyMachineRestartPolicyEnum +} + +/** A Secret needing to be set in the environment of the Machine. env_var is required */ +export interface FlyMachineSecret { + /** + * EnvVar is required and is the name of the environment variable that will be set from the + * secret. It must be a valid environment variable name. + */ + env_var?: string + /** + * Name is optional and when provided is used to reference a secret name where the EnvVar is + * different from what was set as the secret name. + */ + name?: string } -export interface ApiMachineService { +export interface FlyMachineService { autostart?: boolean autostop?: boolean - checks?: ApiMachineCheck[] - concurrency?: ApiMachineServiceConcurrency + checks?: FlyMachineCheck[] + concurrency?: FlyMachineServiceConcurrency force_instance_description?: string force_instance_key?: string internal_port?: number min_machines_running?: number - ports?: ApiMachinePort[] + ports?: FlyMachinePort[] protocol?: string } -export interface ApiMachineServiceConcurrency { +export interface FlyMachineServiceConcurrency { hard_limit?: number soft_limit?: number type?: string } -export interface ApiProxyProtoOptions { +export interface FlyProxyProtoOptions { version?: string } -export interface ApiStatic { +export interface FlyStatic { guest_path: string + tigris_bucket?: string url_prefix: string } -export interface ApiStopConfig { +export interface FlyStopConfig { signal?: string - timeout?: string + timeout?: FlyDuration } -export interface ApiTLSOptions { +export interface FlyTLSOptions { alpn?: string[] default_self_signed?: boolean versions?: string[] } +export interface FlyDnsForwardRule { + addr?: string + basename?: string +} + +export interface FlyDnsOption { + name?: string + value?: string +} + export enum MainStatusCode { Unknown = 'unknown', CapacityErr = 'insufficient_capacity', } +export enum MachineHostStatusEnum { + Ok = 'ok', + Unknown = 'unknown', + Unreachable = 'unreachable', +} + export enum SignalRequestSignalEnum { SIGABRT = 'SIGABRT', SIGALRM = 'SIGALRM', @@ -446,12 +521,47 @@ export enum SignalRequestSignalEnum { SIGUSR1 = 'SIGUSR1', } +export enum VolumeHostStatusEnum { + Ok = 'ok', + Unknown = 'unknown', + Unreachable = 'unreachable', +} + +export enum FlyDurationTimeDurationEnum { + MinDuration = -9223372036854776000, + MaxDuration = 9223372036854776000, + Nanosecond = 1, + Microsecond = 1000, + Millisecond = 1000000, + Second = 1000000000, + Minute = 60000000000, + Hour = 3600000000000, + MinDuration1 = -9223372036854776000, + MaxDuration2 = 9223372036854776000, + Nanosecond3 = 1, + Microsecond4 = 1000, + Millisecond5 = 1000000, + Second6 = 1000000000, + Minute7 = 60000000000, + Hour8 = 3600000000000, +} + +/** FieldRef selects a field of the Machine: supports id, version, app_name, private_ip, region, image. */ +export enum FlyEnvFromFieldRefEnum { + Id = 'id', + Version = 'version', + AppName = 'app_name', + PrivateIp = 'private_ip', + Region = 'region', + Image = 'image', +} + /** * * no - Never try to restart a Machine automatically when its main process exits, whether that’s on purpose or on a crash. * * always - Always restart a Machine automatically and never let it enter a stopped state, even when the main process exits cleanly. * * on-failure - Try up to MaxRetries times to automatically restart the Machine if it exits with a non-zero exit code. Default when no explicit policy is set, and for Machines with schedules. */ -export enum ApiMachineRestartPolicyEnum { +export enum FlyMachineRestartPolicyEnum { No = 'no', Always = 'always', OnFailure = 'on-failure', @@ -471,6 +581,15 @@ export interface MachinesListParams { appName: string } +export interface MachinesDeleteParams { + /** Force kill the machine if it's running */ + force?: boolean + /** Fly App Name */ + appName: string + /** Machine ID */ + machineId: string +} + export interface MachinesListProcessesParams { /** Sort by */ sort_by?: string @@ -485,6 +604,8 @@ export interface MachinesListProcessesParams { export interface MachinesRestartParams { /** Restart timeout as a Go duration string or number of seconds */ timeout?: string + /** Unix signal name */ + signal?: string /** Fly App Name */ appName: string /** Machine ID */ From f40a53241fa8e4fd831ac7044b7d49114d3bccf1 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:43:38 -0500 Subject: [PATCH 08/23] Bump minor version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13aa1d3..0d14017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triplit/fly-admin", - "version": "1.6.4", + "version": "1.7.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triplit/fly-admin", - "version": "1.6.4", + "version": "1.7.4", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/package.json b/package.json index ccd4eb9..1b7a8b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.6.4", + "version": "1.7.4", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From f3cc55569add14a5578898675f6765893f637770 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:44:06 -0500 Subject: [PATCH 09/23] NPM audit fix --- package-lock.json | 214 +++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d14017..938eebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,12 +39,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -96,23 +97,23 @@ "dev": true }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.3.tgz", - "integrity": "sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", + "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.3", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -139,43 +140,43 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.1.tgz", - "integrity": "sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -234,30 +235,30 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", + "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -287,14 +288,15 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -372,9 +374,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.3.tgz", - "integrity": "sha512-vrukxyW/ep8UD1UDzOYpTKQ6abgjFoeG6L+4ar9+c5TN9QnlqiOi6QK7LSR5ewm/ERyGkT/Ai6VboNrxhbr9Uw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -573,34 +575,34 @@ } }, "node_modules/@babel/template": { - "version": "7.21.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz", - "integrity": "sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/parser": "^7.21.9", - "@babel/types": "^7.21.5" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.1.tgz", - "integrity": "sha512-lAWkdCoUFnmwLBhIRLciFntGYsIIoC6vIbN8zrLPqBnJmPu7Z6nzqnKd7FsxQUNAvZfVZ0x6KdNvNp8zWIOHSQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.22.0", - "@babel/helper-environment-visitor": "^7.22.1", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.22.0", - "@babel/types": "^7.22.0", - "debug": "^4.1.0", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", + "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/parser": "^7.24.5", + "@babel/types": "^7.24.5", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -617,13 +619,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.3.tgz", - "integrity": "sha512-P3na3xIQHTKY4L0YOG7pM8M8uoUIB910WQaSiiMCZUC2Cy8XFEQONGABFnHWBa2gpGKODTAJcNhi5Zk0sLRrzg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", + "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.24.1", + "@babel/helper-validator-identifier": "^7.24.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1118,14 +1120,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -1141,9 +1143,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1156,21 +1158,15 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2716,9 +2712,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2779,9 +2775,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3892,9 +3888,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4712,9 +4708,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5507,9 +5503,9 @@ } }, "node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6180,9 +6176,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" From 5c927cf41ad92aaa7948e1a628fc080fa87f4bd8 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:47:21 -0500 Subject: [PATCH 10/23] Restore version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 938eebb..f80d067 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triplit/fly-admin", - "version": "1.7.4", + "version": "1.6.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triplit/fly-admin", - "version": "1.7.4", + "version": "1.6.7", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/package.json b/package.json index 1b7a8b9..133374e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.7.4", + "version": "1.6.7", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From b2bb27662ab1be04f796d1a17ec48dcec105c317 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:47:24 -0500 Subject: [PATCH 11/23] 1.7.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f80d067..782ca80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triplit/fly-admin", - "version": "1.6.7", + "version": "1.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triplit/fly-admin", - "version": "1.6.7", + "version": "1.7.0", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/package.json b/package.json index 133374e..af9f3e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.6.7", + "version": "1.7.0", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From d399cde51db0d066a47bcf3ccdecf48dec975885 Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:52:33 -0500 Subject: [PATCH 12/23] Fix deleteLease path --- src/lib/machine.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/machine.ts b/src/lib/machine.ts index 06baf1f..a647f7f 100644 --- a/src/lib/machine.ts +++ b/src/lib/machine.ts @@ -448,10 +448,15 @@ export class Machine { payload: DeleteLeaseRequest ): Promise> { const { app_name, machine_id, nonce } = payload - const path = `apps/${app_name}/machines/${machine_id}/lease/${nonce}` - return await this.client.safeRest(path, 'DELETE', { - 'fly-machine-lease-nonce': nonce, - }) + const path = `apps/${app_name}/machines/${machine_id}/lease` + return await this.client.safeRest( + path, + 'DELETE', + {}, + { + 'fly-machine-lease-nonce': nonce, + } + ) } async cordonMachine( From 0dc22f6914235b4c0973bd61c11fd816ee460c8d Mon Sep 17 00:00:00 2001 From: Matthew Linkous Date: Mon, 6 May 2024 14:52:44 -0500 Subject: [PATCH 13/23] 1.7.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 782ca80..18a36b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triplit/fly-admin", - "version": "1.7.0", + "version": "1.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triplit/fly-admin", - "version": "1.7.0", + "version": "1.7.1", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/package.json b/package.json index af9f3e5..dccab27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.7.0", + "version": "1.7.1", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From 4d96913ada2b6e455c4bf3cb698b01ca6b5cdff2 Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Thu, 2 May 2024 14:27:08 -0700 Subject: [PATCH 14/23] add method for detailed app list --- src/lib/app.ts | 92 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 14 deletions(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 1bffac4..46e13cc 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -12,8 +12,42 @@ export interface ListAppResponse { }[] } +export interface ListAppDetailedResponse { + apps: AppResponse[] +} + export type GetAppRequest = string +const getOrganizationApps = `query($slug: String!) { + organization(slug: $slug) { + apps { + nodes { + name + status + organization { + name + slug + } + ipAddresses { + nodes { + type + region + address + } + } + machines { + nodes { + id + name + state + region + } + } + } + } + } +}` + const getAppQuery = `query($name: String!) { app(name: $name) { name @@ -57,7 +91,7 @@ export interface AppResponse { machines: AppMachine[] } -interface AppMachine { +export interface AppMachine { id: string name: string state: string @@ -91,6 +125,25 @@ export class App { return await this.client.safeRest(path) } + async listAppsDetailed( + org_slug: ListAppRequest + ): Promise> { + const response = await this.client.safeGqlPost< + string, + { app: AppResponse } + >({ + query: getOrganizationApps, + variables: { slug: org_slug }, + }) + if (response.error) { + return response + } + return { + data: parseOrgResponse(response), + error: undefined, + } + } + async getApp(app_name: GetAppRequest): Promise> { const path = `apps/${app_name}` return await this.client.safeRest(path) @@ -111,20 +164,8 @@ export class App { return response } - const ipAddresses = response.data.app.ipAddresses as unknown as { - nodes: IPAddress[] - } - - const machines = response.data.app.machines as unknown as { - nodes: AppMachine[] - } - return { - data: { - ...response.data.app, - ipAddresses: ipAddresses.nodes, - machines: machines.nodes, - }, + data: parseAppResponse(response), error: undefined, } } @@ -139,3 +180,26 @@ export class App { return await this.client.safeRest(path, 'DELETE') } } + +function parseAppResponse(appData: any) { + const ipAddresses = parseNodes(appData, 'ipAddresses') + const machines = parseNodes(appData, 'machines') + + return { + ...appData, + ipAddresses, + machines, + } +} + +function parseOrgResponse(orgData: any) { + const apps = parseNodes(orgData, 'apps').map(parseAppResponse) + return { + ...orgData, + apps, + } +} + +function parseNodes(data: any, key: string): T[] { + return data[key].nodes +} From 456e693a4036f7a280c732e74f761379aa980bbc Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Thu, 2 May 2024 14:30:38 -0700 Subject: [PATCH 15/23] fixup typo --- src/lib/app.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 46e13cc..faad7d1 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -130,7 +130,7 @@ export class App { ): Promise> { const response = await this.client.safeGqlPost< string, - { app: AppResponse } + { organization: any } >({ query: getOrganizationApps, variables: { slug: org_slug }, @@ -139,7 +139,7 @@ export class App { return response } return { - data: parseOrgResponse(response), + data: parseOrgResponse(response.data.organization), error: undefined, } } @@ -152,10 +152,7 @@ export class App { async getAppDetailed( app_name: GetAppRequest ): Promise> { - const response = await this.client.safeGqlPost< - string, - { app: AppResponse } - >({ + const response = await this.client.safeGqlPost({ query: getAppQuery, variables: { name: app_name }, }) @@ -165,7 +162,7 @@ export class App { } return { - data: parseAppResponse(response), + data: parseAppResponse(response.data.app), error: undefined, } } From 5cd5ad0edcce093aa4aa2b45a6c0a615f2ea7dda Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Thu, 2 May 2024 14:32:50 -0700 Subject: [PATCH 16/23] return apps array from listAppsDetailed --- src/lib/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index faad7d1..0bc579e 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -139,7 +139,7 @@ export class App { return response } return { - data: parseOrgResponse(response.data.organization), + data: parseOrgResponse(response.data.organization).apps, error: undefined, } } From 699aa8d2b6d71bc0608000c3600044158c20ccdb Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 30 Oct 2024 09:20:48 -0700 Subject: [PATCH 17/23] fixup types --- src/lib/app.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 0bc579e..9eabc32 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -13,7 +13,7 @@ export interface ListAppResponse { } export interface ListAppDetailedResponse { - apps: AppResponse[] + apps: AppDetailedResponse[] } export type GetAppRequest = string @@ -87,6 +87,9 @@ export interface AppResponse { name: string slug: string } +} + +export interface AppDetailedResponse extends AppResponse { ipAddresses: IPAddress[] machines: AppMachine[] } @@ -151,7 +154,7 @@ export class App { async getAppDetailed( app_name: GetAppRequest - ): Promise> { + ): Promise> { const response = await this.client.safeGqlPost({ query: getAppQuery, variables: { name: app_name }, From 28f608e5a59e7d2b4c84208c7a519bbd0174a2da Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 30 Oct 2024 09:24:49 -0700 Subject: [PATCH 18/23] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dccab27..7ffdc8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triplit/fly-admin", - "version": "1.7.1", + "version": "1.7.3", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", From b2c485ca1bce35bf80748c6f8158920fbe8c76d3 Mon Sep 17 00:00:00 2001 From: Will Ernst Date: Wed, 30 Oct 2024 09:29:47 -0700 Subject: [PATCH 19/23] fix naming --- src/lib/app.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 9eabc32..47cb6ee 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -18,7 +18,7 @@ export interface ListAppDetailedResponse { export type GetAppRequest = string -const getOrganizationApps = `query($slug: String!) { +const getOrganizationAppsDetailedQuery = `query($slug: String!) { organization(slug: $slug) { apps { nodes { @@ -48,7 +48,7 @@ const getOrganizationApps = `query($slug: String!) { } }` -const getAppQuery = `query($name: String!) { +const getAppDetailedQuery = `query($name: String!) { app(name: $name) { name status @@ -135,7 +135,7 @@ export class App { string, { organization: any } >({ - query: getOrganizationApps, + query: getOrganizationAppsDetailedQuery, variables: { slug: org_slug }, }) if (response.error) { @@ -156,7 +156,7 @@ export class App { app_name: GetAppRequest ): Promise> { const response = await this.client.safeGqlPost({ - query: getAppQuery, + query: getAppDetailedQuery, variables: { name: app_name }, }) From 4edb135823dec56cab240cf6f9b219439dff02b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Nicol=C3=A1s=20Liszewski?= Date: Thu, 10 Apr 2025 15:29:20 -0300 Subject: [PATCH 20/23] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ffdc8f..b3874c7 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/supabase/fly-admin.git" + "url": "git+https://github.com/aspen-cloud/fly-admin.git" }, "keywords": [ "fly", From 68044c0a6312909bff527fbb79dec2b177b69092 Mon Sep 17 00:00:00 2001 From: Matt Linkous Date: Mon, 29 Sep 2025 14:45:57 -0500 Subject: [PATCH 21/23] Reset package.json metadata to match upstream --- package-lock.json | 8 ++++---- package.json | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18a36b5..1bd6efa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "@triplit/fly-admin", - "version": "1.7.1", + "name": "fly-admin", + "version": "0.0.0-automated", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@triplit/fly-admin", - "version": "1.7.1", + "name": "fly-admin", + "version": "0.0.0-automated", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" diff --git a/package.json b/package.json index b3874c7..20482f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@triplit/fly-admin", - "version": "1.7.3", + "name": "fly-admin", + "version": "0.0.0-automated", "description": "A Typescript client for managing Fly infrastructure.", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -14,18 +14,18 @@ "lint": "eslint src/**/*.ts", "test": "jest", "gen:types": "npx swagger-typescript-api -p https://docs.machines.dev/swagger/doc.json -o ./src/lib --extract-enums --extract-request-params --no-client -n types.ts", - "all": "npm run build && npm run format && npm run lint && npm test", - "publish": "npm run build && npm publish --access public" + "all": "npm run build && npm run format && npm run lint && npm test" }, "repository": { "type": "git", - "url": "git+https://github.com/aspen-cloud/fly-admin.git" + "url": "git+https://github.com/supabase/fly-admin.git" }, "keywords": [ "fly", "api", "client" ], + "author": "Supabase", "license": "MIT", "dependencies": { "cross-fetch": "^4.0.0" @@ -43,4 +43,4 @@ "ts-jest": "^29.1.0", "typescript": "^5.0.4" } -} +} \ No newline at end of file From f34099fa3971bb0711f3699ea57c8da0d8c76a6b Mon Sep 17 00:00:00 2001 From: matlin Date: Wed, 1 Oct 2025 12:24:48 -0500 Subject: [PATCH 22/23] Apply suggestion from @sweatybridge Co-authored-by: Han Qiao --- src/lib/app.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/app.ts b/src/lib/app.ts index 47cb6ee..e8f4026 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -30,9 +30,9 @@ const getOrganizationAppsDetailedQuery = `query($slug: String!) { } ipAddresses { nodes { - type - region - address + type + region + address } } machines { From 59a7162973abb19fa62c1960f6a5849f6315eb9e Mon Sep 17 00:00:00 2001 From: matlin Date: Wed, 1 Oct 2025 12:25:17 -0500 Subject: [PATCH 23/23] Apply suggestion from @sweatybridge Co-authored-by: Han Qiao --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20482f3..a654f93 100644 --- a/package.json +++ b/package.json @@ -43,4 +43,4 @@ "ts-jest": "^29.1.0", "typescript": "^5.0.4" } -} \ No newline at end of file +}