@nabnflow/cli 0.0.5 → 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/hooks/init/auto-update.d.ts +4 -0
- package/dist/hooks/init/auto-update.d.ts.map +1 -0
- package/dist/hooks/init/auto-update.js +28 -0
- package/dist/hooks/init/auto-update.js.map +1 -0
- package/dist/lib/client.js +1 -1
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/config.d.ts +2 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +2 -0
- package/dist/lib/config.js.map +1 -1
- package/package.json +7 -2
|
@@ -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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update.d.ts","sourceRoot":"","sources":["../../../src/hooks/init/auto-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,aAAa,CAAA;AAMhC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,CAwBtB,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { getLastUpdateCheck, setLastUpdateCheck } from '../../lib/config.js';
|
|
3
|
+
const ONE_DAY = 24 * 60 * 60 * 1000;
|
|
4
|
+
const hook = async function () {
|
|
5
|
+
try {
|
|
6
|
+
const lastCheck = getLastUpdateCheck();
|
|
7
|
+
const now = Date.now();
|
|
8
|
+
if (lastCheck && now - lastCheck < ONE_DAY)
|
|
9
|
+
return;
|
|
10
|
+
setLastUpdateCheck(now);
|
|
11
|
+
const res = await fetch('https://registry.npmjs.org/@nabnflow/cli/latest');
|
|
12
|
+
if (!res.ok)
|
|
13
|
+
return;
|
|
14
|
+
const data = (await res.json());
|
|
15
|
+
const latest = data.version;
|
|
16
|
+
const current = this.config.version;
|
|
17
|
+
if (latest !== current) {
|
|
18
|
+
this.log(`Updating nabnflow ${current} → ${latest}...`);
|
|
19
|
+
execSync('npm install -g @nabnflow/cli@latest', { stdio: 'inherit' });
|
|
20
|
+
this.log('Update complete.\n');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// silently fail — never block the command
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export default hook;
|
|
28
|
+
//# sourceMappingURL=auto-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update.js","sourceRoot":"","sources":["../../../src/hooks/init/auto-update.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAC,kBAAkB,EAAE,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAE1E,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEnC,MAAM,IAAI,GAAiB,KAAK;IAC9B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAA;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,IAAI,SAAS,IAAI,GAAG,GAAG,SAAS,GAAG,OAAO;YAAE,OAAM;QAElD,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAEvB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAC1E,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAM;QAEnB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAA;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QAEnC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,qBAAqB,OAAO,MAAM,MAAM,KAAK,CAAC,CAAA;YACvD,QAAQ,CAAC,qCAAqC,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAA;YACnE,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;AACH,CAAC,CAAA;AAED,eAAe,IAAI,CAAA"}
|
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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -3,4 +3,6 @@ export declare const setToken: (token: string) => void;
|
|
|
3
3
|
export declare const clearToken: () => void;
|
|
4
4
|
export declare const getBaseUrl: () => string;
|
|
5
5
|
export declare const setBaseUrl: (url: string) => void;
|
|
6
|
+
export declare const getLastUpdateCheck: () => number | undefined;
|
|
7
|
+
export declare const setLastUpdateCheck: (ts: number) => void;
|
|
6
8
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,SAA+B,CAAA;AACpE,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,KAAG,IAAiC,CAAA;AAC1E,eAAO,MAAM,UAAU,QAAO,IAA6B,CAAA;AAE3D,eAAO,MAAM,UAAU,QAAO,MACqE,CAAA;AAEnG,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,IAAiC,CAAA;AAE1E,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,SAAyC,CAAA;AACxF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,KAAG,IAAwC,CAAA"}
|
package/dist/lib/config.js
CHANGED
|
@@ -5,4 +5,6 @@ export const setToken = (token) => store.set('token', token);
|
|
|
5
5
|
export const clearToken = () => store.delete('token');
|
|
6
6
|
export const getBaseUrl = () => process.env.NABFLOW_API_URL ?? store.get('baseUrl') ?? 'https://industrious-wren-495.convex.site';
|
|
7
7
|
export const setBaseUrl = (url) => store.set('baseUrl', url);
|
|
8
|
+
export const getLastUpdateCheck = () => store.get('lastUpdateCheck');
|
|
9
|
+
export const setLastUpdateCheck = (ts) => store.set('lastUpdateCheck', ts);
|
|
8
10
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAQvB,MAAM,KAAK,GAAG,IAAI,IAAI,CAAgB,EAAC,WAAW,EAAE,UAAU,EAAC,CAAC,CAAA;AAEhE,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAuB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,GAAS,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;AAE3D,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CACrC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,0CAA0C,CAAA;AAEnG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;AAE1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAuB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;AACxF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nabnflow/cli",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Nab&Flow CLI — project management from your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,12 @@
|
|
|
31
31
|
"topicSeparator": " ",
|
|
32
32
|
"plugins": [
|
|
33
33
|
"@oclif/plugin-update"
|
|
34
|
-
]
|
|
34
|
+
],
|
|
35
|
+
"hooks": {
|
|
36
|
+
"init": [
|
|
37
|
+
"./dist/hooks/init/auto-update"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
35
40
|
},
|
|
36
41
|
"engines": {
|
|
37
42
|
"node": ">=18"
|