@nabnflow/cli 0.0.6 → 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/dist/commands/blog/content-format.d.ts +7 -0
- package/dist/commands/blog/content-format.d.ts.map +1 -0
- package/dist/commands/blog/content-format.js +30 -0
- package/dist/commands/blog/content-format.js.map +1 -0
- package/dist/commands/blog/create.d.ts +22 -0
- package/dist/commands/blog/create.d.ts.map +1 -0
- package/dist/commands/blog/create.js +40 -0
- package/dist/commands/blog/create.js.map +1 -0
- package/dist/commands/blog/deploy.d.ts +12 -0
- package/dist/commands/blog/deploy.d.ts.map +1 -0
- package/dist/commands/blog/deploy.js +20 -0
- package/dist/commands/blog/deploy.js.map +1 -0
- package/dist/commands/blog/publish.d.ts +22 -0
- package/dist/commands/blog/publish.d.ts.map +1 -0
- package/dist/commands/blog/publish.js +23 -0
- package/dist/commands/blog/publish.js.map +1 -0
- package/dist/commands/blog/set-cover.d.ts +22 -0
- package/dist/commands/blog/set-cover.d.ts.map +1 -0
- package/dist/commands/blog/set-cover.js +92 -0
- package/dist/commands/blog/set-cover.js.map +1 -0
- package/dist/commands/blog/unpublish.d.ts +21 -0
- package/dist/commands/blog/unpublish.d.ts.map +1 -0
- package/dist/commands/blog/unpublish.js +20 -0
- package/dist/commands/blog/unpublish.js.map +1 -0
- package/dist/commands/blog/update.d.ts +5 -0
- package/dist/commands/blog/update.d.ts.map +1 -1
- package/dist/commands/blog/update.js +40 -6
- package/dist/commands/blog/update.js.map +1 -1
- package/dist/commands/files/upload.d.ts +18 -0
- package/dist/commands/files/upload.d.ts.map +1 -0
- package/dist/commands/files/upload.js +83 -0
- package/dist/commands/files/upload.js.map +1 -0
- package/dist/commands/notes/content-format.d.ts +7 -0
- package/dist/commands/notes/content-format.d.ts.map +1 -0
- package/dist/commands/notes/content-format.js +30 -0
- package/dist/commands/notes/content-format.js.map +1 -0
- package/dist/commands/notes/create.d.ts +2 -2
- package/dist/commands/notes/create.d.ts.map +1 -1
- package/dist/commands/notes/create.js +76 -12
- package/dist/commands/notes/create.js.map +1 -1
- package/dist/commands/notes/get.d.ts +12 -5
- package/dist/commands/notes/get.d.ts.map +1 -1
- package/dist/commands/notes/get.js +12 -6
- package/dist/commands/notes/get.js.map +1 -1
- package/dist/commands/notes/update.d.ts +3 -2
- package/dist/commands/notes/update.d.ts.map +1 -1
- package/dist/commands/notes/update.js +108 -11
- package/dist/commands/notes/update.js.map +1 -1
- package/dist/lib/client.js +1 -1
- package/dist/lib/client.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-format.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/content-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAGnC,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,OAAO;IACpD,MAAM,CAAC,WAAW,SAC0I;IAE5J,MAAM,CAAC,QAAQ,WAGd;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqB3B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { requireAuth, requireBaseUrl } from '../../lib/client.js';
|
|
3
|
+
export default class BlogContentFormat extends Command {
|
|
4
|
+
static description = "Show the block (JSONContent) format expected by the --content flag. Use this to learn how to structure post content for 'blog create' and 'blog update'.";
|
|
5
|
+
static examples = [
|
|
6
|
+
'<%= config.bin %> blog content-format',
|
|
7
|
+
'<%= config.bin %> blog content-format | less',
|
|
8
|
+
];
|
|
9
|
+
async run() {
|
|
10
|
+
const token = requireAuth();
|
|
11
|
+
const baseUrl = requireBaseUrl();
|
|
12
|
+
const url = `${baseUrl.replace(/\/$/, '')}/api/docs/editor-blocks`;
|
|
13
|
+
const res = await fetch(url, {
|
|
14
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
15
|
+
});
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
let message = `HTTP ${res.status}`;
|
|
18
|
+
try {
|
|
19
|
+
const body = (await res.json());
|
|
20
|
+
if (body.error)
|
|
21
|
+
message = body.error;
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
this.error(`Failed to fetch content format docs: ${message}`);
|
|
25
|
+
}
|
|
26
|
+
const docs = await res.text();
|
|
27
|
+
this.log(docs);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=content-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-format.js","sourceRoot":"","sources":["../../../src/commands/blog/content-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAE/D,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,OAAO;IACpD,MAAM,CAAC,WAAW,GAChB,0JAA0J,CAAA;IAE5J,MAAM,CAAC,QAAQ,GAAG;QAChB,uCAAuC;QACvC,8CAA8C;KAC/C,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;QAEhC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAA;QAClE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,OAAO,EAAE,EAAC,aAAa,EAAE,UAAU,KAAK,EAAE,EAAC;SAC5C,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAA;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAA;gBACnD,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAA;YACtC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAA;QAC/D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface BlogPost {
|
|
3
|
+
id: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
title: string;
|
|
6
|
+
status: string;
|
|
7
|
+
}
|
|
8
|
+
interface CreateBlogPostResponse {
|
|
9
|
+
post: BlogPost;
|
|
10
|
+
}
|
|
11
|
+
export default class BlogCreate extends Command {
|
|
12
|
+
static description: string;
|
|
13
|
+
static enableJsonFlag: boolean;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static flags: {
|
|
16
|
+
title: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
content: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<CreateBlogPostResponse>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAG1C,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAA6C;IAE/D,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAId;IAED,MAAM,CAAC,KAAK;;;MASX;IAEK,GAAG,IAAI,OAAO,CAAC,sBAAsB,CAAC;CAwB7C"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { apiRequest } from '../../lib/client.js';
|
|
3
|
+
export default class BlogCreate extends Command {
|
|
4
|
+
static description = 'Create a new blog post (starts as draft)';
|
|
5
|
+
static enableJsonFlag = true;
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> blog create --title "My First Post"',
|
|
8
|
+
'<%= config.bin %> blog create --title "Deep Dive" --content \'{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Hello world"}]}]}\'',
|
|
9
|
+
'<%= config.bin %> blog create --title "My Post" --json',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
title: Flags.string({
|
|
13
|
+
description: 'Post title',
|
|
14
|
+
required: true,
|
|
15
|
+
}),
|
|
16
|
+
content: Flags.string({
|
|
17
|
+
description: "Post content in block (JSONContent) format. Run 'nabnflow blog content-format' to see the expected JSON format.",
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { flags } = await this.parse(BlogCreate);
|
|
22
|
+
const body = { title: flags.title };
|
|
23
|
+
if (flags.content !== undefined) {
|
|
24
|
+
try {
|
|
25
|
+
body.content = JSON.parse(flags.content);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
this.error("Invalid JSON in --content flag. Run 'nabnflow blog content-format' to see the expected JSON format.");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const result = await apiRequest('/api/blog/posts', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
body: JSON.stringify(body),
|
|
34
|
+
});
|
|
35
|
+
this.log(`Created post: ${result.post.slug}`);
|
|
36
|
+
this.log(`Status: ${result.post.status}`);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/blog/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAa9C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,GAAG,0CAA0C,CAAA;IAE/D,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,uDAAuD;QACvD,kKAAkK;QAClK,wDAAwD;KACzD,CAAA;IAED,MAAM,CAAC,KAAK,GAAG;QACb,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC;YAClB,WAAW,EAAE,YAAY;YACzB,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC;YACpB,WAAW,EACT,iHAAiH;SACpH,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAE5C,MAAM,IAAI,GAA4B,EAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAC,CAAA;QAE1D,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,KAAK,CACR,qGAAqG,CACtG,CAAA;YACH,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAyB,iBAAiB,EAAE;YACzE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC7C,IAAI,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACzC,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface DeployResponse {
|
|
3
|
+
success: boolean;
|
|
4
|
+
}
|
|
5
|
+
export default class BlogDeploy extends Command {
|
|
6
|
+
static description: string;
|
|
7
|
+
static enableJsonFlag: boolean;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
run(): Promise<DeployResponse>;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAGnC,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAA0D;IAE5E,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAGd;IAEK,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;CAUrC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { apiRequest } from '../../lib/client.js';
|
|
3
|
+
export default class BlogDeploy extends Command {
|
|
4
|
+
static description = 'Trigger a Cloudflare Pages deploy to rebuild the blog';
|
|
5
|
+
static enableJsonFlag = true;
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> blog deploy',
|
|
8
|
+
'<%= config.bin %> blog deploy --json',
|
|
9
|
+
];
|
|
10
|
+
async run() {
|
|
11
|
+
const result = await apiRequest('/api/blog/deploy', {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
body: '{}',
|
|
14
|
+
});
|
|
15
|
+
this.log('Deploy triggered successfully.');
|
|
16
|
+
this.log('Cloudflare Pages will rebuild your blog.');
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/commands/blog/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAM9C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,GAAG,uDAAuD,CAAA;IAE5E,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,+BAA+B;QAC/B,sCAAsC;KACvC,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,MAAM,UAAU,CAAiB,kBAAkB,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI;SACX,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC1C,IAAI,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface BlogPost {
|
|
3
|
+
id: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
title: string;
|
|
6
|
+
status: string;
|
|
7
|
+
publishedAt?: string;
|
|
8
|
+
}
|
|
9
|
+
interface BlogPostResponse {
|
|
10
|
+
post: BlogPost;
|
|
11
|
+
}
|
|
12
|
+
export default class BlogPublish extends Command {
|
|
13
|
+
static description: string;
|
|
14
|
+
static enableJsonFlag: boolean;
|
|
15
|
+
static examples: string[];
|
|
16
|
+
static args: {
|
|
17
|
+
slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<BlogPostResponse>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAGzC,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAA8B;IAEhD,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAGd;IAED,MAAM,CAAC,IAAI;;MAEV;IAEK,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAevC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Args, Command } from '@oclif/core';
|
|
2
|
+
import { apiRequest } from '../../lib/client.js';
|
|
3
|
+
export default class BlogPublish extends Command {
|
|
4
|
+
static description = 'Publish a draft blog post';
|
|
5
|
+
static enableJsonFlag = true;
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> blog publish my-first-post',
|
|
8
|
+
'<%= config.bin %> blog publish my-first-post --json',
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
slug: Args.string({ description: 'Post slug', required: true }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { args } = await this.parse(BlogPublish);
|
|
15
|
+
const result = await apiRequest(`/api/blog/posts/${args.slug}/publish`, { method: 'POST', body: '{}' });
|
|
16
|
+
this.log(`Published: ${result.post.slug}`);
|
|
17
|
+
if (result.post.publishedAt) {
|
|
18
|
+
this.log(`Published at: ${result.post.publishedAt}`);
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/commands/blog/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAc9C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,GAAG,2BAA2B,CAAA;IAEhD,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,8CAA8C;QAC9C,qDAAqD;KACtD,CAAA;IAED,MAAM,CAAC,IAAI,GAAG;QACZ,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KAC9D,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAE5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAC7B,mBAAmB,IAAI,CAAC,IAAI,UAAU,EACtC,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAC,CAC7B,CAAA;QAED,IAAI,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QACtD,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface BlogPost {
|
|
3
|
+
id: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
title: string;
|
|
6
|
+
ogImage: string | null;
|
|
7
|
+
}
|
|
8
|
+
interface BlogPostResponse {
|
|
9
|
+
post: BlogPost;
|
|
10
|
+
}
|
|
11
|
+
export default class BlogSetCover extends Command {
|
|
12
|
+
static description: string;
|
|
13
|
+
static enableJsonFlag: boolean;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static args: {
|
|
16
|
+
slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
17
|
+
imagePath: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<BlogPostResponse>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=set-cover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-cover.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/set-cover.ts"],"names":[],"mappings":"AAGA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAmBzC,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAC,WAAW,SAC0E;IAE5F,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAId;IAED,MAAM,CAAC,IAAI;;;MAGV;IAEK,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC;CA2EvC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { extname } from 'node:path';
|
|
3
|
+
import { Args, Command } from '@oclif/core';
|
|
4
|
+
import { requireAuth, requireBaseUrl } from '../../lib/client.js';
|
|
5
|
+
const MIME_TYPES = {
|
|
6
|
+
'.jpg': 'image/jpeg',
|
|
7
|
+
'.jpeg': 'image/jpeg',
|
|
8
|
+
'.png': 'image/png',
|
|
9
|
+
'.gif': 'image/gif',
|
|
10
|
+
'.webp': 'image/webp',
|
|
11
|
+
'.avif': 'image/avif',
|
|
12
|
+
};
|
|
13
|
+
export default class BlogSetCover extends Command {
|
|
14
|
+
static description = 'Set the cover image for a blog post. Uploads the image file and sets it as the OG image.';
|
|
15
|
+
static enableJsonFlag = true;
|
|
16
|
+
static examples = [
|
|
17
|
+
'<%= config.bin %> blog set-cover my-post ./hero.png',
|
|
18
|
+
'<%= config.bin %> blog set-cover my-post ~/Desktop/cover.jpg',
|
|
19
|
+
'<%= config.bin %> blog set-cover my-post ./image.webp --json',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
slug: Args.string({ description: 'Post slug', required: true }),
|
|
23
|
+
imagePath: Args.string({ description: 'Path to local image file', required: true }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { args } = await this.parse(BlogSetCover);
|
|
27
|
+
const token = requireAuth();
|
|
28
|
+
const baseUrl = requireBaseUrl();
|
|
29
|
+
// Detect MIME type from extension
|
|
30
|
+
const ext = extname(args.imagePath).toLowerCase();
|
|
31
|
+
const mimeType = MIME_TYPES[ext];
|
|
32
|
+
if (!mimeType) {
|
|
33
|
+
this.error(`Unsupported image format: ${ext}. Supported formats: ${Object.keys(MIME_TYPES).join(', ')}`);
|
|
34
|
+
}
|
|
35
|
+
// Read the file
|
|
36
|
+
let fileBuffer;
|
|
37
|
+
try {
|
|
38
|
+
fileBuffer = readFileSync(args.imagePath);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
this.error(`Could not read file: ${args.imagePath}`);
|
|
42
|
+
}
|
|
43
|
+
const apiBase = baseUrl.replace(/\/$/, '');
|
|
44
|
+
// Step 1: Upload the file
|
|
45
|
+
this.log(`Uploading image...`);
|
|
46
|
+
const uploadRes = await fetch(`${apiBase}/upload`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: {
|
|
49
|
+
Authorization: `Bearer ${token}`,
|
|
50
|
+
'Content-Type': mimeType,
|
|
51
|
+
},
|
|
52
|
+
body: fileBuffer,
|
|
53
|
+
});
|
|
54
|
+
if (!uploadRes.ok) {
|
|
55
|
+
let message = `Upload failed: HTTP ${uploadRes.status}`;
|
|
56
|
+
try {
|
|
57
|
+
const body = (await uploadRes.json());
|
|
58
|
+
if (body.error)
|
|
59
|
+
message = `Upload failed: ${body.error}`;
|
|
60
|
+
}
|
|
61
|
+
catch { }
|
|
62
|
+
this.error(message);
|
|
63
|
+
}
|
|
64
|
+
const upload = (await uploadRes.json());
|
|
65
|
+
// Step 2: Set as cover image
|
|
66
|
+
const coverRes = await fetch(`${apiBase}/api/blog/posts/${args.slug}/cover`, {
|
|
67
|
+
method: 'PUT',
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${token}`,
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({ storageId: upload.storageId }),
|
|
73
|
+
});
|
|
74
|
+
if (!coverRes.ok) {
|
|
75
|
+
let message = `Failed to set cover: HTTP ${coverRes.status}`;
|
|
76
|
+
try {
|
|
77
|
+
const body = (await coverRes.json());
|
|
78
|
+
if (body.error)
|
|
79
|
+
message = `Failed to set cover: ${body.error}`;
|
|
80
|
+
}
|
|
81
|
+
catch { }
|
|
82
|
+
this.error(message);
|
|
83
|
+
}
|
|
84
|
+
const result = (await coverRes.json());
|
|
85
|
+
this.log(`Cover image set for: ${result.post.slug}`);
|
|
86
|
+
if (result.post.ogImage) {
|
|
87
|
+
this.log(`OG image URL: ${result.post.ogImage}`);
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=set-cover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-cover.js","sourceRoot":"","sources":["../../../src/commands/blog/set-cover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAA;AACpC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAE/D,MAAM,UAAU,GAA2B;IACzC,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,YAAY;CACtB,CAAA;AAoBD,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAC,WAAW,GAChB,0FAA0F,CAAA;IAE5F,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,qDAAqD;QACrD,8DAA8D;QAC9D,8DAA8D;KAC/D,CAAA;IAED,MAAM,CAAC,IAAI,GAAG;QACZ,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;QAC7D,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,0BAA0B,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KAClF,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAE7C,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;QAEhC,kCAAkC;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;QACjD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,CACR,6BAA6B,GAAG,wBAAwB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAA;QACH,CAAC;QAED,gBAAgB;QAChB,IAAI,UAAkB,CAAA;QACtB,IAAI,CAAC;YACH,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QACtD,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAE1C,0BAA0B;QAC1B,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAC9B,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,EAAE;YACjD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,QAAQ;aACzB;YACD,IAAI,EAAE,UAAiC;SACxC,CAAC,CAAA;QAEF,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;YAClB,IAAI,OAAO,GAAG,uBAAuB,SAAS,CAAC,MAAM,EAAE,CAAA;YACvD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,CAAqB,CAAA;gBACzD,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,GAAG,kBAAkB,IAAI,CAAC,KAAK,EAAE,CAAA;YAC1D,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrB,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,CAAmB,CAAA;QAEzD,6BAA6B;QAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,mBAAmB,IAAI,CAAC,IAAI,QAAQ,EAAE;YAC3E,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAC,CAAC;SACpD,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,OAAO,GAAG,6BAA6B,QAAQ,CAAC,MAAM,EAAE,CAAA;YAC5D,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAqB,CAAA;gBACxD,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,GAAG,wBAAwB,IAAI,CAAC,KAAK,EAAE,CAAA;YAChE,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrB,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAqB,CAAA;QAE1D,IAAI,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QACpD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface BlogPost {
|
|
3
|
+
id: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
title: string;
|
|
6
|
+
status: string;
|
|
7
|
+
}
|
|
8
|
+
interface BlogPostResponse {
|
|
9
|
+
post: BlogPost;
|
|
10
|
+
}
|
|
11
|
+
export default class BlogUnpublish extends Command {
|
|
12
|
+
static description: string;
|
|
13
|
+
static enableJsonFlag: boolean;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static args: {
|
|
16
|
+
slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<BlogPostResponse>;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=unpublish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unpublish.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/unpublish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAGzC,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,WAAW,SAA0C;IAE5D,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAGd;IAED,MAAM,CAAC,IAAI;;MAEV;IAEK,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAWvC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Args, Command } from '@oclif/core';
|
|
2
|
+
import { apiRequest } from '../../lib/client.js';
|
|
3
|
+
export default class BlogUnpublish extends Command {
|
|
4
|
+
static description = 'Revert a published blog post to draft';
|
|
5
|
+
static enableJsonFlag = true;
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> blog unpublish my-first-post',
|
|
8
|
+
'<%= config.bin %> blog unpublish my-first-post --json',
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
slug: Args.string({ description: 'Post slug', required: true }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { args } = await this.parse(BlogUnpublish);
|
|
15
|
+
const result = await apiRequest(`/api/blog/posts/${args.slug}/unpublish`, { method: 'POST', body: '{}' });
|
|
16
|
+
this.log(`Unpublished: ${result.post.slug} (now draft)`);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=unpublish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unpublish.js","sourceRoot":"","sources":["../../../src/commands/blog/unpublish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAa9C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,WAAW,GAAG,uCAAuC,CAAA;IAE5D,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,gDAAgD;QAChD,uDAAuD;KACxD,CAAA;IAED,MAAM,CAAC,IAAI,GAAG;QACZ,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KAC9D,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAE9C,MAAM,MAAM,GAAG,MAAM,UAAU,CAC7B,mBAAmB,IAAI,CAAC,IAAI,YAAY,EACxC,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAC,CAC7B,CAAA;QAED,IAAI,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,CAAA;QACxD,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -17,6 +17,11 @@ export default class BlogUpdate extends Command {
|
|
|
17
17
|
};
|
|
18
18
|
static flags: {
|
|
19
19
|
title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
content: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
slug: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
'seo-title': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
'seo-desc': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
|
+
excerpt: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
25
|
};
|
|
21
26
|
run(): Promise<UpdateBlogPostResponse>;
|
|
22
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAQ,MAAM,aAAa,CAAA;AAGhD,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/blog/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAQ,MAAM,aAAa,CAAA;AAGhD,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAA2D;IAE7E,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAMd;IAED,MAAM,CAAC,IAAI;;MAEV;IAED,MAAM,CAAC,KAAK;;;;;;;MAUX;IAEK,GAAG,IAAI,OAAO,CAAC,sBAAsB,CAAC;CA2C7C"}
|
|
@@ -1,27 +1,61 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import { apiRequest } from '../../lib/client.js';
|
|
3
3
|
export default class BlogUpdate extends Command {
|
|
4
|
-
static description = 'Update a blog post';
|
|
4
|
+
static description = 'Update a blog post. Accepts any combination of fields.';
|
|
5
5
|
static enableJsonFlag = true;
|
|
6
6
|
static examples = [
|
|
7
|
-
'<%= config.bin %> blog update my-post
|
|
8
|
-
'<%= config.bin %> blog update my-post
|
|
7
|
+
'<%= config.bin %> blog update my-post --title "New Title"',
|
|
8
|
+
'<%= config.bin %> blog update my-post --slug new-post-slug',
|
|
9
|
+
'<%= config.bin %> blog update my-post --title "New Title" --slug new-slug',
|
|
10
|
+
'<%= config.bin %> blog update my-post --seo-title "SEO Title" --seo-desc "Description"',
|
|
11
|
+
'<%= config.bin %> blog update my-post --content \'{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Updated content"}]}]}\'',
|
|
9
12
|
];
|
|
10
13
|
static args = {
|
|
11
14
|
slug: Args.string({ description: 'Post slug', required: true }),
|
|
12
15
|
};
|
|
13
16
|
static flags = {
|
|
14
17
|
title: Flags.string({ description: 'New title' }),
|
|
18
|
+
content: Flags.string({
|
|
19
|
+
description: "New content in block (JSONContent) format. Run 'nabnflow blog content-format' to see the expected JSON format.",
|
|
20
|
+
}),
|
|
21
|
+
slug: Flags.string({ description: 'New URL slug (must be unique)' }),
|
|
22
|
+
'seo-title': Flags.string({ description: 'SEO title for meta tags' }),
|
|
23
|
+
'seo-desc': Flags.string({ description: 'SEO description for meta tags' }),
|
|
24
|
+
excerpt: Flags.string({ description: 'Short excerpt or summary' }),
|
|
15
25
|
};
|
|
16
26
|
async run() {
|
|
17
27
|
const { args, flags } = await this.parse(BlogUpdate);
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
const hasFlag = [
|
|
29
|
+
flags.title,
|
|
30
|
+
flags.content,
|
|
31
|
+
flags.slug,
|
|
32
|
+
flags['seo-title'],
|
|
33
|
+
flags['seo-desc'],
|
|
34
|
+
flags.excerpt,
|
|
35
|
+
].some((f) => f !== undefined);
|
|
36
|
+
if (!hasFlag) {
|
|
37
|
+
this.error('At least one flag is required.\n\nAvailable flags: --title, --content, --slug, --seo-title, --seo-desc, --excerpt');
|
|
20
38
|
}
|
|
21
39
|
const body = {};
|
|
22
40
|
if (flags.title !== undefined)
|
|
23
41
|
body.title = flags.title;
|
|
24
|
-
|
|
42
|
+
if (flags.slug !== undefined)
|
|
43
|
+
body.slug = flags.slug;
|
|
44
|
+
if (flags['seo-title'] !== undefined)
|
|
45
|
+
body.seoTitle = flags['seo-title'];
|
|
46
|
+
if (flags['seo-desc'] !== undefined)
|
|
47
|
+
body.seoDescription = flags['seo-desc'];
|
|
48
|
+
if (flags.excerpt !== undefined)
|
|
49
|
+
body.excerpt = flags.excerpt;
|
|
50
|
+
if (flags.content !== undefined) {
|
|
51
|
+
try {
|
|
52
|
+
body.content = JSON.parse(flags.content);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
this.error("Invalid JSON in --content flag. Run 'nabnflow blog content-format' to see the expected JSON format.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const result = await apiRequest(`/api/blog/posts/${args.slug}`, { method: 'PATCH', body: JSON.stringify(body) });
|
|
25
59
|
this.log(`Updated post: ${result.post.slug}`);
|
|
26
60
|
return result;
|
|
27
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/blog/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAa9C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/blog/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
interface UploadResponse {
|
|
3
|
+
storageId: string;
|
|
4
|
+
url: string;
|
|
5
|
+
contentType: string;
|
|
6
|
+
size: number;
|
|
7
|
+
}
|
|
8
|
+
export default class FilesUpload extends Command {
|
|
9
|
+
static description: string;
|
|
10
|
+
static enableJsonFlag: boolean;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static args: {
|
|
13
|
+
filePath: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<UploadResponse>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/commands/files/upload.ts"],"names":[],"mappings":"AAGA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAqBzC,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SACgG;IAElH,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAId;IAED,MAAM,CAAC,IAAI;;MAEV;IAEK,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;CAyDrC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
3
|
+
import { Args, Command } from '@oclif/core';
|
|
4
|
+
import { requireAuth, requireBaseUrl } from '../../lib/client.js';
|
|
5
|
+
const MIME_TYPES = {
|
|
6
|
+
'.jpg': 'image/jpeg',
|
|
7
|
+
'.jpeg': 'image/jpeg',
|
|
8
|
+
'.png': 'image/png',
|
|
9
|
+
'.gif': 'image/gif',
|
|
10
|
+
'.webp': 'image/webp',
|
|
11
|
+
'.avif': 'image/avif',
|
|
12
|
+
'.svg': 'image/svg+xml',
|
|
13
|
+
'.pdf': 'application/pdf',
|
|
14
|
+
'.txt': 'text/plain',
|
|
15
|
+
'.md': 'text/markdown',
|
|
16
|
+
'.csv': 'text/csv',
|
|
17
|
+
'.json': 'application/json',
|
|
18
|
+
'.zip': 'application/zip',
|
|
19
|
+
'.mp4': 'video/mp4',
|
|
20
|
+
'.mp3': 'audio/mpeg',
|
|
21
|
+
};
|
|
22
|
+
export default class FilesUpload extends Command {
|
|
23
|
+
static description = 'Upload a file to storage. Returns a storageId you can use to embed the file in content or attach it to a note.';
|
|
24
|
+
static enableJsonFlag = true;
|
|
25
|
+
static examples = [
|
|
26
|
+
'<%= config.bin %> files upload ./hero.png',
|
|
27
|
+
'<%= config.bin %> files upload ./report.pdf --json',
|
|
28
|
+
'<%= config.bin %> files upload ~/Desktop/diagram.png',
|
|
29
|
+
];
|
|
30
|
+
static args = {
|
|
31
|
+
filePath: Args.string({ description: 'Path to the local file to upload', required: true }),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
const { args } = await this.parse(FilesUpload);
|
|
35
|
+
const token = requireAuth();
|
|
36
|
+
const baseUrl = requireBaseUrl();
|
|
37
|
+
const ext = extname(args.filePath).toLowerCase();
|
|
38
|
+
const mimeType = MIME_TYPES[ext] ?? 'application/octet-stream';
|
|
39
|
+
let fileBuffer;
|
|
40
|
+
try {
|
|
41
|
+
fileBuffer = readFileSync(args.filePath);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
this.error(`Could not read file: ${args.filePath}`);
|
|
45
|
+
}
|
|
46
|
+
const apiBase = baseUrl.replace(/\/$/, '');
|
|
47
|
+
const filename = basename(args.filePath);
|
|
48
|
+
const res = await fetch(`${apiBase}/upload`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: `Bearer ${token}`,
|
|
52
|
+
'Content-Type': mimeType,
|
|
53
|
+
},
|
|
54
|
+
body: fileBuffer,
|
|
55
|
+
});
|
|
56
|
+
if (!res.ok) {
|
|
57
|
+
let message = `Upload failed: HTTP ${res.status}`;
|
|
58
|
+
try {
|
|
59
|
+
const body = (await res.json());
|
|
60
|
+
if (body.error)
|
|
61
|
+
message = `Upload failed: ${body.error}`;
|
|
62
|
+
}
|
|
63
|
+
catch { }
|
|
64
|
+
this.error(message);
|
|
65
|
+
}
|
|
66
|
+
const result = (await res.json());
|
|
67
|
+
this.log(`Uploaded: ${filename}`);
|
|
68
|
+
this.log(`Storage ID: ${result.storageId}`);
|
|
69
|
+
this.log(`URL: ${result.url}`);
|
|
70
|
+
this.log(`Content-Type: ${result.contentType}`);
|
|
71
|
+
this.log(`Size: ${result.size.toLocaleString()} bytes`);
|
|
72
|
+
this.log(``);
|
|
73
|
+
if (result.contentType.startsWith('image/')) {
|
|
74
|
+
this.log(`To embed inline in content (blog or notes):`);
|
|
75
|
+
this.log(` {"type":"figure","attrs":{"src":"storage:${result.storageId}","alt":"Description"}}`);
|
|
76
|
+
this.log(``);
|
|
77
|
+
}
|
|
78
|
+
this.log(`To attach as a file to a note:`);
|
|
79
|
+
this.log(` nabnflow notes create --title "..." --file ${args.filePath}`);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/commands/files/upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-format.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/content-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAGnC,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,MAAM,CAAC,WAAW,SAC8L;IAEhN,MAAM,CAAC,QAAQ,WAGd;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqB3B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { requireAuth, requireBaseUrl } from '../../lib/client.js';
|
|
3
|
+
export default class NotesContentFormat extends Command {
|
|
4
|
+
static description = "Show the block (JSONContent) format expected by the --content flag. The same format is used for both notes and blog posts. Use this to learn how to structure content for 'notes create' and 'notes update'.";
|
|
5
|
+
static examples = [
|
|
6
|
+
'<%= config.bin %> notes content-format',
|
|
7
|
+
'<%= config.bin %> notes content-format | less',
|
|
8
|
+
];
|
|
9
|
+
async run() {
|
|
10
|
+
const token = requireAuth();
|
|
11
|
+
const baseUrl = requireBaseUrl();
|
|
12
|
+
const url = `${baseUrl.replace(/\/$/, '')}/api/docs/editor-blocks`;
|
|
13
|
+
const res = await fetch(url, {
|
|
14
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
15
|
+
});
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
let message = `HTTP ${res.status}`;
|
|
18
|
+
try {
|
|
19
|
+
const body = (await res.json());
|
|
20
|
+
if (body.error)
|
|
21
|
+
message = body.error;
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
this.error(`Failed to fetch content format docs: ${message}`);
|
|
25
|
+
}
|
|
26
|
+
const docs = await res.text();
|
|
27
|
+
this.log(docs);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=content-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-format.js","sourceRoot":"","sources":["../../../src/commands/notes/content-format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAE/D,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,MAAM,CAAC,WAAW,GAChB,8MAA8M,CAAA;IAEhN,MAAM,CAAC,QAAQ,GAAG;QAChB,wCAAwC;QACxC,+CAA+C;KAChD,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;QAEhC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAA;QAClE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,OAAO,EAAE,EAAC,aAAa,EAAE,UAAU,KAAK,EAAE,EAAC;SAC5C,CAAC,CAAA;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAA;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAA;gBACnD,IAAI,IAAI,CAAC,KAAK;oBAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAA;YACtC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAA;QAC/D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC"}
|
|
@@ -9,9 +9,9 @@ export default class NotesCreate extends Command {
|
|
|
9
9
|
static examples: string[];
|
|
10
10
|
static flags: {
|
|
11
11
|
title: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
|
|
12
|
+
content: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
|
|
14
|
+
file: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
15
|
'skip-todo-extraction': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
16
|
};
|
|
17
17
|
run(): Promise<CreateNoteResponse>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/create.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAyB1C,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAyCD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAAsB;IAExC,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAMd;IAED,MAAM,CAAC,KAAK;;;;;;MAqBX;IAEK,GAAG,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAqCzC"}
|
|
@@ -1,26 +1,79 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
1
3
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import { apiRequest } from '../../lib/client.js';
|
|
4
|
+
import { requireAuth, requireBaseUrl, apiRequest } from '../../lib/client.js';
|
|
5
|
+
const MIME_TYPES = {
|
|
6
|
+
'.jpg': 'image/jpeg',
|
|
7
|
+
'.jpeg': 'image/jpeg',
|
|
8
|
+
'.png': 'image/png',
|
|
9
|
+
'.gif': 'image/gif',
|
|
10
|
+
'.webp': 'image/webp',
|
|
11
|
+
'.avif': 'image/avif',
|
|
12
|
+
'.svg': 'image/svg+xml',
|
|
13
|
+
'.pdf': 'application/pdf',
|
|
14
|
+
'.txt': 'text/plain',
|
|
15
|
+
'.md': 'text/markdown',
|
|
16
|
+
'.csv': 'text/csv',
|
|
17
|
+
'.json': 'application/json',
|
|
18
|
+
'.zip': 'application/zip',
|
|
19
|
+
};
|
|
20
|
+
async function uploadFile(filePath, token, baseUrl) {
|
|
21
|
+
const ext = extname(filePath).toLowerCase();
|
|
22
|
+
const mimeType = MIME_TYPES[ext] ?? 'application/octet-stream';
|
|
23
|
+
const filename = basename(filePath);
|
|
24
|
+
let fileBuffer;
|
|
25
|
+
try {
|
|
26
|
+
fileBuffer = readFileSync(filePath);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error(`Could not read file: ${filePath}`);
|
|
30
|
+
}
|
|
31
|
+
const apiBase = baseUrl.replace(/\/$/, '');
|
|
32
|
+
const res = await fetch(`${apiBase}/upload`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${token}`,
|
|
36
|
+
'Content-Type': mimeType,
|
|
37
|
+
},
|
|
38
|
+
body: fileBuffer,
|
|
39
|
+
});
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
let message = `Upload failed for ${filename}: HTTP ${res.status}`;
|
|
42
|
+
try {
|
|
43
|
+
const body = (await res.json());
|
|
44
|
+
if (body.error)
|
|
45
|
+
message = `Upload failed for ${filename}: ${body.error}`;
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
throw new Error(message);
|
|
49
|
+
}
|
|
50
|
+
const result = (await res.json());
|
|
51
|
+
return { storageId: result.storageId, filename, contentType: result.contentType, size: result.size };
|
|
52
|
+
}
|
|
3
53
|
export default class NotesCreate extends Command {
|
|
4
54
|
static description = 'Create a new note';
|
|
5
55
|
static enableJsonFlag = true;
|
|
6
56
|
static examples = [
|
|
7
57
|
'<%= config.bin %> notes create --title "My note"',
|
|
8
|
-
'<%= config.bin %> notes create --title "Meeting notes" --
|
|
9
|
-
'<%= config.bin %> notes create --title "
|
|
58
|
+
'<%= config.bin %> notes create --title "Meeting notes" --content \'{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Key decisions made today"}]}]}\'',
|
|
59
|
+
'<%= config.bin %> notes create --title "Q1 Report" --file ./report.pdf',
|
|
60
|
+
'<%= config.bin %> notes create --title "Design docs" --file ./mockup.png --file ./spec.pdf',
|
|
61
|
+
'<%= config.bin %> notes create --title "Rich note" --content \'...\' --file ./attachment.pdf --json',
|
|
10
62
|
];
|
|
11
63
|
static flags = {
|
|
12
64
|
title: Flags.string({
|
|
13
65
|
description: 'Note title',
|
|
14
66
|
required: true,
|
|
15
67
|
}),
|
|
16
|
-
|
|
17
|
-
description:
|
|
68
|
+
content: Flags.string({
|
|
69
|
+
description: "Note content in block (JSONContent) format. Run 'nabnflow notes content-format' to see the expected JSON structure.",
|
|
18
70
|
}),
|
|
19
71
|
project: Flags.string({
|
|
20
|
-
description:
|
|
72
|
+
description: "Project ID to associate the note with. Run 'nabnflow projects' to list available projects and their IDs.",
|
|
21
73
|
}),
|
|
22
|
-
|
|
23
|
-
description: '
|
|
74
|
+
file: Flags.string({
|
|
75
|
+
description: "Path to a local file to upload and attach to the note. Can be specified multiple times. For inline images within --content, run 'nabnflow notes content-format' to learn how to embed images directly in the content.",
|
|
76
|
+
multiple: true,
|
|
24
77
|
}),
|
|
25
78
|
'skip-todo-extraction': Flags.boolean({
|
|
26
79
|
description: 'Skip automatic todo extraction from note content',
|
|
@@ -30,14 +83,25 @@ export default class NotesCreate extends Command {
|
|
|
30
83
|
async run() {
|
|
31
84
|
const { flags } = await this.parse(NotesCreate);
|
|
32
85
|
const body = { title: flags.title };
|
|
33
|
-
if (flags.
|
|
34
|
-
|
|
86
|
+
if (flags.content !== undefined) {
|
|
87
|
+
try {
|
|
88
|
+
body.content = JSON.parse(flags.content);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
this.error("Invalid JSON in --content flag. Run 'nabnflow notes content-format' to see the expected JSON structure.");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
35
94
|
if (flags.project)
|
|
36
95
|
body.projectId = flags.project;
|
|
37
|
-
if (flags.tags)
|
|
38
|
-
body.tags = flags.tags.split(',').map((t) => t.trim());
|
|
39
96
|
if (flags['skip-todo-extraction'])
|
|
40
97
|
body.skipTodoExtraction = true;
|
|
98
|
+
// Upload --file attachments
|
|
99
|
+
if (flags.file && flags.file.length > 0) {
|
|
100
|
+
const token = requireAuth();
|
|
101
|
+
const baseUrl = requireBaseUrl();
|
|
102
|
+
const files = await Promise.all(flags.file.map((filePath) => uploadFile(filePath, token, baseUrl)));
|
|
103
|
+
body.files = files;
|
|
104
|
+
}
|
|
41
105
|
const result = await apiRequest('/api/notes', {
|
|
42
106
|
method: 'POST',
|
|
43
107
|
body: JSON.stringify(body),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/notes/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/notes/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
+
interface NoteFile {
|
|
3
|
+
storageId: string;
|
|
4
|
+
filename?: string;
|
|
5
|
+
contentType: string;
|
|
6
|
+
size: number;
|
|
7
|
+
url?: string | null;
|
|
8
|
+
}
|
|
2
9
|
interface Note {
|
|
3
10
|
id: string;
|
|
4
11
|
title: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
createdAt:
|
|
9
|
-
updatedAt:
|
|
12
|
+
content?: unknown;
|
|
13
|
+
projectId?: string | null;
|
|
14
|
+
files?: NoteFile[];
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
10
17
|
}
|
|
11
18
|
interface GetNoteResponse {
|
|
12
19
|
note: Note;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAGzC,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAC,MAAM,aAAa,CAAA;AAGzC,UAAU,QAAQ;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,UAAU,IAAI;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,IAAI,CAAA;CACX;AAED,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAC,WAAW,SAAqB;IAEvC,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAGd;IAED,MAAM,CAAC,IAAI;;MAEV;IAEK,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC;CAsBtC"}
|
|
@@ -16,14 +16,20 @@ export default class NotesGet extends Command {
|
|
|
16
16
|
const { note } = result;
|
|
17
17
|
this.log(`ID: ${note.id}`);
|
|
18
18
|
this.log(`Title: ${note.title}`);
|
|
19
|
-
if (note.description)
|
|
20
|
-
this.log(`Body: ${note.description}`);
|
|
21
|
-
if (note.tags?.length)
|
|
22
|
-
this.log(`Tags: ${note.tags.join(', ')}`);
|
|
23
19
|
if (note.projectId)
|
|
24
20
|
this.log(`Project: ${note.projectId}`);
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
if (note.files && note.files.length > 0) {
|
|
22
|
+
this.log(`Files: ${note.files.length} attachment(s)`);
|
|
23
|
+
for (const f of note.files) {
|
|
24
|
+
this.log(` - ${f.filename ?? f.storageId} (${f.contentType}, ${f.size.toLocaleString()} bytes)`);
|
|
25
|
+
if (f.url)
|
|
26
|
+
this.log(` ${f.url}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (note.content)
|
|
30
|
+
this.log(`Content: [blocks present — use --json to inspect]`);
|
|
31
|
+
this.log(`Created: ${note.createdAt}`);
|
|
32
|
+
this.log(`Updated: ${note.updatedAt}`);
|
|
27
33
|
return result;
|
|
28
34
|
}
|
|
29
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/commands/notes/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/commands/notes/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;AAwB9C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAC,WAAW,GAAG,kBAAkB,CAAA;IAEvC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAA;IAE5B,MAAM,CAAC,QAAQ,GAAG;QAChB,kCAAkC;QAClC,yCAAyC;KAC1C,CAAA;IAED,MAAM,CAAC,IAAI,GAAG;QACZ,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KAC1D,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAEzC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAkB,cAAc,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QACzE,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,CAAA;QAErB,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QAC/B,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAClC,IAAI,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QAC1D,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,MAAM,gBAAgB,CAAC,CAAA;YACvD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;gBACjG,IAAI,CAAC,CAAC,GAAG;oBAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;QAC/E,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QAEtC,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -12,9 +12,10 @@ export default class NotesUpdate extends Command {
|
|
|
12
12
|
};
|
|
13
13
|
static flags: {
|
|
14
14
|
title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
-
|
|
15
|
+
content: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
16
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
-
|
|
17
|
+
file: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
'clear-files': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
19
|
};
|
|
19
20
|
run(): Promise<UpdateNoteResponse>;
|
|
20
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/notes/update.ts"],"names":[],"mappings":"AAGA,OAAO,EAAO,OAAO,EAAQ,MAAM,aAAa,CAAA;AAuChD,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAyCD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;IAC9C,MAAM,CAAC,WAAW,SAAkB;IAEpC,MAAM,CAAC,cAAc,UAAO;IAE5B,MAAM,CAAC,QAAQ,WAMd;IAED,MAAM,CAAC,IAAI;;MAEV;IAED,MAAM,CAAC,KAAK;;;;;;MAgBX;IAEK,GAAG,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAwEzC"}
|
|
@@ -1,11 +1,63 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, extname } from 'node:path';
|
|
1
3
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
import { apiRequest } from '../../lib/client.js';
|
|
4
|
+
import { requireAuth, requireBaseUrl, apiRequest } from '../../lib/client.js';
|
|
5
|
+
const MIME_TYPES = {
|
|
6
|
+
'.jpg': 'image/jpeg',
|
|
7
|
+
'.jpeg': 'image/jpeg',
|
|
8
|
+
'.png': 'image/png',
|
|
9
|
+
'.gif': 'image/gif',
|
|
10
|
+
'.webp': 'image/webp',
|
|
11
|
+
'.avif': 'image/avif',
|
|
12
|
+
'.svg': 'image/svg+xml',
|
|
13
|
+
'.pdf': 'application/pdf',
|
|
14
|
+
'.txt': 'text/plain',
|
|
15
|
+
'.md': 'text/markdown',
|
|
16
|
+
'.csv': 'text/csv',
|
|
17
|
+
'.json': 'application/json',
|
|
18
|
+
'.zip': 'application/zip',
|
|
19
|
+
};
|
|
20
|
+
async function uploadFile(filePath, token, baseUrl) {
|
|
21
|
+
const ext = extname(filePath).toLowerCase();
|
|
22
|
+
const mimeType = MIME_TYPES[ext] ?? 'application/octet-stream';
|
|
23
|
+
const filename = basename(filePath);
|
|
24
|
+
let fileBuffer;
|
|
25
|
+
try {
|
|
26
|
+
fileBuffer = readFileSync(filePath);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error(`Could not read file: ${filePath}`);
|
|
30
|
+
}
|
|
31
|
+
const apiBase = baseUrl.replace(/\/$/, '');
|
|
32
|
+
const res = await fetch(`${apiBase}/upload`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${token}`,
|
|
36
|
+
'Content-Type': mimeType,
|
|
37
|
+
},
|
|
38
|
+
body: fileBuffer,
|
|
39
|
+
});
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
let message = `Upload failed for ${filename}: HTTP ${res.status}`;
|
|
42
|
+
try {
|
|
43
|
+
const body = (await res.json());
|
|
44
|
+
if (body.error)
|
|
45
|
+
message = `Upload failed for ${filename}: ${body.error}`;
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
throw new Error(message);
|
|
49
|
+
}
|
|
50
|
+
const result = (await res.json());
|
|
51
|
+
return { storageId: result.storageId, filename, contentType: result.contentType, size: result.size };
|
|
52
|
+
}
|
|
3
53
|
export default class NotesUpdate extends Command {
|
|
4
54
|
static description = 'Update a note';
|
|
5
55
|
static enableJsonFlag = true;
|
|
6
56
|
static examples = [
|
|
7
57
|
'<%= config.bin %> notes update <id> --title "New title"',
|
|
8
|
-
'<%= config.bin %> notes update <id> --
|
|
58
|
+
'<%= config.bin %> notes update <id> --content \'{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Updated content"}]}]}\'',
|
|
59
|
+
'<%= config.bin %> notes update <id> --file ./new-attachment.pdf',
|
|
60
|
+
'<%= config.bin %> notes update <id> --clear-files',
|
|
9
61
|
'<%= config.bin %> notes update <id> --project proj_abc123 --json',
|
|
10
62
|
];
|
|
11
63
|
static args = {
|
|
@@ -13,25 +65,70 @@ export default class NotesUpdate extends Command {
|
|
|
13
65
|
};
|
|
14
66
|
static flags = {
|
|
15
67
|
title: Flags.string({ description: 'New title' }),
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
68
|
+
content: Flags.string({
|
|
69
|
+
description: "New content in block (JSONContent) format. Run 'nabnflow notes content-format' to see the expected JSON structure.",
|
|
70
|
+
}),
|
|
71
|
+
project: Flags.string({ description: 'Project ID to move note to (pass "inbox" to clear). Run \'nabnflow projects\' to list available projects and their IDs.' }),
|
|
72
|
+
file: Flags.string({
|
|
73
|
+
description: "Path to a local file to upload and append to existing file attachments. Can be specified multiple times. For inline images within --content, run 'nabnflow notes content-format' to learn how to embed images directly in the content.",
|
|
74
|
+
multiple: true,
|
|
75
|
+
}),
|
|
76
|
+
'clear-files': Flags.boolean({
|
|
77
|
+
description: 'Remove all file attachments from the note (workflow-managed link/image entries are preserved)',
|
|
78
|
+
default: false,
|
|
79
|
+
}),
|
|
19
80
|
};
|
|
20
81
|
async run() {
|
|
21
82
|
const { args, flags } = await this.parse(NotesUpdate);
|
|
22
|
-
const hasFlag = flags.title !== undefined ||
|
|
83
|
+
const hasFlag = flags.title !== undefined ||
|
|
84
|
+
flags.content !== undefined ||
|
|
85
|
+
flags.project !== undefined ||
|
|
86
|
+
(flags.file && flags.file.length > 0) ||
|
|
87
|
+
flags['clear-files'];
|
|
23
88
|
if (!hasFlag) {
|
|
24
|
-
this.error('At least one flag is required.\n\
|
|
89
|
+
this.error('At least one flag is required.\n\nAvailable flags: --title, --content, --project, --file, --clear-files');
|
|
25
90
|
}
|
|
26
91
|
const body = {};
|
|
27
92
|
if (flags.title !== undefined)
|
|
28
93
|
body.title = flags.title;
|
|
29
|
-
if (flags.body !== undefined)
|
|
30
|
-
body.description = flags.body || null;
|
|
31
94
|
if (flags.project !== undefined)
|
|
32
95
|
body.projectId = flags.project === 'inbox' ? null : flags.project;
|
|
33
|
-
if (flags.
|
|
34
|
-
|
|
96
|
+
if (flags.content !== undefined) {
|
|
97
|
+
try {
|
|
98
|
+
body.content = JSON.parse(flags.content);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
this.error("Invalid JSON in --content flag. Run 'nabnflow notes content-format' to see the expected JSON structure.");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Handle --clear-files: sends files: null to clear all file entries
|
|
105
|
+
if (flags['clear-files']) {
|
|
106
|
+
body.files = null;
|
|
107
|
+
}
|
|
108
|
+
else if (flags.file && flags.file.length > 0) {
|
|
109
|
+
// --file: upload new files, then append to existing files on the note
|
|
110
|
+
const token = requireAuth();
|
|
111
|
+
const baseUrl = requireBaseUrl();
|
|
112
|
+
// Fetch current note to get existing files
|
|
113
|
+
const current = await apiRequest(`/api/notes/${args.id}`);
|
|
114
|
+
const existingFiles = (current.note.files ?? []).map((f) => ({
|
|
115
|
+
storageId: f.storageId,
|
|
116
|
+
filename: f.filename,
|
|
117
|
+
contentType: f.contentType,
|
|
118
|
+
size: f.size,
|
|
119
|
+
// omit url — not needed in request
|
|
120
|
+
}));
|
|
121
|
+
const newFiles = await Promise.all(flags.file.map((filePath) => uploadFile(filePath, token, baseUrl)));
|
|
122
|
+
body.files = [
|
|
123
|
+
...existingFiles.map((f) => ({
|
|
124
|
+
storageId: f.storageId,
|
|
125
|
+
...(f.filename && { filename: f.filename }),
|
|
126
|
+
contentType: f.contentType,
|
|
127
|
+
size: f.size,
|
|
128
|
+
})),
|
|
129
|
+
...newFiles,
|
|
130
|
+
];
|
|
131
|
+
}
|
|
35
132
|
const result = await apiRequest(`/api/notes/${args.id}`, {
|
|
36
133
|
method: 'PUT',
|
|
37
134
|
body: JSON.stringify(body),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/notes/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/notes/update.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/client.js
CHANGED
|
@@ -8,7 +8,7 @@ export class NabflowError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
export function requireAuth() {
|
|
11
|
-
const token = getToken();
|
|
11
|
+
const token = process.env.NABFLOW_TOKEN ?? getToken();
|
|
12
12
|
if (!token) {
|
|
13
13
|
throw new NabflowError(401, 'Not authenticated. Run:\n\n nabnflow auth login --token <token>');
|
|
14
14
|
}
|
package/dist/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEhD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAE5B;IADT,YACS,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAA;QAHP,WAAM,GAAN,MAAM,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEhD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAE5B;IADT,YACS,MAAc,EACrB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAA;QAHP,WAAM,GAAN,MAAM,CAAQ;QAIrB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,EAAE,CAAA;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CACpB,GAAG,EACH,kEAAkE,CACnE,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAA;IACxB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,YAAY,CACpB,CAAC,EACD,uFAAuF,CACxF,CAAA;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,UAAuB,EAAE;IAEzB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;IAEhC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAA;IAClD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,GAAG,OAAO;QACV,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,GAAG,OAAO,CAAC,OAAO;SACnB;KACF,CAAC,CAAA;IAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,IAAI,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAA;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAuC,CAAA;YACrE,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAA;AACjC,CAAC"}
|