Skip to content

Commit

Permalink
feat: add base implementation of changelog hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes Busch committed Jun 24, 2024
1 parent 4f6bbf9 commit b52c957
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?

# UpdateHive specific files
.env
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist
64 changes: 64 additions & 0 deletions lib/changelog.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useEffect, useState } from "react";
import {
Changelog,
UpdateHiveConfig,
UpdateHiveHookResult,
} from "./changelog.types.ts";

const DEFAULT_API_URL = "https://updatehive.com/api";

const buildRequestURL = (config: UpdateHiveConfig): string => {
const API_URL = `${config.connection.url ?? DEFAULT_API_URL}`;
const API_ENDPOINT = config.changelogs.onlyLast
? "/changelogs/latest?"
: "/changelogs?";
const searchParams = new URLSearchParams({
product: config.changelogs.product,
});

return `${API_URL}${API_ENDPOINT}` + searchParams.toString();
};

/**
* Base hook to get all changelogs for a product.
*/
export function useChangelogs(config: UpdateHiveConfig): UpdateHiveHookResult {
const [data, setData] = useState<Changelog[] | undefined>(undefined);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | undefined>();

const fetchData = async () => {
setIsLoading(true);

const requestURL = buildRequestURL(config);

try {
const result = await fetch(requestURL, {
headers: {
Authorization: `Bearer ${config.connection.API_KEY}`,
Accept: "application/vnd.wertarbyte.changelog.v1+json",
},
});

setData(await result.json());
} catch (error) {
if (error instanceof Error) {
setError(error.message);
} else {
setError("An unknown error occurred.");
}
}

setIsLoading(false);
};

useEffect(() => {
void fetchData();
}, []);

return {
loading: isLoading,
error,
data,
};
}
59 changes: 59 additions & 0 deletions lib/changelog.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Configuration to retrieve changelogs from UpdateHive.
*
* @param connection
* API_KEY: API_KEY to access UpdateHive public REST API.
* url: Override the default URL to UpdateHive API.
*
* @param changelogs
* product: Product ID to retrieve changelogs for.
* onlyLast: Retrieve only the last changelog.
*/
export type UpdateHiveConfig = {
connection: {
API_KEY: string;
url?: string;
};
changelogs: {
product: string;
onlyLast?: boolean;
};
};

export type UpdateHiveHookResult = {
loading: boolean;
error?: string;
data?: Changelog[];
};

export enum VariantType {
TEXT_ONLY = "TEXT_ONLY",
IMAGE_AND_TEXT = "IMAGE_AND_TEXT",
}

export enum ChangeType {
FEATURE = "FEATURE",
FIX = "FIX",
IMPROVEMENT = "IMPROVEMENT",
KNOWNISSUE = "KNOWNISSUE",
BREAKING = "BREAKING",
REMOVED = "REMOVED",
NOTE = "NOTE",
}

export type ChangelogEntryInterface = {
changeType: ChangeType;
description: string;
name?: string;
tags?: string[];
};

export type Changelog = {
product: string;
variant: VariantType;
version: string;
releaseDate: Date;
title?: string;
description?: string;
entries: ChangelogEntryInterface[];
};
2 changes: 1 addition & 1 deletion lib/components/ChangelogContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import * as React from "react";

export const ChangelogContainer: React.FC = () => {
return <div>ChangelogContainer</div>;
Expand Down
19 changes: 10 additions & 9 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export { ChangelogContainer } from './components/ChangelogContainer';
export type {
UpdateHiveConfig,
Changelog,
ChangelogEntryInterface,
ChangeType,
VariantType,
} from "./changelog.types";

/**
* Base hook to get all changelogs for a product.
*/
export function useChangelogs() {
return {
changelog: 'changelog',
};
}
export { useChangelogs } from "./changelog.hook";

export { ChangelogContainer } from "./components/ChangelogContainer";
25 changes: 25 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ChangelogContainer, useChangelogs } from "../lib";
import * as React from "react";

export const App: React.FC = () => {
const API_KEY = import.meta.env.VITE_UPDATEHIVE_API_KEY;

const { loading, error, data } = useChangelogs({
connection: {
API_KEY,
url: "http://localhost:3000/api",
},
changelogs: {
product: "66587d16c9f5d3bca4bc2b9d",
},
});

console.log(loading, error, data);

return (
<>
<div>UpdateHive - React Client Component</div>
<ChangelogContainer />
</>
);
};
7 changes: 3 additions & 4 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from "react";
import * as React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import {ChangelogContainer} from "../lib";
import { App } from "./App.tsx";

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<div>UpdateHive - React Client Component</div>
<ChangelogContainer/>
<App />
</React.StrictMode>,
);
4 changes: 2 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
port: 3080,
host: true,
},
build: {
Expand All @@ -23,6 +23,6 @@ export default defineConfig({
"react-dom": "ReactDOM",
},
},
}
},
},
});

0 comments on commit b52c957

Please sign in to comment.