pubblue 0.1.1 → 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/dist/index.js +62 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createInterface } from "readline/promises";
|
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/lib/api.ts
|
|
10
|
-
var
|
|
10
|
+
var PubApiClient = class {
|
|
11
11
|
constructor(baseUrl, apiKey) {
|
|
12
12
|
this.baseUrl = baseUrl;
|
|
13
13
|
this.apiKey = apiKey;
|
|
@@ -28,14 +28,14 @@ var PublishApiClient = class {
|
|
|
28
28
|
}
|
|
29
29
|
return data;
|
|
30
30
|
}
|
|
31
|
-
async
|
|
32
|
-
return this.request("/api/v1/
|
|
31
|
+
async create(opts) {
|
|
32
|
+
return this.request("/api/v1/publications", {
|
|
33
33
|
method: "POST",
|
|
34
34
|
body: JSON.stringify(opts)
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
async get(slug) {
|
|
38
|
-
const data = await this.request(`/api/v1/publications
|
|
38
|
+
const data = await this.request(`/api/v1/publications/${encodeURIComponent(slug)}`);
|
|
39
39
|
return data.publication;
|
|
40
40
|
}
|
|
41
41
|
async list() {
|
|
@@ -43,13 +43,14 @@ var PublishApiClient = class {
|
|
|
43
43
|
return data.publications;
|
|
44
44
|
}
|
|
45
45
|
async update(opts) {
|
|
46
|
-
|
|
46
|
+
const { slug, ...body } = opts;
|
|
47
|
+
return this.request(`/api/v1/publications/${encodeURIComponent(slug)}`, {
|
|
47
48
|
method: "PATCH",
|
|
48
|
-
body: JSON.stringify(
|
|
49
|
+
body: JSON.stringify(body)
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
52
|
async remove(slug) {
|
|
52
|
-
await this.request(`/api/v1/publications
|
|
53
|
+
await this.request(`/api/v1/publications/${encodeURIComponent(slug)}`, {
|
|
53
54
|
method: "DELETE"
|
|
54
55
|
});
|
|
55
56
|
}
|
|
@@ -113,7 +114,7 @@ function getConfig(homeDir) {
|
|
|
113
114
|
var program = new Command();
|
|
114
115
|
function createClient() {
|
|
115
116
|
const config = getConfig();
|
|
116
|
-
return new
|
|
117
|
+
return new PubApiClient(config.baseUrl, config.apiKey);
|
|
117
118
|
}
|
|
118
119
|
async function readFromStdin() {
|
|
119
120
|
const chunks = [];
|
|
@@ -122,10 +123,6 @@ async function readFromStdin() {
|
|
|
122
123
|
}
|
|
123
124
|
return Buffer.concat(chunks).toString("utf-8").trim();
|
|
124
125
|
}
|
|
125
|
-
function printPublishResult(result) {
|
|
126
|
-
const verb = result.updated ? "Updated" : "Published";
|
|
127
|
-
console.log(`${verb}: ${result.url}`);
|
|
128
|
-
}
|
|
129
126
|
function formatVisibility(isPublic) {
|
|
130
127
|
return isPublic ? "public" : "private";
|
|
131
128
|
}
|
|
@@ -160,7 +157,18 @@ async function resolveConfigureApiKey(opts) {
|
|
|
160
157
|
}
|
|
161
158
|
return readApiKeyFromPrompt();
|
|
162
159
|
}
|
|
163
|
-
|
|
160
|
+
function readFile(filePath) {
|
|
161
|
+
const resolved = path2.resolve(filePath);
|
|
162
|
+
if (!fs2.existsSync(resolved)) {
|
|
163
|
+
console.error(`File not found: ${resolved}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
content: fs2.readFileSync(resolved, "utf-8"),
|
|
168
|
+
basename: path2.basename(resolved)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
program.name("pubblue").description("Publish static content and get shareable URLs").version("0.2.0");
|
|
164
172
|
program.command("configure").description("Configure the CLI with your API key").option("--api-key <key>", "Your API key (less secure: appears in shell history)").option("--api-key-stdin", "Read API key from stdin").action(async (opts) => {
|
|
165
173
|
try {
|
|
166
174
|
const apiKey = await resolveConfigureApiKey(opts);
|
|
@@ -172,43 +180,37 @@ program.command("configure").description("Configure the CLI with your API key").
|
|
|
172
180
|
process.exit(1);
|
|
173
181
|
}
|
|
174
182
|
});
|
|
175
|
-
program.command("
|
|
176
|
-
|
|
177
|
-
const filePath = path2.resolve(file);
|
|
178
|
-
if (!fs2.existsSync(filePath)) {
|
|
179
|
-
console.error(`File not found: ${filePath}`);
|
|
180
|
-
process.exit(1);
|
|
181
|
-
}
|
|
182
|
-
const content = fs2.readFileSync(filePath, "utf-8");
|
|
183
|
-
const filename = path2.basename(filePath);
|
|
184
|
-
const result = await client.publish({
|
|
185
|
-
filename,
|
|
186
|
-
content,
|
|
187
|
-
title: opts.title,
|
|
188
|
-
slug: opts.slug,
|
|
189
|
-
isPublic: !opts.private
|
|
190
|
-
});
|
|
191
|
-
printPublishResult(result);
|
|
192
|
-
});
|
|
193
|
-
program.command("publish-content").description("Publish content directly from stdin or argument").requiredOption("--filename <name>", "Filename (determines content type, e.g. page.html)").option("--content <content>", "Content string (if not provided, reads from stdin)").option("--slug <slug>", "Custom slug for the URL").option("--title <title>", "Title for the publication").option("--private", "Make the publication private").action(
|
|
194
|
-
async (opts) => {
|
|
183
|
+
program.command("create").description("Create a new publication").argument("[file]", "Path to the file (reads stdin if omitted)").option("--slug <slug>", "Custom slug for the URL").option("--title <title>", "Title for the publication").option("--public", "Make the publication public (default: private)").option("--private", "Make the publication private (this is the default)").action(
|
|
184
|
+
async (fileArg, opts) => {
|
|
195
185
|
const client = createClient();
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
186
|
+
const filePath = fileArg;
|
|
187
|
+
let content;
|
|
188
|
+
let filename;
|
|
189
|
+
if (filePath) {
|
|
190
|
+
const file = readFile(filePath);
|
|
191
|
+
content = file.content;
|
|
192
|
+
filename = file.basename;
|
|
193
|
+
} else {
|
|
194
|
+
content = await readFromStdin();
|
|
195
|
+
}
|
|
196
|
+
const result = await client.create({
|
|
199
197
|
content,
|
|
198
|
+
filename,
|
|
200
199
|
title: opts.title,
|
|
201
200
|
slug: opts.slug,
|
|
202
|
-
isPublic:
|
|
201
|
+
isPublic: opts.public ?? false
|
|
203
202
|
});
|
|
204
|
-
|
|
203
|
+
console.log(`Created: ${result.url}`);
|
|
205
204
|
}
|
|
206
205
|
);
|
|
207
|
-
program.command("get").description("Get details of a publication").argument("<slug>", "Slug of the publication").action(async (slug) => {
|
|
206
|
+
program.command("get").description("Get details of a publication").argument("<slug>", "Slug of the publication").option("--content", "Output raw content to stdout (no metadata, pipeable)").action(async (slug, opts) => {
|
|
208
207
|
const client = createClient();
|
|
209
208
|
const pub = await client.get(slug);
|
|
209
|
+
if (opts.content) {
|
|
210
|
+
process.stdout.write(pub.content);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
210
213
|
console.log(` Slug: ${pub.slug}`);
|
|
211
|
-
console.log(` File: ${pub.filename}`);
|
|
212
214
|
console.log(` Type: ${pub.contentType}`);
|
|
213
215
|
if (pub.title) console.log(` Title: ${pub.title}`);
|
|
214
216
|
console.log(` Status: ${formatVisibility(pub.isPublic)}`);
|
|
@@ -216,16 +218,25 @@ program.command("get").description("Get details of a publication").argument("<sl
|
|
|
216
218
|
console.log(` Updated: ${new Date(pub.updatedAt).toLocaleDateString()}`);
|
|
217
219
|
console.log(` Size: ${pub.content.length} bytes`);
|
|
218
220
|
});
|
|
219
|
-
program.command("update").description("Update publication metadata").argument("<slug>", "Slug of the publication to update").option("--title <title>", "New title").option("--public", "Make the publication public").option("--private", "Make the publication private").action(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
221
|
+
program.command("update").description("Update a publication's content and/or metadata").argument("<slug>", "Slug of the publication to update").option("--file <file>", "New content from file").option("--title <title>", "New title").option("--public", "Make the publication public").option("--private", "Make the publication private").action(
|
|
222
|
+
async (slug, opts) => {
|
|
223
|
+
const client = createClient();
|
|
224
|
+
let content;
|
|
225
|
+
let filename;
|
|
226
|
+
if (opts.file) {
|
|
227
|
+
const file = readFile(opts.file);
|
|
228
|
+
content = file.content;
|
|
229
|
+
filename = file.basename;
|
|
230
|
+
}
|
|
231
|
+
let isPublic;
|
|
232
|
+
if (opts.public) isPublic = true;
|
|
233
|
+
else if (opts.private) isPublic = false;
|
|
234
|
+
const result = await client.update({ slug, content, filename, title: opts.title, isPublic });
|
|
235
|
+
console.log(`Updated: ${result.slug}`);
|
|
236
|
+
if (result.title) console.log(` Title: ${result.title}`);
|
|
237
|
+
console.log(` Status: ${formatVisibility(result.isPublic)}`);
|
|
238
|
+
}
|
|
239
|
+
);
|
|
229
240
|
program.command("list").description("List your publications").action(async () => {
|
|
230
241
|
const client = createClient();
|
|
231
242
|
const pubs = await client.list();
|
|
@@ -236,7 +247,7 @@ program.command("list").description("List your publications").action(async () =>
|
|
|
236
247
|
for (const pub of pubs) {
|
|
237
248
|
const date = new Date(pub.createdAt).toLocaleDateString();
|
|
238
249
|
console.log(
|
|
239
|
-
` ${pub.slug}
|
|
250
|
+
` ${pub.slug} [${pub.contentType}] ${formatVisibility(pub.isPublic)} ${date}`
|
|
240
251
|
);
|
|
241
252
|
}
|
|
242
253
|
});
|