Skip to content

Commit

Permalink
Update pinejs-client and make use of improved typings
Browse files Browse the repository at this point in the history
Change-type: patch
  • Loading branch information
Page- committed Jul 19, 2024
1 parent ab32bbf commit 1085c2c
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 107 deletions.
124 changes: 90 additions & 34 deletions lib/release/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,27 @@ export async function updateRelease(
id: number,
body: Partial<models.ReleaseAttributes>,
): Promise<void> {
return models.update(api, 'release', id, body);
await api
.patch({
resource: 'release',
id,
body,
} as const)
.catch(models.wrapResponseError);
}

export async function updateImage(
api: PinejsClientCore<unknown>,
id: number,
body: Partial<models.ImageAttributes>,
): Promise<void> {
return models.update(api, 'image', id, body);
await api
.patch({
resource: 'image',
id,
body,
} as const)
.catch(models.wrapResponseError);
}

// Helpers
Expand All @@ -161,31 +173,62 @@ async function getUser(
api: PinejsClientCore<unknown>,
id: number,
): Promise<models.UserModel> {
return models.get(api, 'user', id);
const user = await api
.get({
resource: 'user',
id,
options: { $select: 'id' },
} as const)
.catch(models.wrapResponseError);
if (user == null) {
throw new Error('Could not find user with id: ' + id);
}
return user;
}

async function getApplication(
api: PinejsClientCore<unknown>,
id: number,
): Promise<models.ApplicationModel> {
return models.get(api, 'application', id);
const app = await api
.get({
resource: 'application',
id,
options: { $select: 'id' },
} as const)
.catch(models.wrapResponseError);
if (app == null) {
throw new Error('Could not find application with id: ' + id);
}
return app;
}

async function getOrCreateService(
api: PinejsClientCore<unknown>,
body: models.ServiceAttributes,
): Promise<models.ServiceModel> {
return models.getOrCreate(api, 'service', body, {
application: body.application,
service_name: body.service_name,
});
return (await api
.getOrCreate({
resource: 'service',
id: {
application: body.application,
service_name: body.service_name,
},
body,
} as const)
.catch(models.wrapResponseError)) as models.ServiceModel;
}

async function createRelease(
api: PinejsClientCore<unknown>,
body: models.ReleaseAttributes,
): Promise<models.ReleaseModel> {
return models.create(api, 'release', body);
return (await api
.post({
resource: 'release',
body,
})
.catch(models.wrapResponseError)) as models.ReleaseModel;
}

async function createImage(
Expand All @@ -195,29 +238,37 @@ async function createImage(
envvars: Dict<string> | undefined,
body: models.ImageAttributes,
): Promise<models.ImageModel> {
const image = await models.create<models.ImageModel, models.ImageAttributes>(
api,
'image',
body,
);

const releaseImage = await models.create<
models.ReleaseImageModel,
models.ReleaseImageAttributes
>(api, 'image__is_part_of__release', {
is_part_of__release: release,
image: image.id,
});
const image = (await api
.post({
resource: 'image',
body,
} as const)
.catch(models.wrapResponseError)) as models.ImageModel;

const releaseImage = (await api
.post({
resource: 'image__is_part_of__release',
body: {
is_part_of__release: release,
image: image.id,
},
} as const)
.catch(models.wrapResponseError)) as models.ReleaseImageModel;

if (labels) {
await pMap(
Object.entries(labels),
([name, value]) => {
return models.create(api, 'image_label', {
release_image: releaseImage.id,
label_name: name,
value: (value || '').toString(),
});
async ([name, value]) => {
await api
.post({
resource: 'image_label',
body: {
release_image: releaseImage.id,
label_name: name,
value: (value || '').toString(),
},
} as const)
.catch(models.wrapResponseError);
},
{
concurrency: MAX_CONCURRENT_REQUESTS,
Expand All @@ -228,12 +279,17 @@ async function createImage(
if (envvars) {
await pMap(
Object.entries(envvars),
([name, value]) => {
return models.create(api, 'image_environment_variable', {
release_image: releaseImage.id,
name,
value: (value || '').toString(),
});
async ([name, value]) => {
await api
.post({
resource: 'image_environment_variable',
body: {
release_image: releaseImage.id,
name,
value: (value || '').toString(),
},
} as const)
.catch(models.wrapResponseError);
},
{
concurrency: MAX_CONCURRENT_REQUESTS,
Expand Down
72 changes: 2 additions & 70 deletions lib/release/models.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import type {
Expand,
Filter,
ODataOptions,
PinejsClientCore,
} from 'pinejs-client-core';

import type { Composition } from '../../lib/parse';

import * as errors from './errors';
Expand Down Expand Up @@ -99,69 +92,8 @@ export interface ReleaseImageModel extends ReleaseImageAttributesBase {

// Helpers

export function getOrCreate<T, U extends object, V extends Filter>(
api: PinejsClientCore<unknown>,
resource: string,
body: U,
filter: V,
): Promise<T> {
return create(api, resource, body).catch((error) => {
if (error instanceof errors.UniqueConstraintError) {
return find<T>(api, resource, { $filter: filter }).then((obj) => {
if (obj.length > 0) {
return obj[0];
}
throw new errors.ObjectDoesNotExistError();
});
}
throw error;
}) as Promise<T>;
}

export function create<T, U extends object>(
api: PinejsClientCore<unknown>,
resource: string,
body: U,
): Promise<T> {
return api.post({ resource, body }).catch(wrapResponseError) as Promise<T>;
}

export function update<T extends object>(
api: PinejsClientCore<unknown>,
resource: string,
id: number,
body: T,
): Promise<void> {
return api.patch({ resource, id, body }).catch(wrapResponseError);
}

export function find<T>(
api: PinejsClientCore<unknown>,
resource: string,
options: ODataOptions,
): Promise<T[]> {
return api.get({ resource, options }).catch(wrapResponseError) as Promise<
T[]
>;
}

export function get<T>(
api: PinejsClientCore<unknown>,
resource: string,
id: number,
expand?: Expand,
): Promise<T> {
return api
.get({
resource,
id,
options: expand ? { $expand: expand } : undefined,
})
.catch(wrapResponseError) as Promise<T>;
}

function wrapResponseError<E extends Error>(e: E): void {
const error: { statusCode?: number; message?: unknown } = e as any;
export function wrapResponseError(e: Error): void {
const error: { statusCode?: number; message?: unknown } = e;
if (!error.statusCode) {
throw e;
}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"homepage": "https://github.com/balena-io-modules/balena-compose#readme",
"devDependencies": {
"@balena/lint": "^7.2.1",
"@balena/lint": "^7.3.0",
"@types/chai-as-promised": "^7.1.3",
"@types/docker-modem": "^3.0.6",
"@types/dockerode": "^3.3.23",
Expand All @@ -60,7 +60,7 @@
"proxyquire": "^2.1.3",
"rimraf": "^5.0.1",
"ts-mocha": "^10.0.0",
"typescript": "^5.2.2"
"typescript": "^5.5.3"
},
"dependencies": {
"ajv": "^6.12.3",
Expand All @@ -82,7 +82,7 @@
"memoizee": "^0.4.15",
"mz": "^2.7.0",
"p-map": "^4.0.0",
"pinejs-client-core": "^6.13.0",
"pinejs-client-core": "^6.15.10",
"semver": "^7.3.5",
"stream-to-promise": "^3.0.0",
"tar-stream": "^3.1.6",
Expand Down

0 comments on commit 1085c2c

Please sign in to comment.