@chigisoft-web/cms-sdk 1.0.3
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/README.md +278 -0
- package/dist/cli.js +313 -0
- package/dist/index.d.mts +164 -0
- package/dist/index.d.ts +164 -0
- package/dist/index.global.js +245 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +249 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +222 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# @chigisoft-web/cms-sdk
|
|
2
|
+
|
|
3
|
+
A lightweight, TypeScript-first SDK to dynamically fetch and display content from ChigiSoft CMS in your custom frontend applications. Works out-of-the-box in **Nuxt 3/4** and **Next.js**.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the package via npm or yarn:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @chigisoft-web/cms-sdk
|
|
11
|
+
# or
|
|
12
|
+
yarn add @chigisoft-web/cms-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Quick Setup Wizard ⚡
|
|
16
|
+
|
|
17
|
+
You can automatically configure your project's environment variables (`CHIGISOFT_PROJECT_ID`, `CHIGISOFT_API_TOKEN`, and `CHIGISOFT_STUDIO_URL`), generate the client setup helpers, and create the dynamic `/studio` routing pages using the interactive CLI wizard:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @chigisoft-web/cms-sdk
|
|
21
|
+
```
|
|
22
|
+
*(If the package is already installed locally in your workspace, you can run `npx chigisoft` instead).*
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
### 1. Zero-Configuration (Recommended)
|
|
29
|
+
If you have set the environment variables `CHIGISOFT_PROJECT_ID` and `CHIGISOFT_API_TOKEN` in your project (`.env` file or hosting provider), you can initialize the client without arguments:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
33
|
+
|
|
34
|
+
const chigisoft = createClient();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Manual Configuration
|
|
38
|
+
You can also pass config values explicitly:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
42
|
+
|
|
43
|
+
const chigisoft = createClient({
|
|
44
|
+
projectId: 'your-project-id',
|
|
45
|
+
token: 'your-access-token',
|
|
46
|
+
// Optional: override API endpoint for local development
|
|
47
|
+
// baseUrl: 'http://localhost:3000',
|
|
48
|
+
// useCdn: true
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Browser / Script Tag (cPanel / Static HTML)
|
|
53
|
+
|
|
54
|
+
For static HTML sites or environments like cPanel where you do not run a Node build step, you can include the pre-built global script:
|
|
55
|
+
|
|
56
|
+
1. Upload the `dist/index.global.js` bundle to your host.
|
|
57
|
+
2. Load it in your HTML:
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<!-- Load the global SDK client -->
|
|
61
|
+
<script src="./dist/index.global.js"></script>
|
|
62
|
+
<script>
|
|
63
|
+
// The SDK is exposed on the global `ChigiSoft` object
|
|
64
|
+
const chigisoft = ChigiSoft.createClient({
|
|
65
|
+
projectId: 'your-project-id',
|
|
66
|
+
token: 'your-access-token'
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Fetch blogs
|
|
70
|
+
chigisoft.getBlogs().then(blogs => {
|
|
71
|
+
console.log('Blogs:', blogs);
|
|
72
|
+
});
|
|
73
|
+
</script>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Content Module Integration Guides
|
|
79
|
+
|
|
80
|
+
ChigiSoft CMS organizes your website content into four core modules: **Pages**, **Blogs**, **Menus**, and **Testimonies**.
|
|
81
|
+
|
|
82
|
+
### 1. Pages Module
|
|
83
|
+
|
|
84
|
+
Dynamic pages consist of structured visual blocks (such as headings, rich text, images, and call-to-actions) constructed inside the CMS Page Builder.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
// Example: Rendering a page inside a Next.js Server Component
|
|
88
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
89
|
+
import { notFound } from 'next/navigation';
|
|
90
|
+
|
|
91
|
+
const chigisoft = createClient();
|
|
92
|
+
|
|
93
|
+
export default async function CMSPage({ params }: { params: { slug: string } }) {
|
|
94
|
+
const page = await chigisoft.getPageBySlug(params.slug);
|
|
95
|
+
if (!page) notFound();
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<main className="max-w-4xl mx-auto py-12 px-6">
|
|
99
|
+
<h1 className="text-4xl font-bold mb-8">{page.title}</h1>
|
|
100
|
+
|
|
101
|
+
{/* Loop through blocks and render corresponding UI components */}
|
|
102
|
+
<div className="space-y-8">
|
|
103
|
+
{page.blocks.map((block) => {
|
|
104
|
+
switch (block.type) {
|
|
105
|
+
case 'heading':
|
|
106
|
+
return <h2 key={block.id} className="text-2xl font-semibold">{block.content.text}</h2>;
|
|
107
|
+
case 'richText':
|
|
108
|
+
return <div key={block.id} className="prose" dangerouslySetInnerHTML={{ __html: block.content.html || block.content.text }} />;
|
|
109
|
+
case 'image':
|
|
110
|
+
return <img key={block.id} src={block.content.mediaUrl} alt={block.content.alt || ''} className="rounded-lg shadow-lg" />;
|
|
111
|
+
case 'ctaStrip':
|
|
112
|
+
return (
|
|
113
|
+
<div key={block.id} className="p-6 bg-brand-50 border rounded-xl flex items-center justify-between">
|
|
114
|
+
<div>
|
|
115
|
+
<h3 className="text-lg font-bold">{block.content.heading}</h3>
|
|
116
|
+
<p className="text-sm text-gray-600">{block.content.body}</p>
|
|
117
|
+
</div>
|
|
118
|
+
<a href={block.content.primaryUrl} className="px-4 py-2 bg-brand-600 text-white rounded-lg">{block.content.primaryLabel}</a>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
default:
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
})}
|
|
125
|
+
</div>
|
|
126
|
+
</main>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 2. Blogs Module
|
|
132
|
+
|
|
133
|
+
Blog posts represent long-form articles/news which can contain structured blocks similar to pages.
|
|
134
|
+
|
|
135
|
+
```vue
|
|
136
|
+
<!-- Example: Fetching and rendering a blog in a Vue / Nuxt Page component -->
|
|
137
|
+
<script setup lang="ts">
|
|
138
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
139
|
+
|
|
140
|
+
const route = useRoute();
|
|
141
|
+
const chigisoft = createClient();
|
|
142
|
+
|
|
143
|
+
const { data: blog } = await useAsyncData(`blog-${route.params.slug}`, () =>
|
|
144
|
+
chigisoft.getBlogBySlug(route.params.slug as string)
|
|
145
|
+
);
|
|
146
|
+
</script>
|
|
147
|
+
|
|
148
|
+
<template>
|
|
149
|
+
<article v-if="blog" class="max-w-3xl mx-auto py-12">
|
|
150
|
+
<h1 class="text-4xl font-extrabold mb-4">{{ blog.title }}</h1>
|
|
151
|
+
<p class="text-gray-500 mb-8">Published on {{ new Date(blog.createdAt).toLocaleDateString() }}</p>
|
|
152
|
+
|
|
153
|
+
<div class="space-y-6">
|
|
154
|
+
<div v-for="block in blog.blocks" :key="block.id">
|
|
155
|
+
<p v-if="block.type === 'richText'" v-html="block.content.html || block.content.text"></p>
|
|
156
|
+
<img v-else-if="block.type === 'image'" :src="block.content.mediaUrl" :alt="block.content.alt" class="rounded-lg" />
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</article>
|
|
160
|
+
</template>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3. Menus Module
|
|
164
|
+
|
|
165
|
+
Retrieve navigation structures (headers, sidebars, footers) and their items, supporting custom external links as well as items linked to internal CMS pages.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Fetching a navigation structure by name
|
|
169
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
170
|
+
|
|
171
|
+
const chigisoft = createClient();
|
|
172
|
+
|
|
173
|
+
async function renderHeader() {
|
|
174
|
+
const menu = await chigisoft.getMenuByName('header');
|
|
175
|
+
if (!menu) return;
|
|
176
|
+
|
|
177
|
+
console.log(`Menu: ${menu.name}`);
|
|
178
|
+
// items are sorted by their configured order
|
|
179
|
+
menu.items.forEach((item) => {
|
|
180
|
+
const linkUrl = item.pageId ? `/pages/${item.pageId}` : item.url;
|
|
181
|
+
console.log(` - Link: ${item.label} -> ${linkUrl} (New Tab: ${item.openInNewTab})`);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 4. Testimonies Module
|
|
187
|
+
|
|
188
|
+
Testimonies capture user feedback, reviews, and quotes.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Fetch and display client testimonials
|
|
192
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
193
|
+
|
|
194
|
+
const chigisoft = createClient();
|
|
195
|
+
|
|
196
|
+
async function loadTestimonials() {
|
|
197
|
+
const testimonies = await chigisoft.getTestimonies();
|
|
198
|
+
testimonies.forEach((testimony) => {
|
|
199
|
+
console.log(`Client: ${testimony.title}`);
|
|
200
|
+
console.log(`Quote: ${testimony.description}`);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## API Reference
|
|
208
|
+
|
|
209
|
+
### `ChigiSoftClient`
|
|
210
|
+
|
|
211
|
+
#### `getPages(options?)`
|
|
212
|
+
Fetches all pages matching the configured project ID.
|
|
213
|
+
* **Arguments:** `options?: ChigiSoftRequestInit`
|
|
214
|
+
* **Returns:** `Promise<CMSPage[]>`
|
|
215
|
+
|
|
216
|
+
#### `getPageBySlug(slug, options?)`
|
|
217
|
+
Fetches a specific page by its URL slug or ID. Returns `null` if not found.
|
|
218
|
+
* **Arguments:**
|
|
219
|
+
- `slug: string`
|
|
220
|
+
- `options?: ChigiSoftRequestInit`
|
|
221
|
+
* **Returns:** `Promise<CMSPage | null>`
|
|
222
|
+
|
|
223
|
+
#### `getBlogs(options?)`
|
|
224
|
+
Fetches all blog posts matching the configured project ID.
|
|
225
|
+
* **Arguments:** `options?: ChigiSoftRequestInit`
|
|
226
|
+
* **Returns:** `Promise<CMSBlog[]>`
|
|
227
|
+
|
|
228
|
+
#### `getBlogBySlug(slug, options?)`
|
|
229
|
+
Fetches a specific blog post by its URL slug or ID. Returns `null` if not found.
|
|
230
|
+
* **Arguments:**
|
|
231
|
+
- `slug: string`
|
|
232
|
+
- `options?: ChigiSoftRequestInit`
|
|
233
|
+
* **Returns:** `Promise<CMSBlog | null>`
|
|
234
|
+
|
|
235
|
+
#### `getTestimonies(options?)`
|
|
236
|
+
Fetches all client testimonies matching the configured project ID.
|
|
237
|
+
* **Arguments:** `options?: ChigiSoftRequestInit`
|
|
238
|
+
* **Returns:** `Promise<CMSTestimony[]>`
|
|
239
|
+
|
|
240
|
+
#### `getTestimonyBySlug(slug, options?)`
|
|
241
|
+
Fetches a specific testimony by its slug or ID. Returns `null` if not found.
|
|
242
|
+
* **Arguments:**
|
|
243
|
+
- `slug: string`
|
|
244
|
+
- `options?: ChigiSoftRequestInit`
|
|
245
|
+
* **Returns:** `Promise<CMSTestimony | null>`
|
|
246
|
+
|
|
247
|
+
#### `getMenus(options?)`
|
|
248
|
+
Fetches all navigation menus for the project.
|
|
249
|
+
* **Arguments:** `options?: ChigiSoftRequestInit`
|
|
250
|
+
* **Returns:** `Promise<CMSMenu[]>`
|
|
251
|
+
|
|
252
|
+
#### `getMenuById(id, options?)`
|
|
253
|
+
Fetches a specific menu structure by its ID.
|
|
254
|
+
* **Arguments:**
|
|
255
|
+
- `id: string`
|
|
256
|
+
- `options?: ChigiSoftRequestInit`
|
|
257
|
+
* **Returns:** `Promise<CMSMenu | null>`
|
|
258
|
+
|
|
259
|
+
#### `getMenuByName(name, options?)`
|
|
260
|
+
Fetches a specific menu structure by its name (e.g., `'header'`, `'sidebar'`).
|
|
261
|
+
* **Arguments:**
|
|
262
|
+
- `name: string`
|
|
263
|
+
- `options?: ChigiSoftRequestInit`
|
|
264
|
+
* **Returns:** `Promise<CMSMenu | null>`
|
|
265
|
+
|
|
266
|
+
#### `fetch(path, options?)`
|
|
267
|
+
Executes a generic GET request to any endpoint on the CMS. Useful for querying custom endpoints.
|
|
268
|
+
* **Arguments:**
|
|
269
|
+
- `path: string` (e.g., `'/v1/audits'`)
|
|
270
|
+
- `options?: ChigiSoftRequestInit`
|
|
271
|
+
* **Returns:** `Promise<T>`
|
|
272
|
+
|
|
273
|
+
#### `mountStudio(target, options?)`
|
|
274
|
+
Embeds the CMS dashboard iframe inside the DOM container.
|
|
275
|
+
* **Arguments:**
|
|
276
|
+
- `target: string | HTMLElement`
|
|
277
|
+
- `options?: { studioUrl?: string; style?: Partial<CSSStyleDeclaration> }`
|
|
278
|
+
* **Returns:** `HTMLIFrameElement`
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/cli.ts
|
|
27
|
+
var import_readline = __toESM(require("readline"));
|
|
28
|
+
var import_fs = __toESM(require("fs"));
|
|
29
|
+
var import_path = __toESM(require("path"));
|
|
30
|
+
var rl = import_readline.default.createInterface({
|
|
31
|
+
input: process.stdin,
|
|
32
|
+
output: process.stdout
|
|
33
|
+
});
|
|
34
|
+
var askQuestion = (query) => {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
rl.question(query, (answer) => {
|
|
37
|
+
resolve(answer.trim());
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
function writeEnv(envFile, projectId, token) {
|
|
42
|
+
const envPath = import_path.default.join(process.cwd(), envFile);
|
|
43
|
+
let content = "";
|
|
44
|
+
if (import_fs.default.existsSync(envPath)) {
|
|
45
|
+
content = import_fs.default.readFileSync(envPath, "utf8");
|
|
46
|
+
}
|
|
47
|
+
if (content && !content.endsWith("\n")) {
|
|
48
|
+
content += "\n";
|
|
49
|
+
}
|
|
50
|
+
let updated = false;
|
|
51
|
+
if (!content.includes("CHIGISOFT_PROJECT_ID")) {
|
|
52
|
+
content += `CHIGISOFT_PROJECT_ID="${projectId}"
|
|
53
|
+
`;
|
|
54
|
+
updated = true;
|
|
55
|
+
} else {
|
|
56
|
+
console.log(`\u26A0\uFE0F CHIGISOFT_PROJECT_ID is already defined in ${envFile}. Skipping overwrite.`);
|
|
57
|
+
}
|
|
58
|
+
if (!content.includes("CHIGISOFT_API_TOKEN")) {
|
|
59
|
+
content += `CHIGISOFT_API_TOKEN="${token}"
|
|
60
|
+
`;
|
|
61
|
+
updated = true;
|
|
62
|
+
} else {
|
|
63
|
+
console.log(`\u26A0\uFE0F CHIGISOFT_API_TOKEN is already defined in ${envFile}. Skipping overwrite.`);
|
|
64
|
+
}
|
|
65
|
+
if (!content.includes("CHIGISOFT_STUDIO_URL")) {
|
|
66
|
+
content += `CHIGISOFT_STUDIO_URL="https://cms.staging.chigisoft.co"
|
|
67
|
+
`;
|
|
68
|
+
updated = true;
|
|
69
|
+
} else {
|
|
70
|
+
console.log(`\u26A0\uFE0F CHIGISOFT_STUDIO_URL is already defined in ${envFile}. Skipping overwrite.`);
|
|
71
|
+
}
|
|
72
|
+
if (updated) {
|
|
73
|
+
import_fs.default.writeFileSync(envPath, content, "utf8");
|
|
74
|
+
console.log(`\u2705 Updated ${envFile} successfully with configurations.`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function ensureDir(dirPath) {
|
|
78
|
+
const absolutePath = import_path.default.join(process.cwd(), dirPath);
|
|
79
|
+
if (!import_fs.default.existsSync(absolutePath)) {
|
|
80
|
+
import_fs.default.mkdirSync(absolutePath, { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function main() {
|
|
84
|
+
console.log("\n===========================================");
|
|
85
|
+
console.log(" chigisoft-cms SDK Setup Wizard \u{1F680} ");
|
|
86
|
+
console.log("===========================================\n");
|
|
87
|
+
console.log("Choose your framework:");
|
|
88
|
+
console.log("1. Next.js (App Router)");
|
|
89
|
+
console.log("2. Nuxt.js (3/4)");
|
|
90
|
+
console.log("3. Vanilla HTML / JS");
|
|
91
|
+
const frameworkChoice = await askQuestion("\nEnter framework number (1-3): ");
|
|
92
|
+
if (!["1", "2", "3"].includes(frameworkChoice)) {
|
|
93
|
+
console.error("\u274C Invalid choice. Exiting setup.");
|
|
94
|
+
rl.close();
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
const projectId = await askQuestion("Enter your ChigiSoft Project ID/Slug: ");
|
|
98
|
+
if (!projectId) {
|
|
99
|
+
console.error("\u274C Project ID is required. Exiting setup.");
|
|
100
|
+
rl.close();
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const token = await askQuestion("Enter your ChigiSoft Access Token: ");
|
|
104
|
+
if (!token) {
|
|
105
|
+
console.error("\u274C Access Token is required. Exiting setup.");
|
|
106
|
+
rl.close();
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
if (frameworkChoice === "1") {
|
|
110
|
+
console.log("\n\u{1F527} Setting up Next.js integration...");
|
|
111
|
+
writeEnv(".env.local", projectId, token);
|
|
112
|
+
ensureDir("lib");
|
|
113
|
+
const clientFileContent = `import { createClient } from '@chigisoft-web/cms-sdk';
|
|
114
|
+
|
|
115
|
+
export const chigisoft = createClient();
|
|
116
|
+
`;
|
|
117
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), "lib/chigisoft.ts"), clientFileContent, "utf8");
|
|
118
|
+
console.log("\u2705 Created library helper at lib/chigisoft.ts");
|
|
119
|
+
ensureDir("app/studio");
|
|
120
|
+
const studioClientContent = `"use client";
|
|
121
|
+
|
|
122
|
+
import { useEffect, useRef } from "react";
|
|
123
|
+
import { createClient } from "@chigisoft-web/cms-sdk";
|
|
124
|
+
|
|
125
|
+
interface StudioClientProps {
|
|
126
|
+
projectId: string;
|
|
127
|
+
token: string;
|
|
128
|
+
studioUrl?: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default function StudioClient({ projectId, token, studioUrl }: StudioClientProps) {
|
|
132
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (!containerRef.current) return;
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const client = createClient({
|
|
139
|
+
projectId,
|
|
140
|
+
token,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
client.mountStudio(containerRef.current, {
|
|
144
|
+
studioUrl: studioUrl || "http://localhost:3000",
|
|
145
|
+
style: {
|
|
146
|
+
width: "100%",
|
|
147
|
+
height: "100vh",
|
|
148
|
+
border: "none",
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error("[ChigiSoft] Failed to mount studio:", error);
|
|
153
|
+
}
|
|
154
|
+
}, [projectId, token, studioUrl]);
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<div style={{ width: "100%", height: "100vh", overflow: "hidden", background: "#111" }}>
|
|
158
|
+
<div ref={containerRef} />
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), "app/studio/StudioClient.tsx"), studioClientContent, "utf8");
|
|
164
|
+
console.log("\u2705 Created studio UI component at app/studio/StudioClient.tsx");
|
|
165
|
+
const studioPageContent = `import StudioClient from "./StudioClient";
|
|
166
|
+
|
|
167
|
+
export default function StudioPage() {
|
|
168
|
+
const projectId = process.env.CHIGISOFT_PROJECT_ID || "";
|
|
169
|
+
const token = process.env.CHIGISOFT_API_TOKEN || "";
|
|
170
|
+
const studioUrl = process.env.CHIGISOFT_STUDIO_URL || "https://cms.staging.chigisoft.co";
|
|
171
|
+
|
|
172
|
+
if (!projectId || !token) {
|
|
173
|
+
return (
|
|
174
|
+
<div style={{ padding: "40px", fontFamily: "sans-serif", color: "#fff", background: "#1e1f21", height: "100vh" }}>
|
|
175
|
+
<h1>ChigiSoft CMS Setup Incomplete</h1>
|
|
176
|
+
<p>Please check your <code>.env.local</code> file and configure:</p>
|
|
177
|
+
<pre style={{ background: "#2a2b2d", padding: "16px", borderRadius: "8px", color: "#60a5fa" }}>
|
|
178
|
+
{\`CHIGISOFT_PROJECT_ID="your-project-id"
|
|
179
|
+
CHIGISOFT_API_TOKEN="your-api-token"
|
|
180
|
+
CHIGISOFT_STUDIO_URL="https://cms.staging.chigisoft.co" (optional)\`}
|
|
181
|
+
</pre>
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<StudioClient
|
|
188
|
+
projectId={projectId}
|
|
189
|
+
token={token}
|
|
190
|
+
studioUrl={studioUrl}
|
|
191
|
+
/>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
`;
|
|
195
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), "app/studio/page.tsx"), studioPageContent, "utf8");
|
|
196
|
+
console.log("\u2705 Created studio page router at app/studio/page.tsx");
|
|
197
|
+
console.log("\n\u{1F389} Next.js Setup Complete!");
|
|
198
|
+
console.log("You can now:");
|
|
199
|
+
console.log('1. Import the client helper in components: `import { chigisoft } from "@/lib/chigisoft";`');
|
|
200
|
+
console.log("2. Access the CMS login/dashboard from the `/studio` route of your site.");
|
|
201
|
+
} else if (frameworkChoice === "2") {
|
|
202
|
+
console.log("\n\u{1F527} Setting up Nuxt.js integration...");
|
|
203
|
+
writeEnv(".env", projectId, token);
|
|
204
|
+
ensureDir("plugins");
|
|
205
|
+
const pluginContent = `import { createClient } from '@chigisoft-web/cms-sdk';
|
|
206
|
+
|
|
207
|
+
export default defineNuxtPlugin(() => {
|
|
208
|
+
// Auto-resolves CHIGISOFT_PROJECT_ID and CHIGISOFT_API_TOKEN from your .env variables
|
|
209
|
+
const client = createClient();
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
provide: {
|
|
213
|
+
chigisoft: client
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
});
|
|
217
|
+
`;
|
|
218
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), "plugins/chigisoft.ts"), pluginContent, "utf8");
|
|
219
|
+
console.log("\u2705 Created Nuxt client plugin at plugins/chigisoft.ts");
|
|
220
|
+
const isNuxt4 = import_fs.default.existsSync(import_path.default.join(process.cwd(), "app"));
|
|
221
|
+
const pagesDir = isNuxt4 ? "app/pages" : "pages";
|
|
222
|
+
ensureDir(pagesDir);
|
|
223
|
+
const nuxtStudioPageContent = `<script setup lang="ts">
|
|
224
|
+
import { onMounted, ref } from 'vue';
|
|
225
|
+
import { createClient } from '@chigisoft-web/cms-sdk';
|
|
226
|
+
|
|
227
|
+
const containerRef = ref<HTMLElement | null>(null);
|
|
228
|
+
|
|
229
|
+
onMounted(() => {
|
|
230
|
+
if (!containerRef.value) return;
|
|
231
|
+
|
|
232
|
+
const client = createClient();
|
|
233
|
+
const env = (globalThis as any).process?.env || {};
|
|
234
|
+
const studioUrl = env.CHIGISOFT_STUDIO_URL || 'https://cms.staging.chigisoft.co';
|
|
235
|
+
|
|
236
|
+
client.mountStudio(containerRef.value, {
|
|
237
|
+
studioUrl,
|
|
238
|
+
style: {
|
|
239
|
+
width: '100%',
|
|
240
|
+
height: '100vh',
|
|
241
|
+
border: 'none',
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
</script>
|
|
246
|
+
|
|
247
|
+
<template>
|
|
248
|
+
<div style="width: 100%; height: 100vh; overflow: hidden; background: #111;">
|
|
249
|
+
<div ref="containerRef" />
|
|
250
|
+
</div>
|
|
251
|
+
</template>
|
|
252
|
+
`;
|
|
253
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), pagesDir, "studio.vue"), nuxtStudioPageContent, "utf8");
|
|
254
|
+
console.log(`\u2705 Created studio page at ${pagesDir}/studio.vue`);
|
|
255
|
+
console.log("\n\u{1F389} Nuxt.js Setup Complete!");
|
|
256
|
+
console.log("You can now:");
|
|
257
|
+
console.log("1. Access the client from Nuxt context: `const { $chigisoft } = useNuxtApp();`");
|
|
258
|
+
console.log("2. Access the CMS login/dashboard from the `/studio` route of your site.");
|
|
259
|
+
} else if (frameworkChoice === "3") {
|
|
260
|
+
console.log("\n\u{1F527} Setting up Vanilla HTML/JS demo...");
|
|
261
|
+
const demoHtmlContent = `<!DOCTYPE html>
|
|
262
|
+
<html lang="en">
|
|
263
|
+
<head>
|
|
264
|
+
<meta charset="UTF-8">
|
|
265
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
266
|
+
<title>ChigiSoft CMS Demo</title>
|
|
267
|
+
<!-- Load the global SDK client -->
|
|
268
|
+
<script src="https://cdn.jsdelivr.net/npm/@chigisoft-web/cms-sdk/dist/index.global.js"></script>
|
|
269
|
+
</head>
|
|
270
|
+
<body>
|
|
271
|
+
<h1>ChigiSoft CMS Integration</h1>
|
|
272
|
+
<div id="blogs-container">Loading blogs...</div>
|
|
273
|
+
|
|
274
|
+
<script>
|
|
275
|
+
// Initialize the CMS client
|
|
276
|
+
const chigisoft = ChigiSoft.createClient({
|
|
277
|
+
projectId: '${projectId}',
|
|
278
|
+
token: '${token}'
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Fetch and display blogs
|
|
282
|
+
chigisoft.getBlogs()
|
|
283
|
+
.then(blogs => {
|
|
284
|
+
const container = document.getElementById('blogs-container');
|
|
285
|
+
if (blogs.length === 0) {
|
|
286
|
+
container.textContent = 'No blog posts found.';
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
container.innerHTML = '<ul>' + blogs.map(blog => '<li>' + blog.title + '</li>').join('') + '</ul>';
|
|
290
|
+
})
|
|
291
|
+
.catch(error => {
|
|
292
|
+
console.error('Error fetching blogs:', error);
|
|
293
|
+
document.getElementById('blogs-container').textContent = 'Error loading content.';
|
|
294
|
+
});
|
|
295
|
+
</script>
|
|
296
|
+
</body>
|
|
297
|
+
</html>
|
|
298
|
+
`;
|
|
299
|
+
import_fs.default.writeFileSync(import_path.default.join(process.cwd(), "chigisoft-demo.html"), demoHtmlContent, "utf8");
|
|
300
|
+
console.log("\u2705 Created demo file at chigisoft-demo.html");
|
|
301
|
+
console.log("\n\u{1F389} Vanilla Setup Complete!");
|
|
302
|
+
console.log("Open `chigisoft-demo.html` in your browser to view your dynamic CMS contents!");
|
|
303
|
+
}
|
|
304
|
+
console.log("\n===========================================");
|
|
305
|
+
console.log(" Enjoy building! \u{1F4BB} ");
|
|
306
|
+
console.log("===========================================\n");
|
|
307
|
+
rl.close();
|
|
308
|
+
}
|
|
309
|
+
main().catch((error) => {
|
|
310
|
+
console.error("\u274C An unexpected error occurred during setup:", error);
|
|
311
|
+
rl.close();
|
|
312
|
+
process.exit(1);
|
|
313
|
+
});
|