diff --git a/.gitignore b/.gitignore index a547bf3..60e1f67 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +# UpdateHive specific files +.env diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..3e22129 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +/dist \ No newline at end of file diff --git a/lib/changelog.hook.ts b/lib/changelog.hook.ts new file mode 100644 index 0000000..f8cb8bd --- /dev/null +++ b/lib/changelog.hook.ts @@ -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(undefined); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(); + + 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, + }; +} diff --git a/lib/changelog.types.ts b/lib/changelog.types.ts new file mode 100644 index 0000000..1bb8809 --- /dev/null +++ b/lib/changelog.types.ts @@ -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[]; +}; diff --git a/lib/components/ChangelogContainer/index.tsx b/lib/components/ChangelogContainer/index.tsx index 2e924c0..0f78811 100644 --- a/lib/components/ChangelogContainer/index.tsx +++ b/lib/components/ChangelogContainer/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import * as React from "react"; export const ChangelogContainer: React.FC = () => { return
ChangelogContainer
; diff --git a/lib/index.ts b/lib/index.ts index f838f57..f690c54 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -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', - }; -} \ No newline at end of file +export { useChangelogs } from "./changelog.hook"; + +export { ChangelogContainer } from "./components/ChangelogContainer"; diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..b2e3662 --- /dev/null +++ b/src/App.tsx @@ -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 ( + <> +
UpdateHive - React Client Component
+ + + ); +}; diff --git a/src/main.tsx b/src/main.tsx index d825abf..6866c37 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -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( -
UpdateHive - React Client Component
- +
, ); diff --git a/vite.config.ts b/vite.config.ts index 6a20bd8..cfcc977 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,7 @@ import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [react()], server: { - port: 3000, + port: 3080, host: true, }, build: { @@ -23,6 +23,6 @@ export default defineConfig({ "react-dom": "ReactDOM", }, }, - } + }, }, });