@wirecat/cli-core 0.581.0 → 0.583.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/CHANGELOG.md +54 -0
- package/dist/cli/compact.js +46 -9
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/project-status-rows.js +1 -1
- package/dist/cli/project-status.d.ts +4 -12
- package/dist/cli/project-status.js +35 -16
- package/dist/entities/index.d.ts +2 -0
- package/dist/entities/mail-findings.d.ts +3 -0
- package/dist/entities/mail-findings.js +3 -0
- package/dist/errors/reasons.js +1 -0
- package/dist/mail/cli/marks.js +9 -3
- package/dist/mail/cli/review.js +2 -2
- package/dist/mail/findings.d.ts +56 -2
- package/dist/mail/findings.js +98 -81
- package/dist/mail/index.d.ts +1 -1
- package/dist/mail/index.js +1 -1
- package/dist/mail/marks.js +5 -6
- package/dist/meetings/findings-rules.d.ts +4 -1
- package/dist/meetings/findings-rules.js +36 -19
- package/dist/meetings/index.d.ts +1 -1
- package/dist/meetings/index.js +1 -1
- package/dist/meetings/timestamp.js +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/proposals/index.d.ts +1 -1
- package/dist/services/proposals/index.js +1 -1
- package/dist/services/proposals/kinds/organization.d.ts +7 -0
- package/dist/services/proposals/kinds/organization.js +22 -5
- package/dist/store/knowledge-query.js +7 -1
- package/dist/store/sqlite/finance.d.ts +2 -0
- package/dist/store/sqlite/finance.js +2 -2
- package/dist/store/sqlite/knowledge.d.ts +2 -2
- package/dist/store/sqlite/knowledge.js +2 -21
- package/dist/store/sqlite/organizations.d.ts +14 -0
- package/dist/store/sqlite/organizations.js +48 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ import { type MeetingProjectsStore } from "./meeting-projects.js";
|
|
|
5
5
|
import type { Author } from "./memories.js";
|
|
6
6
|
import { type Link } from "./notes.js";
|
|
7
7
|
import type { StoreContext } from "./open.js";
|
|
8
|
+
import { type OrganizationsStore } from "./organizations.js";
|
|
8
9
|
import type { ProposedAction } from "./proposed-actions.js";
|
|
9
10
|
import { type KnowledgeRelation, type LinkDecision, type RelateInput, type RelationUpdate, type Scored } from "./relation-proposals.js";
|
|
10
11
|
import type { TagCreationOptions } from "./tag-creation.js";
|
|
@@ -100,7 +101,7 @@ export interface Reminder {
|
|
|
100
101
|
receipt: string | null;
|
|
101
102
|
}
|
|
102
103
|
export type LabelledType = "note" | "document" | "person" | "organization" | "project" | "task" | "meeting" | "folder";
|
|
103
|
-
export interface KnowledgeStore extends VocabularyStore, MeetingProjectsStore {
|
|
104
|
+
export interface KnowledgeStore extends VocabularyStore, MeetingProjectsStore, OrganizationsStore {
|
|
104
105
|
taskIds(key: AccountKey, options?: {
|
|
105
106
|
state?: "open" | "done" | "dismissed";
|
|
106
107
|
limit?: number;
|
|
@@ -159,7 +160,6 @@ export interface KnowledgeStore extends VocabularyStore, MeetingProjectsStore {
|
|
|
159
160
|
name: string;
|
|
160
161
|
scope?: Organization["scope"];
|
|
161
162
|
}): Promise<Organization>;
|
|
162
|
-
organizations(query?: QueryAst): Promise<Organization[]>;
|
|
163
163
|
/** A project; its key is made from the name when none is given. */
|
|
164
164
|
addProject(input: {
|
|
165
165
|
name: string;
|
|
@@ -14,6 +14,7 @@ import { linkKind, RELATION_KINDS } from "./link-kinds.js";
|
|
|
14
14
|
import { meetingProjectsStoreOver } from "./meeting-projects.js";
|
|
15
15
|
import { holdingText } from "./note-index.js";
|
|
16
16
|
import { insertLink, linkOf } from "./notes.js";
|
|
17
|
+
import { organizationOf, organizationsStoreOver } from "./organizations.js";
|
|
17
18
|
import { queryFilter } from "./query-filter.js";
|
|
18
19
|
import { relationOf, relationProposalsOver, } from "./relation-proposals.js";
|
|
19
20
|
import { addTags as addThingTags, canonicalTagNamed, createTag, labelsOf, liveTagging, removeTags as removeThingTags, setMainTopic, } from "./tags.js";
|
|
@@ -205,14 +206,6 @@ export const knowledgeStoreOver = (context) => {
|
|
|
205
206
|
throw new CliError("not_found", "no annotation with that id");
|
|
206
207
|
return found;
|
|
207
208
|
};
|
|
208
|
-
const organizationOf = (row) => ({
|
|
209
|
-
id: String(row.id),
|
|
210
|
-
ref: `organization:${row.id}`,
|
|
211
|
-
kind: row.kind,
|
|
212
|
-
name: String(row.name),
|
|
213
|
-
scope: row.scope,
|
|
214
|
-
createdAt: iso(row.created_at),
|
|
215
|
-
});
|
|
216
209
|
const projectOf = (row) => ({
|
|
217
210
|
id: String(row.id),
|
|
218
211
|
ref: `project:${row.id}`,
|
|
@@ -294,6 +287,7 @@ export const knowledgeStoreOver = (context) => {
|
|
|
294
287
|
const tagsOf = (list) => [...new Set(list.map(canonicalTagName))];
|
|
295
288
|
return {
|
|
296
289
|
...vocabularyStoreOver(context),
|
|
290
|
+
...organizationsStoreOver(context),
|
|
297
291
|
...meetingProjectsStoreOver(context),
|
|
298
292
|
taskIds: async (key, options = {}) => {
|
|
299
293
|
const { limit, offset } = bounded(options.limit, options.offset);
|
|
@@ -445,19 +439,6 @@ export const knowledgeStoreOver = (context) => {
|
|
|
445
439
|
.get(oneOf(kind, ORGANIZATION_KINDS, "an organization's kind"), textOf(name, 200), oneOf(scope, SCOPES, "a scope"), at, at);
|
|
446
440
|
return organizationOf(row);
|
|
447
441
|
},
|
|
448
|
-
organizations: async (query) => {
|
|
449
|
-
const where = query &&
|
|
450
|
-
queryFilter(query, {
|
|
451
|
-
id: { type: "kw", sql: "CAST(id AS TEXT)" },
|
|
452
|
-
kind: { type: "enum", sql: "kind" },
|
|
453
|
-
scope: { type: "enum", sql: "scope" },
|
|
454
|
-
created_at: { type: "time", sql: "created_at" },
|
|
455
|
-
});
|
|
456
|
-
return database
|
|
457
|
-
.prepare(`SELECT * FROM organizations WHERE deleted_at IS NULL${where ? ` AND (${where.sql})` : ""} ORDER BY name, id LIMIT 500`)
|
|
458
|
-
.all(...(where?.params ?? []))
|
|
459
|
-
.map(organizationOf);
|
|
460
|
-
},
|
|
461
442
|
addProject: async ({ name, key, type = "other", organization, scope = "personal", description }) => write(database, () => {
|
|
462
443
|
const title = textOf(name, 200);
|
|
463
444
|
const organizationId = organization === undefined
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type QueryAst } from "@wirecat/cli-base/query";
|
|
2
|
+
import type { Organization } from "./knowledge.js";
|
|
3
|
+
import type { StoreContext } from "./open.js";
|
|
4
|
+
type Row = Record<string, unknown>;
|
|
5
|
+
export declare const organizationOf: (row: Row) => Organization;
|
|
6
|
+
export interface OrganizationsStore {
|
|
7
|
+
organizations(query?: QueryAst): Promise<Organization[]>;
|
|
8
|
+
/** Renames an organization given as `organization:<id>` or by its id; its kind and scope stay. */
|
|
9
|
+
updateOrganization(organization: string, input: {
|
|
10
|
+
name: string;
|
|
11
|
+
}): Promise<Organization>;
|
|
12
|
+
}
|
|
13
|
+
export declare const organizationsStoreOver: ({ database, now }: StoreContext) => OrganizationsStore;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { evaluate, walkQuery } from "@wirecat/cli-base/query";
|
|
3
|
+
import { ORGANIZATIONS_QUERY } from "../knowledge-query.js";
|
|
4
|
+
import { queryFilter } from "./query-filter.js";
|
|
5
|
+
import { thingOf } from "./things.js";
|
|
6
|
+
import { write } from "./transaction.js";
|
|
7
|
+
export const organizationOf = (row) => ({
|
|
8
|
+
id: String(row.id),
|
|
9
|
+
ref: `organization:${row.id}`,
|
|
10
|
+
kind: row.kind,
|
|
11
|
+
name: String(row.name),
|
|
12
|
+
scope: row.scope,
|
|
13
|
+
createdAt: new Date(Number(row.created_at)).toISOString(),
|
|
14
|
+
});
|
|
15
|
+
export const organizationsStoreOver = ({ database, now }) => ({
|
|
16
|
+
organizations: async (query) => {
|
|
17
|
+
// `lower()` folds ASCII only and an organization has no folded copy, so a name filter runs on the rows.
|
|
18
|
+
if (query && walkQuery(query.root).some((node) => node.field === "name"))
|
|
19
|
+
return database.prepare("SELECT * FROM organizations WHERE deleted_at IS NULL ORDER BY name, id").all()
|
|
20
|
+
.map(organizationOf)
|
|
21
|
+
.filter((one) => evaluate(query, ORGANIZATIONS_QUERY.fields, { ...one, created_at: one.createdAt }))
|
|
22
|
+
.slice(0, 500);
|
|
23
|
+
const where = query &&
|
|
24
|
+
queryFilter(query, {
|
|
25
|
+
id: { type: "kw", sql: "CAST(id AS TEXT)" },
|
|
26
|
+
kind: { type: "enum", sql: "kind" },
|
|
27
|
+
scope: { type: "enum", sql: "scope" },
|
|
28
|
+
created_at: { type: "time", sql: "created_at" },
|
|
29
|
+
});
|
|
30
|
+
return database
|
|
31
|
+
.prepare(`SELECT * FROM organizations WHERE deleted_at IS NULL${where ? ` AND (${where.sql})` : ""} ORDER BY name, id LIMIT 500`)
|
|
32
|
+
.all(...(where?.params ?? []))
|
|
33
|
+
.map(organizationOf);
|
|
34
|
+
},
|
|
35
|
+
updateOrganization: async (organization, { name }) => write(database, () => {
|
|
36
|
+
const title = name.trim();
|
|
37
|
+
if (!title || title.length > 200)
|
|
38
|
+
throw new CliError("validation_error", "text takes 1–200 characters");
|
|
39
|
+
const thing = thingOf(database, organization.includes(":") ? organization : `organization:${organization}`);
|
|
40
|
+
const row = thing?.type === "organization" &&
|
|
41
|
+
database
|
|
42
|
+
.prepare("UPDATE organizations SET name = ?, updated_at = ? WHERE id = ? AND deleted_at IS NULL RETURNING *")
|
|
43
|
+
.get(title, now(), thing.id);
|
|
44
|
+
if (!row)
|
|
45
|
+
throw new CliError("not_found", `no organization ${organization}`);
|
|
46
|
+
return organizationOf(row);
|
|
47
|
+
}),
|
|
48
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.583.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|