{title}
diff --git a/packages/core-sdk/README.md b/packages/core-sdk/README.md new file mode 100644 index 0000000..2bad938 --- /dev/null +++ b/packages/core-sdk/README.md @@ -0,0 +1,81 @@ +# @changespage/core + +Framework-agnostic JavaScript SDK for changes.page. + +## Installation + +```bash +npm install @changespage/core +``` + +## Usage + +```ts +import { createChangesPageClient } from '@changespage/core'; + +const client = createChangesPageClient({ + baseUrl: 'https://yourpage.changes.page' +}); + +const { posts, totalCount, hasMore } = await client.getPosts({ limit: 10 }); + +const latestPost = await client.getLatestPost(); + +const pinnedPost = await client.getPinnedPost(); +``` + +## API + +### `createChangesPageClient(config)` + +| Option | Type | Description | +|--------|------|-------------| +| `baseUrl` | `string` | Your changes.page URL | + +### `client.getPosts(options?)` + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `limit` | `number` | 10 | Posts per page (max 50) | +| `offset` | `number` | 0 | Pagination offset | + +Returns `{ posts, totalCount, hasMore }` + +### `client.getLatestPost()` + +Returns the most recent post or `null`. + +### `client.getPinnedPost()` + +Returns the pinned post or `null` if none is pinned. + +## Utilities + +### `getTagLabel(tag)` + +Returns a display label for a post tag. + +```ts +import { getTagLabel } from '@changespage/core'; + +getTagLabel('new'); // "New" +getTagLabel('fix'); // "Fix" +``` + +## Types + +```ts +type PostTag = 'fix' | 'new' | 'improvement' | 'announcement' | 'alert'; + +interface Post { + id: string; + title: string; + content: string; + tags: PostTag[]; + publication_date: string | null; + updated_at: string; + created_at: string; + url: string; + plain_text_content: string; +} +``` diff --git a/packages/core-sdk/package.json b/packages/core-sdk/package.json new file mode 100644 index 0000000..2203eb9 --- /dev/null +++ b/packages/core-sdk/package.json @@ -0,0 +1,34 @@ +{ + "name": "@changespage/core", + "version": "0.1.0", + "type": "module", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "rimraf dist && tsc", + "prepublishOnly": "npm run build" + }, + "dependencies": {}, + "devDependencies": { + "rimraf": "^6.1.0", + "typescript": "^5.3.3" + }, + "author": "Arjun Komath
{posts.map(post => (
- {({ title, content, tags, formattedDate, url }) => (
+ {({ title, content, tags, publicationDate, url }) => (
{content}
@@ -65,7 +65,7 @@ Returns the most recent post or `null`.
Render prop component exposing:
-- `id`, `title`, `content` (markdown), `plainText`, `tags`, `date`, `formattedDate`, `url`
+- `id`, `title`, `content` (markdown), `plainText`, `tags`, `publicationDate`, `url`
## Hook
diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json
index ee1cd19..a914a8b 100644
--- a/packages/react-sdk/package.json
+++ b/packages/react-sdk/package.json
@@ -17,7 +17,9 @@
"build": "rimraf dist && tsc",
"prepublishOnly": "npm run build"
},
- "dependencies": {},
+ "dependencies": {
+ "@changespage/core": "workspace:*"
+ },
"devDependencies": {
"@types/react": "^18.3.18",
"react": "^18.3.1",
diff --git a/packages/react-sdk/src/components/ChangelogPost.tsx b/packages/react-sdk/src/components/ChangelogPost.tsx
index a90e568..4e417e0 100644
--- a/packages/react-sdk/src/components/ChangelogPost.tsx
+++ b/packages/react-sdk/src/components/ChangelogPost.tsx
@@ -1,15 +1,13 @@
import type { ChangelogPostProps, ChangelogPostRenderProps } from "../types";
-import { formatDate, parseDate } from "../utils";
-export function ChangelogPost({ post, locale, children }: ChangelogPostProps) {
+export function ChangelogPost({ post, children }: ChangelogPostProps) {
const renderProps: ChangelogPostRenderProps = {
id: post.id,
title: post.title,
content: post.content,
plainText: post.plain_text_content,
tags: post.tags,
- date: parseDate(post.publication_date),
- formattedDate: formatDate(post.publication_date, locale),
+ publicationDate: post.publication_date,
url: post.url,
};
diff --git a/packages/react-sdk/src/hooks/usePosts.ts b/packages/react-sdk/src/hooks/usePosts.ts
index acc823f..d79b24b 100644
--- a/packages/react-sdk/src/hooks/usePosts.ts
+++ b/packages/react-sdk/src/hooks/usePosts.ts
@@ -1,7 +1,7 @@
"use client";
import { useState, useCallback, useEffect, useRef } from "react";
-import type { ChangesPageClient, Post } from "../types";
+import type { ChangesPageClient, Post } from "@changespage/core";
export interface UsePostsInitialData {
posts: Post[];
diff --git a/packages/react-sdk/src/index.ts b/packages/react-sdk/src/index.ts
index ef4aaeb..cda0b21 100644
--- a/packages/react-sdk/src/index.ts
+++ b/packages/react-sdk/src/index.ts
@@ -1,17 +1,16 @@
-export { createChangesPageClient } from "./client";
-export { ChangelogPost } from "./components";
-export { usePosts } from "./hooks";
-export { formatDate, getTagLabel, parseDate } from "./utils";
+export { createChangesPageClient, getTagLabel } from "@changespage/core";
export type {
ChangesPageClient,
- ChangelogPostProps,
- ChangelogPostRenderProps,
ClientConfig,
GetPostsOptions,
GetPostsResult,
Post,
PostTag,
-} from "./types";
+} from "@changespage/core";
+
+export { ChangelogPost } from "./components";
+export { usePosts } from "./hooks";
+export type { ChangelogPostProps, ChangelogPostRenderProps } from "./types";
export type {
UsePostsInitialData,
UsePostsOptions,
diff --git a/packages/react-sdk/src/types.ts b/packages/react-sdk/src/types.ts
index c5d8ee9..60017da 100644
--- a/packages/react-sdk/src/types.ts
+++ b/packages/react-sdk/src/types.ts
@@ -1,33 +1,14 @@
import type { ReactNode } from "react";
+import type { Post, PostTag } from "@changespage/core";
-export type PostTag = "fix" | "new" | "improvement" | "announcement" | "alert";
-
-export interface Post {
- id: string;
- title: string;
- content: string;
- tags: PostTag[];
- publication_date: string | null;
- updated_at: string;
- created_at: string;
- url: string;
- plain_text_content: string;
-}
-
-export interface ClientConfig {
- baseUrl: string;
-}
-
-export interface GetPostsOptions {
- limit?: number;
- offset?: number;
-}
-
-export interface GetPostsResult {
- posts: Post[];
- totalCount: number;
- hasMore: boolean;
-}
+export type {
+ ChangesPageClient,
+ ClientConfig,
+ GetPostsOptions,
+ GetPostsResult,
+ Post,
+ PostTag,
+} from "@changespage/core";
export interface ChangelogPostRenderProps {
id: string;
@@ -35,18 +16,11 @@ export interface ChangelogPostRenderProps {
content: string;
plainText: string;
tags: PostTag[];
- date: Date | null;
- formattedDate: string;
+ publicationDate: string | null;
url: string;
}
export interface ChangelogPostProps {
post: Post;
- locale?: string;
children: (props: ChangelogPostRenderProps) => ReactNode;
}
-
-export interface ChangesPageClient {
- getPosts: (options?: GetPostsOptions) => Promise;
- getLatestPost: () => Promise;
-}
diff --git a/packages/react-sdk/src/utils.ts b/packages/react-sdk/src/utils.ts
deleted file mode 100644
index 14ddfba..0000000
--- a/packages/react-sdk/src/utils.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { PostTag } from "./types";
-
-const tagLabels: Record = {
- fix: "Fix",
- new: "New",
- improvement: "Improvement",
- announcement: "Announcement",
- alert: "Alert",
-};
-
-export function getTagLabel(tag: PostTag): string {
- return tagLabels[tag] ?? tag;
-}
-
-export function formatDate(
- dateString: string | null,
- locale: string = "en-US"
-): string {
- if (!dateString) return "";
-
- const date = new Date(dateString);
- return date.toLocaleDateString(locale, {
- year: "numeric",
- month: "long",
- day: "numeric",
- });
-}
-
-export function parseDate(dateString: string | null): Date | null {
- if (!dateString) return null;
- return new Date(dateString);
-}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 98a4dff..a292cc2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -455,7 +455,20 @@ importers:
specifier: ^5
version: 5.8.3
+ packages/core-sdk:
+ devDependencies:
+ rimraf:
+ specifier: ^6.1.0
+ version: 6.1.2
+ typescript:
+ specifier: ^5.3.3
+ version: 5.8.3
+
packages/react-sdk:
+ dependencies:
+ '@changespage/core':
+ specifier: workspace:*
+ version: link:../core-sdk
devDependencies:
'@types/react':
specifier: ^18.3.18
{title}
- + {publicationDate && }{tags.map(t => {t})}