directify-cli 1.0.0 → 1.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/package.json +1 -1
- package/src/commands/pages.js +187 -0
- package/src/index.js +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { api, resolveDirectory } from '../utils/api.js';
|
|
3
|
+
import { printTable, printJson, printSuccess, printError } from '../utils/output.js';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
|
|
6
|
+
const pages = new Command('pages').description('Manage custom pages');
|
|
7
|
+
|
|
8
|
+
pages
|
|
9
|
+
.command('list')
|
|
10
|
+
.alias('ls')
|
|
11
|
+
.description('List all custom pages')
|
|
12
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
13
|
+
.option('--json', 'Output as JSON')
|
|
14
|
+
.action(async (opts) => {
|
|
15
|
+
const spinner = ora('Fetching pages...').start();
|
|
16
|
+
try {
|
|
17
|
+
const dir = resolveDirectory(opts);
|
|
18
|
+
const data = await api.get(`/directories/${dir}/pages`);
|
|
19
|
+
spinner.stop();
|
|
20
|
+
if (opts.json) {
|
|
21
|
+
printJson(data);
|
|
22
|
+
} else {
|
|
23
|
+
const items = data.data || data;
|
|
24
|
+
printTable(items, [
|
|
25
|
+
{ key: 'id', label: 'ID' },
|
|
26
|
+
{ key: 'title', label: 'Title', maxWidth: 40 },
|
|
27
|
+
{ key: 'slug', label: 'Slug', maxWidth: 25 },
|
|
28
|
+
{ key: 'placement', label: 'Placement' },
|
|
29
|
+
{ key: 'is_published', label: 'Published' },
|
|
30
|
+
{ key: 'order', label: 'Order' },
|
|
31
|
+
]);
|
|
32
|
+
if (data.meta) {
|
|
33
|
+
console.log(`\nPage ${data.meta.current_page} of ${data.meta.last_page} (${data.meta.total} total)`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
spinner.stop();
|
|
38
|
+
printError(err.message);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
pages
|
|
44
|
+
.command('get <id>')
|
|
45
|
+
.description('Get a specific page')
|
|
46
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
47
|
+
.action(async (id, opts) => {
|
|
48
|
+
try {
|
|
49
|
+
const dir = resolveDirectory(opts);
|
|
50
|
+
const data = await api.get(`/directories/${dir}/pages/${id}`);
|
|
51
|
+
printJson(data.data || data);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
printError(err.message);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
pages
|
|
59
|
+
.command('create')
|
|
60
|
+
.description('Create a new custom page')
|
|
61
|
+
.requiredOption('--title <title>', 'Page title')
|
|
62
|
+
.option('--slug <slug>', 'URL slug (auto-generated from title if not set)')
|
|
63
|
+
.option('--markdown <text>', 'Page content in markdown')
|
|
64
|
+
.option('--placement <type>', 'Where the link appears: navbar, footer, sidebar, unlisted (default: unlisted)')
|
|
65
|
+
.option('--order <n>', 'Sort order for navigation', '0')
|
|
66
|
+
.option('--seo-title <text>', 'SEO title')
|
|
67
|
+
.option('--seo-description <text>', 'SEO description')
|
|
68
|
+
.option('--external-url <url>', 'External URL (makes this a link, not a page)')
|
|
69
|
+
.option('--new-tab', 'Open external links in new tab')
|
|
70
|
+
.option('--unpublished', 'Create as unpublished')
|
|
71
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
72
|
+
.action(async (opts) => {
|
|
73
|
+
const spinner = ora('Creating page...').start();
|
|
74
|
+
try {
|
|
75
|
+
const dir = resolveDirectory(opts);
|
|
76
|
+
const body = { title: opts.title };
|
|
77
|
+
if (opts.slug) body.slug = opts.slug;
|
|
78
|
+
if (opts.markdown) body.markdown = opts.markdown;
|
|
79
|
+
if (opts.placement) body.placement = opts.placement;
|
|
80
|
+
if (opts.order) body.order = parseInt(opts.order, 10);
|
|
81
|
+
if (opts.externalUrl) {
|
|
82
|
+
body.is_external = true;
|
|
83
|
+
body.external_url = opts.externalUrl;
|
|
84
|
+
}
|
|
85
|
+
if (opts.newTab) body.new_tab = true;
|
|
86
|
+
if (opts.seoTitle || opts.seoDescription) {
|
|
87
|
+
body.seo = {};
|
|
88
|
+
if (opts.seoTitle) body.seo.title = opts.seoTitle;
|
|
89
|
+
if (opts.seoDescription) body.seo.description = opts.seoDescription;
|
|
90
|
+
}
|
|
91
|
+
body.is_published = !opts.unpublished;
|
|
92
|
+
|
|
93
|
+
const data = await api.post(`/directories/${dir}/pages`, body);
|
|
94
|
+
spinner.stop();
|
|
95
|
+
const result = data.data || data;
|
|
96
|
+
printSuccess(`Page created: ${result.title} (ID: ${result.id})`);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
spinner.stop();
|
|
99
|
+
printError(err.message);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
pages
|
|
105
|
+
.command('update <id>')
|
|
106
|
+
.description('Update a custom page')
|
|
107
|
+
.option('--title <title>', 'Page title')
|
|
108
|
+
.option('--slug <slug>', 'URL slug')
|
|
109
|
+
.option('--markdown <text>', 'Page content in markdown')
|
|
110
|
+
.option('--placement <type>', 'Where the link appears: navbar, footer, sidebar, unlisted')
|
|
111
|
+
.option('--order <n>', 'Sort order for navigation')
|
|
112
|
+
.option('--seo-title <text>', 'SEO title')
|
|
113
|
+
.option('--seo-description <text>', 'SEO description')
|
|
114
|
+
.option('--external-url <url>', 'External URL')
|
|
115
|
+
.option('--new-tab <bool>', 'Open in new tab (true/false)')
|
|
116
|
+
.option('--published <bool>', 'Published status (true/false)')
|
|
117
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
118
|
+
.action(async (id, opts) => {
|
|
119
|
+
const spinner = ora('Updating page...').start();
|
|
120
|
+
try {
|
|
121
|
+
const dir = resolveDirectory(opts);
|
|
122
|
+
const body = {};
|
|
123
|
+
if (opts.title) body.title = opts.title;
|
|
124
|
+
if (opts.slug) body.slug = opts.slug;
|
|
125
|
+
if (opts.markdown) body.markdown = opts.markdown;
|
|
126
|
+
if (opts.placement) body.placement = opts.placement;
|
|
127
|
+
if (opts.order !== undefined) body.order = parseInt(opts.order, 10);
|
|
128
|
+
if (opts.externalUrl) {
|
|
129
|
+
body.is_external = true;
|
|
130
|
+
body.external_url = opts.externalUrl;
|
|
131
|
+
}
|
|
132
|
+
if (opts.newTab !== undefined) body.new_tab = opts.newTab === 'true';
|
|
133
|
+
if (opts.published !== undefined) body.is_published = opts.published === 'true';
|
|
134
|
+
if (opts.seoTitle || opts.seoDescription) {
|
|
135
|
+
body.seo = {};
|
|
136
|
+
if (opts.seoTitle) body.seo.title = opts.seoTitle;
|
|
137
|
+
if (opts.seoDescription) body.seo.description = opts.seoDescription;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const data = await api.put(`/directories/${dir}/pages/${id}`, body);
|
|
141
|
+
spinner.stop();
|
|
142
|
+
printSuccess(`Page updated: ${data.data?.title || data.title}`);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
spinner.stop();
|
|
145
|
+
printError(err.message);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
pages
|
|
151
|
+
.command('delete <id>')
|
|
152
|
+
.description('Delete a custom page')
|
|
153
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
154
|
+
.action(async (id, opts) => {
|
|
155
|
+
const spinner = ora('Deleting page...').start();
|
|
156
|
+
try {
|
|
157
|
+
const dir = resolveDirectory(opts);
|
|
158
|
+
await api.delete(`/directories/${dir}/pages/${id}`);
|
|
159
|
+
spinner.stop();
|
|
160
|
+
printSuccess(`Page ${id} deleted.`);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
spinner.stop();
|
|
163
|
+
printError(err.message);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
pages
|
|
169
|
+
.command('toggle <id>')
|
|
170
|
+
.description('Toggle page published/unpublished status')
|
|
171
|
+
.option('-d, --directory <id>', 'Directory ID')
|
|
172
|
+
.action(async (id, opts) => {
|
|
173
|
+
const spinner = ora('Toggling page...').start();
|
|
174
|
+
try {
|
|
175
|
+
const dir = resolveDirectory(opts);
|
|
176
|
+
const data = await api.patch(`/directories/${dir}/pages/${id}/toggle`);
|
|
177
|
+
spinner.stop();
|
|
178
|
+
const result = data.data || data;
|
|
179
|
+
printSuccess(`Page "${result.title}" is now ${result.is_published ? 'published' : 'unpublished'}.`);
|
|
180
|
+
} catch (err) {
|
|
181
|
+
spinner.stop();
|
|
182
|
+
printError(err.message);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
export default pages;
|
package/src/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import tags from './commands/tags.js';
|
|
|
9
9
|
import fields from './commands/fields.js';
|
|
10
10
|
import listings from './commands/listings.js';
|
|
11
11
|
import articles from './commands/articles.js';
|
|
12
|
+
import pages from './commands/pages.js';
|
|
12
13
|
|
|
13
14
|
const program = new Command();
|
|
14
15
|
|
|
@@ -25,5 +26,6 @@ program.addCommand(tags);
|
|
|
25
26
|
program.addCommand(fields);
|
|
26
27
|
program.addCommand(listings);
|
|
27
28
|
program.addCommand(articles);
|
|
29
|
+
program.addCommand(pages);
|
|
28
30
|
|
|
29
31
|
program.parse();
|