@synnaxlabs/client 0.44.1 → 0.44.2
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 +5 -5
- package/dist/channel/client.d.ts +11 -4
- package/dist/channel/client.d.ts.map +1 -1
- package/dist/channel/payload.d.ts +86 -14
- package/dist/channel/payload.d.ts.map +1 -1
- package/dist/channel/writer.d.ts.map +1 -1
- package/dist/client.cjs +20 -20
- package/dist/client.js +1803 -1764
- package/dist/framer/streamer.d.ts +96 -0
- package/dist/framer/streamer.d.ts.map +1 -1
- package/dist/framer/writer.d.ts +80 -0
- package/dist/framer/writer.d.ts.map +1 -1
- package/dist/hardware/device/payload.d.ts +4 -4
- package/dist/hardware/rack/payload.d.ts +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/ontology/payload.d.ts +1 -0
- package/dist/ontology/payload.d.ts.map +1 -1
- package/dist/ranger/alias.d.ts +5 -1
- package/dist/ranger/alias.d.ts.map +1 -1
- package/dist/ranger/client.d.ts +5 -1
- package/dist/ranger/client.d.ts.map +1 -1
- package/dist/ranger/external.d.ts +1 -1
- package/dist/ranger/external.d.ts.map +1 -1
- package/dist/ranger/kv.d.ts +1 -0
- package/dist/ranger/kv.d.ts.map +1 -1
- package/dist/ranger/payload.d.ts +3 -7
- package/dist/ranger/payload.d.ts.map +1 -1
- package/dist/ranger/writer.d.ts +1 -1
- package/dist/testutil/client.d.ts +1 -1
- package/dist/testutil/client.d.ts.map +1 -1
- package/dist/workspace/payload.d.ts +1 -1
- package/package.json +2 -2
- package/src/access/policy/policy.spec.ts +3 -3
- package/src/channel/channel.spec.ts +2 -2
- package/src/channel/client.ts +21 -5
- package/src/channel/payload.ts +4 -4
- package/src/channel/writer.ts +4 -1
- package/src/control/state.spec.ts +2 -2
- package/src/errors.spec.ts +2 -2
- package/src/framer/adapter.spec.ts +2 -2
- package/src/framer/client.spec.ts +2 -2
- package/src/framer/deleter.spec.ts +2 -2
- package/src/framer/iterator.spec.ts +2 -2
- package/src/framer/streamer.spec.ts +2 -2
- package/src/framer/writer.spec.ts +3 -2
- package/src/hardware/device/device.spec.ts +2 -2
- package/src/hardware/rack/rack.spec.ts +2 -2
- package/src/hardware/task/task.spec.ts +2 -2
- package/src/index.ts +1 -1
- package/src/label/label.spec.ts +2 -2
- package/src/ontology/group/group.spec.ts +2 -2
- package/src/ontology/ontology.spec.ts +2 -2
- package/src/ontology/payload.ts +3 -0
- package/src/ranger/alias.ts +27 -1
- package/src/ranger/client.ts +30 -3
- package/src/ranger/external.ts +1 -9
- package/src/ranger/kv.ts +3 -0
- package/src/ranger/payload.ts +4 -2
- package/src/ranger/ranger.spec.ts +3 -3
- package/src/testutil/client.ts +1 -1
- package/src/user/user.spec.ts +2 -2
- package/src/workspace/lineplot/lineplot.spec.ts +2 -2
- package/src/workspace/log/log.spec.ts +2 -2
- package/src/workspace/schematic/schematic.spec.ts +2 -2
- package/src/workspace/table/table.spec.ts +2 -2
- package/src/workspace/workspace.spec.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { default as Synnax, SynnaxProps } from '../client';
|
|
2
2
|
export declare const TEST_CLIENT_PROPS: SynnaxProps;
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const createTestClient: (props?: Partial<SynnaxProps>) => Synnax;
|
|
4
4
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/testutil/client.ts"],"names":[],"mappings":"AASA,OAAO,MAAM,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAE,WAK/B,CAAC;AAEF,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/testutil/client.ts"],"names":[],"mappings":"AASA,OAAO,MAAM,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAE,WAK/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,CAAC,WAAW,CAAC,KAAG,MAChB,CAAC"}
|
|
@@ -26,8 +26,8 @@ export declare const newZ: z.ZodPipe<z.ZodObject<{
|
|
|
26
26
|
export interface New extends z.input<typeof newZ> {
|
|
27
27
|
}
|
|
28
28
|
export declare const remoteZ: z.ZodObject<{
|
|
29
|
-
name: z.ZodString;
|
|
30
29
|
key: z.ZodUUID;
|
|
30
|
+
name: z.ZodString;
|
|
31
31
|
layout: z.ZodPipe<z.ZodString, z.ZodTransform<record.Unknown, string>>;
|
|
32
32
|
}, z.core.$strip>;
|
|
33
33
|
//# sourceMappingURL=payload.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synnaxlabs/client",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.2",
|
|
4
4
|
"description": "The Synnax Client Library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"synnax",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"async-mutex": "^0.5.0",
|
|
28
28
|
"zod": "^4.0.2",
|
|
29
29
|
"@synnaxlabs/freighter": "^0.44.0",
|
|
30
|
-
"@synnaxlabs/x": "^0.44.
|
|
30
|
+
"@synnaxlabs/x": "^0.44.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@vitest/coverage-v8": "^3.2.4",
|
|
@@ -12,10 +12,10 @@ import { describe, expect, test } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { type policy } from "@/access/policy";
|
|
14
14
|
import { AuthError } from "@/errors";
|
|
15
|
-
import {
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
16
|
import { user } from "@/user";
|
|
17
17
|
|
|
18
|
-
const client =
|
|
18
|
+
const client = createTestClient();
|
|
19
19
|
|
|
20
20
|
describe("Policy", () => {
|
|
21
21
|
describe("create", () => {
|
|
@@ -299,7 +299,7 @@ describe("privilege", async () => {
|
|
|
299
299
|
const username = id.create();
|
|
300
300
|
const user2 = await client.user.create({ username, password: "pwd1" });
|
|
301
301
|
expect(user2).toBeDefined();
|
|
302
|
-
const client2 =
|
|
302
|
+
const client2 = createTestClient({ username: user2.username, password: "pwd1" });
|
|
303
303
|
await expect(
|
|
304
304
|
client2.user.create({ username: id.create(), password: id.create() }),
|
|
305
305
|
).rejects.toThrow(AuthError);
|
|
@@ -12,9 +12,9 @@ import { beforeAll, describe, expect, it, test } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { Channel } from "@/channel/client";
|
|
14
14
|
import { NotFoundError, PathError } from "@/errors";
|
|
15
|
-
import {
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
16
|
|
|
17
|
-
const client =
|
|
17
|
+
const client = createTestClient();
|
|
18
18
|
|
|
19
19
|
describe("Channel", () => {
|
|
20
20
|
describe("create", () => {
|
package/src/channel/client.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
-
import { array } from "@synnaxlabs/x";
|
|
11
|
+
import { array, status } from "@synnaxlabs/x";
|
|
12
12
|
import {
|
|
13
13
|
type CrudeDensity,
|
|
14
14
|
type CrudeTimeStamp,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
type Params,
|
|
28
28
|
type Payload,
|
|
29
29
|
payloadZ,
|
|
30
|
+
type Status,
|
|
30
31
|
} from "@/channel/payload";
|
|
31
32
|
import {
|
|
32
33
|
analyzeParams,
|
|
@@ -99,7 +100,7 @@ export class Channel {
|
|
|
99
100
|
* An alias for the channel under a specific range. This parameter is unstable and
|
|
100
101
|
* should not be relied upon in the current version of Synnax.
|
|
101
102
|
*/
|
|
102
|
-
|
|
103
|
+
alias: string | undefined;
|
|
103
104
|
/**
|
|
104
105
|
* Whether the channel is virtual. Virtual channels do not store any data in the
|
|
105
106
|
* database, but can still be used for streaming purposes.
|
|
@@ -114,6 +115,10 @@ export class Channel {
|
|
|
114
115
|
* Only used for calculated channels. Specifies the channels required for calculation
|
|
115
116
|
*/
|
|
116
117
|
readonly requires: Key[];
|
|
118
|
+
/**
|
|
119
|
+
* The status of the channel.
|
|
120
|
+
*/
|
|
121
|
+
readonly status?: Status;
|
|
117
122
|
|
|
118
123
|
constructor({
|
|
119
124
|
dataType,
|
|
@@ -126,9 +131,14 @@ export class Channel {
|
|
|
126
131
|
virtual = false,
|
|
127
132
|
frameClient,
|
|
128
133
|
alias,
|
|
134
|
+
status: argsStatus,
|
|
129
135
|
expression = "",
|
|
130
136
|
requires = [],
|
|
131
|
-
}: New & {
|
|
137
|
+
}: New & {
|
|
138
|
+
frameClient?: framer.Client;
|
|
139
|
+
density?: CrudeDensity;
|
|
140
|
+
status?: status.Crude;
|
|
141
|
+
}) {
|
|
132
142
|
this.key = key;
|
|
133
143
|
this.name = name;
|
|
134
144
|
this.dataType = new DataType(dataType);
|
|
@@ -140,6 +150,7 @@ export class Channel {
|
|
|
140
150
|
this.virtual = virtual;
|
|
141
151
|
this.expression = expression;
|
|
142
152
|
this.requires = requires ?? [];
|
|
153
|
+
if (argsStatus != null) this.status = status.create(argsStatus);
|
|
143
154
|
this._frameClient = frameClient ?? null;
|
|
144
155
|
}
|
|
145
156
|
|
|
@@ -166,6 +177,7 @@ export class Channel {
|
|
|
166
177
|
virtual: this.virtual,
|
|
167
178
|
expression: this.expression,
|
|
168
179
|
requires: this.requires,
|
|
180
|
+
status: this.status,
|
|
169
181
|
});
|
|
170
182
|
}
|
|
171
183
|
|
|
@@ -397,9 +409,13 @@ export class Client {
|
|
|
397
409
|
);
|
|
398
410
|
}
|
|
399
411
|
|
|
400
|
-
|
|
412
|
+
sugar(payload: Payload): Channel;
|
|
413
|
+
sugar(payloads: Payload[]): Channel[];
|
|
414
|
+
sugar(payloads: Payload | Payload[]): Channel | Channel[] {
|
|
401
415
|
const { frameClient } = this;
|
|
402
|
-
|
|
416
|
+
if (Array.isArray(payloads))
|
|
417
|
+
return payloads.map((p) => new Channel({ ...p, frameClient }));
|
|
418
|
+
return new Channel({ ...payloads, frameClient });
|
|
403
419
|
}
|
|
404
420
|
|
|
405
421
|
async retrieveGroup(): Promise<group.Group> {
|
package/src/channel/payload.ts
CHANGED
|
@@ -22,6 +22,8 @@ export type KeyOrName = Key | Name;
|
|
|
22
22
|
export type KeysOrNames = Keys | Names;
|
|
23
23
|
export type PrimitiveParams = Key | Name | Keys | Names;
|
|
24
24
|
|
|
25
|
+
export const statusZ = status.statusZ();
|
|
26
|
+
export type Status = z.infer<typeof statusZ>;
|
|
25
27
|
export const payloadZ = z.object({
|
|
26
28
|
name: nameZ,
|
|
27
29
|
key: keyZ,
|
|
@@ -34,6 +36,7 @@ export const payloadZ = z.object({
|
|
|
34
36
|
alias: z.string().optional(),
|
|
35
37
|
expression: z.string().default(""),
|
|
36
38
|
requires: nullableArrayZ(keyZ),
|
|
39
|
+
status: statusZ.optional(),
|
|
37
40
|
});
|
|
38
41
|
export interface Payload extends z.infer<typeof payloadZ> {}
|
|
39
42
|
|
|
@@ -48,13 +51,10 @@ export const newZ = payloadZ.extend({
|
|
|
48
51
|
requires: nullableArrayZ(keyZ).optional().default([]),
|
|
49
52
|
});
|
|
50
53
|
|
|
51
|
-
export interface New extends Omit<z.input<typeof newZ>, "dataType"> {
|
|
54
|
+
export interface New extends Omit<z.input<typeof newZ>, "dataType" | "status"> {
|
|
52
55
|
dataType: CrudeDataType;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
export const calculationStatusZ = status.statusZ();
|
|
56
|
-
export type CalculationStatus = z.infer<typeof calculationStatusZ>;
|
|
57
|
-
|
|
58
58
|
export const paramsZ = z.union([
|
|
59
59
|
zod.toArray(keyZ),
|
|
60
60
|
zod.toArray(nameZ),
|
package/src/channel/writer.ts
CHANGED
|
@@ -58,7 +58,10 @@ export class Writer {
|
|
|
58
58
|
this.client,
|
|
59
59
|
CREATE_ENDPOINT,
|
|
60
60
|
{
|
|
61
|
-
channels: channels.map((c) => ({
|
|
61
|
+
channels: channels.map((c) => ({
|
|
62
|
+
...c,
|
|
63
|
+
dataType: c.dataType as DataType,
|
|
64
|
+
})),
|
|
62
65
|
},
|
|
63
66
|
createReqZ,
|
|
64
67
|
createResZ,
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, expect, it } from "vitest";
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { createTestClient } from "@/testutil/client";
|
|
13
13
|
|
|
14
|
-
const client =
|
|
14
|
+
const client = createTestClient();
|
|
15
15
|
|
|
16
16
|
describe("state", () => {
|
|
17
17
|
it("should receive the initial control state from the cluster", async () => {
|
package/src/errors.spec.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
UnexpectedError,
|
|
25
25
|
ValidationError,
|
|
26
26
|
} from "@/errors";
|
|
27
|
-
import {
|
|
27
|
+
import { createTestClient } from "@/testutil/client";
|
|
28
28
|
|
|
29
29
|
describe("error", () => {
|
|
30
30
|
describe("type matching", () => {
|
|
@@ -54,7 +54,7 @@ describe("error", () => {
|
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
const client =
|
|
57
|
+
const client = createTestClient();
|
|
58
58
|
|
|
59
59
|
test("client", async () => {
|
|
60
60
|
expect.assertions(2);
|
|
@@ -13,9 +13,9 @@ import { beforeAll, describe, expect, it } from "vitest";
|
|
|
13
13
|
import { type channel } from "@/channel";
|
|
14
14
|
import { ReadAdapter, WriteAdapter } from "@/framer/adapter";
|
|
15
15
|
import { Frame } from "@/index";
|
|
16
|
-
import {
|
|
16
|
+
import { createTestClient } from "@/testutil/client";
|
|
17
17
|
|
|
18
|
-
const client =
|
|
18
|
+
const client = createTestClient();
|
|
19
19
|
|
|
20
20
|
describe("WriteFrameAdapter", () => {
|
|
21
21
|
let timeCh: channel.Channel;
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
import { TimeSpan, TimeStamp } from "@synnaxlabs/x";
|
|
11
11
|
import { describe, expect, it } from "vitest";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { createTestClient } from "@/testutil/client";
|
|
14
14
|
|
|
15
|
-
const client =
|
|
15
|
+
const client = createTestClient();
|
|
16
16
|
|
|
17
17
|
describe("Client", () => {
|
|
18
18
|
describe("read + write", () => {
|
|
@@ -12,11 +12,11 @@ import { describe, expect, test } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { NotFoundError, UnauthorizedError } from "@/errors";
|
|
14
14
|
import { newIndexedPair } from "@/testutil/channels";
|
|
15
|
-
import {
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
16
|
import { secondsLinspace } from "@/testutil/telem";
|
|
17
17
|
import { randomSeries } from "@/util/telem";
|
|
18
18
|
|
|
19
|
-
const client =
|
|
19
|
+
const client = createTestClient();
|
|
20
20
|
|
|
21
21
|
describe("Deleter", () => {
|
|
22
22
|
test("Client - basic delete", async () => {
|
|
@@ -12,11 +12,11 @@ import { describe, expect, test } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { AUTO_SPAN } from "@/framer/iterator";
|
|
14
14
|
import { newIndexedPair } from "@/testutil/channels";
|
|
15
|
-
import {
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
16
|
import { secondsLinspace } from "@/testutil/telem";
|
|
17
17
|
import { randomSeries } from "@/util/telem";
|
|
18
18
|
|
|
19
|
-
const client =
|
|
19
|
+
const client = createTestClient();
|
|
20
20
|
|
|
21
21
|
describe("Iterator", () => {
|
|
22
22
|
test("happy path", async () => {
|
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
streamerConfigZ,
|
|
21
21
|
} from "@/framer/streamer";
|
|
22
22
|
import { newVirtualChannel } from "@/testutil/channels";
|
|
23
|
-
import {
|
|
23
|
+
import { createTestClient } from "@/testutil/client";
|
|
24
24
|
|
|
25
|
-
const client =
|
|
25
|
+
const client = createTestClient();
|
|
26
26
|
|
|
27
27
|
describe("Streamer", () => {
|
|
28
28
|
describe("standard", () => {
|
|
@@ -13,11 +13,12 @@ import { describe, expect, it, test } from "vitest";
|
|
|
13
13
|
import { UnauthorizedError, ValidationError } from "@/errors";
|
|
14
14
|
import { ALWAYS_INDEX_PERSIST_ON_AUTO_COMMIT, WriterMode } from "@/framer/writer";
|
|
15
15
|
import { newIndexedPair } from "@/testutil/channels";
|
|
16
|
-
import {
|
|
16
|
+
import { createTestClient } from "@/testutil/client";
|
|
17
17
|
import { secondsLinspace } from "@/testutil/telem";
|
|
18
18
|
import { randomSeries } from "@/util/telem";
|
|
19
19
|
|
|
20
|
-
const client =
|
|
20
|
+
const client = createTestClient();
|
|
21
|
+
|
|
21
22
|
describe("Writer", () => {
|
|
22
23
|
describe("Writer", () => {
|
|
23
24
|
test("basic write", async () => {
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
import { id, unique } from "@synnaxlabs/x";
|
|
11
11
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { createTestClient } from "@/testutil/client";
|
|
14
14
|
|
|
15
|
-
const client =
|
|
15
|
+
const client = createTestClient();
|
|
16
16
|
|
|
17
17
|
describe("Device", async () => {
|
|
18
18
|
const testRack = await client.hardware.racks.create({ name: "test" });
|
|
@@ -11,9 +11,9 @@ import { describe, expect, it } from "vitest";
|
|
|
11
11
|
import { ZodError } from "zod";
|
|
12
12
|
|
|
13
13
|
import { type rack } from "@/hardware/rack";
|
|
14
|
-
import {
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
15
|
|
|
16
|
-
const client =
|
|
16
|
+
const client = createTestClient();
|
|
17
17
|
|
|
18
18
|
describe("Rack", () => {
|
|
19
19
|
describe("create", () => {
|
|
@@ -11,9 +11,9 @@ import { id, TimeStamp } from "@synnaxlabs/x";
|
|
|
11
11
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { task } from "@/hardware/task";
|
|
14
|
-
import {
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
15
|
|
|
16
|
-
const client =
|
|
16
|
+
const client = createTestClient();
|
|
17
17
|
|
|
18
18
|
describe("Task", async () => {
|
|
19
19
|
const testRack = await client.hardware.racks.create({ name: "test" });
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ export { label } from "@/label";
|
|
|
35
35
|
export { ontology } from "@/ontology";
|
|
36
36
|
export { group } from "@/ontology/group";
|
|
37
37
|
export { ranger } from "@/ranger";
|
|
38
|
-
export {
|
|
38
|
+
export { createTestClient, TEST_CLIENT_PROPS } from "@/testutil/client";
|
|
39
39
|
export { user } from "@/user";
|
|
40
40
|
export { workspace } from "@/workspace";
|
|
41
41
|
export { linePlot } from "@/workspace/lineplot";
|
package/src/label/label.spec.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
import { describe, expect, it } from "vitest";
|
|
11
11
|
|
|
12
12
|
import { label } from "@/label";
|
|
13
|
-
import {
|
|
13
|
+
import { createTestClient } from "@/testutil/client";
|
|
14
14
|
|
|
15
|
-
const client =
|
|
15
|
+
const client = createTestClient();
|
|
16
16
|
|
|
17
17
|
describe("Label", () => {
|
|
18
18
|
describe("create", () => {
|
|
@@ -11,9 +11,9 @@ import { describe, expect, it } from "vitest";
|
|
|
11
11
|
|
|
12
12
|
import { NotFoundError } from "@/errors";
|
|
13
13
|
import { ontology } from "@/ontology";
|
|
14
|
-
import {
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
15
|
|
|
16
|
-
const client =
|
|
16
|
+
const client = createTestClient();
|
|
17
17
|
|
|
18
18
|
describe("Group", () => {
|
|
19
19
|
describe("create", () => {
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
import { describe, expect, it, test } from "vitest";
|
|
11
11
|
|
|
12
12
|
import { ontology } from "@/ontology";
|
|
13
|
-
import {
|
|
13
|
+
import { createTestClient } from "@/testutil/client";
|
|
14
14
|
|
|
15
|
-
const client =
|
|
15
|
+
const client = createTestClient();
|
|
16
16
|
|
|
17
17
|
const randomName = (): string => `group-${Math.random()}`;
|
|
18
18
|
|
package/src/ontology/payload.ts
CHANGED
|
@@ -96,6 +96,9 @@ export const relationshipZ = z.object({ from: idZ, type: z.string(), to: idZ }).
|
|
|
96
96
|
);
|
|
97
97
|
export type Relationship = z.infer<typeof relationshipZ>;
|
|
98
98
|
|
|
99
|
+
export const relationshipToString = (relationship: Relationship) =>
|
|
100
|
+
`${idToString(relationship.from)}->${relationship.type}->${idToString(relationship.to)}`;
|
|
101
|
+
|
|
99
102
|
export const PARENT_OF_RELATIONSHIP_TYPE = "parent";
|
|
100
103
|
|
|
101
104
|
export interface MatchRelationshipArgs {
|
package/src/ranger/alias.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
10
|
import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
|
+
import { array } from "@synnaxlabs/x";
|
|
11
12
|
import { type change } from "@synnaxlabs/x/change";
|
|
12
13
|
import { z } from "zod";
|
|
13
14
|
|
|
@@ -37,10 +38,15 @@ const listReqZ = z.object({ range: keyZ });
|
|
|
37
38
|
|
|
38
39
|
const listResZ = z.object({ aliases: z.record(z.string(), z.string()) });
|
|
39
40
|
|
|
41
|
+
const retrieveReqZ = z.object({ range: keyZ, channels: channel.keyZ.array() });
|
|
42
|
+
|
|
43
|
+
const retrieveResZ = z.object({ aliases: z.record(z.string(), z.string()) });
|
|
44
|
+
|
|
40
45
|
export class Aliaser {
|
|
41
46
|
private static readonly SET_ENDPOINT = "/range/alias/set";
|
|
42
47
|
private static readonly RESOLVE_ENDPOINT = "/range/alias/resolve";
|
|
43
48
|
private static readonly LIST_ENDPOINT = "/range/alias/list";
|
|
49
|
+
private static readonly RETRIEVE_ENDPOINT = "/range/alias/retrieve";
|
|
44
50
|
private static readonly DELETE_ENDPOINT = "/range/alias/delete";
|
|
45
51
|
private readonly frameClient: framer.Client;
|
|
46
52
|
private readonly cache = new Map<string, channel.Key>();
|
|
@@ -108,6 +114,23 @@ export class Aliaser {
|
|
|
108
114
|
).aliases;
|
|
109
115
|
}
|
|
110
116
|
|
|
117
|
+
async retrieve(alias: channel.Key): Promise<string>;
|
|
118
|
+
async retrieve(aliases: channel.Key[]): Promise<Record<channel.Key, string>>;
|
|
119
|
+
|
|
120
|
+
async retrieve(
|
|
121
|
+
alias: channel.Key | channel.Key[],
|
|
122
|
+
): Promise<string | Record<channel.Key, string>> {
|
|
123
|
+
const isSingle = typeof alias === "number";
|
|
124
|
+
const res = await sendRequired<typeof retrieveReqZ, typeof retrieveResZ>(
|
|
125
|
+
this.client,
|
|
126
|
+
Aliaser.RETRIEVE_ENDPOINT,
|
|
127
|
+
{ range: this.rangeKey, channels: array.toArray(alias) },
|
|
128
|
+
retrieveReqZ,
|
|
129
|
+
retrieveResZ,
|
|
130
|
+
);
|
|
131
|
+
return isSingle ? res.aliases[alias] : res.aliases;
|
|
132
|
+
}
|
|
133
|
+
|
|
111
134
|
async delete(aliases: channel.Key[]): Promise<void> {
|
|
112
135
|
await sendRequired<typeof deleteReqZ, typeof deleteResZ>(
|
|
113
136
|
this.client,
|
|
@@ -120,7 +143,7 @@ export class Aliaser {
|
|
|
120
143
|
}
|
|
121
144
|
|
|
122
145
|
export const aliasZ = z.object({
|
|
123
|
-
alias: z.string(),
|
|
146
|
+
alias: z.string().optional(),
|
|
124
147
|
channel: channel.keyZ,
|
|
125
148
|
range: keyZ,
|
|
126
149
|
});
|
|
@@ -130,6 +153,9 @@ export type AliasChange = change.Change<string, Alias>;
|
|
|
130
153
|
|
|
131
154
|
const SEPARATOR = "---";
|
|
132
155
|
|
|
156
|
+
export const aliasKey = (alias: Pick<Alias, "range" | "channel">): string =>
|
|
157
|
+
`${alias.range}${SEPARATOR}${alias.channel}`;
|
|
158
|
+
|
|
133
159
|
export interface DecodedDeleteAliasChange {
|
|
134
160
|
range: Key;
|
|
135
161
|
channel: channel.Key;
|
package/src/ranger/client.ts
CHANGED
|
@@ -54,7 +54,7 @@ export class Range {
|
|
|
54
54
|
readonly timeRange: TimeRange;
|
|
55
55
|
readonly color: string | undefined;
|
|
56
56
|
readonly parent: Payload | null;
|
|
57
|
-
readonly labels
|
|
57
|
+
readonly labels?: label.Label[];
|
|
58
58
|
readonly channels: channel.Retriever;
|
|
59
59
|
private readonly aliaser: Aliaser;
|
|
60
60
|
private readonly frameClient: framer.Client;
|
|
@@ -63,7 +63,7 @@ export class Range {
|
|
|
63
63
|
private readonly rangeClient: Client;
|
|
64
64
|
|
|
65
65
|
constructor(
|
|
66
|
-
{ name, timeRange = TimeRange.ZERO, key, color, parent, labels
|
|
66
|
+
{ name, timeRange = TimeRange.ZERO, key, color, parent, labels }: Payload,
|
|
67
67
|
{
|
|
68
68
|
frameClient,
|
|
69
69
|
kv,
|
|
@@ -94,13 +94,17 @@ export class Range {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
get payload(): Payload {
|
|
97
|
+
let parent: Payload | null = null;
|
|
98
|
+
if (this.parent != null)
|
|
99
|
+
if ("payload" in this.parent) parent = (this.parent as Range).payload;
|
|
100
|
+
else parent = this.parent;
|
|
97
101
|
return {
|
|
98
102
|
key: this.key,
|
|
99
103
|
name: this.name,
|
|
100
104
|
timeRange: this.timeRange,
|
|
101
105
|
color: this.color,
|
|
102
106
|
labels: this.labels,
|
|
103
|
-
parent
|
|
107
|
+
parent,
|
|
104
108
|
};
|
|
105
109
|
}
|
|
106
110
|
|
|
@@ -268,6 +272,29 @@ export class Client {
|
|
|
268
272
|
return this.sugarOne(convertOntologyResourceToPayload(resource));
|
|
269
273
|
}
|
|
270
274
|
|
|
275
|
+
async retrieveAlias(range: Key, channel: channel.Key): Promise<string> {
|
|
276
|
+
const aliaser = new Aliaser(range, this.frameClient, this.unaryClient);
|
|
277
|
+
return await aliaser.retrieve(channel);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async retrieveAliases(
|
|
281
|
+
range: Key,
|
|
282
|
+
channels: channel.Key[],
|
|
283
|
+
): Promise<Record<channel.Key, string>> {
|
|
284
|
+
const aliaser = new Aliaser(range, this.frameClient, this.unaryClient);
|
|
285
|
+
return await aliaser.retrieve(channels);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async listAliases(range: Key): Promise<Record<channel.Key, string>> {
|
|
289
|
+
const aliaser = new Aliaser(range, this.frameClient, this.unaryClient);
|
|
290
|
+
return await aliaser.list();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async setAlias(range: Key, channel: channel.Key, alias: string): Promise<void> {
|
|
294
|
+
const aliaser = new Aliaser(range, this.frameClient, this.unaryClient);
|
|
295
|
+
await aliaser.set({ [channel]: alias });
|
|
296
|
+
}
|
|
297
|
+
|
|
271
298
|
sugarOne(payload: Payload): Range {
|
|
272
299
|
return new Range(payload, {
|
|
273
300
|
frameClient: this.frameClient,
|
package/src/ranger/external.ts
CHANGED
|
@@ -7,15 +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
|
-
export
|
|
11
|
-
type Alias,
|
|
12
|
-
type AliasChange,
|
|
13
|
-
aliasZ,
|
|
14
|
-
type DecodedDeleteAliasChange,
|
|
15
|
-
decodeDeleteAliasChange,
|
|
16
|
-
DELETE_ALIAS_CHANNEL_NAME,
|
|
17
|
-
SET_ALIAS_CHANNEL_NAME,
|
|
18
|
-
} from "@/ranger/alias";
|
|
10
|
+
export * from "@/ranger/alias";
|
|
19
11
|
export * from "@/ranger/client";
|
|
20
12
|
export * from "@/ranger/kv";
|
|
21
13
|
export * from "@/ranger/payload";
|
package/src/ranger/kv.ts
CHANGED
|
@@ -21,6 +21,9 @@ export const KV_DELETE_CHANNEL = "sy_range_kv_delete";
|
|
|
21
21
|
export const kvPairZ = z.object({ range: keyZ, key: z.string(), value: z.string() });
|
|
22
22
|
export interface KVPair extends z.infer<typeof kvPairZ> {}
|
|
23
23
|
|
|
24
|
+
export const kvPairKey = ({ range, key }: Omit<KVPair, "value">) =>
|
|
25
|
+
`${range}<--->${key}`;
|
|
26
|
+
|
|
24
27
|
const getReqZ = z.object({ range: keyZ, keys: z.string().array() });
|
|
25
28
|
export interface GetRequest extends z.infer<typeof getReqZ> {}
|
|
26
29
|
|
package/src/ranger/payload.ts
CHANGED
|
@@ -11,7 +11,6 @@ import { TimeRange } from "@synnaxlabs/x/telem";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
import { label } from "@/label";
|
|
14
|
-
import { nullableArrayZ } from "@/util/zod";
|
|
15
14
|
|
|
16
15
|
export const keyZ = z.uuid();
|
|
17
16
|
export type Key = z.infer<typeof keyZ>;
|
|
@@ -26,7 +25,10 @@ export const payloadZ = z.object({
|
|
|
26
25
|
name: nameZ,
|
|
27
26
|
timeRange: TimeRange.z,
|
|
28
27
|
color: z.string().optional(),
|
|
29
|
-
labels:
|
|
28
|
+
labels: label.labelZ
|
|
29
|
+
.array()
|
|
30
|
+
.or(z.null().transform(() => undefined))
|
|
31
|
+
.optional(),
|
|
30
32
|
get parent(): z.ZodUnion<readonly [z.ZodNull, typeof payloadZ]> {
|
|
31
33
|
// Using as unknown is bad, but unfortunately resolving the output type of this
|
|
32
34
|
// transform is nearly impossible.
|
|
@@ -12,9 +12,9 @@ import { describe, expect, it } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { NotFoundError } from "@/errors";
|
|
14
14
|
import { type ranger } from "@/ranger";
|
|
15
|
-
import {
|
|
15
|
+
import { createTestClient } from "@/testutil/client";
|
|
16
16
|
|
|
17
|
-
const client =
|
|
17
|
+
const client = createTestClient();
|
|
18
18
|
|
|
19
19
|
describe("Ranger", () => {
|
|
20
20
|
describe("create", () => {
|
|
@@ -194,7 +194,7 @@ describe("Ranger", () => {
|
|
|
194
194
|
includeLabels: true,
|
|
195
195
|
});
|
|
196
196
|
expect(newRange[0].labels).toHaveLength(1);
|
|
197
|
-
expect(newRange[0].labels[0]).toEqual(label);
|
|
197
|
+
expect(newRange[0].labels?.[0]).toEqual(label);
|
|
198
198
|
});
|
|
199
199
|
});
|
|
200
200
|
|
package/src/testutil/client.ts
CHANGED
|
@@ -16,5 +16,5 @@ export const TEST_CLIENT_PROPS: SynnaxProps = {
|
|
|
16
16
|
password: "seldon",
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const
|
|
19
|
+
export const createTestClient = (props?: Partial<SynnaxProps>): Synnax =>
|
|
20
20
|
new Synnax({ ...TEST_CLIENT_PROPS, ...props });
|
package/src/user/user.spec.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { id } from "@synnaxlabs/x";
|
|
|
11
11
|
import { describe, expect, test } from "vitest";
|
|
12
12
|
|
|
13
13
|
import { AuthError, NotFoundError } from "@/errors";
|
|
14
|
-
import {
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
15
|
import { type user } from "@/user";
|
|
16
16
|
|
|
17
17
|
interface SortType {
|
|
@@ -20,7 +20,7 @@ interface SortType {
|
|
|
20
20
|
|
|
21
21
|
const sort = (a: SortType, b: SortType) => a.username.localeCompare(b.username);
|
|
22
22
|
|
|
23
|
-
const client =
|
|
23
|
+
const client = createTestClient();
|
|
24
24
|
|
|
25
25
|
const userOne: user.New = {
|
|
26
26
|
username: id.create(),
|