@synnaxlabs/client 0.45.1 → 0.46.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/.turbo/turbo-build.log +7 -7
- package/dist/access/policy/client.d.ts +38 -26
- package/dist/access/policy/client.d.ts.map +1 -1
- package/dist/access/policy/payload.d.ts +22 -10
- package/dist/access/policy/payload.d.ts.map +1 -1
- package/dist/arc/client.d.ts +72 -0
- package/dist/arc/client.d.ts.map +1 -0
- package/dist/arc/external.d.ts +3 -0
- package/dist/arc/external.d.ts.map +1 -0
- package/dist/arc/index.d.ts +2 -0
- package/dist/arc/index.d.ts.map +1 -0
- package/dist/arc/payload.d.ts +155 -0
- package/dist/arc/payload.d.ts.map +1 -0
- package/dist/channel/client.d.ts +2 -3
- package/dist/channel/client.d.ts.map +1 -1
- package/dist/channel/payload.d.ts +23 -63
- package/dist/channel/payload.d.ts.map +1 -1
- package/dist/channel/retriever.d.ts.map +1 -1
- package/dist/client.cjs +44 -25
- package/dist/client.d.ts +5 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7449 -4753
- package/dist/framer/client.d.ts +2 -2
- package/dist/framer/client.d.ts.map +1 -1
- package/dist/framer/deleter.d.ts +2 -2
- package/dist/framer/frame.d.ts +2 -2
- package/dist/framer/streamer.d.ts +42 -56
- package/dist/framer/streamer.d.ts.map +1 -1
- package/dist/framer/writer.d.ts +45 -43
- package/dist/framer/writer.d.ts.map +1 -1
- package/dist/hardware/device/client.d.ts +5 -6
- package/dist/hardware/device/client.d.ts.map +1 -1
- package/dist/hardware/device/payload.d.ts +83 -18
- package/dist/hardware/device/payload.d.ts.map +1 -1
- package/dist/hardware/rack/client.d.ts +4 -5
- package/dist/hardware/rack/client.d.ts.map +1 -1
- package/dist/hardware/rack/payload.d.ts +81 -17
- package/dist/hardware/rack/payload.d.ts.map +1 -1
- package/dist/hardware/task/client.d.ts +61 -12
- package/dist/hardware/task/client.d.ts.map +1 -1
- package/dist/hardware/task/payload.d.ts +18 -51
- package/dist/hardware/task/payload.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/label/client.d.ts +14 -9
- package/dist/label/client.d.ts.map +1 -1
- package/dist/label/payload.d.ts +10 -11
- package/dist/label/payload.d.ts.map +1 -1
- package/dist/ontology/client.d.ts +7 -3
- package/dist/ontology/client.d.ts.map +1 -1
- package/dist/ontology/group/client.d.ts +45 -9
- package/dist/ontology/group/client.d.ts.map +1 -1
- package/dist/ontology/group/external.d.ts +0 -1
- package/dist/ontology/group/external.d.ts.map +1 -1
- package/dist/ontology/group/payload.d.ts +3 -1
- package/dist/ontology/group/payload.d.ts.map +1 -1
- package/dist/ontology/payload.d.ts +30 -17
- package/dist/ontology/payload.d.ts.map +1 -1
- package/dist/ontology/writer.d.ts +161 -0
- package/dist/ontology/writer.d.ts.map +1 -1
- package/dist/ranger/alias.d.ts +1 -1
- package/dist/ranger/alias.d.ts.map +1 -1
- package/dist/ranger/client.d.ts +9 -8
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/kv.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts +5 -5
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts +6 -4
- package/dist/ranger/writer.d.ts.map +1 -1
- package/dist/status/client.d.ts +63 -0
- package/dist/status/client.d.ts.map +1 -0
- package/dist/status/external.d.ts +3 -0
- package/dist/status/external.d.ts.map +1 -0
- package/dist/status/index.d.ts +2 -0
- package/dist/status/index.d.ts.map +1 -0
- package/dist/status/payload.d.ts +32 -0
- package/dist/status/payload.d.ts.map +1 -0
- package/dist/status/status.spec.d.ts +2 -0
- package/dist/status/status.spec.d.ts.map +1 -0
- package/dist/user/client.d.ts.map +1 -1
- package/dist/user/retriever.d.ts.map +1 -1
- package/dist/workspace/client.d.ts +11 -6
- package/dist/workspace/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/client.d.ts +28 -5
- package/dist/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/workspace/lineplot/index.d.ts +1 -1
- package/dist/workspace/log/client.d.ts +28 -5
- package/dist/workspace/log/client.d.ts.map +1 -1
- package/dist/workspace/schematic/client.d.ts +35 -6
- package/dist/workspace/schematic/client.d.ts.map +1 -1
- package/dist/workspace/schematic/symbol/client.d.ts +6 -7
- package/dist/workspace/schematic/symbol/client.d.ts.map +1 -1
- package/dist/workspace/table/client.d.ts +28 -5
- package/dist/workspace/table/client.d.ts.map +1 -1
- package/examples/node/package-lock.json +30 -95
- package/examples/node/package.json +1 -1
- package/package.json +9 -9
- package/src/access/policy/client.ts +5 -6
- package/src/access/policy/payload.ts +4 -4
- package/src/access/policy/policy.spec.ts +4 -4
- package/src/arc/client.ts +117 -0
- package/src/{util/zod.ts → arc/external.ts} +2 -7
- package/src/arc/index.ts +10 -0
- package/src/arc/payload.ts +69 -0
- package/src/channel/client.ts +3 -4
- package/src/channel/payload.ts +4 -6
- package/src/channel/retriever.ts +2 -2
- package/src/client.ts +8 -2
- package/src/errors.spec.ts +1 -1
- package/src/framer/client.ts +4 -3
- package/src/framer/codec.spec.ts +1 -1
- package/src/hardware/device/client.ts +6 -8
- package/src/hardware/device/payload.ts +7 -6
- package/src/hardware/rack/client.ts +6 -8
- package/src/hardware/rack/payload.ts +2 -1
- package/src/hardware/task/client.ts +140 -100
- package/src/hardware/task/payload.ts +4 -4
- package/src/hardware/task/task.spec.ts +9 -2
- package/src/index.ts +3 -1
- package/src/label/client.ts +5 -8
- package/src/label/payload.ts +6 -11
- package/src/ontology/client.ts +3 -3
- package/src/ontology/group/client.ts +51 -18
- package/src/ontology/group/external.ts +0 -1
- package/src/ontology/group/group.spec.ts +6 -5
- package/src/ontology/group/payload.ts +5 -1
- package/src/ontology/ontology.spec.ts +88 -21
- package/src/ontology/payload.ts +15 -6
- package/src/ontology/writer.ts +3 -5
- package/src/ranger/alias.ts +2 -2
- package/src/ranger/client.ts +7 -3
- package/src/ranger/kv.ts +1 -2
- package/src/ranger/payload.ts +13 -1
- package/src/ranger/ranger.spec.ts +65 -1
- package/src/status/client.ts +129 -0
- package/src/status/external.ts +11 -0
- package/src/status/index.ts +10 -0
- package/src/status/payload.ts +35 -0
- package/src/status/status.spec.ts +352 -0
- package/src/user/client.ts +1 -2
- package/src/user/payload.ts +1 -1
- package/src/user/retriever.ts +2 -2
- package/src/user/user.spec.ts +41 -41
- package/src/workspace/client.ts +18 -15
- package/src/workspace/lineplot/client.ts +27 -13
- package/src/workspace/lineplot/index.ts +1 -1
- package/src/workspace/lineplot/lineplot.spec.ts +13 -10
- package/src/workspace/log/client.ts +26 -12
- package/src/workspace/log/log.spec.ts +13 -10
- package/src/workspace/payload.ts +1 -1
- package/src/workspace/schematic/client.ts +42 -17
- package/src/workspace/schematic/schematic.spec.ts +29 -25
- package/src/workspace/schematic/symbol/client.spec.ts +27 -24
- package/src/workspace/schematic/symbol/client.ts +6 -9
- package/src/workspace/table/client.ts +26 -12
- package/src/workspace/table/table.spec.ts +13 -10
- package/dist/ontology/group/group.d.ts +0 -10
- package/dist/ontology/group/group.d.ts.map +0 -1
- package/dist/ontology/group/writer.d.ts +0 -14
- package/dist/ontology/group/writer.d.ts.map +0 -1
- package/dist/util/zod.d.ts +0 -3
- package/dist/util/zod.d.ts.map +0 -1
- package/src/ontology/group/group.ts +0 -27
- package/src/ontology/group/writer.ts +0 -71
|
@@ -92,6 +92,7 @@ describe("Task", async () => {
|
|
|
92
92
|
const w = await client.openWriter([task.STATUS_CHANNEL_NAME]);
|
|
93
93
|
const communicatedStatus: task.Status = {
|
|
94
94
|
key: id.create(),
|
|
95
|
+
name: "test",
|
|
95
96
|
variant: "success",
|
|
96
97
|
details: { task: t.key, running: false, data: {} },
|
|
97
98
|
message: "test",
|
|
@@ -289,7 +290,11 @@ describe("Task", async () => {
|
|
|
289
290
|
type: "ni",
|
|
290
291
|
});
|
|
291
292
|
const streamer = await client.openStreamer(task.COMMAND_CHANNEL_NAME);
|
|
292
|
-
const key = await client.hardware.tasks.executeCommand(
|
|
293
|
+
const key = await client.hardware.tasks.executeCommand({
|
|
294
|
+
task: t.key,
|
|
295
|
+
type,
|
|
296
|
+
args,
|
|
297
|
+
});
|
|
293
298
|
await expect
|
|
294
299
|
.poll<Promise<task.Command>>(async () => {
|
|
295
300
|
const fr = await streamer.read();
|
|
@@ -305,7 +310,9 @@ describe("Task", async () => {
|
|
|
305
310
|
config: {},
|
|
306
311
|
type: "ni",
|
|
307
312
|
});
|
|
308
|
-
await expect(t.executeCommandSync("test", 0)).rejects.toThrow(
|
|
313
|
+
await expect(t.executeCommandSync({ type: "test", timeout: 0 })).rejects.toThrow(
|
|
314
|
+
"timed out",
|
|
315
|
+
);
|
|
309
316
|
});
|
|
310
317
|
});
|
|
311
318
|
});
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
export { access } from "@/access";
|
|
11
11
|
export { policy } from "@/access/policy";
|
|
12
|
+
export { arc } from "@/arc";
|
|
12
13
|
export { channel } from "@/channel";
|
|
13
14
|
export { Channel, isCalculated } from "@/channel/client";
|
|
14
15
|
export { default as Synnax, type SynnaxProps, synnaxPropsZ } from "@/client";
|
|
@@ -35,10 +36,11 @@ export { label } from "@/label";
|
|
|
35
36
|
export { ontology } from "@/ontology";
|
|
36
37
|
export { group } from "@/ontology/group";
|
|
37
38
|
export { ranger } from "@/ranger";
|
|
39
|
+
export { status } from "@/status";
|
|
38
40
|
export { createTestClient, TEST_CLIENT_PROPS } from "@/testutil/client";
|
|
39
41
|
export { user } from "@/user";
|
|
40
42
|
export { workspace } from "@/workspace";
|
|
41
|
-
export {
|
|
43
|
+
export { lineplot } from "@/workspace/lineplot";
|
|
42
44
|
export { log } from "@/workspace/log";
|
|
43
45
|
export { schematic } from "@/workspace/schematic";
|
|
44
46
|
export { table } from "@/workspace/table";
|
package/src/label/client.ts
CHANGED
|
@@ -14,7 +14,6 @@ import z from "zod";
|
|
|
14
14
|
import { type Key, keyZ, type Label, labelZ } from "@/label/payload";
|
|
15
15
|
import { ontology } from "@/ontology";
|
|
16
16
|
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
17
|
-
import { nullableArrayZ } from "@/util/zod";
|
|
18
17
|
|
|
19
18
|
export const SET_CHANNEL_NAME = "sy_label_set";
|
|
20
19
|
export const DELETE_CHANNEL_NAME = "sy_label_delete";
|
|
@@ -58,10 +57,10 @@ const singleRetrieveArgsZ = z
|
|
|
58
57
|
const retrieveArgsZ = z.union([singleRetrieveArgsZ, retrieveRequestZ]);
|
|
59
58
|
|
|
60
59
|
export type RetrieveArgs = z.input<typeof retrieveArgsZ>;
|
|
61
|
-
export type
|
|
62
|
-
export type
|
|
60
|
+
export type RetrieveSingleParams = z.input<typeof singleRetrieveArgsZ>;
|
|
61
|
+
export type RetrieveMultipleParams = z.input<typeof retrieveRequestZ>;
|
|
63
62
|
|
|
64
|
-
const retrieveResponseZ = z.object({ labels:
|
|
63
|
+
const retrieveResponseZ = z.object({ labels: array.nullableZ(labelZ) });
|
|
65
64
|
|
|
66
65
|
export class Client {
|
|
67
66
|
readonly type: string = "label";
|
|
@@ -71,8 +70,8 @@ export class Client {
|
|
|
71
70
|
this.client = client;
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
async retrieve(args:
|
|
75
|
-
async retrieve(args:
|
|
73
|
+
async retrieve(args: RetrieveSingleParams): Promise<Label>;
|
|
74
|
+
async retrieve(args: RetrieveMultipleParams): Promise<Label[]>;
|
|
76
75
|
async retrieve(args: RetrieveArgs): Promise<Label | Label[]> {
|
|
77
76
|
const isSingle = "key" in args;
|
|
78
77
|
const res = await sendRequired(
|
|
@@ -120,8 +119,6 @@ export class Client {
|
|
|
120
119
|
return isMany ? res.labels : res.labels[0];
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
async delete(key: Key): Promise<void>;
|
|
124
|
-
async delete(keys: Key[]): Promise<void>;
|
|
125
122
|
async delete(keys: Key | Key[]): Promise<void> {
|
|
126
123
|
await sendRequired<typeof deleteReqZ, typeof emptyResZ>(
|
|
127
124
|
this.client,
|
package/src/label/payload.ts
CHANGED
|
@@ -7,18 +7,13 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { label } from "@synnaxlabs/x";
|
|
11
11
|
|
|
12
|
-
export
|
|
13
|
-
export type Key = z.infer<typeof keyZ>;
|
|
12
|
+
export type Params = label.Key | label.Key[];
|
|
14
13
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
export const labelZ =
|
|
18
|
-
|
|
19
|
-
name: z.string().min(1),
|
|
20
|
-
color: z.string(),
|
|
21
|
-
});
|
|
22
|
-
export interface Label extends z.infer<typeof labelZ> {}
|
|
14
|
+
export const keyZ = label.keyZ;
|
|
15
|
+
export type Key = label.Key;
|
|
16
|
+
export const labelZ = label.labelZ;
|
|
17
|
+
export type Label = label.Label;
|
|
23
18
|
|
|
24
19
|
export const LABELED_BY_ONTOLOGY_RELATIONSHIP_TYPE = "labeled_by";
|
package/src/ontology/client.ts
CHANGED
|
@@ -71,7 +71,7 @@ export class Client {
|
|
|
71
71
|
* @returns The resource with the given ID.
|
|
72
72
|
* @throws {QueryError} If no resource is found with the given ID.
|
|
73
73
|
*/
|
|
74
|
-
async retrieve(id: ID
|
|
74
|
+
async retrieve(id: ID, options?: RetrieveOptions): Promise<Resource>;
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Retrieves the resources in the ontology with the given IDs.
|
|
@@ -83,12 +83,12 @@ export class Client {
|
|
|
83
83
|
* @returns The resources with the given IDs.
|
|
84
84
|
* @throws {QueryError} If no resource is found with any of the given IDs.
|
|
85
85
|
*/
|
|
86
|
-
async retrieve(ids: ID[]
|
|
86
|
+
async retrieve(ids: ID[], options?: RetrieveOptions): Promise<Resource[]>;
|
|
87
87
|
|
|
88
88
|
async retrieve(params: RetrieveRequest): Promise<Resource[]>;
|
|
89
89
|
|
|
90
90
|
async retrieve(
|
|
91
|
-
ids: ID | ID[] |
|
|
91
|
+
ids: ID | ID[] | RetrieveRequest,
|
|
92
92
|
options?: RetrieveOptions,
|
|
93
93
|
): Promise<Resource | Resource[]> {
|
|
94
94
|
if (!Array.isArray(ids) && typeof ids === "object" && !("key" in ids))
|
|
@@ -7,36 +7,69 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { type UnaryClient } from "@synnaxlabs/freighter";
|
|
10
|
+
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { array } from "@synnaxlabs/x";
|
|
12
|
+
import z from "zod";
|
|
11
13
|
|
|
12
|
-
import { type
|
|
13
|
-
import {
|
|
14
|
-
import { type Key, type Name, type Payload } from "@/ontology/group/payload";
|
|
15
|
-
import { Writer } from "@/ontology/group/writer";
|
|
14
|
+
import { type Group, groupZ, type Key, keyZ } from "@/ontology/group/payload";
|
|
15
|
+
import { idZ as ontologyIDZ } from "@/ontology/payload";
|
|
16
16
|
|
|
17
17
|
export const SET_CHANNEL_NAME = "sy_group_set";
|
|
18
18
|
export const DELETE_CHANNEL_NAME = "sy_group_delete";
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
private readonly creator: Writer;
|
|
20
|
+
const resZ = z.object({ group: groupZ });
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const createReqZ = z.object({
|
|
23
|
+
parent: ontologyIDZ,
|
|
24
|
+
key: keyZ.optional(),
|
|
25
|
+
name: z.string(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const renameReqZ = z.object({ key: keyZ, name: z.string() });
|
|
29
|
+
|
|
30
|
+
const deleteReqZ = z.object({ keys: z.array(keyZ) });
|
|
31
|
+
|
|
32
|
+
const CREATE_ENDPOINT = "/ontology/create-group";
|
|
33
|
+
const RENAME_ENDPOINT = "/ontology/rename-group";
|
|
34
|
+
const DELETE_ENDPOINT = "/ontology/delete-group";
|
|
35
|
+
|
|
36
|
+
export interface CreateArgs extends z.infer<typeof createReqZ> {}
|
|
37
|
+
|
|
38
|
+
export class Client {
|
|
39
|
+
client: UnaryClient;
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
constructor(client: UnaryClient) {
|
|
42
|
+
this.client = client;
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
async
|
|
32
|
-
|
|
45
|
+
async create(args: CreateArgs): Promise<Group> {
|
|
46
|
+
const res = await sendRequired(
|
|
47
|
+
this.client,
|
|
48
|
+
CREATE_ENDPOINT,
|
|
49
|
+
args,
|
|
50
|
+
createReqZ,
|
|
51
|
+
resZ,
|
|
52
|
+
);
|
|
53
|
+
return res.group;
|
|
33
54
|
}
|
|
34
55
|
|
|
35
|
-
async
|
|
36
|
-
|
|
56
|
+
async rename(key: Key, name: string): Promise<void> {
|
|
57
|
+
await sendRequired(
|
|
58
|
+
this.client,
|
|
59
|
+
RENAME_ENDPOINT,
|
|
60
|
+
{ key, name },
|
|
61
|
+
renameReqZ,
|
|
62
|
+
z.object({}),
|
|
63
|
+
);
|
|
37
64
|
}
|
|
38
65
|
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
async delete(keys: Key | Key[]): Promise<void> {
|
|
67
|
+
await sendRequired(
|
|
68
|
+
this.client,
|
|
69
|
+
DELETE_ENDPOINT,
|
|
70
|
+
{ keys: array.toArray(keys) },
|
|
71
|
+
deleteReqZ,
|
|
72
|
+
z.object({}),
|
|
73
|
+
);
|
|
41
74
|
}
|
|
42
75
|
}
|
|
@@ -11,6 +11,7 @@ import { describe, expect, it } from "vitest";
|
|
|
11
11
|
|
|
12
12
|
import { NotFoundError } from "@/errors";
|
|
13
13
|
import { ontology } from "@/ontology";
|
|
14
|
+
import { group } from "@/ontology/group";
|
|
14
15
|
import { createTestClient } from "@/testutil/client";
|
|
15
16
|
|
|
16
17
|
const client = createTestClient();
|
|
@@ -19,27 +20,27 @@ describe("Group", () => {
|
|
|
19
20
|
describe("create", () => {
|
|
20
21
|
it("should correctly create a group", async () => {
|
|
21
22
|
const name = `group-${Math.random()}`;
|
|
22
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
23
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
23
24
|
expect(g.name).toEqual(name);
|
|
24
25
|
});
|
|
25
26
|
});
|
|
26
27
|
describe("rename", () => {
|
|
27
28
|
it("should correctly rename a group", async () => {
|
|
28
29
|
const name = `group-${Math.random()}`;
|
|
29
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
30
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
30
31
|
const newName = `group-${Math.random()}`;
|
|
31
32
|
await client.ontology.groups.rename(g.key, newName);
|
|
32
|
-
const g2 = await client.ontology.retrieve(g.
|
|
33
|
+
const g2 = await client.ontology.retrieve(group.ontologyID(g.key));
|
|
33
34
|
expect(g2.name).toEqual(newName);
|
|
34
35
|
});
|
|
35
36
|
});
|
|
36
37
|
describe("delete", () => {
|
|
37
38
|
it("should correctly delete the group", async () => {
|
|
38
39
|
const name = `group-${Math.random()}`;
|
|
39
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
40
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
40
41
|
await client.ontology.groups.delete(g.key);
|
|
41
42
|
await expect(
|
|
42
|
-
async () => await client.ontology.retrieve(g.
|
|
43
|
+
async () => await client.ontology.retrieve(group.ontologyID(g.key)),
|
|
43
44
|
).rejects.toThrowError(NotFoundError);
|
|
44
45
|
});
|
|
45
46
|
});
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
|
+
import { type ID as OntologyID } from "@/ontology/payload";
|
|
13
|
+
|
|
12
14
|
export const keyZ = z.uuid();
|
|
13
15
|
export type Key = z.infer<typeof keyZ>;
|
|
14
16
|
export const nameZ = z.string();
|
|
@@ -17,4 +19,6 @@ export type Keys = Key[];
|
|
|
17
19
|
export type Names = Name[];
|
|
18
20
|
export type Params = Key | Name | Keys | Names;
|
|
19
21
|
export const groupZ = z.object({ key: keyZ, name: nameZ });
|
|
20
|
-
export interface
|
|
22
|
+
export interface Group extends z.infer<typeof groupZ> {}
|
|
23
|
+
|
|
24
|
+
export const ontologyID = (key: Key): OntologyID => ({ type: "group", key });
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { describe, expect, it, test } from "vitest";
|
|
11
11
|
|
|
12
12
|
import { ontology } from "@/ontology";
|
|
13
|
+
import { group } from "@/ontology/group";
|
|
13
14
|
import { createTestClient } from "@/testutil/client";
|
|
14
15
|
|
|
15
16
|
const client = createTestClient();
|
|
@@ -125,59 +126,88 @@ describe("Ontology", () => {
|
|
|
125
126
|
describe("retrieve", () => {
|
|
126
127
|
test("retrieve", async () => {
|
|
127
128
|
const name = randomName();
|
|
128
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
129
|
-
const g2 = await client.ontology.retrieve(g.
|
|
129
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
130
|
+
const g2 = await client.ontology.retrieve(group.ontologyID(g.key));
|
|
130
131
|
expect(g2.name).toEqual(name);
|
|
131
132
|
});
|
|
132
133
|
test("retrieve children", async () => {
|
|
133
134
|
const name = randomName();
|
|
134
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
135
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
135
136
|
const name2 = randomName();
|
|
136
|
-
await client.ontology.groups.create(
|
|
137
|
-
|
|
137
|
+
await client.ontology.groups.create({
|
|
138
|
+
parent: group.ontologyID(g.key),
|
|
139
|
+
name: name2,
|
|
140
|
+
});
|
|
141
|
+
const children = await client.ontology.retrieveChildren(group.ontologyID(g.key));
|
|
138
142
|
expect(children.length).toEqual(1);
|
|
139
143
|
expect(children[0].name).toEqual(name2);
|
|
140
144
|
});
|
|
141
145
|
test("retrieve parents", async () => {
|
|
142
146
|
const name = randomName();
|
|
143
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
147
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
144
148
|
const name2 = randomName();
|
|
145
|
-
const g2 = await client.ontology.groups.create(
|
|
146
|
-
|
|
149
|
+
const g2 = await client.ontology.groups.create({
|
|
150
|
+
parent: group.ontologyID(g.key),
|
|
151
|
+
name: name2,
|
|
152
|
+
});
|
|
153
|
+
const parents = await client.ontology.retrieveParents(group.ontologyID(g2.key));
|
|
147
154
|
expect(parents.length).toEqual(1);
|
|
148
155
|
expect(parents[0].name).toEqual(name);
|
|
149
156
|
});
|
|
150
157
|
});
|
|
158
|
+
|
|
151
159
|
describe("write", () => {
|
|
152
160
|
test("add children", async () => {
|
|
153
161
|
const name = randomName();
|
|
154
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
162
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
155
163
|
const name2 = randomName();
|
|
156
|
-
const g2 = await client.ontology.groups.create(
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
const g2 = await client.ontology.groups.create({
|
|
165
|
+
parent: ontology.ROOT_ID,
|
|
166
|
+
name: name2,
|
|
167
|
+
});
|
|
168
|
+
await client.ontology.addChildren(
|
|
169
|
+
group.ontologyID(g.key),
|
|
170
|
+
group.ontologyID(g2.key),
|
|
171
|
+
);
|
|
172
|
+
const children = await client.ontology.retrieveChildren(group.ontologyID(g.key));
|
|
159
173
|
expect(children.length).toEqual(1);
|
|
160
174
|
expect(children[0].name).toEqual(name2);
|
|
161
175
|
});
|
|
162
176
|
test("remove children", async () => {
|
|
163
177
|
const name = randomName();
|
|
164
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
178
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
165
179
|
const name2 = randomName();
|
|
166
|
-
const g2 = await client.ontology.groups.create(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
const g2 = await client.ontology.groups.create({
|
|
181
|
+
parent: ontology.ROOT_ID,
|
|
182
|
+
name: name2,
|
|
183
|
+
});
|
|
184
|
+
await client.ontology.addChildren(
|
|
185
|
+
group.ontologyID(g.key),
|
|
186
|
+
group.ontologyID(g2.key),
|
|
187
|
+
);
|
|
188
|
+
await client.ontology.removeChildren(
|
|
189
|
+
group.ontologyID(g.key),
|
|
190
|
+
group.ontologyID(g2.key),
|
|
191
|
+
);
|
|
192
|
+
const children = await client.ontology.retrieveChildren(group.ontologyID(g.key));
|
|
170
193
|
expect(children.length).toEqual(0);
|
|
171
194
|
});
|
|
172
195
|
test("move children", async () => {
|
|
173
196
|
const name = randomName();
|
|
174
|
-
const g = await client.ontology.groups.create(ontology.ROOT_ID, name);
|
|
197
|
+
const g = await client.ontology.groups.create({ parent: ontology.ROOT_ID, name });
|
|
175
198
|
const name2 = randomName();
|
|
176
|
-
const g2 = await client.ontology.groups.create(
|
|
199
|
+
const g2 = await client.ontology.groups.create({
|
|
200
|
+
parent: ontology.ROOT_ID,
|
|
201
|
+
name: name2,
|
|
202
|
+
});
|
|
177
203
|
const oldRootLength = (await client.ontology.retrieveChildren(ontology.ROOT_ID))
|
|
178
204
|
.length;
|
|
179
|
-
await client.ontology.moveChildren(
|
|
180
|
-
|
|
205
|
+
await client.ontology.moveChildren(
|
|
206
|
+
ontology.ROOT_ID,
|
|
207
|
+
group.ontologyID(g.key),
|
|
208
|
+
group.ontologyID(g2.key),
|
|
209
|
+
);
|
|
210
|
+
const children = await client.ontology.retrieveChildren(group.ontologyID(g.key));
|
|
181
211
|
expect(children.length).toEqual(1);
|
|
182
212
|
const newRootLength = (await client.ontology.retrieveChildren(ontology.ROOT_ID))
|
|
183
213
|
.length;
|
|
@@ -439,4 +469,41 @@ describe("Ontology", () => {
|
|
|
439
469
|
});
|
|
440
470
|
});
|
|
441
471
|
});
|
|
472
|
+
|
|
473
|
+
describe("idToString", () => {
|
|
474
|
+
it("should convert an ID to a string", () => {
|
|
475
|
+
const result = ontology.idToString({ type: "group", key: "one" });
|
|
476
|
+
expect(result).toEqual("group:one");
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it("should convert an array of IDs to strings", () => {
|
|
480
|
+
const result = ontology.idToString([
|
|
481
|
+
{ type: "group", key: "one" },
|
|
482
|
+
{ type: "channel", key: "two" },
|
|
483
|
+
]);
|
|
484
|
+
expect(result).toEqual(["group:one", "channel:two"]);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it("should pass through string IDs", () => {
|
|
488
|
+
const result = ontology.idToString("group:one");
|
|
489
|
+
expect(result).toEqual("group:one");
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("should validate string IDs that get passed", () => {
|
|
493
|
+
expect(() => {
|
|
494
|
+
ontology.idToString("dog");
|
|
495
|
+
}).toThrow();
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it("should pass through an array of string IDs", () => {
|
|
499
|
+
const result = ontology.idToString(["group:one", "channel:two"]);
|
|
500
|
+
expect(result).toEqual(["group:one", "channel:two"]);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it("should validate an array of string IDs that get passed", () => {
|
|
504
|
+
expect(() => {
|
|
505
|
+
ontology.idToString(["group:one", "channel:two", "dog"]);
|
|
506
|
+
}).toThrow();
|
|
507
|
+
});
|
|
508
|
+
});
|
|
442
509
|
});
|
package/src/ontology/payload.ts
CHANGED
|
@@ -17,9 +17,7 @@ export type RelationshipChange = change.Change<Relationship, undefined>;
|
|
|
17
17
|
export interface RelationshipSet extends change.Set<Relationship, undefined> {}
|
|
18
18
|
export interface RelationshipDelete extends change.Delete<Relationship, undefined> {}
|
|
19
19
|
|
|
20
|
-
export
|
|
21
|
-
export const CLUSTER_TYPE = "cluster";
|
|
22
|
-
export const NODE_TYPE = "node";
|
|
20
|
+
export interface RelationshipDelete extends change.Delete<Relationship, undefined> {}
|
|
23
21
|
|
|
24
22
|
export const resourceTypeZ = z.enum([
|
|
25
23
|
"label",
|
|
@@ -42,7 +40,9 @@ export const resourceTypeZ = z.enum([
|
|
|
42
40
|
"task",
|
|
43
41
|
"policy",
|
|
44
42
|
"table",
|
|
43
|
+
"arc",
|
|
45
44
|
"schematic_symbol",
|
|
45
|
+
"status",
|
|
46
46
|
]);
|
|
47
47
|
export type ResourceType = z.infer<typeof resourceTypeZ>;
|
|
48
48
|
|
|
@@ -55,14 +55,23 @@ export const idZ = z.object({ type: resourceTypeZ, key: z.string() }).or(stringI
|
|
|
55
55
|
|
|
56
56
|
export type ID = z.infer<typeof idZ>;
|
|
57
57
|
|
|
58
|
-
export const ROOT_ID: ID = { type:
|
|
58
|
+
export const ROOT_ID: ID = { type: "builtin", key: "root" };
|
|
59
|
+
|
|
60
|
+
export interface IDToString {
|
|
61
|
+
(id: ID | string): string;
|
|
62
|
+
(ids: (ID | string)[]): string[];
|
|
63
|
+
}
|
|
59
64
|
|
|
60
|
-
export const idToString = (id: ID) =>
|
|
65
|
+
export const idToString = ((id: ID | string | (ID | string)[]) => {
|
|
66
|
+
if (typeof id === "string") id = stringIDZ.parse(id);
|
|
67
|
+
if (Array.isArray(id)) return id.map((id) => idToString(id));
|
|
68
|
+
return `${id.type}:${id.key}`;
|
|
69
|
+
}) as IDToString;
|
|
61
70
|
|
|
62
71
|
export const idsEqual = (a: ID, b: ID) => a.type === b.type && a.key === b.key;
|
|
63
72
|
|
|
64
73
|
export const parseIDs = (
|
|
65
|
-
ids: ID |
|
|
74
|
+
ids: ID | string | Resource | (ID | string | Resource)[],
|
|
66
75
|
): ID[] => {
|
|
67
76
|
const arr = array.toArray(ids);
|
|
68
77
|
if (arr.length === 0) return [];
|
package/src/ontology/writer.ts
CHANGED
|
@@ -16,11 +16,9 @@ const ADD_CHILDREN_ENDPOINT = "/ontology/add-children";
|
|
|
16
16
|
const REMOVE_CHILDREN_ENDPOINT = "/ontology/remove-children";
|
|
17
17
|
const MOVE_CHILDREN_ENDPOINT = "/ontology/move-children";
|
|
18
18
|
|
|
19
|
-
const addRemoveChildrenReqZ = z.object({ id: idZ, children: idZ.array() });
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const emptyResZ = z.object({});
|
|
19
|
+
export const addRemoveChildrenReqZ = z.object({ id: idZ, children: idZ.array() });
|
|
20
|
+
export const moveChildrenReqZ = z.object({ from: idZ, to: idZ, children: idZ.array() });
|
|
21
|
+
export const emptyResZ = z.object({});
|
|
24
22
|
|
|
25
23
|
export class Writer {
|
|
26
24
|
client: UnaryClient;
|
package/src/ranger/alias.ts
CHANGED
|
@@ -128,11 +128,11 @@ export class Aliaser {
|
|
|
128
128
|
return isSingle ? res.aliases[alias] : res.aliases;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
async delete(aliases: channel.Key[]): Promise<void> {
|
|
131
|
+
async delete(aliases: channel.Key | channel.Key[]): Promise<void> {
|
|
132
132
|
await sendRequired<typeof deleteReqZ, typeof deleteResZ>(
|
|
133
133
|
this.client,
|
|
134
134
|
Aliaser.DELETE_ENDPOINT,
|
|
135
|
-
{ range: this.rangeKey, channels: aliases },
|
|
135
|
+
{ range: this.rangeKey, channels: array.toArray(aliases) },
|
|
136
136
|
deleteReqZ,
|
|
137
137
|
deleteResZ,
|
|
138
138
|
);
|
package/src/ranger/client.ts
CHANGED
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
} from "@/ranger/payload";
|
|
33
33
|
import { type CreateOptions, type Writer } from "@/ranger/writer";
|
|
34
34
|
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
35
|
-
import { nullableArrayZ } from "@/util/zod";
|
|
36
35
|
|
|
37
36
|
export const SET_CHANNEL_NAME = "sy_range_set";
|
|
38
37
|
export const DELETE_CHANNEL_NAME = "sy_range_delete";
|
|
@@ -193,7 +192,7 @@ export type RetrieveArgs = z.input<typeof retrieveArgsZ>;
|
|
|
193
192
|
|
|
194
193
|
const RETRIEVE_ENDPOINT = "/range/retrieve";
|
|
195
194
|
|
|
196
|
-
const retrieveResZ = z.object({ ranges:
|
|
195
|
+
const retrieveResZ = z.object({ ranges: array.nullableZ(payloadZ) });
|
|
197
196
|
|
|
198
197
|
export class Client {
|
|
199
198
|
readonly type: string = "range";
|
|
@@ -240,7 +239,7 @@ export class Client {
|
|
|
240
239
|
|
|
241
240
|
async retrieve(params: Key | Name): Promise<Range>;
|
|
242
241
|
async retrieve(params: Keys | Names): Promise<Range[]>;
|
|
243
|
-
async retrieve(params:
|
|
242
|
+
async retrieve(params: CrudeTimeRange): Promise<Range[]>;
|
|
244
243
|
async retrieve(params: RetrieveRequest): Promise<Range[]>;
|
|
245
244
|
async retrieve(params: RetrieveArgs): Promise<Range | Range[]> {
|
|
246
245
|
const isSingle = typeof params === "string";
|
|
@@ -295,6 +294,11 @@ export class Client {
|
|
|
295
294
|
await aliaser.set({ [channel]: alias });
|
|
296
295
|
}
|
|
297
296
|
|
|
297
|
+
async deleteAlias(range: Key, channels: channel.Key | channel.Key[]): Promise<void> {
|
|
298
|
+
const aliaser = new Aliaser(range, this.frameClient, this.unaryClient);
|
|
299
|
+
await aliaser.delete(channels);
|
|
300
|
+
}
|
|
301
|
+
|
|
298
302
|
sugarOne(payload: Payload): Range {
|
|
299
303
|
return new Range(payload, {
|
|
300
304
|
frameClient: this.frameClient,
|
package/src/ranger/kv.ts
CHANGED
|
@@ -13,7 +13,6 @@ import { isObject } from "@synnaxlabs/x/identity";
|
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
15
|
import { type Key, keyZ } from "@/ranger/payload";
|
|
16
|
-
import { nullableArrayZ } from "@/util/zod";
|
|
17
16
|
|
|
18
17
|
export const KV_SET_CHANNEL = "sy_range_kv_set";
|
|
19
18
|
export const KV_DELETE_CHANNEL = "sy_range_kv_delete";
|
|
@@ -27,7 +26,7 @@ export const kvPairKey = ({ range, key }: Omit<KVPair, "value">) =>
|
|
|
27
26
|
const getReqZ = z.object({ range: keyZ, keys: z.string().array() });
|
|
28
27
|
export interface GetRequest extends z.infer<typeof getReqZ> {}
|
|
29
28
|
|
|
30
|
-
const getResZ = z.object({ pairs:
|
|
29
|
+
const getResZ = z.object({ pairs: array.nullableZ(kvPairZ) });
|
|
31
30
|
|
|
32
31
|
const setReqZ = z.object({ range: keyZ, pairs: kvPairZ.array() });
|
|
33
32
|
export interface SetRequest extends z.infer<typeof setReqZ> {}
|
package/src/ranger/payload.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
+
import { math } from "@synnaxlabs/x";
|
|
10
11
|
import { TimeRange } from "@synnaxlabs/x/telem";
|
|
11
12
|
import { z } from "zod";
|
|
12
13
|
|
|
@@ -23,7 +24,18 @@ export type Params = Key | Name | Keys | Names;
|
|
|
23
24
|
export const payloadZ = z.object({
|
|
24
25
|
key: keyZ,
|
|
25
26
|
name: nameZ,
|
|
26
|
-
timeRange: TimeRange.z
|
|
27
|
+
timeRange: TimeRange.z
|
|
28
|
+
.refine(({ isValid }) => isValid, {
|
|
29
|
+
error: "Time range start time must be before or equal to time range end time",
|
|
30
|
+
})
|
|
31
|
+
.refine(({ end }) => end.valueOf() <= math.MAX_INT64, {
|
|
32
|
+
error:
|
|
33
|
+
"Time range end time must be less than or equal to the maximum value of an int64",
|
|
34
|
+
})
|
|
35
|
+
.refine(({ start }) => start.valueOf() >= math.MIN_INT64, {
|
|
36
|
+
error:
|
|
37
|
+
"Time range start time must be greater than or equal to the minimum value of an int64",
|
|
38
|
+
}),
|
|
27
39
|
color: z.string().optional(),
|
|
28
40
|
labels: label.labelZ
|
|
29
41
|
.array()
|