Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add AppVersion model #72

Closed
wants to merge 9 commits into from
20 changes: 20 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/models/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@
"@mittwald/api-client": "workspace:^",
"another-deep-freeze": "^1.0.0",
"polytype": "^0.17.0",
"semver-compare": "^1.0.0",
"type-fest": "^4.12.0"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@mittwald/react-use-promise": "^2.3.12",
"@types/jest": "^29.5.12",
"@types/react": "^18.2.64",
"@types/semver-compare": "^1",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"eslint": "^8.57.0",
Expand Down
115 changes: 115 additions & 0 deletions packages/models/src/app/AppVersion/AppVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { ReferenceModel } from "../../base/ReferenceModel.js";
import {
type AsyncResourceVariant,
provideReact,
} from "../../lib/provideReact.js";
import { DataModel } from "../../base/DataModel.js";
import { classes } from "polytype";
import {
AppVersionData,
AppVersionListItemData,
AppVersionListQuery,
} from "./types.js";
import { config } from "../../config/config.js";
import assertObjectFound from "../../base/assertObjectFound.js";
import semverCompare from "semver-compare";

export class AppVersion extends ReferenceModel {
public readonly appId: string;

public constructor(id: string, appid: string) {
super(id);
this.appId = appid;
}

public static ofId(id: string, appId: string): AppVersion {
return new AppVersion(id, appId);
}

public static find = provideReact(
async (
id: string,
appId: string,
): Promise<AppVersionDetailed | undefined> => {
const data = await config.behaviors.appVersion.find(id, appId);
if (data !== undefined) {
return new AppVersionDetailed(data);
}
},
);

public static get = provideReact(
async (id: string, appId: string): Promise<AppVersionDetailed> => {
const appVersion = await this.find(id, appId);
assertObjectFound(appVersion, this, id);
return appVersion;
},
);

public getDetailed = provideReact(() =>
AppVersion.get(this.id, this.appId),
) as AsyncResourceVariant<AppVersionDetailed, []>;

public static list = provideReact(
async (
appId: string,
query: AppVersionListQuery = {},
): Promise<Readonly<Array<AppVersionListItem>>> => {
const data = await config.behaviors.appVersion.list(appId, query);
return Object.freeze(
data
.map((d) => new AppVersionListItem(d))
.sort((a, b) =>
semverCompare(b.data.internalVersion, a.data.internalVersion),
),
);
},
);

public listUpdateCandidates = provideReact(
async (appId: string): Promise<Readonly<Array<AppVersionListItem>>> => {
const data = await config.behaviors.appVersion.listUpdateCandidates(
appId,
this.id,
);
return Object.freeze(
data
.map((d) => new AppVersionListItem(d))
.sort((a, b) =>
semverCompare(b.data.internalVersion, a.data.internalVersion),
),
);
},
);
}

class AppVersionCommon extends classes(
DataModel<AppVersionData | AppVersionListItemData>,
AppVersion,
) {
public constructor(data: AppVersionData | AppVersionListItemData) {
super([data], [data.id, data.appId]);
}
}

export class AppVersionDetailed extends classes(
AppVersionCommon,
DataModel<AppVersionData>,
) {
// ToDo: activate when App model is merged
// public readonly app: App;

public constructor(data: AppVersionData) {
super([data], [data]);
// this.app = App.ofId(data.appId);
}
}

export class AppVersionListItem extends classes(
AppVersionCommon,
DataModel<AppVersionListItemData>,
) {
public constructor(data: AppVersionListItemData) {
super([data], [data]);
}
}
45 changes: 45 additions & 0 deletions packages/models/src/app/AppVersion/behaviors/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
assertStatus,
assertOneOfStatus,
MittwaldAPIV2Client,
} from "@mittwald/api-client";
import { AppVersionBehaviors } from "./types.js";

export const apiAppVersionBehaviors = (
client: MittwaldAPIV2Client,
): AppVersionBehaviors => ({
find: async (id, appId) => {
const response = await client.app.getAppversion({
appVersionId: id,
appId,
});

if (response.status === 200) {
return response.data;
}

assertOneOfStatus(response, [404]);
},

list: async (appId, query) => {
const response = await client.app.listAppversions({
appId,
queryParameters: query,
});

assertStatus(response, 200);

return response.data;
},

listUpdateCandidates: async (appId, baseAppVersionId) => {
const response = await client.app.listUpdateCandidatesForAppversion({
appId,
baseAppVersionId,
});

assertStatus(response, 200);

return response.data;
},
});
2 changes: 2 additions & 0 deletions packages/models/src/app/AppVersion/behaviors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./api.js";
export * from "./types.js";
19 changes: 19 additions & 0 deletions packages/models/src/app/AppVersion/behaviors/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
AppVersionData,
AppVersionListItemData,
AppVersionListQuery,
} from "../types.js";

export interface AppVersionBehaviors {
find: (id: string, appId: string) => Promise<AppVersionData | undefined>;

list: (
appId: string,
query?: AppVersionListQuery,
) => Promise<AppVersionListItemData[]>;

listUpdateCandidates: (
appId: string,
baseAppVersionId: string,
) => Promise<AppVersionListItemData[]>;
}
2 changes: 2 additions & 0 deletions packages/models/src/app/AppVersion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./AppVersion.js";
export * from "./types.js";
10 changes: 10 additions & 0 deletions packages/models/src/app/AppVersion/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { MittwaldAPIV2 } from "@mittwald/api-client";

export type AppVersionData =
MittwaldAPIV2.Operations.AppGetAppversion.ResponseData;

export type AppVersionListItemData =
MittwaldAPIV2.Operations.AppListAppversions.ResponseData[number];

export type AppVersionListQuery =
MittwaldAPIV2.Paths.V2AppsAppIdVersions.Get.Parameters.Query;
1 change: 1 addition & 0 deletions packages/models/src/app/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./AppInstallation/index.js";
export * from "./AppVersion/index.js";
2 changes: 2 additions & 0 deletions packages/models/src/config/behaviors/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { apiServerBehaviors } from "../../server/Server/behaviors/index.js";
import { apiCustomerBehaviors } from "../../customer/Customer/behaviors/index.js";
import { apiIngressBehaviors } from "../../domain/Ingress/behaviors/index.js";
import { apiAppInstallationBehaviors } from "../../app/AppInstallation/behaviors/index.js";
import { apiAppVersionBehaviors } from "../../app/AppVersion/behaviors/index.js";

class ApiSetupState {
private _client: MittwaldAPIV2Client | undefined;
Expand All @@ -22,6 +23,7 @@ class ApiSetupState {
config.behaviors.customer = apiCustomerBehaviors(client);
config.behaviors.ingress = apiIngressBehaviors(client);
config.behaviors.appInstallation = apiAppInstallationBehaviors(client);
config.behaviors.appVersion = apiAppVersionBehaviors(client);
}

public setupWithApiToken(apiToken: string) {
Expand Down
3 changes: 3 additions & 0 deletions packages/models/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ServerBehaviors } from "../server/Server/behaviors/index.js";
import { CustomerBehaviors } from "../customer/Customer/behaviors/index.js";
import { IngressBehaviors } from "../domain/Ingress/behaviors/index.js";
import { AppInstallationBehaviors } from "../app/AppInstallation/behaviors/index.js";
import { AppVersionBehaviors } from "../app/AppVersion/behaviors/index.js";

interface Config {
behaviors: {
Expand All @@ -11,6 +12,7 @@ interface Config {
customer: CustomerBehaviors;
ingress: IngressBehaviors;
appInstallation: AppInstallationBehaviors;
appVersion: AppVersionBehaviors;
};
}

Expand All @@ -21,5 +23,6 @@ export const config: Config = {
customer: undefined as unknown as CustomerBehaviors,
ingress: undefined as unknown as IngressBehaviors,
appInstallation: undefined as unknown as AppInstallationBehaviors,
appVersion: undefined as unknown as AppVersionBehaviors,
},
};
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,7 @@ __metadata:
"@mittwald/react-use-promise": "npm:^2.3.12"
"@types/jest": "npm:^29.5.12"
"@types/react": "npm:^18.2.64"
"@types/semver-compare": "npm:^1"
"@typescript-eslint/eslint-plugin": "npm:^7.1.1"
"@typescript-eslint/parser": "npm:^7.1.1"
another-deep-freeze: "npm:^1.0.0"
Expand All @@ -1467,6 +1468,7 @@ __metadata:
prettier: "npm:^3.2.5"
react: "npm:^18.2.0"
rimraf: "npm:^5.0.5"
semver-compare: "npm:^1.0.0"
ts-jest: "npm:^29.1.2"
type-fest: "npm:^4.12.0"
typescript: "npm:^5.4.2"
Expand Down Expand Up @@ -2628,6 +2630,13 @@ __metadata:
languageName: node
linkType: hard

"@types/semver-compare@npm:^1":
version: 1.0.3
resolution: "@types/semver-compare@npm:1.0.3"
checksum: 10/be6d31ee0de2132ae53d9c675c9774e11037240656e227f6551e7e404293c157a6cd6181c42cec7e85a8a00b3512f0c43e13dac7aaee4a94cbebf73e11e2b68c
languageName: node
linkType: hard

"@types/semver@npm:^7.1.0":
version: 7.3.13
resolution: "@types/semver@npm:7.3.13"
Expand Down Expand Up @@ -10161,6 +10170,13 @@ __metadata:
languageName: node
linkType: hard

"semver-compare@npm:^1.0.0":
version: 1.0.0
resolution: "semver-compare@npm:1.0.0"
checksum: 10/75f9c7a7786d1756f64b1429017746721e07bd7691bdad6368f7643885d3a98a27586777e9699456564f4844b407e9f186cc1d588a3f9c0be71310e517e942c3
languageName: node
linkType: hard

"semver@npm:2 || 3 || 4 || 5 || 6 || 7, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0":
version: 7.6.0
resolution: "semver@npm:7.6.0"
Expand Down