use autogenerated types

This commit is contained in:
Hayden 2022-09-11 16:10:53 -08:00
parent b672e6a739
commit a1d05011d4
17 changed files with 300 additions and 102 deletions

View file

@ -30,6 +30,7 @@
defineProps({
details: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Object as () => Record<string, StringLike | any>,
required: true,
},

View file

@ -37,10 +37,12 @@
default: "",
},
modelValue: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Array as () => any[],
default: null,
},
items: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Array as () => any[],
required: true,
},

View file

@ -24,10 +24,12 @@
default: "",
},
modelValue: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Object as any,
default: null,
},
items: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Array as () => any[],
required: true,
},

View file

@ -22,11 +22,11 @@
</template>
<script setup lang="ts">
import { Item } from "~~/lib/api/classes/items";
import { ItemOut } from "~~/lib/api/types/data-contracts";
const props = defineProps({
item: {
type: Object as () => Item,
type: Object as () => ItemOut,
required: true,
},
});

View file

@ -1,10 +1,10 @@
<script setup lang="ts">
import { Label } from "~~/lib/api/classes/labels";
import { LabelOut, LabelSummary } from "~~/lib/api/types/data-contracts";
export type sizes = "sm" | "md" | "lg";
defineProps({
label: {
type: Object as () => Label,
type: Object as () => LabelOut | LabelSummary,
required: true,
},
size: {

View file

@ -26,11 +26,11 @@
</template>
<script lang="ts" setup>
import { Location } from "~~/lib/api/classes/locations";
import { LocationCount } from "~~/lib/api/types/data-contracts";
defineProps({
location: {
type: Object as () => Location,
type: Object as () => LocationCount,
required: true,
},
dense: {

View file

@ -1,6 +1,7 @@
import { UseConfirmDialogReturn } from "@vueuse/core";
import { Ref } from "vue";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Store = UseConfirmDialogReturn<any, boolean, boolean> & {
text: Ref<string>;
setup: boolean;
@ -21,6 +22,7 @@ const store: Partial<Store> = {
export function useConfirm(): Store {
if (!store.setup) {
store.setup = true;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { isRevealed, reveal, confirm, cancel } = useConfirmDialog<any, boolean, boolean>();
store.isRevealed = isRevealed;
store.reveal = reveal;

View file

@ -1,5 +1,5 @@
import { describe, expect, test } from "vitest";
import { Label } from "../../classes/labels";
import { LabelOut } from "../../types/data-contracts";
import { UserApi } from "../../user";
import { sharedUserClient } from "../test-utils";
@ -10,7 +10,7 @@ describe("locations lifecycle (create, update, delete)", () => {
* useLabel sets up a label resource for testing, and returns a function
* that can be used to delete the label from the backend server.
*/
async function useLabel(api: UserApi): Promise<[Label, () => Promise<void>]> {
async function useLabel(api: UserApi): Promise<[LabelOut, () => Promise<void>]> {
const { response, data } = await api.labels.create({
name: `__test__.label.name_${increment}`,
description: `__test__.label.description_${increment}`,

View file

@ -1,5 +1,5 @@
import { describe, expect, test } from "vitest";
import { Location } from "../../classes/locations";
import { LocationOut } from "../../types/data-contracts";
import { UserApi } from "../../user";
import { sharedUserClient } from "../test-utils";
@ -10,7 +10,7 @@ describe("locations lifecycle (create, update, delete)", () => {
* useLocatio sets up a location resource for testing, and returns a function
* that can be used to delete the location from the backend server.
*/
async function useLocation(api: UserApi): Promise<[Location, () => Promise<void>]> {
async function useLocation(api: UserApi): Promise<[LocationOut, () => Promise<void>]> {
const { response, data } = await api.locations.create({
name: `__test__.location.name_${increment}`,
description: `__test__.location.description_${increment}`,

View file

@ -0,0 +1,30 @@
import { describe, expect, test } from "vitest";
import { hasKey, parseDate } from "./base-api";
describe("hasKey works as expected", () => {
test("hasKey returns true if the key exists", () => {
const obj = { createdAt: "2021-01-01" };
expect(hasKey(obj, "createdAt")).toBe(true);
});
test("hasKey returns false if the key does not exist", () => {
const obj = { createdAt: "2021-01-01" };
expect(hasKey(obj, "updatedAt")).toBe(false);
});
});
describe("parseDate should work as expected", () => {
test("parseDate should set defaults", () => {
const obj = { createdAt: "2021-01-01", updatedAt: "2021-01-01" };
const result = parseDate(obj);
expect(result.createdAt).toBeInstanceOf(Date);
expect(result.updatedAt).toBeInstanceOf(Date);
});
test("parseDate should set passed in types", () => {
const obj = { key1: "2021-01-01", key2: "2021-01-01" };
const result = parseDate(obj, ["key1", "key2"]);
expect(result.key1).toBeInstanceOf(Date);
expect(result.key2).toBeInstanceOf(Date);
});
});

View file

@ -8,6 +8,28 @@ import { Requests } from "../../requests";
// TDeleteResult = void
// >
type BaseApiType = {
createdAt: string;
updatedAt: string;
};
export function hasKey(obj: object, key: string): obj is Required<BaseApiType> {
return typeof obj[key] === "string";
}
export function parseDate<T>(obj: T, keys: Array<keyof T> = []): T {
const result = { ...obj };
[...keys, "createdAt", "updatedAt"].forEach(key => {
// @ts-ignore - we are checking for the key above
if (hasKey(result, key)) {
// @ts-ignore - we are guarding against this above
result[key] = new Date(result[key]);
}
});
return result;
}
export class BaseAPI {
http: Requests;

View file

@ -1,60 +1,26 @@
import { BaseAPI, route } from "../base";
import { Label } from "./labels";
import { Location } from "./locations";
import { parseDate } from "../base/base-api";
import { ItemCreate, ItemOut } from "../types/data-contracts";
import { Results } from "./types";
export interface ItemCreate {
name: string;
description: string;
locationId: string;
labelIds: string[];
}
export interface Item {
createdAt: string;
description: string;
id: string;
labels: Label[];
location: Location;
manufacturer: string;
modelNumber: string;
name: string;
notes: string;
purchaseFrom: string;
purchasePrice: number;
purchaseTime: Date;
serialNumber: string;
soldNotes: string;
soldPrice: number;
soldTime: Date;
soldTo: string;
updatedAt: string;
lifetimeWarranty: boolean;
warrantyExpires: Date;
warrantyDetails: string;
}
export class ItemsApi extends BaseAPI {
getAll() {
return this.http.get<Results<Item>>({ url: route("/items") });
return this.http.get<Results<ItemOut>>({ url: route("/items") });
}
create(item: ItemCreate) {
return this.http.post<ItemCreate, Item>({ url: route("/items"), body: item });
return this.http.post<ItemCreate, ItemOut>({ url: route("/items"), body: item });
}
async get(id: string) {
const payload = await this.http.get<Item>({ url: route(`/items/${id}`) });
const payload = await this.http.get<ItemOut>({ url: route(`/items/${id}`) });
if (!payload.data) {
return payload;
}
// Parse Date Types
payload.data.purchaseTime = new Date(payload.data.purchaseTime);
payload.data.soldTime = new Date(payload.data.soldTime);
payload.data.warrantyExpires = new Date(payload.data.warrantyExpires);
payload.data = parseDate(payload.data, ["purchaseTime", "soldTime", "warrantyExpires"]);
return payload;
}
@ -63,7 +29,7 @@ export class ItemsApi extends BaseAPI {
}
update(id: string, item: ItemCreate) {
return this.http.put<ItemCreate, Item>({ url: route(`/items/${id}`), body: item });
return this.http.put<ItemCreate, ItemOut>({ url: route(`/items/${id}`), body: item });
}
import(file: File) {

View file

@ -1,37 +1,25 @@
import { BaseAPI, route } from "../base";
import { Item } from "./items";
import { Details, OutType, Results } from "./types";
export type LabelCreate = Details & {
color: string;
};
export type LabelUpdate = LabelCreate;
export type Label = LabelCreate &
OutType & {
groupId: string;
items: Item[];
};
import { LabelCreate, LabelOut } from "../types/data-contracts";
import { Results } from "./types";
export class LabelsApi extends BaseAPI {
getAll() {
return this.http.get<Results<Label>>({ url: route("/labels") });
return this.http.get<Results<LabelOut>>({ url: route("/labels") });
}
create(body: LabelCreate) {
return this.http.post<LabelCreate, Label>({ url: route("/labels"), body });
return this.http.post<LabelCreate, LabelOut>({ url: route("/labels"), body });
}
get(id: string) {
return this.http.get<Label>({ url: route(`/labels/${id}`) });
return this.http.get<LabelOut>({ url: route(`/labels/${id}`) });
}
delete(id: string) {
return this.http.delete<void>({ url: route(`/labels/${id}`) });
}
update(id: string, body: LabelUpdate) {
return this.http.put<LabelUpdate, Label>({ url: route(`/labels/${id}`), body });
update(id: string, body: LabelCreate) {
return this.http.put<LabelCreate, LabelOut>({ url: route(`/labels/${id}`), body });
}
}

View file

@ -1,29 +1,20 @@
import { BaseAPI, route } from "../base";
import { Item } from "./items";
import { Details, OutType, Results } from "./types";
export type LocationCreate = Details;
export type Location = LocationCreate &
OutType & {
groupId: string;
items: Item[];
itemCount: number;
};
import { LocationCount, LocationCreate, LocationOut } from "../types/data-contracts";
import { Results } from "./types";
export type LocationUpdate = LocationCreate;
export class LocationsApi extends BaseAPI {
getAll() {
return this.http.get<Results<Location>>({ url: route("/locations") });
return this.http.get<Results<LocationCount>>({ url: route("/locations") });
}
create(body: LocationCreate) {
return this.http.post<LocationCreate, Location>({ url: route("/locations"), body });
return this.http.post<LocationCreate, LocationOut>({ url: route("/locations"), body });
}
get(id: string) {
return this.http.get<Location>({ url: route(`/locations/${id}`) });
return this.http.get<LocationOut>({ url: route(`/locations/${id}`) });
}
delete(id: string) {
@ -31,6 +22,6 @@ export class LocationsApi extends BaseAPI {
}
update(id: string, body: LocationUpdate) {
return this.http.put<LocationUpdate, Location>({ url: route(`/locations/${id}`), body });
return this.http.put<LocationUpdate, LocationOut>({ url: route(`/locations/${id}`), body });
}
}

View file

@ -1,19 +1,3 @@
/**
* OutType is the base type that is returned from the API.
* In contains the common fields that are included with every
* API response that isn't a bulk result
*/
export type OutType = {
id: string;
createdAt: string;
updatedAt: string;
};
export type Details = {
name: string;
description: string;
};
export type Results<T> = {
items: T[];
};

View file

@ -0,0 +1,210 @@
/* post-processed by ./scripts/process-types.py */
/* eslint-disable */
/* tslint:disable */
/*
* ---------------------------------------------------------------
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
* ## ##
* ## AUTHOR: acacode ##
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
* ---------------------------------------------------------------
*/
export interface ServerResult {
details: any;
error: boolean;
item: any;
message: string;
}
export interface ServerResults {
items: any;
}
export interface ApiSummary {
health: boolean;
message: string;
title: string;
versions: string[];
}
export interface DocumentOut {
id: string;
path: string;
title: string;
}
export interface ItemAttachment {
createdAt: Date;
document: DocumentOut;
id: string;
updatedAt: Date;
}
export interface ItemCreate {
description: string;
labelIds: string[];
/** Edges */
locationId: string;
name: string;
}
export interface ItemOut {
attachments: ItemAttachment[];
createdAt: Date;
description: string;
id: string;
labels: LabelSummary[];
/** Warranty */
lifetimeWarranty: boolean;
/** Edges */
location: LocationSummary;
manufacturer: string;
modelNumber: string;
name: string;
/** Extras */
notes: string;
purchaseFrom: string;
purchasePrice: number;
/** Purchase */
purchaseTime: Date;
/** Identifications */
serialNumber: string;
soldNotes: string;
soldPrice: number;
/** Sold */
soldTime: Date;
soldTo: string;
updatedAt: Date;
warrantyDetails: string;
warrantyExpires: Date;
}
export interface ItemSummary {
createdAt: Date;
description: string;
id: string;
labels: LabelSummary[];
/** Warranty */
lifetimeWarranty: boolean;
/** Edges */
location: LocationSummary;
manufacturer: string;
modelNumber: string;
name: string;
/** Extras */
notes: string;
purchaseFrom: string;
purchasePrice: number;
/** Purchase */
purchaseTime: Date;
/** Identifications */
serialNumber: string;
soldNotes: string;
soldPrice: number;
/** Sold */
soldTime: Date;
soldTo: string;
updatedAt: Date;
warrantyDetails: string;
warrantyExpires: Date;
}
export interface LabelCreate {
color: string;
description: string;
name: string;
}
export interface LabelOut {
createdAt: Date;
description: string;
groupId: string;
id: string;
items: ItemSummary[];
name: string;
updatedAt: Date;
}
export interface LabelSummary {
createdAt: Date;
description: string;
groupId: string;
id: string;
name: string;
updatedAt: Date;
}
export interface LocationCount {
createdAt: Date;
description: string;
id: string;
itemCount: number;
name: string;
updatedAt: Date;
}
export interface LocationCreate {
description: string;
name: string;
}
export interface LocationOut {
createdAt: Date;
description: string;
id: string;
items: ItemSummary[];
name: string;
updatedAt: Date;
}
export interface LocationSummary {
createdAt: Date;
description: string;
id: string;
name: string;
updatedAt: Date;
}
export interface TokenResponse {
expiresAt: string;
token: string;
}
export interface UserIn {
email: string;
name: string;
password: string;
}
export interface UserOut {
email: string;
groupId: string;
groupName: string;
id: string;
isSuperuser: boolean;
name: string;
}
export interface UserRegistration {
groupName: string;
user: UserIn;
}
export interface UserUpdate {
email: string;
name: string;
}