@traiwa/cms-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +98 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Traiwa Holidays
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# @traiwa/cms-client
|
|
2
|
+
|
|
3
|
+
Tiny typed TypeScript client for the **Traiwa / FlexCMS** public REST API. Fetch block-based pages from the Page Builder, list published slugs for sitemaps, load site-wide settings, and pull rich-text articles — all with full end-to-end types.
|
|
4
|
+
|
|
5
|
+
- ✅ Zero runtime dependencies
|
|
6
|
+
- ✅ Works in Node 18+, browsers, Next.js (RSC + ISR), Nuxt, Astro, Cloudflare Workers
|
|
7
|
+
- ✅ Fully typed — every response has an interface generated from the backend Pydantic models
|
|
8
|
+
- ✅ ~2 KB gzipped
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
yarn add @traiwa/cms-client
|
|
14
|
+
# or
|
|
15
|
+
npm i @traiwa/cms-client
|
|
16
|
+
# or
|
|
17
|
+
pnpm add @traiwa/cms-client
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createClient } from "@traiwa/cms-client";
|
|
24
|
+
|
|
25
|
+
const cms = createClient({ baseUrl: "https://cms.example.com" });
|
|
26
|
+
|
|
27
|
+
// Site page composed of blocks (Hero, Packages, Testimonials, FAQ, Stats)
|
|
28
|
+
const home = await cms.getPage("home");
|
|
29
|
+
|
|
30
|
+
// List every published page (for sitemaps / nav menus)
|
|
31
|
+
const { data } = await cms.listPages();
|
|
32
|
+
const urls = data.map((p) => `https://example.com/${p.slug}`);
|
|
33
|
+
|
|
34
|
+
// Site-wide settings (favicon, default SEO, social image)
|
|
35
|
+
const settings = await cms.getSettings();
|
|
36
|
+
|
|
37
|
+
// Rich-text article
|
|
38
|
+
const article = await cms.getContent("my-first-post");
|
|
39
|
+
|
|
40
|
+
// Feed of published articles
|
|
41
|
+
const { data: posts } = await cms.listContent({ type: "article", limit: 20 });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### `createClient(options)`
|
|
47
|
+
|
|
48
|
+
| Option | Type | Description |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `baseUrl` | `string` | **Required.** Origin of your CMS (no trailing `/api`). |
|
|
51
|
+
| `token` | `string?` | Optional JWT for admin endpoints. Public endpoints don't need one. |
|
|
52
|
+
| `fetch` | `typeof fetch?` | Custom fetch (Node <18, edge runtimes). Defaults to `globalThis.fetch`. |
|
|
53
|
+
| `headers` | `Record<string,string>?` | Extra headers merged into every request. |
|
|
54
|
+
|
|
55
|
+
### Methods
|
|
56
|
+
|
|
57
|
+
| Method | Endpoint | Returns |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `getPage(slug)` | `GET /api/public/pages/:slug` | `SitePage` (with `sections: PageSection[]`) |
|
|
60
|
+
| `listPages()` | `GET /api/public/pages` | `{ data: SitePageSummary[], count: number }` |
|
|
61
|
+
| `getSettings()` | `GET /api/public/settings` | `SiteSettings` |
|
|
62
|
+
| `getContent(slug)` | `GET /api/public/content/:slug` | `Article` |
|
|
63
|
+
| `listContent(query?)` | `GET /api/public/content?...` | `{ data: Article[], count: number }` |
|
|
64
|
+
| `raw<T>(path, init?)` | any | Escape hatch for admin/authenticated endpoints |
|
|
65
|
+
|
|
66
|
+
Errors throw `CmsClientError` with `status`, `body`, and `path` fields for easy handling.
|
|
67
|
+
|
|
68
|
+
## Type-safe block rendering
|
|
69
|
+
|
|
70
|
+
Every section in `page.sections` is a discriminated union — switch on `section.type` for exhaustive rendering:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import type { PageSection } from "@traiwa/cms-client";
|
|
74
|
+
|
|
75
|
+
function renderSection(section: PageSection) {
|
|
76
|
+
switch (section.type) {
|
|
77
|
+
case "hero": return <Hero {...section} />;
|
|
78
|
+
case "packages": return <PackageCollection {...section} />;
|
|
79
|
+
case "testimonials": return <TestimonialCollection {...section} />;
|
|
80
|
+
case "faq": return <FAQSection {...section} />;
|
|
81
|
+
case "stats": return <StatsSection {...section} />;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Next.js (App Router + ISR)
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// app/[slug]/page.tsx
|
|
90
|
+
import { createClient } from "@traiwa/cms-client";
|
|
91
|
+
|
|
92
|
+
const cms = createClient({ baseUrl: process.env.CMS_URL! });
|
|
93
|
+
|
|
94
|
+
export async function generateStaticParams() {
|
|
95
|
+
const { data } = await cms.listPages();
|
|
96
|
+
return data.map((p) => ({ slug: p.slug }));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const revalidate = 60; // ISR — regenerate every minute
|
|
100
|
+
|
|
101
|
+
export default async function Page({ params }: { params: { slug: string } }) {
|
|
102
|
+
const page = await cms.getPage(params.slug);
|
|
103
|
+
return <PageLayout config={page} />;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Nuxt 3
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
// composables/useCms.ts
|
|
111
|
+
import { createClient } from "@traiwa/cms-client";
|
|
112
|
+
|
|
113
|
+
export const useCms = () => createClient({
|
|
114
|
+
baseUrl: useRuntimeConfig().public.cmsUrl,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// pages/[slug].vue
|
|
118
|
+
const cms = useCms();
|
|
119
|
+
const { data: page } = await useAsyncData(() => cms.getPage(route.params.slug));
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Cloudflare Workers / edge
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
export default {
|
|
126
|
+
async fetch(req: Request, env: Env) {
|
|
127
|
+
const cms = createClient({ baseUrl: env.CMS_URL, fetch });
|
|
128
|
+
const home = await cms.getPage("home");
|
|
129
|
+
return Response.json(home);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Errors
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { CmsClientError } from "@traiwa/cms-client";
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const page = await cms.getPage("missing");
|
|
141
|
+
} catch (e) {
|
|
142
|
+
if (e instanceof CmsClientError && e.status === 404) {
|
|
143
|
+
return notFound();
|
|
144
|
+
}
|
|
145
|
+
throw e;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Authenticated / admin usage
|
|
150
|
+
|
|
151
|
+
Pass a JWT to hit protected endpoints via the `raw()` escape hatch:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const admin = createClient({
|
|
155
|
+
baseUrl: "https://cms.example.com",
|
|
156
|
+
token: process.env.CMS_ADMIN_TOKEN!,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const allPages = await admin.raw("/api/site-pages"); // requires auth
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Development
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
yarn install
|
|
166
|
+
yarn build # emits dist/{index.js,index.d.ts,index.js.map}
|
|
167
|
+
yarn typecheck # tsc --noEmit
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @traiwa/cms-client
|
|
3
|
+
* Tiny typed client for the Nova Panel (Traiwa CMS) public + admin API.
|
|
4
|
+
*
|
|
5
|
+
* Quick start:
|
|
6
|
+
* import { createClient } from "@traiwa/cms-client";
|
|
7
|
+
* const cms = createClient({ baseUrl: "https://cms.example.com" });
|
|
8
|
+
* const home = await cms.getPage("home");
|
|
9
|
+
*
|
|
10
|
+
* Admin usage (JWT required):
|
|
11
|
+
* const cms = createClient({ baseUrl, token });
|
|
12
|
+
* const page = await cms.admin.createPage({ title: "New", sections: [] });
|
|
13
|
+
*/
|
|
14
|
+
export * from "./types.js";
|
|
15
|
+
import type { Article, ContentStatus, ListResponse, PageSEO, PageSection, SitePage, SitePageSummary, SiteSettings } from "./types.js";
|
|
16
|
+
export interface ClientOptions {
|
|
17
|
+
/** Full origin, e.g. https://cms.example.com — NO trailing /api (added internally). */
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
/** Optional JWT for admin endpoints. Public endpoints don't need one. */
|
|
20
|
+
token?: string;
|
|
21
|
+
/** Custom fetch implementation (Node <18 or edge runtimes). Defaults to globalThis.fetch. */
|
|
22
|
+
fetch?: typeof fetch;
|
|
23
|
+
/** Extra headers merged into every request. */
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
export declare class CmsClientError extends Error {
|
|
27
|
+
status: number;
|
|
28
|
+
body: string;
|
|
29
|
+
path: string;
|
|
30
|
+
constructor(status: number, body: string, path: string);
|
|
31
|
+
}
|
|
32
|
+
export interface ListContentQuery {
|
|
33
|
+
type?: "article" | "page";
|
|
34
|
+
limit?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface SitePageInput {
|
|
37
|
+
title: string;
|
|
38
|
+
slug?: string;
|
|
39
|
+
status?: ContentStatus;
|
|
40
|
+
seo?: PageSEO;
|
|
41
|
+
sections?: PageSection[];
|
|
42
|
+
}
|
|
43
|
+
export interface TranslateRequest {
|
|
44
|
+
text: string;
|
|
45
|
+
target_language: string;
|
|
46
|
+
source_language?: string;
|
|
47
|
+
model?: "gpt-5.2" | "claude-sonnet-4-5";
|
|
48
|
+
preserve_markdown?: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface SummarizeRequest {
|
|
51
|
+
text: string;
|
|
52
|
+
max_bullets?: number;
|
|
53
|
+
style?: "bullets" | "paragraph" | "tldr";
|
|
54
|
+
model?: "gpt-5.2" | "claude-sonnet-4-5";
|
|
55
|
+
}
|
|
56
|
+
export interface AiTextResponse {
|
|
57
|
+
content: string;
|
|
58
|
+
model: string;
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
export interface RichResultsCheck {
|
|
62
|
+
type: string | null;
|
|
63
|
+
status: "pass" | "warn" | "fail";
|
|
64
|
+
richResultsEligible: boolean;
|
|
65
|
+
errors: string[];
|
|
66
|
+
warnings: string[];
|
|
67
|
+
}
|
|
68
|
+
export interface RichResultsReport {
|
|
69
|
+
overall: "pass" | "warn" | "fail";
|
|
70
|
+
results: RichResultsCheck[];
|
|
71
|
+
}
|
|
72
|
+
export interface LoginResponse {
|
|
73
|
+
access_token: string;
|
|
74
|
+
token_type: string;
|
|
75
|
+
user: {
|
|
76
|
+
id: string;
|
|
77
|
+
email: string;
|
|
78
|
+
name: string;
|
|
79
|
+
role: string;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export interface AdminNamespace {
|
|
83
|
+
/** Exchange email/password for a JWT (call once, then re-create client with token). */
|
|
84
|
+
login(email: string, password: string): Promise<LoginResponse>;
|
|
85
|
+
/** List every site page (all statuses, includes full sections). Requires token. */
|
|
86
|
+
listPages(): Promise<SitePage[]>;
|
|
87
|
+
/** Create a new site page. */
|
|
88
|
+
createPage(input: SitePageInput): Promise<SitePage>;
|
|
89
|
+
/** Fetch a single page by id (any status). */
|
|
90
|
+
getPage(id: string): Promise<SitePage>;
|
|
91
|
+
/** Update an existing page (partial). */
|
|
92
|
+
updatePage(id: string, patch: Partial<SitePageInput>): Promise<SitePage>;
|
|
93
|
+
/** Delete a page permanently. */
|
|
94
|
+
deletePage(id: string): Promise<{
|
|
95
|
+
ok: true;
|
|
96
|
+
}>;
|
|
97
|
+
/** Translate arbitrary text/markdown via the Nova Panel LLM proxy. */
|
|
98
|
+
translate(input: TranslateRequest): Promise<AiTextResponse>;
|
|
99
|
+
/** Summarise long text (bullets / paragraph / tldr) via the Nova Panel LLM proxy. */
|
|
100
|
+
summarize(input: SummarizeRequest): Promise<AiTextResponse>;
|
|
101
|
+
/** Validate a JSON-LD payload (single object or array) against Google Rich Results rules. */
|
|
102
|
+
validateJsonLd(payload: Record<string, unknown> | Record<string, unknown>[]): Promise<RichResultsReport>;
|
|
103
|
+
}
|
|
104
|
+
export interface TraiwaClient {
|
|
105
|
+
/** Fetch a single site page by slug. Only `status: published` pages resolve. */
|
|
106
|
+
getPage(slug: string): Promise<SitePage>;
|
|
107
|
+
/** Fetch the pre-computed JSON-LD payload for a published page (application/ld+json). */
|
|
108
|
+
getPageJsonLd(slug: string): Promise<Record<string, unknown>>;
|
|
109
|
+
/** Fetch the XML sitemap of every published page. Returns raw XML text. */
|
|
110
|
+
getSitemap(): Promise<string>;
|
|
111
|
+
/** List every published site page (metadata only, no sections). */
|
|
112
|
+
listPages(): Promise<ListResponse<SitePageSummary>>;
|
|
113
|
+
/** Site-wide settings (name, favicon, default SEO, social sharing image). */
|
|
114
|
+
getSettings(): Promise<SiteSettings>;
|
|
115
|
+
/** Fetch a single published article/page by slug. */
|
|
116
|
+
getContent(slug: string): Promise<Article>;
|
|
117
|
+
/** List published articles/pages, optionally filtered by type. */
|
|
118
|
+
listContent(query?: ListContentQuery): Promise<ListResponse<Article>>;
|
|
119
|
+
/** Escape hatch: hit any API path with the current auth. */
|
|
120
|
+
raw<T>(path: string, init?: RequestInit): Promise<T>;
|
|
121
|
+
/** Authenticated admin operations. Requires `token` in ClientOptions. */
|
|
122
|
+
admin: AdminNamespace;
|
|
123
|
+
}
|
|
124
|
+
/** Create a memoized client instance. */
|
|
125
|
+
export declare function createClient(opts: ClientOptions): TraiwaClient;
|
|
126
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,YAAY,EACZ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,eAAe,EACf,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;gBACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAOvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,GAAG,mBAAmB,CAAC;IACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,EAAE,SAAS,GAAG,mBAAmB,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE;AAED,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/D,mFAAmF;IACnF,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjC,8BAA8B;IAC9B,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,8CAA8C;IAC9C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,yCAAyC;IACzC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAC9C,sEAAsE;IACtE,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5D,qFAAqF;IACrF,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5D,6FAA6F;IAC7F,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC1G;AAED,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,yFAAyF;IACzF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,2EAA2E;IAC3E,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,mEAAmE;IACnE,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC;IACpD,6EAA6E;IAC7E,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,qDAAqD;IACrD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,kEAAkE;IAClE,WAAW,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,4DAA4D;IAC5D,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrD,yEAAyE;IACzE,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAiF9D"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @traiwa/cms-client
|
|
3
|
+
* Tiny typed client for the Nova Panel (Traiwa CMS) public + admin API.
|
|
4
|
+
*
|
|
5
|
+
* Quick start:
|
|
6
|
+
* import { createClient } from "@traiwa/cms-client";
|
|
7
|
+
* const cms = createClient({ baseUrl: "https://cms.example.com" });
|
|
8
|
+
* const home = await cms.getPage("home");
|
|
9
|
+
*
|
|
10
|
+
* Admin usage (JWT required):
|
|
11
|
+
* const cms = createClient({ baseUrl, token });
|
|
12
|
+
* const page = await cms.admin.createPage({ title: "New", sections: [] });
|
|
13
|
+
*/
|
|
14
|
+
export * from "./types.js";
|
|
15
|
+
export class CmsClientError extends Error {
|
|
16
|
+
constructor(status, body, path) {
|
|
17
|
+
super(`CMS ${path} failed (${status}): ${body.slice(0, 200)}`);
|
|
18
|
+
this.name = "CmsClientError";
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.body = body;
|
|
21
|
+
this.path = path;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Create a memoized client instance. */
|
|
25
|
+
export function createClient(opts) {
|
|
26
|
+
const baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
27
|
+
const fetchImpl = opts.fetch ??
|
|
28
|
+
(typeof globalThis !== "undefined" && typeof globalThis.fetch === "function"
|
|
29
|
+
? globalThis.fetch.bind(globalThis)
|
|
30
|
+
: (() => { throw new Error("No fetch implementation. Pass `fetch` in options."); })());
|
|
31
|
+
const baseHeaders = { Accept: "application/json", ...opts.headers };
|
|
32
|
+
if (opts.token)
|
|
33
|
+
baseHeaders.Authorization = `Bearer ${opts.token}`;
|
|
34
|
+
async function raw(path, init) {
|
|
35
|
+
const url = `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
|
|
36
|
+
const headers = {
|
|
37
|
+
...baseHeaders,
|
|
38
|
+
...init?.headers,
|
|
39
|
+
};
|
|
40
|
+
// Auto Content-Type when body is JSON.
|
|
41
|
+
if (init?.body && typeof init.body === "string" && !headers["Content-Type"]) {
|
|
42
|
+
headers["Content-Type"] = "application/json";
|
|
43
|
+
}
|
|
44
|
+
const res = await fetchImpl(url, { ...init, headers });
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const body = await res.text().catch(() => res.statusText);
|
|
47
|
+
throw new CmsClientError(res.status, body, path);
|
|
48
|
+
}
|
|
49
|
+
if (res.status === 204)
|
|
50
|
+
return undefined;
|
|
51
|
+
return (await res.json());
|
|
52
|
+
}
|
|
53
|
+
const admin = {
|
|
54
|
+
login: (email, password) => raw(`/api/auth/login`, { method: "POST", body: JSON.stringify({ email, password }) }),
|
|
55
|
+
listPages: () => raw(`/api/site-pages`),
|
|
56
|
+
createPage: (input) => raw(`/api/site-pages`, { method: "POST", body: JSON.stringify(input) }),
|
|
57
|
+
getPage: (id) => raw(`/api/site-pages/${encodeURIComponent(id)}`),
|
|
58
|
+
updatePage: (id, patch) => raw(`/api/site-pages/${encodeURIComponent(id)}`, {
|
|
59
|
+
method: "PUT",
|
|
60
|
+
body: JSON.stringify(patch),
|
|
61
|
+
}),
|
|
62
|
+
deletePage: (id) => raw(`/api/site-pages/${encodeURIComponent(id)}`, { method: "DELETE" }),
|
|
63
|
+
translate: (input) => raw(`/api/ai/translate`, { method: "POST", body: JSON.stringify(input) }),
|
|
64
|
+
summarize: (input) => raw(`/api/ai/summarize`, { method: "POST", body: JSON.stringify(input) }),
|
|
65
|
+
validateJsonLd: (payload) => raw(`/api/seo/validate-jsonld`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: JSON.stringify({ payload }),
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
raw,
|
|
72
|
+
admin,
|
|
73
|
+
getPage: (slug) => raw(`/api/public/pages/${encodeURIComponent(slug)}`),
|
|
74
|
+
getPageJsonLd: (slug) => raw(`/api/public/pages/${encodeURIComponent(slug)}/jsonld`),
|
|
75
|
+
getSitemap: async () => {
|
|
76
|
+
const url = `${baseUrl}/api/public/sitemap.xml`;
|
|
77
|
+
const res = await fetchImpl(url, { headers: { Accept: "application/xml" } });
|
|
78
|
+
if (!res.ok) {
|
|
79
|
+
const body = await res.text().catch(() => res.statusText);
|
|
80
|
+
throw new CmsClientError(res.status, body, "/api/public/sitemap.xml");
|
|
81
|
+
}
|
|
82
|
+
return res.text();
|
|
83
|
+
},
|
|
84
|
+
listPages: () => raw(`/api/public/pages`),
|
|
85
|
+
getSettings: () => raw(`/api/public/settings`),
|
|
86
|
+
getContent: (slug) => raw(`/api/public/content/${encodeURIComponent(slug)}`),
|
|
87
|
+
listContent: (query) => {
|
|
88
|
+
const qs = new URLSearchParams();
|
|
89
|
+
if (query?.type)
|
|
90
|
+
qs.set("type", query.type);
|
|
91
|
+
if (typeof query?.limit === "number")
|
|
92
|
+
qs.set("limit", String(query.limit));
|
|
93
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
94
|
+
return raw(`/api/public/content${suffix}`);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
export type ContentStatus = "draft" | "published" | "archived";
|
|
2
|
+
export type SchemaKind = "Article" | "FAQ" | "Review" | "Product" | "Event" | "HowTo" | "Custom";
|
|
3
|
+
export type SchemaType = "None" | SchemaKind;
|
|
4
|
+
export interface SchemaEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
type: SchemaKind;
|
|
7
|
+
data: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export type SectionType = "hero" | "packages" | "testimonials" | "faq" | "stats";
|
|
10
|
+
export interface HeroSlide {
|
|
11
|
+
image: string;
|
|
12
|
+
alt?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface CTAButton {
|
|
15
|
+
label: string;
|
|
16
|
+
href: string;
|
|
17
|
+
variant?: "primary" | "secondary";
|
|
18
|
+
}
|
|
19
|
+
export interface HeroBlock {
|
|
20
|
+
type: "hero";
|
|
21
|
+
id?: string;
|
|
22
|
+
hidden?: boolean;
|
|
23
|
+
eyebrow?: string;
|
|
24
|
+
title: string;
|
|
25
|
+
subtitle?: string;
|
|
26
|
+
slides: HeroSlide[];
|
|
27
|
+
ctas?: CTAButton[];
|
|
28
|
+
autoPlayMs?: number;
|
|
29
|
+
overlayOpacity?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface PackageItem {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
price: string;
|
|
35
|
+
originalPrice?: string;
|
|
36
|
+
duration?: string;
|
|
37
|
+
image: string;
|
|
38
|
+
link: string;
|
|
39
|
+
badge?: string;
|
|
40
|
+
rating?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface PackagesBlock {
|
|
43
|
+
type: "packages";
|
|
44
|
+
id?: string;
|
|
45
|
+
hidden?: boolean;
|
|
46
|
+
eyebrow?: string;
|
|
47
|
+
title: string;
|
|
48
|
+
subtitle?: string;
|
|
49
|
+
packages: PackageItem[];
|
|
50
|
+
cta?: CTAButton;
|
|
51
|
+
}
|
|
52
|
+
export interface Testimonial {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
location?: string;
|
|
56
|
+
quote: string;
|
|
57
|
+
rating: number;
|
|
58
|
+
avatar?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface TestimonialsBlock {
|
|
61
|
+
type: "testimonials";
|
|
62
|
+
id?: string;
|
|
63
|
+
hidden?: boolean;
|
|
64
|
+
eyebrow?: string;
|
|
65
|
+
title: string;
|
|
66
|
+
subtitle?: string;
|
|
67
|
+
testimonials: Testimonial[];
|
|
68
|
+
}
|
|
69
|
+
export interface FAQItem {
|
|
70
|
+
id: string;
|
|
71
|
+
question: string;
|
|
72
|
+
answer: string;
|
|
73
|
+
}
|
|
74
|
+
export interface FAQBlock {
|
|
75
|
+
type: "faq";
|
|
76
|
+
id?: string;
|
|
77
|
+
hidden?: boolean;
|
|
78
|
+
eyebrow?: string;
|
|
79
|
+
title: string;
|
|
80
|
+
subtitle?: string;
|
|
81
|
+
items: FAQItem[];
|
|
82
|
+
}
|
|
83
|
+
export interface StatItem {
|
|
84
|
+
id: string;
|
|
85
|
+
label: string;
|
|
86
|
+
value: string;
|
|
87
|
+
suffix?: string;
|
|
88
|
+
}
|
|
89
|
+
export interface StatsBlock {
|
|
90
|
+
type: "stats";
|
|
91
|
+
id?: string;
|
|
92
|
+
hidden?: boolean;
|
|
93
|
+
eyebrow?: string;
|
|
94
|
+
title?: string;
|
|
95
|
+
stats: StatItem[];
|
|
96
|
+
variant?: "light" | "dark";
|
|
97
|
+
}
|
|
98
|
+
export type PageSection = HeroBlock | PackagesBlock | TestimonialsBlock | FAQBlock | StatsBlock;
|
|
99
|
+
export interface PageSEO {
|
|
100
|
+
metaTitle?: string;
|
|
101
|
+
metaDescription?: string;
|
|
102
|
+
focusKeyword?: string;
|
|
103
|
+
canonicalUrl?: string;
|
|
104
|
+
ogImage?: string;
|
|
105
|
+
/** New canonical shape: multiple schema markups per page. */
|
|
106
|
+
schemas?: SchemaEntry[];
|
|
107
|
+
/** Legacy fields — still accepted for backwards compatibility. */
|
|
108
|
+
schemaType?: SchemaType;
|
|
109
|
+
schemaData?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
export interface SitePage {
|
|
112
|
+
id: string;
|
|
113
|
+
title: string;
|
|
114
|
+
slug: string;
|
|
115
|
+
status: ContentStatus;
|
|
116
|
+
seo: PageSEO;
|
|
117
|
+
sections: PageSection[];
|
|
118
|
+
created_at: string;
|
|
119
|
+
updated_at: string;
|
|
120
|
+
}
|
|
121
|
+
export interface SitePageSummary {
|
|
122
|
+
id: string;
|
|
123
|
+
title: string;
|
|
124
|
+
slug: string;
|
|
125
|
+
status: ContentStatus;
|
|
126
|
+
seo: PageSEO;
|
|
127
|
+
created_at: string;
|
|
128
|
+
updated_at: string;
|
|
129
|
+
}
|
|
130
|
+
export interface ContentSeo {
|
|
131
|
+
meta_title?: string;
|
|
132
|
+
meta_description?: string;
|
|
133
|
+
focus_keyword?: string;
|
|
134
|
+
canonical_url?: string;
|
|
135
|
+
og_image?: string;
|
|
136
|
+
schema_type?: SchemaType;
|
|
137
|
+
schema_data?: Record<string, unknown>;
|
|
138
|
+
}
|
|
139
|
+
export interface Article {
|
|
140
|
+
id: string;
|
|
141
|
+
type: "article" | "page";
|
|
142
|
+
title: string;
|
|
143
|
+
slug: string;
|
|
144
|
+
body: string;
|
|
145
|
+
excerpt: string;
|
|
146
|
+
status: ContentStatus;
|
|
147
|
+
seo: ContentSeo;
|
|
148
|
+
tags: string[];
|
|
149
|
+
featured_image: string;
|
|
150
|
+
created_at: string;
|
|
151
|
+
updated_at: string;
|
|
152
|
+
published_at?: string | null;
|
|
153
|
+
}
|
|
154
|
+
export interface SiteSettings {
|
|
155
|
+
id: string;
|
|
156
|
+
site_name: string;
|
|
157
|
+
site_description: string;
|
|
158
|
+
site_url: string;
|
|
159
|
+
favicon_url: string;
|
|
160
|
+
default_meta_title: string;
|
|
161
|
+
default_meta_description: string;
|
|
162
|
+
social_sharing_image: string;
|
|
163
|
+
twitter_handle: string;
|
|
164
|
+
updated_at: string;
|
|
165
|
+
}
|
|
166
|
+
export interface ListResponse<T> {
|
|
167
|
+
data: T[];
|
|
168
|
+
count: number;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,mFAAmF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@traiwa/cms-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tiny typed client for the FlexCMS / Traiwa Page Builder API. Fetch pages, list published slugs, and load site settings in any TypeScript/JavaScript app.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"prepublishOnly": "npm run build",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"cms",
|
|
28
|
+
"headless-cms",
|
|
29
|
+
"traiwa",
|
|
30
|
+
"flexcms",
|
|
31
|
+
"page-builder",
|
|
32
|
+
"typescript"
|
|
33
|
+
],
|
|
34
|
+
"author": "Traiwa Holidays",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/traiwa/cms-client"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/traiwa/cms-client#readme",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "^5.9.3"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|