Skip to content

Commit

Permalink
Merge pull request #1410 from balena-io/refactor-to-use-satisfies
Browse files Browse the repository at this point in the history
Drop the toWritable helper in favor of TypeScript's satisfies
  • Loading branch information
thgreasi committed Mar 29, 2024
2 parents c5a5af2 + 4463a5c commit 153b4a3
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 57 deletions.
43 changes: 21 additions & 22 deletions src/models/device.supervisor-api.partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
InjectedOptionsParam,
InjectedDependenciesParam,
PineTypedResult,
PineOptions,
} from '..';
import type { Device } from '../types/models';

Expand All @@ -30,8 +31,6 @@ import {

import { ensureVersionCompatibility } from '../util/device-os-version';

import { toWritable } from '../util/types';

// The min version where /apps API endpoints are implemented is 1.8.0 but we'll
// be accepting >= 1.8.0-alpha.0 instead. This is a workaround for a published 1.8.0-p1
// prerelease supervisor version, which precedes 1.8.0 but comes after 1.8.0-alpha.0
Expand Down Expand Up @@ -150,9 +149,9 @@ export const getSupervisorApiHelper = function (
imageId: string;
}> => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} as const;
} satisfies PineOptions<Device>;

const device = (await sdkInstance.models.device.get(
uuidOrId,
Expand Down Expand Up @@ -232,9 +231,9 @@ export const getSupervisorApiHelper = function (
withSupervisorLockedError(async () => {
try {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down Expand Up @@ -304,9 +303,9 @@ export const getSupervisorApiHelper = function (
*/
startApplication: async (uuidOrId: string | number): Promise<void> => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down Expand Up @@ -358,9 +357,9 @@ export const getSupervisorApiHelper = function (
stopApplication: (uuidOrId: string | number): Promise<void> =>
withSupervisorLockedError(async () => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down Expand Up @@ -643,9 +642,9 @@ export const getSupervisorApiHelper = function (
imageId: number,
): Promise<void> => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down Expand Up @@ -696,9 +695,9 @@ export const getSupervisorApiHelper = function (
stopService: (uuidOrId: string | number, imageId: number): Promise<void> =>
withSupervisorLockedError(async () => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down Expand Up @@ -752,9 +751,9 @@ export const getSupervisorApiHelper = function (
): Promise<void> =>
withSupervisorLockedError(async () => {
const deviceOptions = {
$select: toWritable(['id', 'supervisor_version'] as const),
$expand: { belongs_to__application: { $select: 'id' as const } },
};
$select: ['id', 'supervisor_version'],
$expand: { belongs_to__application: { $select: 'id' } },
} satisfies PineOptions<Device>;
const device = (await sdkInstance.models.device.get(
uuidOrId,
deviceOptions,
Expand Down
7 changes: 3 additions & 4 deletions src/models/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
import * as errors from 'balena-errors';
import type { Image, PineOptions, InjectedDependenciesParam } from '..';
import { mergePineOptions } from '../util';
import { toWritable } from '../util/types';

const getImageModel = function (deps: InjectedDependenciesParam) {
const { pine } = deps;
Expand All @@ -41,7 +40,7 @@ const getImageModel = function (deps: InjectedDependenciesParam) {
*/
async get(id: number, options: PineOptions<Image> = {}): Promise<Image> {
const baseOptions = {
$select: toWritable([
$select: [
// Select all the interesting fields *except* build_log
// (which can be very large)
'id',
Expand All @@ -55,8 +54,8 @@ const getImageModel = function (deps: InjectedDependenciesParam) {
'push_timestamp',
'start_timestamp',
'end_timestamp',
] as const),
};
],
} satisfies PineOptions<Image>;
const image = await pine.get({
resource: 'image',
id,
Expand Down
13 changes: 3 additions & 10 deletions src/models/os.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import type {
PineTypedResult,
} from '..';
import { getAuthDependentMemoize } from '../util/cache';
import { toWritable } from '../util/types';

const RELEASE_POLICY_TAG_NAME = 'release-policy';
const ESR_NEXT_TAG_NAME = 'esr-next';
Expand All @@ -68,19 +67,13 @@ export enum OsVariant {
export type OsLines = 'next' | 'current' | 'sunset' | 'outdated' | undefined;

const baseReleasePineOptions = {
$select: toWritable([
'id',
'known_issue_list',
'raw_version',
'variant',
'phase',
] as const),
$select: ['id', 'known_issue_list', 'raw_version', 'variant', 'phase'],
$expand: {
release_tag: {
$select: toWritable(['tag_key', 'value'] as const),
$select: ['tag_key', 'value'],
},
},
};
} satisfies PineOptions<Release>;

export interface OsVersion
extends PineTypedResult<Release, typeof baseReleasePineOptions> {
Expand Down
7 changes: 3 additions & 4 deletions src/models/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import type {
PineTypedResult,
} from '..';
import { isId, mergePineOptions } from '../util';
import { toWritable } from '../util/types';
import type { Application, ReleaseTag, Release, User } from '../types/models';
import type { BuilderUrlDeployOptions } from '../util/builder';

Expand Down Expand Up @@ -222,7 +221,7 @@ const getReleaseModel = function (
$select: 'service_name',
},
},
} as const;
} satisfies BalenaSdk.PineOptions<BalenaSdk.Image>;

const baseReleaseOptions = {
$expand: {
Expand All @@ -235,10 +234,10 @@ const getReleaseModel = function (
},
},
is_created_by__user: {
$select: toWritable(['id', 'username'] as const),
$select: ['id', 'username'],
},
},
} as const;
} satisfies BalenaSdk.PineOptions<BalenaSdk.Release>;

const rawRelease = (await get(
commitOrIdOrRawVersion,
Expand Down
4 changes: 0 additions & 4 deletions src/util/types.ts

This file was deleted.

5 changes: 2 additions & 3 deletions tests/integration/models/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as _ from 'lodash';
import { expect } from 'chai';
import parallel from 'mocha.parallel';
import type * as BalenaSdk from '../../..';
import { toWritable } from '../../../src/util/types';
import { timeSuite } from '../../util';
import type * as tagsHelper from './tags';

Expand Down Expand Up @@ -1575,14 +1574,14 @@ describe('Application Model', function () {
image_install: {
$expand: {
is_provided_by__release: {
$select: toWritable(['id', 'commit'] as const),
$select: ['id', 'commit'],
},
},
},
},
},
},
} as const;
} satisfies BalenaSdk.PineOptions<BalenaSdk.Application>;

describe('balena.models.application.getWithDeviceServiceDetails()', () => {
it("should retrieve the application and it's devices along with service details including their commit", function () {
Expand Down
16 changes: 8 additions & 8 deletions tests/integration/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import chaiSamsam from 'chai-samsam';
import memoizee from 'memoizee';
import type * as BalenaSdk from '../../';
import type { Dictionary } from '../../typings/utils';
import { toWritable } from '../../src/util/types';
import { getInitialOrganization } from './utils';
chai.use(chaiAsPromised);
chai.use(chaiSamsam);
Expand Down Expand Up @@ -675,13 +674,14 @@ export function givenASupervisorRelease(
});
}

export const organizationRetrievalFields = toWritable([
'id',
'handle',
] as const);
export const applicationRetrievalFields = toWritable([
export const organizationRetrievalFields = ['id', 'handle'] satisfies Array<
keyof BalenaSdk.Organization
>;
export const applicationRetrievalFields = [
'id',
'slug',
'uuid',
] as const);
export const deviceUniqueFields = toWritable(['id', 'uuid'] as const);
] satisfies Array<keyof BalenaSdk.Application>;
export const deviceUniqueFields = ['id', 'uuid'] satisfies Array<
keyof BalenaSdk.Device
>;
2 changes: 0 additions & 2 deletions typings/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ export type ResolvableReturnType<T extends (...args: any[]) => any> =

export type AtLeast<T, K extends keyof T> = Pick<T, K> & Partial<Omit<T, K>>;

export type Writable<T> = { -readonly [K in keyof T]: T[K] };

// TODO: Change this approximation once TS properly supports Exact Types for generics.
// See: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-711172739
export type ExactlyExtends<T, ExtendsBase> = ExtendsBase extends T
Expand Down

0 comments on commit 153b4a3

Please sign in to comment.