myaidev-method 0.1.0 → 0.2.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/.env.example +20 -0
- package/PUBLISHING_GUIDE.md +521 -0
- package/README.md +123 -25
- package/package.json +25 -3
- package/src/lib/payloadcms-utils.js +394 -0
- package/src/lib/static-site-utils.js +377 -0
- package/src/scripts/astro-publish.js +209 -0
- package/src/scripts/docusaurus-publish.js +209 -0
- package/src/scripts/init-project.js +91 -0
- package/src/scripts/mintlify-publish.js +205 -0
- package/src/scripts/payloadcms-publish.js +202 -0
- package/src/templates/claude/agents/astro-publish.md +43 -0
- package/src/templates/claude/agents/docusaurus-publish.md +42 -0
- package/src/templates/claude/agents/mintlify-publish.md +42 -0
- package/src/templates/claude/agents/payloadcms-publish.md +134 -0
- package/src/templates/claude/commands/myai-astro-publish.md +54 -0
- package/src/templates/claude/commands/myai-docusaurus-publish.md +45 -0
- package/src/templates/claude/commands/myai-mintlify-publish.md +45 -0
- package/src/templates/claude/commands/myai-payloadcms-publish.md +45 -0
package/README.md
CHANGED
|
@@ -33,11 +33,13 @@ A comprehensive package for AI CLI tools (Claude Code, Gemini CLI, Codex CLI) th
|
|
|
33
33
|
- 🤖 **Custom Subagents**: Pre-configured AI agents in Markdown format with YAML frontmatter
|
|
34
34
|
- 📝 **Content Writer Agent**: Professional content creation with SEO optimization
|
|
35
35
|
- 🔐 **WordPress Admin Agent**: Site administration, security analysis, and performance optimization
|
|
36
|
-
-
|
|
37
|
-
-
|
|
36
|
+
- 📤 **Multi-Platform Publishing**: Publish to WordPress, PayloadCMS, Docusaurus, Mintlify, and Astro
|
|
37
|
+
- 🚀 **Coolify Deployment**: Self-hosted PaaS deployment and management
|
|
38
|
+
- 🔌 **MCP Integration**: WordPress, git-based workflows, and more
|
|
39
|
+
- 💻 **SSH Integration**: Server-level operations for advanced administration
|
|
38
40
|
- 🎯 **Slash Commands**: Easy-to-use Markdown-based commands for Claude Code
|
|
39
|
-
-
|
|
40
|
-
- ✅ **Standards Compliant**: Follows Claude Code
|
|
41
|
+
- 🔄 **Git-Based Publishing**: Automated git workflows for static sites
|
|
42
|
+
- ✅ **Standards Compliant**: Follows Claude Code 2.0 agent patterns
|
|
41
43
|
|
|
42
44
|
## 🚀 Installation
|
|
43
45
|
|
|
@@ -111,16 +113,76 @@ Professional content writer specializing in creating high-quality, engaging, and
|
|
|
111
113
|
- Multiple tone and audience support
|
|
112
114
|
- Keyword optimization
|
|
113
115
|
|
|
114
|
-
###
|
|
116
|
+
### Publishing Agents
|
|
117
|
+
|
|
118
|
+
#### WordPress Admin Agent
|
|
115
119
|
**File:** `.claude/agents/wordpress-admin.md`
|
|
116
120
|
|
|
117
121
|
WordPress administrator for comprehensive site management, security, performance, and health analysis.
|
|
118
122
|
|
|
119
123
|
**Capabilities:**
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
+
- Security: Vulnerability scanning, malware detection, user auditing
|
|
125
|
+
- Performance: Speed optimization, database cleanup, caching setup
|
|
126
|
+
- Health: Site monitoring, error analysis, backup verification
|
|
127
|
+
- Administration: User/plugin/theme management, content cleanup
|
|
128
|
+
|
|
129
|
+
#### PayloadCMS Publishing Agent
|
|
130
|
+
**File:** `.claude/agents/payloadcms-publish.md`
|
|
131
|
+
|
|
132
|
+
Publish markdown content to PayloadCMS headless CMS with Lexical rich text conversion.
|
|
133
|
+
|
|
134
|
+
**Capabilities:**
|
|
135
|
+
- Markdown to Lexical conversion
|
|
136
|
+
- JWT authentication
|
|
137
|
+
- Draft and published workflows
|
|
138
|
+
- Custom collections support
|
|
139
|
+
- Document updates
|
|
140
|
+
|
|
141
|
+
#### Docusaurus Publishing Agent
|
|
142
|
+
**File:** `.claude/agents/docusaurus-publish.md`
|
|
143
|
+
|
|
144
|
+
Git-based publishing for Docusaurus documentation sites.
|
|
145
|
+
|
|
146
|
+
**Capabilities:**
|
|
147
|
+
- Docs, blog, and pages support
|
|
148
|
+
- Automatic frontmatter transformation
|
|
149
|
+
- Sidebar configuration
|
|
150
|
+
- Git commit and push automation
|
|
151
|
+
|
|
152
|
+
#### Mintlify Publishing Agent
|
|
153
|
+
**File:** `.claude/agents/mintlify-publish.md`
|
|
154
|
+
|
|
155
|
+
Git-based publishing for Mintlify documentation with automatic navigation.
|
|
156
|
+
|
|
157
|
+
**Capabilities:**
|
|
158
|
+
- MDX transformation
|
|
159
|
+
- mint.json navigation updates
|
|
160
|
+
- Icon and metadata support
|
|
161
|
+
- Git workflow automation
|
|
162
|
+
|
|
163
|
+
#### Astro Publishing Agent
|
|
164
|
+
**File:** `.claude/agents/astro-publish.md`
|
|
165
|
+
|
|
166
|
+
Git-based publishing for Astro sites with content collections support.
|
|
167
|
+
|
|
168
|
+
**Capabilities:**
|
|
169
|
+
- Content collections publishing
|
|
170
|
+
- Schema-validated frontmatter
|
|
171
|
+
- pubDate transformation
|
|
172
|
+
- Draft/published workflow
|
|
173
|
+
|
|
174
|
+
### Deployment Agent
|
|
175
|
+
|
|
176
|
+
#### Coolify Deployment Agent
|
|
177
|
+
**File:** `.claude/agents/coolify-deploy.md`
|
|
178
|
+
|
|
179
|
+
Self-hosted PaaS deployment for applications.
|
|
180
|
+
|
|
181
|
+
**Capabilities:**
|
|
182
|
+
- Application deployment
|
|
183
|
+
- Health monitoring
|
|
184
|
+
- Resource management
|
|
185
|
+
- Multi-environment support
|
|
124
186
|
|
|
125
187
|
## 🎯 Slash Commands
|
|
126
188
|
|
|
@@ -179,34 +241,70 @@ Comprehensive WordPress site administration.
|
|
|
179
241
|
/myai-wordpress-admin staging-deploy
|
|
180
242
|
```
|
|
181
243
|
|
|
182
|
-
###
|
|
183
|
-
|
|
244
|
+
### Publishing Commands
|
|
245
|
+
|
|
246
|
+
#### `/myai-wordpress-publish`
|
|
247
|
+
Publish markdown content to WordPress.
|
|
184
248
|
|
|
185
249
|
```bash
|
|
186
|
-
|
|
187
|
-
/myai-wordpress-publish "
|
|
250
|
+
/myai-wordpress-publish "article.md" --status draft
|
|
251
|
+
/myai-wordpress-publish "article.md" --status published
|
|
252
|
+
```
|
|
188
253
|
|
|
189
|
-
|
|
190
|
-
|
|
254
|
+
#### `/myai-payloadcms-publish`
|
|
255
|
+
Publish markdown content to PayloadCMS.
|
|
191
256
|
|
|
192
|
-
|
|
193
|
-
/myai-
|
|
257
|
+
```bash
|
|
258
|
+
/myai-payloadcms-publish "article.md" --collection posts
|
|
259
|
+
/myai-payloadcms-publish "article.md" --status published --id 12345
|
|
194
260
|
```
|
|
195
261
|
|
|
196
|
-
|
|
197
|
-
|
|
262
|
+
#### `/myai-docusaurus-publish`
|
|
263
|
+
Publish markdown content to Docusaurus.
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
/myai-docusaurus-publish "guide.md"
|
|
267
|
+
/myai-docusaurus-publish "post.md" --type blog
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
#### `/myai-mintlify-publish`
|
|
271
|
+
Publish markdown content to Mintlify.
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
/myai-mintlify-publish "guide.mdx"
|
|
275
|
+
/myai-mintlify-publish "api-ref.md" --nav-section "API Reference"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
#### `/myai-astro-publish`
|
|
279
|
+
Publish markdown content to Astro.
|
|
198
280
|
|
|
199
281
|
```bash
|
|
200
|
-
|
|
201
|
-
/myai-
|
|
282
|
+
/myai-astro-publish "article.md" --collection blog
|
|
283
|
+
/myai-astro-publish "page.md" --pages
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Deployment Commands
|
|
202
287
|
|
|
203
|
-
|
|
204
|
-
|
|
288
|
+
#### `/myai-coolify-deploy`
|
|
289
|
+
Deploy applications to Coolify.
|
|
205
290
|
|
|
206
|
-
|
|
207
|
-
/myai-
|
|
291
|
+
```bash
|
|
292
|
+
/myai-coolify-deploy
|
|
208
293
|
```
|
|
209
294
|
|
|
295
|
+
### Configuration
|
|
296
|
+
|
|
297
|
+
#### `/myai-configure`
|
|
298
|
+
Configure MyAI Method settings.
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
/myai-configure
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Comprehensive Guide
|
|
305
|
+
|
|
306
|
+
For detailed publishing workflows and platform-specific guides, see **[PUBLISHING_GUIDE.md](PUBLISHING_GUIDE.md)**
|
|
307
|
+
|
|
210
308
|
## ⚙️ Configuration
|
|
211
309
|
|
|
212
310
|
After installation for Claude Code, the package creates a `.claude` directory following official standards:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myaidev-method",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "AI CLI tools package with custom subagents and MCP integrations for Claude Code, Gemini CLI, and more",
|
|
5
5
|
"mcpName": "io.github.myaione/myaidev-method",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -29,15 +29,31 @@
|
|
|
29
29
|
"wordpress:performance-check": "node src/scripts/wordpress-performance-check.js",
|
|
30
30
|
"wordpress:comprehensive-report": "node src/scripts/wordpress-comprehensive-report.js",
|
|
31
31
|
"coolify:status": "node src/scripts/coolify-status.js",
|
|
32
|
-
"coolify:list": "node src/scripts/coolify-list-resources.js"
|
|
32
|
+
"coolify:list": "node src/scripts/coolify-list-resources.js",
|
|
33
|
+
"payloadcms:publish": "node src/scripts/payloadcms-publish.js",
|
|
34
|
+
"docusaurus:publish": "node src/scripts/docusaurus-publish.js",
|
|
35
|
+
"mintlify:publish": "node src/scripts/mintlify-publish.js",
|
|
36
|
+
"astro:publish": "node src/scripts/astro-publish.js",
|
|
37
|
+
"configure": "node src/scripts/configure-cms.js",
|
|
38
|
+
"init": "node src/scripts/init-project.js"
|
|
33
39
|
},
|
|
34
40
|
"keywords": [
|
|
35
41
|
"claude-code",
|
|
36
42
|
"ai-cli",
|
|
37
43
|
"mcp",
|
|
38
44
|
"wordpress",
|
|
45
|
+
"payloadcms",
|
|
46
|
+
"payload",
|
|
47
|
+
"docusaurus",
|
|
48
|
+
"mintlify",
|
|
49
|
+
"astro",
|
|
39
50
|
"coolify",
|
|
40
51
|
"content-writer",
|
|
52
|
+
"cms",
|
|
53
|
+
"headless-cms",
|
|
54
|
+
"publishing",
|
|
55
|
+
"static-site",
|
|
56
|
+
"documentation",
|
|
41
57
|
"ai-agents",
|
|
42
58
|
"automation",
|
|
43
59
|
"deployment",
|
|
@@ -56,9 +72,12 @@
|
|
|
56
72
|
"commander": "^12.0.0",
|
|
57
73
|
"dotenv": "^16.4.1",
|
|
58
74
|
"fs-extra": "^11.2.0",
|
|
75
|
+
"gray-matter": "^4.0.3",
|
|
59
76
|
"inquirer": "^9.2.15",
|
|
77
|
+
"marked": "^11.0.0",
|
|
60
78
|
"node-fetch": "^3.3.2",
|
|
61
79
|
"ora": "^8.0.1",
|
|
80
|
+
"simple-git": "^3.22.0",
|
|
62
81
|
"ssh2": "^1.15.0",
|
|
63
82
|
"zod": "^3.23.8"
|
|
64
83
|
},
|
|
@@ -80,7 +99,10 @@
|
|
|
80
99
|
"LICENSE",
|
|
81
100
|
".env.example",
|
|
82
101
|
"WORDPRESS_ADMIN_SCRIPTS.md",
|
|
83
|
-
"COOLIFY_DEPLOYMENT.md"
|
|
102
|
+
"COOLIFY_DEPLOYMENT.md",
|
|
103
|
+
"PAYLOADCMS_PUBLISHING.md",
|
|
104
|
+
"STATIC_SITE_PUBLISHING.md",
|
|
105
|
+
"PUBLISHING_GUIDE.md"
|
|
84
106
|
],
|
|
85
107
|
"engines": {
|
|
86
108
|
"node": ">=18.0.0"
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PayloadCMS API Utilities
|
|
3
|
+
* Reusable functions for PayloadCMS content publishing and management
|
|
4
|
+
* Optimized for Claude Code 2.0 agent integration
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fetch from 'node-fetch';
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { parse } from 'dotenv';
|
|
10
|
+
import { marked } from 'marked';
|
|
11
|
+
|
|
12
|
+
export class PayloadCMSUtils {
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
// Load config from .env if not provided
|
|
15
|
+
if (!config.url || (!config.email && !config.apiKey)) {
|
|
16
|
+
const envConfig = this.loadEnvConfig();
|
|
17
|
+
config = { ...envConfig, ...config };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.url = config.url?.replace(/\/$/, '');
|
|
21
|
+
this.email = config.email;
|
|
22
|
+
this.password = config.password;
|
|
23
|
+
this.apiKey = config.apiKey;
|
|
24
|
+
this.token = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
loadEnvConfig() {
|
|
28
|
+
try {
|
|
29
|
+
const envPath = process.env.ENV_PATH || '.env';
|
|
30
|
+
const envContent = readFileSync(envPath, 'utf8');
|
|
31
|
+
const parsed = parse(envContent);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
url: parsed.PAYLOADCMS_URL,
|
|
35
|
+
email: parsed.PAYLOADCMS_EMAIL,
|
|
36
|
+
password: parsed.PAYLOADCMS_PASSWORD,
|
|
37
|
+
apiKey: parsed.PAYLOADCMS_API_KEY
|
|
38
|
+
};
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error(`Failed to load PayloadCMS configuration: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Authenticate with PayloadCMS and get JWT token
|
|
46
|
+
*/
|
|
47
|
+
async authenticate() {
|
|
48
|
+
// If API key is provided, use that instead
|
|
49
|
+
if (this.apiKey) {
|
|
50
|
+
this.token = this.apiKey;
|
|
51
|
+
return { success: true, method: 'api-key' };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!this.email || !this.password) {
|
|
55
|
+
throw new Error('Email and password required for authentication');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(`${this.url}/api/users/login`, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type': 'application/json'
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({
|
|
65
|
+
email: this.email,
|
|
66
|
+
password: this.password
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
const error = await response.text();
|
|
72
|
+
throw new Error(`Authentication failed: ${error}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const data = await response.json();
|
|
76
|
+
this.token = data.token;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
method: 'jwt',
|
|
81
|
+
user: data.user,
|
|
82
|
+
token: this.token
|
|
83
|
+
};
|
|
84
|
+
} catch (error) {
|
|
85
|
+
throw new Error(`PayloadCMS authentication failed: ${error.message}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Make authenticated API request
|
|
91
|
+
*/
|
|
92
|
+
async request(endpoint, options = {}) {
|
|
93
|
+
if (!this.token) {
|
|
94
|
+
await this.authenticate();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const url = `${this.url}${endpoint}`;
|
|
98
|
+
const headers = {
|
|
99
|
+
'Content-Type': 'application/json',
|
|
100
|
+
'Authorization': `JWT ${this.token}`,
|
|
101
|
+
...options.headers
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const response = await fetch(url, {
|
|
106
|
+
...options,
|
|
107
|
+
headers
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const data = await response.json().catch(() => ({}));
|
|
111
|
+
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
throw new Error(`HTTP ${response.status}: ${data.message || response.statusText}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return data;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
throw new Error(`PayloadCMS API request failed: ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Convert markdown to Lexical rich text format
|
|
124
|
+
* PayloadCMS uses Lexical editor by default
|
|
125
|
+
*/
|
|
126
|
+
convertMarkdownToLexical(markdown) {
|
|
127
|
+
const tokens = marked.lexer(markdown);
|
|
128
|
+
|
|
129
|
+
const convertToken = (token) => {
|
|
130
|
+
switch (token.type) {
|
|
131
|
+
case 'heading':
|
|
132
|
+
return {
|
|
133
|
+
type: 'heading',
|
|
134
|
+
tag: `h${token.depth}`,
|
|
135
|
+
children: [{ type: 'text', text: token.text, format: 0 }],
|
|
136
|
+
direction: 'ltr',
|
|
137
|
+
format: '',
|
|
138
|
+
indent: 0,
|
|
139
|
+
version: 1
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
case 'paragraph':
|
|
143
|
+
return {
|
|
144
|
+
type: 'paragraph',
|
|
145
|
+
children: this.parseInlineText(token.text),
|
|
146
|
+
direction: 'ltr',
|
|
147
|
+
format: '',
|
|
148
|
+
indent: 0,
|
|
149
|
+
version: 1
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
case 'list':
|
|
153
|
+
return {
|
|
154
|
+
type: token.ordered ? 'number' : 'bullet',
|
|
155
|
+
listType: token.ordered ? 'number' : 'bullet',
|
|
156
|
+
start: token.start || 1,
|
|
157
|
+
tag: token.ordered ? 'ol' : 'ul',
|
|
158
|
+
children: token.items.map(item => ({
|
|
159
|
+
type: 'listitem',
|
|
160
|
+
value: 1,
|
|
161
|
+
children: [{
|
|
162
|
+
type: 'paragraph',
|
|
163
|
+
children: this.parseInlineText(item.text),
|
|
164
|
+
direction: 'ltr',
|
|
165
|
+
format: '',
|
|
166
|
+
indent: 0
|
|
167
|
+
}],
|
|
168
|
+
direction: 'ltr',
|
|
169
|
+
format: '',
|
|
170
|
+
indent: 0
|
|
171
|
+
})),
|
|
172
|
+
direction: 'ltr',
|
|
173
|
+
format: '',
|
|
174
|
+
indent: 0,
|
|
175
|
+
version: 1
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
case 'code':
|
|
179
|
+
return {
|
|
180
|
+
type: 'code',
|
|
181
|
+
language: token.lang || 'plaintext',
|
|
182
|
+
children: [{ type: 'text', text: token.text, format: 0 }],
|
|
183
|
+
direction: 'ltr',
|
|
184
|
+
format: '',
|
|
185
|
+
indent: 0,
|
|
186
|
+
version: 1
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
case 'blockquote':
|
|
190
|
+
return {
|
|
191
|
+
type: 'quote',
|
|
192
|
+
children: [{
|
|
193
|
+
type: 'paragraph',
|
|
194
|
+
children: this.parseInlineText(token.text),
|
|
195
|
+
direction: 'ltr',
|
|
196
|
+
format: '',
|
|
197
|
+
indent: 0
|
|
198
|
+
}],
|
|
199
|
+
direction: 'ltr',
|
|
200
|
+
format: '',
|
|
201
|
+
indent: 0,
|
|
202
|
+
version: 1
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
case 'hr':
|
|
206
|
+
return {
|
|
207
|
+
type: 'horizontalrule',
|
|
208
|
+
version: 1
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
default:
|
|
212
|
+
return {
|
|
213
|
+
type: 'paragraph',
|
|
214
|
+
children: [{ type: 'text', text: token.raw || '', format: 0 }],
|
|
215
|
+
direction: 'ltr',
|
|
216
|
+
format: '',
|
|
217
|
+
indent: 0,
|
|
218
|
+
version: 1
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const children = tokens.map(convertToken);
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
root: {
|
|
227
|
+
type: 'root',
|
|
228
|
+
format: '',
|
|
229
|
+
indent: 0,
|
|
230
|
+
version: 1,
|
|
231
|
+
children,
|
|
232
|
+
direction: 'ltr'
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Parse inline text with formatting (bold, italic, code, links)
|
|
239
|
+
*/
|
|
240
|
+
parseInlineText(text) {
|
|
241
|
+
// Simple inline parser for bold, italic, code, links
|
|
242
|
+
const children = [];
|
|
243
|
+
|
|
244
|
+
// For now, return simple text node
|
|
245
|
+
// TODO: Enhance with full inline formatting support
|
|
246
|
+
children.push({
|
|
247
|
+
type: 'text',
|
|
248
|
+
text: text.replace(/<[^>]+>/g, ''), // Strip HTML tags
|
|
249
|
+
format: 0,
|
|
250
|
+
mode: 'normal',
|
|
251
|
+
style: '',
|
|
252
|
+
detail: 0,
|
|
253
|
+
version: 1
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
return children;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* List all collections
|
|
261
|
+
*/
|
|
262
|
+
async listCollections() {
|
|
263
|
+
return await this.request('/api');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Get documents from a collection
|
|
268
|
+
*/
|
|
269
|
+
async getDocuments(collection, options = {}) {
|
|
270
|
+
const params = new URLSearchParams();
|
|
271
|
+
if (options.limit) params.append('limit', options.limit);
|
|
272
|
+
if (options.page) params.append('page', options.page);
|
|
273
|
+
if (options.where) params.append('where', JSON.stringify(options.where));
|
|
274
|
+
|
|
275
|
+
const query = params.toString() ? `?${params.toString()}` : '';
|
|
276
|
+
return await this.request(`/api/${collection}${query}`);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Get a single document by ID
|
|
281
|
+
*/
|
|
282
|
+
async getDocument(collection, id) {
|
|
283
|
+
return await this.request(`/api/${collection}/${id}`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Create a new document in a collection
|
|
288
|
+
*/
|
|
289
|
+
async createDocument(collection, data) {
|
|
290
|
+
return await this.request(`/api/${collection}`, {
|
|
291
|
+
method: 'POST',
|
|
292
|
+
body: JSON.stringify(data)
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Update an existing document
|
|
298
|
+
*/
|
|
299
|
+
async updateDocument(collection, id, data) {
|
|
300
|
+
return await this.request(`/api/${collection}/${id}`, {
|
|
301
|
+
method: 'PATCH',
|
|
302
|
+
body: JSON.stringify(data)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Delete a document
|
|
308
|
+
*/
|
|
309
|
+
async deleteDocument(collection, id) {
|
|
310
|
+
return await this.request(`/api/${collection}/${id}`, {
|
|
311
|
+
method: 'DELETE'
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Upload media file
|
|
317
|
+
*/
|
|
318
|
+
async uploadMedia(filePath, altText = '') {
|
|
319
|
+
if (!this.token) {
|
|
320
|
+
await this.authenticate();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const FormData = (await import('form-data')).default;
|
|
324
|
+
const fs = await import('fs');
|
|
325
|
+
|
|
326
|
+
const formData = new FormData();
|
|
327
|
+
formData.append('file', fs.createReadStream(filePath));
|
|
328
|
+
if (altText) formData.append('alt', altText);
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
const response = await fetch(`${this.url}/api/media`, {
|
|
332
|
+
method: 'POST',
|
|
333
|
+
headers: {
|
|
334
|
+
'Authorization': `JWT ${this.token}`,
|
|
335
|
+
...formData.getHeaders()
|
|
336
|
+
},
|
|
337
|
+
body: formData
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
if (!response.ok) {
|
|
341
|
+
const error = await response.text();
|
|
342
|
+
throw new Error(`Upload failed: ${error}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return await response.json();
|
|
346
|
+
} catch (error) {
|
|
347
|
+
throw new Error(`Media upload failed: ${error.message}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Publish markdown content to PayloadCMS
|
|
353
|
+
*/
|
|
354
|
+
async publishContent(markdownFile, collection, options = {}) {
|
|
355
|
+
const fs = await import('fs');
|
|
356
|
+
const grayMatter = (await import('gray-matter')).default;
|
|
357
|
+
|
|
358
|
+
// Read and parse markdown file
|
|
359
|
+
const fileContent = fs.readFileSync(markdownFile, 'utf8');
|
|
360
|
+
const { data: frontmatter, content } = grayMatter(fileContent);
|
|
361
|
+
|
|
362
|
+
// Convert markdown to Lexical format
|
|
363
|
+
const richText = this.convertMarkdownToLexical(content);
|
|
364
|
+
|
|
365
|
+
// Prepare document data
|
|
366
|
+
const documentData = {
|
|
367
|
+
...frontmatter,
|
|
368
|
+
content: richText,
|
|
369
|
+
status: options.status || frontmatter.status || 'draft',
|
|
370
|
+
...options.additionalFields
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
// Create or update document
|
|
374
|
+
if (options.id) {
|
|
375
|
+
return await this.updateDocument(collection, options.id, documentData);
|
|
376
|
+
} else {
|
|
377
|
+
return await this.createDocument(collection, documentData);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Health check
|
|
383
|
+
*/
|
|
384
|
+
async healthCheck() {
|
|
385
|
+
try {
|
|
386
|
+
const response = await fetch(`${this.url}/api`);
|
|
387
|
+
return response.ok;
|
|
388
|
+
} catch (error) {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export default PayloadCMSUtils;
|