@klevar/portal-cli 0.1.11 → 0.1.13
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/index.d.ts +68 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/notes.d.ts +68 -0
- package/dist/commands/notes.js +13 -0
- package/dist/commands/notes.js.map +1 -0
- package/dist/lib/legacy-runner.js +59 -2
- package/package.json +1 -1
package/dist/commands/index.d.ts
CHANGED
|
@@ -522,6 +522,74 @@ export declare const COMMAND_GROUPS: {
|
|
|
522
522
|
description: string;
|
|
523
523
|
};
|
|
524
524
|
};
|
|
525
|
+
notes: {
|
|
526
|
+
'notes.list': {
|
|
527
|
+
method: "GET";
|
|
528
|
+
path: string;
|
|
529
|
+
auth: "apiKey";
|
|
530
|
+
description: string;
|
|
531
|
+
queryParams: string[];
|
|
532
|
+
};
|
|
533
|
+
'notes.create': {
|
|
534
|
+
method: "POST";
|
|
535
|
+
path: string;
|
|
536
|
+
auth: "apiKey";
|
|
537
|
+
description: string;
|
|
538
|
+
body: string[];
|
|
539
|
+
};
|
|
540
|
+
'notes.update': {
|
|
541
|
+
method: "PATCH";
|
|
542
|
+
path: string;
|
|
543
|
+
auth: "apiKey";
|
|
544
|
+
description: string;
|
|
545
|
+
body: string[];
|
|
546
|
+
};
|
|
547
|
+
'notes.comments': {
|
|
548
|
+
method: "GET";
|
|
549
|
+
path: string;
|
|
550
|
+
auth: "apiKey";
|
|
551
|
+
description: string;
|
|
552
|
+
};
|
|
553
|
+
'notes.reply': {
|
|
554
|
+
method: "POST";
|
|
555
|
+
path: string;
|
|
556
|
+
auth: "apiKey";
|
|
557
|
+
description: string;
|
|
558
|
+
body: string[];
|
|
559
|
+
};
|
|
560
|
+
'portal.notes': {
|
|
561
|
+
method: "GET";
|
|
562
|
+
path: string;
|
|
563
|
+
auth: "portalToken";
|
|
564
|
+
description: string;
|
|
565
|
+
};
|
|
566
|
+
'portal.notes.project': {
|
|
567
|
+
method: "GET";
|
|
568
|
+
path: string;
|
|
569
|
+
auth: "portalToken";
|
|
570
|
+
description: string;
|
|
571
|
+
};
|
|
572
|
+
'portal.notes.create': {
|
|
573
|
+
method: "POST";
|
|
574
|
+
path: string;
|
|
575
|
+
auth: "portalToken";
|
|
576
|
+
description: string;
|
|
577
|
+
body: string[];
|
|
578
|
+
};
|
|
579
|
+
'portal.notes.comments': {
|
|
580
|
+
method: "GET";
|
|
581
|
+
path: string;
|
|
582
|
+
auth: "portalToken";
|
|
583
|
+
description: string;
|
|
584
|
+
};
|
|
585
|
+
'portal.notes.reply': {
|
|
586
|
+
method: "POST";
|
|
587
|
+
path: string;
|
|
588
|
+
auth: "portalToken";
|
|
589
|
+
description: string;
|
|
590
|
+
body: string[];
|
|
591
|
+
};
|
|
592
|
+
};
|
|
525
593
|
metrics: {
|
|
526
594
|
'metrics.push': {
|
|
527
595
|
method: "POST";
|
package/dist/commands/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { docsCommands } from './docs.js';
|
|
|
3
3
|
import { capacityCommands } from './capacity.js';
|
|
4
4
|
import { metricCommands } from './metrics.js';
|
|
5
5
|
import { onboardingCommands } from './onboarding.js';
|
|
6
|
+
import { noteCommands } from './notes.js';
|
|
6
7
|
import { portalCommands } from './portal.js';
|
|
7
8
|
import { projectCommands } from './projects.js';
|
|
8
9
|
import { systemCommands } from './system.js';
|
|
@@ -18,6 +19,7 @@ export const COMMAND_GROUPS = {
|
|
|
18
19
|
usage: usageCommands,
|
|
19
20
|
updates: updateCommands,
|
|
20
21
|
onboarding: onboardingCommands,
|
|
22
|
+
notes: noteCommands,
|
|
21
23
|
metrics: metricCommands,
|
|
22
24
|
docs: docsCommands,
|
|
23
25
|
portal: portalCommands,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAK9C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,gBAAgB;IAC1B,KAAK,EAAE,aAAa;IACpB,OAAO,EAAE,cAAc;IACvB,UAAU,EAAE,kBAAkB;IAC9B,OAAO,EAAE,cAAc;IACvB,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,cAAc;CACgB,CAAC;AAEzC,MAAM,CAAC,MAAM,QAAQ,GAA+B,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAK9C,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,gBAAgB;IAC1B,KAAK,EAAE,aAAa;IACpB,OAAO,EAAE,cAAc;IACvB,UAAU,EAAE,kBAAkB;IAC9B,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,cAAc;IACvB,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,cAAc;CACgB,CAAC;AAEzC,MAAM,CAAC,MAAM,QAAQ,GAA+B,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export declare const noteCommands: {
|
|
2
|
+
'notes.list': {
|
|
3
|
+
method: "GET";
|
|
4
|
+
path: string;
|
|
5
|
+
auth: "apiKey";
|
|
6
|
+
description: string;
|
|
7
|
+
queryParams: string[];
|
|
8
|
+
};
|
|
9
|
+
'notes.create': {
|
|
10
|
+
method: "POST";
|
|
11
|
+
path: string;
|
|
12
|
+
auth: "apiKey";
|
|
13
|
+
description: string;
|
|
14
|
+
body: string[];
|
|
15
|
+
};
|
|
16
|
+
'notes.update': {
|
|
17
|
+
method: "PATCH";
|
|
18
|
+
path: string;
|
|
19
|
+
auth: "apiKey";
|
|
20
|
+
description: string;
|
|
21
|
+
body: string[];
|
|
22
|
+
};
|
|
23
|
+
'notes.comments': {
|
|
24
|
+
method: "GET";
|
|
25
|
+
path: string;
|
|
26
|
+
auth: "apiKey";
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
'notes.reply': {
|
|
30
|
+
method: "POST";
|
|
31
|
+
path: string;
|
|
32
|
+
auth: "apiKey";
|
|
33
|
+
description: string;
|
|
34
|
+
body: string[];
|
|
35
|
+
};
|
|
36
|
+
'portal.notes': {
|
|
37
|
+
method: "GET";
|
|
38
|
+
path: string;
|
|
39
|
+
auth: "portalToken";
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
'portal.notes.project': {
|
|
43
|
+
method: "GET";
|
|
44
|
+
path: string;
|
|
45
|
+
auth: "portalToken";
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
'portal.notes.create': {
|
|
49
|
+
method: "POST";
|
|
50
|
+
path: string;
|
|
51
|
+
auth: "portalToken";
|
|
52
|
+
description: string;
|
|
53
|
+
body: string[];
|
|
54
|
+
};
|
|
55
|
+
'portal.notes.comments': {
|
|
56
|
+
method: "GET";
|
|
57
|
+
path: string;
|
|
58
|
+
auth: "portalToken";
|
|
59
|
+
description: string;
|
|
60
|
+
};
|
|
61
|
+
'portal.notes.reply': {
|
|
62
|
+
method: "POST";
|
|
63
|
+
path: string;
|
|
64
|
+
auth: "portalToken";
|
|
65
|
+
description: string;
|
|
66
|
+
body: string[];
|
|
67
|
+
};
|
|
68
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const noteCommands = {
|
|
2
|
+
'notes.list': { method: 'GET', path: '/api/admin/notes', auth: 'apiKey', description: 'List client notes', queryParams: ['clientId', 'projectId', 'status'] },
|
|
3
|
+
'notes.create': { method: 'POST', path: '/api/admin/notes', auth: 'apiKey', description: 'Create client note (--clientId --title --content/--content-file/--stdin --projectIds)', body: ['clientId', 'title', 'content', 'projectIds'] },
|
|
4
|
+
'notes.update': { method: 'PATCH', path: '/api/admin/notes/:noteId', auth: 'apiKey', description: 'Update client note', body: ['title', 'content', 'status', 'projectIds'] },
|
|
5
|
+
'notes.comments': { method: 'GET', path: '/api/admin/notes/:noteId/comments', auth: 'apiKey', description: 'List note comments' },
|
|
6
|
+
'notes.reply': { method: 'POST', path: '/api/admin/notes/:noteId/comments', auth: 'apiKey', description: 'Reply to client note (--content, --content-file, or --stdin)', body: ['content'] },
|
|
7
|
+
'portal.notes': { method: 'GET', path: '/api/portal/notes', auth: 'portalToken', description: 'List portal notes' },
|
|
8
|
+
'portal.notes.project': { method: 'GET', path: '/api/portal/projects/:id/notes', auth: 'portalToken', description: 'List portal notes for a project' },
|
|
9
|
+
'portal.notes.create': { method: 'POST', path: '/api/portal/notes', auth: 'portalToken', description: 'Create portal note (--title --content/--content-file/--stdin --projectIds)', body: ['title', 'content', 'projectIds'] },
|
|
10
|
+
'portal.notes.comments': { method: 'GET', path: '/api/portal/notes/:noteId/comments', auth: 'portalToken', description: 'List portal note comments' },
|
|
11
|
+
'portal.notes.reply': { method: 'POST', path: '/api/portal/notes/:noteId/comments', auth: 'portalToken', description: 'Reply to portal note (--content, --content-file, or --stdin)', body: ['content'] },
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=notes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notes.js","sourceRoot":"","sources":["../../commands/notes.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE;IAC7J,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uFAAuF,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;IACxO,cAAc,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE;IAC5K,gBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,mCAAmC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACjI,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,mCAAmC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8DAA8D,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE;IAC5L,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACnH,sBAAsB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gCAAgC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACtJ,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,4EAA4E,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;IAC9N,uBAAuB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,oCAAoC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,2BAA2B,EAAE;IACrJ,oBAAoB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,oCAAoC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,8DAA8D,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE;CACnL,CAAC"}
|
|
@@ -275,10 +275,24 @@ function normalizeCliMultiline(value) {
|
|
|
275
275
|
: value;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
function normalizeCsvList(value) {
|
|
279
|
+
if (Array.isArray(value)) return value;
|
|
280
|
+
if (typeof value !== 'string') return value;
|
|
281
|
+
return value
|
|
282
|
+
.split(',')
|
|
283
|
+
.map((item) => item.trim())
|
|
284
|
+
.filter(Boolean);
|
|
285
|
+
}
|
|
286
|
+
|
|
278
287
|
function supportsCommentContentInput(commandKey) {
|
|
279
288
|
return commandKey === 'comments.create' ||
|
|
280
289
|
commandKey === 'comments.update' ||
|
|
281
|
-
commandKey === 'portal.comments.create'
|
|
290
|
+
commandKey === 'portal.comments.create' ||
|
|
291
|
+
commandKey === 'notes.create' ||
|
|
292
|
+
commandKey === 'notes.update' ||
|
|
293
|
+
commandKey === 'notes.reply' ||
|
|
294
|
+
commandKey === 'portal.notes.create' ||
|
|
295
|
+
commandKey === 'portal.notes.reply';
|
|
282
296
|
}
|
|
283
297
|
|
|
284
298
|
function interpolatePath(template, id) {
|
|
@@ -499,6 +513,33 @@ function formatOutput(data, commandKey) {
|
|
|
499
513
|
return;
|
|
500
514
|
}
|
|
501
515
|
|
|
516
|
+
if (commandKey === 'notes.list' || commandKey === 'portal.notes' || commandKey === 'portal.notes.project') {
|
|
517
|
+
const items = data.data || [];
|
|
518
|
+
if (items.length === 0) { console.log('No notes found.'); return; }
|
|
519
|
+
console.log(`\nClient Notes (${items.length}):`);
|
|
520
|
+
console.log('-'.repeat(80));
|
|
521
|
+
for (const note of items) {
|
|
522
|
+
const projects = note.projects?.length
|
|
523
|
+
? ` -> ${note.projects.map((project) => project.name).join(', ')}`
|
|
524
|
+
: '';
|
|
525
|
+
console.log(` ${note.title} [${note.status}]${projects} [${note.id}]`);
|
|
526
|
+
if (note.commentCount) console.log(` Discussion: ${note.commentCount} repl${note.commentCount === 1 ? 'y' : 'ies'}`);
|
|
527
|
+
}
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (commandKey === 'notes.comments' || commandKey === 'portal.notes.comments') {
|
|
532
|
+
const items = data.data || [];
|
|
533
|
+
if (items.length === 0) { console.log('No note replies yet.'); return; }
|
|
534
|
+
console.log(`\nNote Discussion (${items.length}):`);
|
|
535
|
+
for (const comment of items) {
|
|
536
|
+
const badge = comment.authorType === 'admin' ? '[klevar]' : '[client]';
|
|
537
|
+
console.log(` ${comment.authorName} ${badge} - ${timeAgo(comment.createdAt)}`);
|
|
538
|
+
console.log(` ${comment.content}`);
|
|
539
|
+
}
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
502
543
|
if (
|
|
503
544
|
commandKey === 'clients.docs-invoices' ||
|
|
504
545
|
commandKey === 'projects.docs-invoices'
|
|
@@ -593,6 +634,12 @@ function formatOutput(data, commandKey) {
|
|
|
593
634
|
return;
|
|
594
635
|
}
|
|
595
636
|
|
|
637
|
+
if ((commandKey === 'notes.reply' || commandKey === 'portal.notes.reply') && data.comment) {
|
|
638
|
+
const c = data.comment;
|
|
639
|
+
console.log(`Note reply posted by ${c.authorName} [${c.authorType}] [${c.id}]`);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
|
|
596
643
|
// Onboarding create/process/reject
|
|
597
644
|
if (commandKey === 'onboarding.create' && data.id) {
|
|
598
645
|
console.log(`Submission created: ${data.id} [${data.status}]`);
|
|
@@ -646,6 +693,13 @@ function formatOutput(data, commandKey) {
|
|
|
646
693
|
console.log(`${action}${vis}: ${u.content.slice(0, 80)}${u.content.length > 80 ? '...' : ''} [${u.id}]${edited}`);
|
|
647
694
|
return;
|
|
648
695
|
}
|
|
696
|
+
if (data.note) {
|
|
697
|
+
const n = data.note;
|
|
698
|
+
const projects = n.projects?.length ? ` (${n.projects.map((project) => project.name).join(', ')})` : '';
|
|
699
|
+
const action = commandKey === 'notes.update' ? 'Note updated' : 'Note created';
|
|
700
|
+
console.log(`${action}: ${n.title} [${n.status}]${projects} [${n.id}]`);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
649
703
|
if (data.portalToken) {
|
|
650
704
|
console.log(`New token: ${data.portalToken}`);
|
|
651
705
|
return;
|
|
@@ -696,7 +750,9 @@ if (!resource || resource === 'help' || resource === '--help') {
|
|
|
696
750
|
console.log('Commands:');
|
|
697
751
|
const grouped = {};
|
|
698
752
|
for (const [key, cmd] of Object.entries(COMMANDS)) {
|
|
699
|
-
const
|
|
753
|
+
const parts = key.split('.');
|
|
754
|
+
const res = parts[0];
|
|
755
|
+
const act = parts.length > 1 ? parts.slice(1).join('.') : '';
|
|
700
756
|
if (!grouped[res]) grouped[res] = [];
|
|
701
757
|
grouped[res].push({ key, action: act, desc: (cmd.description || cmd.desc), body: cmd.body, queryParams: cmd.queryParams });
|
|
702
758
|
}
|
|
@@ -804,6 +860,7 @@ if (cmd.fixedBody) {
|
|
|
804
860
|
if (typeof val === 'string' && (val.startsWith('{') || val.startsWith('['))) {
|
|
805
861
|
try { val = JSON.parse(val); } catch { /* keep as string */ }
|
|
806
862
|
}
|
|
863
|
+
if (key === 'projectIds') val = normalizeCsvList(val);
|
|
807
864
|
if (val === 'true') val = true;
|
|
808
865
|
if (val === 'false') val = false;
|
|
809
866
|
body[key] = val;
|