@synnaxlabs/client 0.47.0 → 0.49.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/client.cjs +35 -35
- package/dist/client.js +6264 -5984
- package/dist/eslint.config.d.ts +3 -2
- package/dist/eslint.config.d.ts.map +1 -1
- package/dist/src/access/client.d.ts +3 -1
- package/dist/src/access/client.d.ts.map +1 -1
- package/dist/src/access/enforce.d.ts +35 -0
- package/dist/src/access/enforce.d.ts.map +1 -0
- package/dist/src/access/enforce.spec.d.ts +2 -0
- package/dist/src/access/enforce.spec.d.ts.map +1 -0
- package/dist/src/access/external.d.ts +3 -0
- package/dist/src/access/external.d.ts.map +1 -1
- package/dist/src/access/payload.d.ts +0 -6
- package/dist/src/access/payload.d.ts.map +1 -1
- package/dist/src/access/policy/access.spec.d.ts +2 -0
- package/dist/src/access/policy/access.spec.d.ts.map +1 -0
- package/dist/src/access/policy/client.d.ts +485 -31
- package/dist/src/access/policy/client.d.ts.map +1 -1
- package/dist/src/access/policy/payload.d.ts +36 -113
- package/dist/src/access/policy/payload.d.ts.map +1 -1
- package/dist/src/access/role/client.d.ts +135 -0
- package/dist/src/access/role/client.d.ts.map +1 -0
- package/dist/src/access/role/external.d.ts.map +1 -0
- package/dist/src/access/role/index.d.ts +2 -0
- package/dist/src/access/role/index.d.ts.map +1 -0
- package/dist/src/access/role/payload.d.ts +27 -0
- package/dist/src/access/role/payload.d.ts.map +1 -0
- package/dist/src/access/role/role.spec.d.ts +2 -0
- package/dist/src/access/role/role.spec.d.ts.map +1 -0
- package/dist/src/arc/access.spec.d.ts +2 -0
- package/dist/src/arc/access.spec.d.ts.map +1 -0
- package/dist/src/arc/client.d.ts +5 -14
- package/dist/src/arc/client.d.ts.map +1 -1
- package/dist/src/arc/payload.d.ts +11 -2
- package/dist/src/arc/payload.d.ts.map +1 -1
- package/dist/src/auth/auth.d.ts +5 -3
- package/dist/src/auth/auth.d.ts.map +1 -1
- package/dist/src/channel/access.spec.d.ts +2 -0
- package/dist/src/channel/access.spec.d.ts.map +1 -0
- package/dist/src/channel/client.d.ts +0 -1
- package/dist/src/channel/client.d.ts.map +1 -1
- package/dist/src/channel/payload.d.ts +19 -8
- package/dist/src/channel/payload.d.ts.map +1 -1
- package/dist/src/channel/payload.spec.d.ts +2 -0
- package/dist/src/channel/payload.spec.d.ts.map +1 -0
- package/dist/src/channel/retriever.d.ts +4 -6
- package/dist/src/channel/retriever.d.ts.map +1 -1
- package/dist/src/channel/writer.d.ts.map +1 -1
- package/dist/src/client.d.ts +18 -10
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/connection/checker.d.ts +2 -3
- package/dist/src/connection/checker.d.ts.map +1 -1
- package/dist/src/connection.spec.d.ts +2 -0
- package/dist/src/connection.spec.d.ts.map +1 -0
- package/dist/src/device/access.spec.d.ts +2 -0
- package/dist/src/device/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/device → device}/client.d.ts +14 -7
- package/dist/src/device/client.d.ts.map +1 -0
- package/dist/src/device/device.spec.d.ts.map +1 -0
- package/dist/src/device/external.d.ts.map +1 -0
- package/dist/src/device/index.d.ts.map +1 -0
- package/dist/src/{hardware/device → device}/payload.d.ts +1 -1
- package/dist/src/device/payload.d.ts.map +1 -0
- package/dist/src/errors.d.ts +3 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/framer/adapter.d.ts +2 -2
- package/dist/src/framer/adapter.d.ts.map +1 -1
- package/dist/src/framer/client.d.ts +8 -1
- package/dist/src/framer/client.d.ts.map +1 -1
- package/dist/src/framer/frame.d.ts +11 -5
- package/dist/src/framer/frame.d.ts.map +1 -1
- package/dist/src/framer/iterator.d.ts +3 -3
- package/dist/src/framer/streamer.d.ts +24 -21
- package/dist/src/framer/streamer.d.ts.map +1 -1
- package/dist/src/framer/writer.d.ts +13 -13
- package/dist/src/index.d.ts +6 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/label/access.spec.d.ts +2 -0
- package/dist/src/label/access.spec.d.ts.map +1 -0
- package/dist/src/label/client.d.ts +20 -11
- package/dist/src/label/client.d.ts.map +1 -1
- package/dist/src/ontology/client.d.ts +6 -6
- package/dist/src/ontology/client.d.ts.map +1 -1
- package/dist/src/ontology/group/access.spec.d.ts +2 -0
- package/dist/src/ontology/group/access.spec.d.ts.map +1 -0
- package/dist/src/ontology/group/client.d.ts +2 -2
- package/dist/src/ontology/group/client.d.ts.map +1 -1
- package/dist/src/ontology/group/payload.d.ts +1 -2
- package/dist/src/ontology/group/payload.d.ts.map +1 -1
- package/dist/src/ontology/payload.d.ts +23 -17
- package/dist/src/ontology/payload.d.ts.map +1 -1
- package/dist/src/ontology/writer.d.ts +10 -10
- package/dist/src/ontology/writer.d.ts.map +1 -1
- package/dist/src/rack/access.spec.d.ts +2 -0
- package/dist/src/rack/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/rack → rack}/client.d.ts +15 -8
- package/dist/src/rack/client.d.ts.map +1 -0
- package/dist/src/rack/external.d.ts.map +1 -0
- package/dist/src/rack/index.d.ts.map +1 -0
- package/dist/src/{hardware/rack → rack}/payload.d.ts +1 -1
- package/dist/src/rack/payload.d.ts.map +1 -0
- package/dist/src/rack/rack.spec.d.ts.map +1 -0
- package/dist/src/ranger/access.spec.d.ts +2 -0
- package/dist/src/ranger/access.spec.d.ts.map +1 -0
- package/dist/src/ranger/alias.d.ts +1 -8
- package/dist/src/ranger/alias.d.ts.map +1 -1
- package/dist/src/ranger/client.d.ts +12 -5
- package/dist/src/ranger/client.d.ts.map +1 -1
- package/dist/src/ranger/kv.d.ts +0 -3
- package/dist/src/ranger/kv.d.ts.map +1 -1
- package/dist/src/ranger/writer.d.ts +2 -2
- package/dist/src/ranger/writer.d.ts.map +1 -1
- package/dist/src/status/access.spec.d.ts +2 -0
- package/dist/src/status/access.spec.d.ts.map +1 -0
- package/dist/src/status/client.d.ts +4 -4
- package/dist/src/status/client.d.ts.map +1 -1
- package/dist/src/status/payload.d.ts +9 -2
- package/dist/src/status/payload.d.ts.map +1 -1
- package/dist/src/task/access.spec.d.ts +2 -0
- package/dist/src/task/access.spec.d.ts.map +1 -0
- package/dist/src/{hardware/task → task}/client.d.ts +26 -15
- package/dist/src/task/client.d.ts.map +1 -0
- package/dist/src/task/external.d.ts +3 -0
- package/dist/src/task/external.d.ts.map +1 -0
- package/dist/src/task/index.d.ts.map +1 -0
- package/dist/src/{hardware/task → task}/payload.d.ts +45 -6
- package/dist/src/task/payload.d.ts.map +1 -0
- package/dist/src/task/task.spec.d.ts.map +1 -0
- package/dist/src/testutil/access.d.ts +4 -0
- package/dist/src/testutil/access.d.ts.map +1 -0
- package/dist/src/testutil/client.d.ts +3 -3
- package/dist/src/testutil/client.d.ts.map +1 -1
- package/dist/src/transport.d.ts.map +1 -1
- package/dist/src/user/access.spec.d.ts +2 -0
- package/dist/src/user/access.spec.d.ts.map +1 -0
- package/dist/src/user/client.d.ts +10 -1
- package/dist/src/user/client.d.ts.map +1 -1
- package/dist/src/user/external.d.ts +1 -1
- package/dist/src/user/external.d.ts.map +1 -1
- package/dist/src/user/payload.d.ts.map +1 -1
- package/dist/src/workspace/access.spec.d.ts +2 -0
- package/dist/src/workspace/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/client.d.ts +10 -5
- package/dist/src/workspace/client.d.ts.map +1 -1
- package/dist/src/workspace/lineplot/access.spec.d.ts +2 -0
- package/dist/src/workspace/lineplot/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/lineplot/client.d.ts +8 -1
- package/dist/src/workspace/lineplot/client.d.ts.map +1 -1
- package/dist/src/workspace/log/access.spec.d.ts +2 -0
- package/dist/src/workspace/log/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/log/client.d.ts +8 -1
- package/dist/src/workspace/log/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/access.spec.d.ts +2 -0
- package/dist/src/workspace/schematic/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/schematic/client.d.ts +8 -1
- package/dist/src/workspace/schematic/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/symbol/access.spec.d.ts +2 -0
- package/dist/src/workspace/schematic/symbol/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/schematic/symbol/client.d.ts +1 -5
- package/dist/src/workspace/schematic/symbol/client.d.ts.map +1 -1
- package/dist/src/workspace/schematic/symbol/payload.d.ts +2 -2
- package/dist/src/workspace/table/access.spec.d.ts +2 -0
- package/dist/src/workspace/table/access.spec.d.ts.map +1 -0
- package/dist/src/workspace/table/client.d.ts +8 -1
- package/dist/src/workspace/table/client.d.ts.map +1 -1
- package/eslint.config.ts +3 -1
- package/package.json +8 -8
- package/src/access/client.ts +5 -2
- package/src/access/enforce.spec.ts +189 -0
- package/src/access/enforce.ts +84 -0
- package/src/access/external.ts +3 -0
- package/src/access/payload.ts +1 -13
- package/src/access/policy/access.spec.ts +147 -0
- package/src/access/policy/client.ts +21 -25
- package/src/access/policy/payload.ts +9 -5
- package/src/access/role/client.ts +135 -0
- package/src/access/role/external.ts +11 -0
- package/src/{hardware → access/role}/index.ts +1 -1
- package/src/access/role/payload.ts +32 -0
- package/src/access/role/role.spec.ts +95 -0
- package/src/arc/access.spec.ts +143 -0
- package/src/arc/client.ts +7 -31
- package/src/arc/payload.ts +4 -0
- package/src/auth/auth.spec.ts +13 -13
- package/src/auth/auth.ts +33 -11
- package/src/channel/access.spec.ts +116 -0
- package/src/channel/channel.spec.ts +63 -73
- package/src/channel/client.ts +2 -8
- package/src/channel/payload.spec.ts +171 -0
- package/src/channel/payload.ts +37 -8
- package/src/channel/retriever.ts +10 -11
- package/src/channel/writer.ts +3 -7
- package/src/client.ts +38 -28
- package/src/connection/checker.ts +10 -10
- package/src/connection/connection.spec.ts +13 -13
- package/src/connection.spec.ts +145 -0
- package/src/device/access.spec.ts +159 -0
- package/src/{hardware/device → device}/client.ts +12 -21
- package/src/{hardware/device → device}/device.spec.ts +70 -34
- package/src/device/external.ts +11 -0
- package/src/{hardware/rack → device}/index.ts +1 -1
- package/src/{hardware/device → device}/payload.ts +3 -3
- package/src/errors.ts +2 -0
- package/src/framer/adapter.spec.ts +351 -13
- package/src/framer/adapter.ts +23 -13
- package/src/framer/client.spec.ts +14 -20
- package/src/framer/client.ts +3 -5
- package/src/framer/deleter.spec.ts +1 -1
- package/src/framer/frame.spec.ts +427 -0
- package/src/framer/frame.ts +30 -3
- package/src/framer/iterator.ts +4 -4
- package/src/framer/streamer.spec.ts +155 -10
- package/src/framer/streamer.ts +35 -12
- package/src/framer/writer.spec.ts +5 -5
- package/src/index.ts +13 -7
- package/src/label/access.spec.ts +109 -0
- package/src/label/client.ts +10 -14
- package/src/ontology/client.ts +4 -6
- package/src/ontology/group/access.spec.ts +77 -0
- package/src/ontology/group/client.ts +3 -7
- package/src/ontology/group/group.spec.ts +18 -0
- package/src/ontology/group/payload.ts +2 -2
- package/src/ontology/ontology.spec.ts +2 -0
- package/src/ontology/payload.ts +18 -2
- package/src/ontology/writer.ts +3 -7
- package/src/rack/access.spec.ts +102 -0
- package/src/{hardware/rack → rack}/client.ts +14 -19
- package/src/{hardware/device/index.ts → rack/external.ts} +2 -1
- package/src/{hardware/external.ts → rack/index.ts} +1 -1
- package/src/{hardware/rack → rack}/payload.ts +2 -2
- package/src/{hardware/rack → rack}/rack.spec.ts +43 -17
- package/src/ranger/access.spec.ts +115 -0
- package/src/ranger/alias.ts +6 -14
- package/src/ranger/client.ts +13 -14
- package/src/ranger/kv.ts +7 -9
- package/src/ranger/ranger.spec.ts +4 -4
- package/src/ranger/writer.ts +3 -7
- package/src/status/access.spec.ts +129 -0
- package/src/status/client.ts +5 -9
- package/src/status/payload.ts +3 -2
- package/src/task/access.spec.ts +131 -0
- package/src/{hardware/task → task}/client.ts +50 -25
- package/src/task/external.ts +11 -0
- package/src/{hardware/task → task}/index.ts +1 -1
- package/src/{hardware/task → task}/payload.ts +22 -3
- package/src/{hardware/task → task}/task.spec.ts +197 -34
- package/src/testutil/access.ts +34 -0
- package/src/testutil/channels.ts +3 -3
- package/src/testutil/client.ts +4 -4
- package/src/transport.ts +1 -3
- package/src/user/access.spec.ts +107 -0
- package/src/user/client.ts +10 -12
- package/src/user/external.ts +12 -1
- package/src/user/payload.ts +3 -5
- package/src/workspace/access.spec.ts +108 -0
- package/src/workspace/client.ts +11 -27
- package/src/workspace/lineplot/access.spec.ts +134 -0
- package/src/workspace/lineplot/client.ts +8 -13
- package/src/workspace/log/access.spec.ts +134 -0
- package/src/workspace/log/client.ts +8 -13
- package/src/workspace/schematic/access.spec.ts +134 -0
- package/src/workspace/schematic/client.ts +9 -18
- package/src/workspace/schematic/symbol/access.spec.ts +172 -0
- package/src/workspace/schematic/symbol/client.ts +6 -17
- package/src/workspace/schematic/symbol/payload.ts +1 -1
- package/src/workspace/table/access.spec.ts +134 -0
- package/src/workspace/table/client.ts +8 -13
- package/dist/src/access/policy/policy.spec.d.ts +0 -2
- package/dist/src/access/policy/policy.spec.d.ts.map +0 -1
- package/dist/src/hardware/client.d.ts +0 -10
- package/dist/src/hardware/client.d.ts.map +0 -1
- package/dist/src/hardware/device/client.d.ts.map +0 -1
- package/dist/src/hardware/device/device.spec.d.ts.map +0 -1
- package/dist/src/hardware/device/external.d.ts.map +0 -1
- package/dist/src/hardware/device/index.d.ts.map +0 -1
- package/dist/src/hardware/device/payload.d.ts.map +0 -1
- package/dist/src/hardware/external.d.ts +0 -2
- package/dist/src/hardware/external.d.ts.map +0 -1
- package/dist/src/hardware/index.d.ts +0 -2
- package/dist/src/hardware/index.d.ts.map +0 -1
- package/dist/src/hardware/rack/client.d.ts.map +0 -1
- package/dist/src/hardware/rack/external.d.ts.map +0 -1
- package/dist/src/hardware/rack/index.d.ts.map +0 -1
- package/dist/src/hardware/rack/payload.d.ts.map +0 -1
- package/dist/src/hardware/rack/rack.spec.d.ts.map +0 -1
- package/dist/src/hardware/task/client.d.ts.map +0 -1
- package/dist/src/hardware/task/external.d.ts.map +0 -1
- package/dist/src/hardware/task/index.d.ts.map +0 -1
- package/dist/src/hardware/task/payload.d.ts.map +0 -1
- package/dist/src/hardware/task/task.spec.d.ts.map +0 -1
- package/dist/src/user/retriever.d.ts +0 -16
- package/dist/src/user/retriever.d.ts.map +0 -1
- package/dist/src/user/writer.d.ts +0 -11
- package/dist/src/user/writer.d.ts.map +0 -1
- package/src/access/policy/policy.spec.ts +0 -329
- package/src/hardware/client.ts +0 -24
- package/src/hardware/device/external.ts +0 -11
- package/src/hardware/rack/external.ts +0 -11
- package/src/hardware/task/external.ts +0 -11
- package/src/user/retriever.ts +0 -41
- package/src/user/writer.ts +0 -84
- /package/dist/src/{hardware/device → access/role}/external.d.ts +0 -0
- /package/dist/src/{hardware/device → device}/device.spec.d.ts +0 -0
- /package/dist/src/{hardware/rack → device}/external.d.ts +0 -0
- /package/dist/src/{hardware/device → device}/index.d.ts +0 -0
- /package/dist/src/{hardware/task → rack}/external.d.ts +0 -0
- /package/dist/src/{hardware/rack → rack}/index.d.ts +0 -0
- /package/dist/src/{hardware/rack → rack}/rack.spec.d.ts +0 -0
- /package/dist/src/{hardware/task → task}/index.d.ts +0 -0
- /package/dist/src/{hardware/task → task}/task.spec.d.ts +0 -0
|
@@ -11,7 +11,7 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
|
11
11
|
import { array, type record } from "@synnaxlabs/x";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { ontology } from "@/ontology";
|
|
15
15
|
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
16
16
|
import {
|
|
17
17
|
type Key,
|
|
@@ -24,12 +24,6 @@ import {
|
|
|
24
24
|
} from "@/workspace/log/payload";
|
|
25
25
|
import { type Key as WorkspaceKey, keyZ as workspaceKeyZ } from "@/workspace/payload";
|
|
26
26
|
|
|
27
|
-
const RETRIEVE_ENDPOINT = "/workspace/log/retrieve";
|
|
28
|
-
const CREATE_ENDPOINT = "/workspace/log/create";
|
|
29
|
-
const RENAME_ENDPOINT = "/workspace/log/rename";
|
|
30
|
-
const SET_DATA_ENDPOINT = "/workspace/log/set-data";
|
|
31
|
-
const DELETE_ENDPOINT = "/workspace/log/delete";
|
|
32
|
-
|
|
33
27
|
const renameReqZ = z.object({ key: keyZ, name: z.string() });
|
|
34
28
|
|
|
35
29
|
const setDataReqZ = z.object({ key: keyZ, data: z.string() });
|
|
@@ -65,7 +59,7 @@ export class Client {
|
|
|
65
59
|
const isMany = Array.isArray(logs);
|
|
66
60
|
const res = await sendRequired(
|
|
67
61
|
this.client,
|
|
68
|
-
|
|
62
|
+
"/workspace/log/create",
|
|
69
63
|
{ workspace, logs: array.toArray(logs) },
|
|
70
64
|
createReqZ,
|
|
71
65
|
createResZ,
|
|
@@ -76,7 +70,7 @@ export class Client {
|
|
|
76
70
|
async rename(key: Key, name: string): Promise<void> {
|
|
77
71
|
await sendRequired(
|
|
78
72
|
this.client,
|
|
79
|
-
|
|
73
|
+
"/workspace/log/rename",
|
|
80
74
|
{ key, name },
|
|
81
75
|
renameReqZ,
|
|
82
76
|
emptyResZ,
|
|
@@ -86,7 +80,7 @@ export class Client {
|
|
|
86
80
|
async setData(key: Key, data: record.Unknown): Promise<void> {
|
|
87
81
|
await sendRequired(
|
|
88
82
|
this.client,
|
|
89
|
-
|
|
83
|
+
"/workspace/log/set-data",
|
|
90
84
|
{ key, data: JSON.stringify(data) },
|
|
91
85
|
setDataReqZ,
|
|
92
86
|
emptyResZ,
|
|
@@ -101,7 +95,7 @@ export class Client {
|
|
|
101
95
|
const isSingle = singleRetrieveArgsZ.safeParse(args).success;
|
|
102
96
|
const res = await sendRequired(
|
|
103
97
|
this.client,
|
|
104
|
-
|
|
98
|
+
"/workspace/log/retrieve",
|
|
105
99
|
args,
|
|
106
100
|
retrieveArgsZ,
|
|
107
101
|
retrieveResZ,
|
|
@@ -113,7 +107,7 @@ export class Client {
|
|
|
113
107
|
async delete(keys: Params): Promise<void> {
|
|
114
108
|
await sendRequired(
|
|
115
109
|
this.client,
|
|
116
|
-
|
|
110
|
+
"/workspace/log/delete",
|
|
117
111
|
{ keys: array.toArray(keys) },
|
|
118
112
|
deleteReqZ,
|
|
119
113
|
emptyResZ,
|
|
@@ -121,4 +115,5 @@ export class Client {
|
|
|
121
115
|
}
|
|
122
116
|
}
|
|
123
117
|
|
|
124
|
-
export const ontologyID =
|
|
118
|
+
export const ontologyID = ontology.createIDFactory<Key>("log");
|
|
119
|
+
export const TYPE_ONTOLOGY_ID = ontologyID("");
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
|
|
12
|
+
import { AuthError, NotFoundError } from "@/errors";
|
|
13
|
+
import { createTestClientWithPolicy } from "@/testutil/access";
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
|
+
import { schematic } from "@/workspace/schematic";
|
|
16
|
+
|
|
17
|
+
const client = createTestClient();
|
|
18
|
+
|
|
19
|
+
describe("schematic", () => {
|
|
20
|
+
describe("access control", () => {
|
|
21
|
+
it("should deny access when no retrieve policy exists", async () => {
|
|
22
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
23
|
+
name: "test",
|
|
24
|
+
objects: [],
|
|
25
|
+
actions: [],
|
|
26
|
+
});
|
|
27
|
+
const ws = await client.workspaces.create({
|
|
28
|
+
name: "test",
|
|
29
|
+
layout: {},
|
|
30
|
+
});
|
|
31
|
+
const randomSchematic = await client.workspaces.schematics.create(ws.key, {
|
|
32
|
+
name: "test",
|
|
33
|
+
data: {},
|
|
34
|
+
});
|
|
35
|
+
await expect(
|
|
36
|
+
userClient.workspaces.schematics.retrieve({ key: randomSchematic.key }),
|
|
37
|
+
).rejects.toThrow(AuthError);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should allow the caller to retrieve schematics with the correct policy", async () => {
|
|
41
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
42
|
+
name: "test",
|
|
43
|
+
objects: [schematic.ontologyID("")],
|
|
44
|
+
actions: ["retrieve"],
|
|
45
|
+
});
|
|
46
|
+
const ws = await client.workspaces.create({
|
|
47
|
+
name: "test",
|
|
48
|
+
layout: {},
|
|
49
|
+
});
|
|
50
|
+
const randomSchematic = await client.workspaces.schematics.create(ws.key, {
|
|
51
|
+
name: "test",
|
|
52
|
+
data: {},
|
|
53
|
+
});
|
|
54
|
+
const retrieved = await userClient.workspaces.schematics.retrieve({
|
|
55
|
+
key: randomSchematic.key,
|
|
56
|
+
});
|
|
57
|
+
expect(retrieved.key).toBe(randomSchematic.key);
|
|
58
|
+
expect(retrieved.name).toBe(randomSchematic.name);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should allow the caller to create schematics with the correct policy", async () => {
|
|
62
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
63
|
+
name: "test",
|
|
64
|
+
objects: [schematic.ontologyID("")],
|
|
65
|
+
actions: ["create"],
|
|
66
|
+
});
|
|
67
|
+
const ws = await client.workspaces.create({
|
|
68
|
+
name: "test",
|
|
69
|
+
layout: {},
|
|
70
|
+
});
|
|
71
|
+
await userClient.workspaces.schematics.create(ws.key, {
|
|
72
|
+
name: "test",
|
|
73
|
+
data: {},
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should deny access when no create policy exists", async () => {
|
|
78
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
79
|
+
name: "test",
|
|
80
|
+
objects: [schematic.ontologyID("")],
|
|
81
|
+
actions: [],
|
|
82
|
+
});
|
|
83
|
+
const ws = await client.workspaces.create({
|
|
84
|
+
name: "test",
|
|
85
|
+
layout: {},
|
|
86
|
+
});
|
|
87
|
+
await expect(
|
|
88
|
+
userClient.workspaces.schematics.create(ws.key, {
|
|
89
|
+
name: "test",
|
|
90
|
+
data: {},
|
|
91
|
+
}),
|
|
92
|
+
).rejects.toThrow(AuthError);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("should allow the caller to delete schematics with the correct policy", async () => {
|
|
96
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
97
|
+
name: "test",
|
|
98
|
+
objects: [schematic.ontologyID("")],
|
|
99
|
+
actions: ["delete", "retrieve"],
|
|
100
|
+
});
|
|
101
|
+
const ws = await client.workspaces.create({
|
|
102
|
+
name: "test",
|
|
103
|
+
layout: {},
|
|
104
|
+
});
|
|
105
|
+
const randomSchematic = await client.workspaces.schematics.create(ws.key, {
|
|
106
|
+
name: "test",
|
|
107
|
+
data: {},
|
|
108
|
+
});
|
|
109
|
+
await userClient.workspaces.schematics.delete(randomSchematic.key);
|
|
110
|
+
await expect(
|
|
111
|
+
userClient.workspaces.schematics.retrieve({ key: randomSchematic.key }),
|
|
112
|
+
).rejects.toThrow(NotFoundError);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("should deny access when no delete policy exists", async () => {
|
|
116
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
117
|
+
name: "test",
|
|
118
|
+
objects: [schematic.ontologyID("")],
|
|
119
|
+
actions: [],
|
|
120
|
+
});
|
|
121
|
+
const ws = await client.workspaces.create({
|
|
122
|
+
name: "test",
|
|
123
|
+
layout: {},
|
|
124
|
+
});
|
|
125
|
+
const randomSchematic = await client.workspaces.schematics.create(ws.key, {
|
|
126
|
+
name: "test",
|
|
127
|
+
data: {},
|
|
128
|
+
});
|
|
129
|
+
await expect(
|
|
130
|
+
userClient.workspaces.schematics.delete(randomSchematic.key),
|
|
131
|
+
).rejects.toThrow(AuthError);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -11,7 +11,7 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
|
|
|
11
11
|
import { array, type record } from "@synnaxlabs/x";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { ontology } from "@/ontology";
|
|
15
15
|
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
16
16
|
import { type Key as WorkspaceKey, keyZ as workspaceKeyZ } from "@/workspace/payload";
|
|
17
17
|
import {
|
|
@@ -26,13 +26,6 @@ import {
|
|
|
26
26
|
} from "@/workspace/schematic/payload";
|
|
27
27
|
import { symbol } from "@/workspace/schematic/symbol";
|
|
28
28
|
|
|
29
|
-
const RETRIEVE_ENDPOINT = "/workspace/schematic/retrieve";
|
|
30
|
-
const CREATE_ENDPOINT = "/workspace/schematic/create";
|
|
31
|
-
const RENAME_ENDPOINT = "/workspace/schematic/rename";
|
|
32
|
-
const SET_DATA_ENDPOINT = "/workspace/schematic/set-data";
|
|
33
|
-
const DELETE_ENDPOINT = "/workspace/schematic/delete";
|
|
34
|
-
const COPY_ENDPOINT = "/workspace/schematic/copy";
|
|
35
|
-
|
|
36
29
|
const renameReqZ = z.object({ key: keyZ, name: z.string() });
|
|
37
30
|
|
|
38
31
|
const setDataReqZ = z.object({ key: keyZ, data: z.string() });
|
|
@@ -84,7 +77,7 @@ export class Client {
|
|
|
84
77
|
const isMany = Array.isArray(schematics);
|
|
85
78
|
const res = await sendRequired(
|
|
86
79
|
this.client,
|
|
87
|
-
|
|
80
|
+
"/workspace/schematic/create",
|
|
88
81
|
{ workspace, schematics: array.toArray(schematics) },
|
|
89
82
|
createReqZ,
|
|
90
83
|
createResZ,
|
|
@@ -95,7 +88,7 @@ export class Client {
|
|
|
95
88
|
async rename(key: Key, name: string): Promise<void> {
|
|
96
89
|
await sendRequired(
|
|
97
90
|
this.client,
|
|
98
|
-
|
|
91
|
+
"/workspace/schematic/rename",
|
|
99
92
|
{ key, name },
|
|
100
93
|
renameReqZ,
|
|
101
94
|
emptyResZ,
|
|
@@ -105,7 +98,7 @@ export class Client {
|
|
|
105
98
|
async setData(key: Key, data: record.Unknown): Promise<void> {
|
|
106
99
|
await sendRequired(
|
|
107
100
|
this.client,
|
|
108
|
-
|
|
101
|
+
"/workspace/schematic/set-data",
|
|
109
102
|
{ key, data: JSON.stringify(data) },
|
|
110
103
|
setDataReqZ,
|
|
111
104
|
emptyResZ,
|
|
@@ -120,7 +113,7 @@ export class Client {
|
|
|
120
113
|
const isSingle = singleRetrieveArgsZ.safeParse(args).success;
|
|
121
114
|
const res = await sendRequired(
|
|
122
115
|
this.client,
|
|
123
|
-
|
|
116
|
+
"/workspace/schematic/retrieve",
|
|
124
117
|
args,
|
|
125
118
|
retrieveArgsZ,
|
|
126
119
|
retrieveResZ,
|
|
@@ -132,7 +125,7 @@ export class Client {
|
|
|
132
125
|
async delete(keys: Params): Promise<void> {
|
|
133
126
|
await sendRequired(
|
|
134
127
|
this.client,
|
|
135
|
-
|
|
128
|
+
"/workspace/schematic/delete",
|
|
136
129
|
{ keys: array.toArray(keys) },
|
|
137
130
|
deleteReqZ,
|
|
138
131
|
emptyResZ,
|
|
@@ -142,7 +135,7 @@ export class Client {
|
|
|
142
135
|
async copy(args: CopyArgs): Promise<Schematic> {
|
|
143
136
|
const res = await sendRequired(
|
|
144
137
|
this.client,
|
|
145
|
-
|
|
138
|
+
"/workspace/schematic/copy",
|
|
146
139
|
args,
|
|
147
140
|
copyReqZ,
|
|
148
141
|
copyResZ,
|
|
@@ -151,7 +144,5 @@ export class Client {
|
|
|
151
144
|
}
|
|
152
145
|
}
|
|
153
146
|
|
|
154
|
-
export const ontologyID =
|
|
155
|
-
|
|
156
|
-
key,
|
|
157
|
-
});
|
|
147
|
+
export const ontologyID = ontology.createIDFactory<Key>("schematic");
|
|
148
|
+
export const TYPE_ONTOLOGY_ID = ontologyID("");
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
|
|
12
|
+
import { AuthError, NotFoundError } from "@/errors";
|
|
13
|
+
import { ontology } from "@/ontology";
|
|
14
|
+
import { group } from "@/ontology/group";
|
|
15
|
+
import { createTestClientWithPolicy } from "@/testutil/access";
|
|
16
|
+
import { createTestClient } from "@/testutil/client";
|
|
17
|
+
import { symbol } from "@/workspace/schematic/symbol";
|
|
18
|
+
|
|
19
|
+
const client = createTestClient();
|
|
20
|
+
|
|
21
|
+
describe("schematic_symbol", () => {
|
|
22
|
+
describe("access control", () => {
|
|
23
|
+
it("should deny access when no retrieve policy exists", async () => {
|
|
24
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
25
|
+
name: "test",
|
|
26
|
+
objects: [],
|
|
27
|
+
actions: [],
|
|
28
|
+
});
|
|
29
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
30
|
+
parent: ontology.ROOT_ID,
|
|
31
|
+
name: "Test Symbols",
|
|
32
|
+
});
|
|
33
|
+
const randomSymbol = await client.workspaces.schematics.symbols.create({
|
|
34
|
+
name: "test",
|
|
35
|
+
data: {
|
|
36
|
+
svg: "<svg></svg>",
|
|
37
|
+
states: [],
|
|
38
|
+
handles: [],
|
|
39
|
+
variant: "sensor",
|
|
40
|
+
},
|
|
41
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
42
|
+
});
|
|
43
|
+
await expect(
|
|
44
|
+
userClient.workspaces.schematics.symbols.retrieve({ key: randomSymbol.key }),
|
|
45
|
+
).rejects.toThrow(AuthError);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should allow the caller to retrieve symbols with the correct policy", async () => {
|
|
49
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
50
|
+
name: "test",
|
|
51
|
+
objects: [symbol.ontologyID("")],
|
|
52
|
+
actions: ["retrieve"],
|
|
53
|
+
});
|
|
54
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
55
|
+
parent: ontology.ROOT_ID,
|
|
56
|
+
name: "Test Symbols",
|
|
57
|
+
});
|
|
58
|
+
const randomSymbol = await client.workspaces.schematics.symbols.create({
|
|
59
|
+
name: "test",
|
|
60
|
+
data: {
|
|
61
|
+
svg: "<svg></svg>",
|
|
62
|
+
states: [],
|
|
63
|
+
handles: [],
|
|
64
|
+
variant: "sensor",
|
|
65
|
+
},
|
|
66
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
67
|
+
});
|
|
68
|
+
const retrieved = await userClient.workspaces.schematics.symbols.retrieve({
|
|
69
|
+
key: randomSymbol.key,
|
|
70
|
+
});
|
|
71
|
+
expect(retrieved.key).toBe(randomSymbol.key);
|
|
72
|
+
expect(retrieved.name).toBe(randomSymbol.name);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should allow the caller to create symbols with the correct policy", async () => {
|
|
76
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
77
|
+
name: "test",
|
|
78
|
+
objects: [symbol.ontologyID("")],
|
|
79
|
+
actions: ["create"],
|
|
80
|
+
});
|
|
81
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
82
|
+
parent: ontology.ROOT_ID,
|
|
83
|
+
name: "Test Symbols",
|
|
84
|
+
});
|
|
85
|
+
await userClient.workspaces.schematics.symbols.create({
|
|
86
|
+
name: "test",
|
|
87
|
+
data: {
|
|
88
|
+
svg: "<svg></svg>",
|
|
89
|
+
states: [],
|
|
90
|
+
handles: [],
|
|
91
|
+
variant: "sensor",
|
|
92
|
+
},
|
|
93
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("should deny access when no create policy exists", async () => {
|
|
98
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
99
|
+
name: "test",
|
|
100
|
+
objects: [symbol.ontologyID("")],
|
|
101
|
+
actions: [],
|
|
102
|
+
});
|
|
103
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
104
|
+
parent: ontology.ROOT_ID,
|
|
105
|
+
name: "Test Symbols",
|
|
106
|
+
});
|
|
107
|
+
await expect(
|
|
108
|
+
userClient.workspaces.schematics.symbols.create({
|
|
109
|
+
name: "test",
|
|
110
|
+
data: {
|
|
111
|
+
svg: "<svg></svg>",
|
|
112
|
+
states: [],
|
|
113
|
+
handles: [],
|
|
114
|
+
variant: "sensor",
|
|
115
|
+
},
|
|
116
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
117
|
+
}),
|
|
118
|
+
).rejects.toThrow(AuthError);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("should allow the caller to delete symbols with the correct policy", async () => {
|
|
122
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
123
|
+
name: "test",
|
|
124
|
+
objects: [symbol.ontologyID("")],
|
|
125
|
+
actions: ["delete", "retrieve"],
|
|
126
|
+
});
|
|
127
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
128
|
+
parent: ontology.ROOT_ID,
|
|
129
|
+
name: "Test Symbols",
|
|
130
|
+
});
|
|
131
|
+
const randomSymbol = await client.workspaces.schematics.symbols.create({
|
|
132
|
+
name: "test",
|
|
133
|
+
data: {
|
|
134
|
+
svg: "<svg></svg>",
|
|
135
|
+
states: [],
|
|
136
|
+
handles: [],
|
|
137
|
+
variant: "sensor",
|
|
138
|
+
},
|
|
139
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
140
|
+
});
|
|
141
|
+
await userClient.workspaces.schematics.symbols.delete(randomSymbol.key);
|
|
142
|
+
await expect(
|
|
143
|
+
userClient.workspaces.schematics.symbols.retrieve({ key: randomSymbol.key }),
|
|
144
|
+
).rejects.toThrow(NotFoundError);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("should deny access when no delete policy exists", async () => {
|
|
148
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
149
|
+
name: "test",
|
|
150
|
+
objects: [symbol.ontologyID("")],
|
|
151
|
+
actions: [],
|
|
152
|
+
});
|
|
153
|
+
const symbolGroup = await client.ontology.groups.create({
|
|
154
|
+
parent: ontology.ROOT_ID,
|
|
155
|
+
name: "Test Symbols",
|
|
156
|
+
});
|
|
157
|
+
const randomSymbol = await client.workspaces.schematics.symbols.create({
|
|
158
|
+
name: "test",
|
|
159
|
+
data: {
|
|
160
|
+
svg: "<svg></svg>",
|
|
161
|
+
states: [],
|
|
162
|
+
handles: [],
|
|
163
|
+
variant: "sensor",
|
|
164
|
+
},
|
|
165
|
+
parent: group.ontologyID(symbolGroup.key),
|
|
166
|
+
});
|
|
167
|
+
await expect(
|
|
168
|
+
userClient.workspaces.schematics.symbols.delete(randomSymbol.key),
|
|
169
|
+
).rejects.toThrow(AuthError);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -23,12 +23,6 @@ import {
|
|
|
23
23
|
symbolZ,
|
|
24
24
|
} from "@/workspace/schematic/symbol/payload";
|
|
25
25
|
|
|
26
|
-
const RETRIEVE_ENDPOINT = "/workspace/schematic/symbol/retrieve";
|
|
27
|
-
const CREATE_ENDPOINT = "/workspace/schematic/symbol/create";
|
|
28
|
-
const RENAME_ENDPOINT = "/workspace/schematic/symbol/rename";
|
|
29
|
-
const DELETE_ENDPOINT = "/workspace/schematic/symbol/delete";
|
|
30
|
-
const RETRIEVE_GROUP_ENDPOINT = "/workspace/schematic/symbol/retrieve_group";
|
|
31
|
-
|
|
32
26
|
const createReqZ = z.object({ symbols: newZ.array(), parent: ontology.idZ });
|
|
33
27
|
const renameReqZ = z.object({ key: keyZ, name: z.string() });
|
|
34
28
|
const deleteReqZ = z.object({ keys: keyZ.array() });
|
|
@@ -36,8 +30,6 @@ const deleteReqZ = z.object({ keys: keyZ.array() });
|
|
|
36
30
|
const retrieveRequestZ = z.object({
|
|
37
31
|
keys: keyZ.array().optional(),
|
|
38
32
|
searchTerm: z.string().optional(),
|
|
39
|
-
offset: z.number().optional(),
|
|
40
|
-
limit: z.number().optional(),
|
|
41
33
|
});
|
|
42
34
|
|
|
43
35
|
const singleRetrieveArgsZ = z
|
|
@@ -82,7 +74,7 @@ export class Client {
|
|
|
82
74
|
const symbols = isMany ? options.symbols : [options];
|
|
83
75
|
const res = await sendRequired(
|
|
84
76
|
this.client,
|
|
85
|
-
|
|
77
|
+
"/workspace/schematic/symbol/create",
|
|
86
78
|
{ symbols, parent: options.parent },
|
|
87
79
|
createReqZ,
|
|
88
80
|
createResZ,
|
|
@@ -93,7 +85,7 @@ export class Client {
|
|
|
93
85
|
async rename(key: Key, name: string): Promise<void> {
|
|
94
86
|
await sendRequired(
|
|
95
87
|
this.client,
|
|
96
|
-
|
|
88
|
+
"/workspace/schematic/symbol/rename",
|
|
97
89
|
{ key, name },
|
|
98
90
|
renameReqZ,
|
|
99
91
|
emptyResZ,
|
|
@@ -106,7 +98,7 @@ export class Client {
|
|
|
106
98
|
const isSingle = "key" in args;
|
|
107
99
|
const res = await sendRequired(
|
|
108
100
|
this.client,
|
|
109
|
-
|
|
101
|
+
"/workspace/schematic/symbol/retrieve",
|
|
110
102
|
args,
|
|
111
103
|
retrieveArgsZ,
|
|
112
104
|
retrieveResZ,
|
|
@@ -118,7 +110,7 @@ export class Client {
|
|
|
118
110
|
async delete(keys: Key | Key[]): Promise<void> {
|
|
119
111
|
await sendRequired(
|
|
120
112
|
this.client,
|
|
121
|
-
|
|
113
|
+
"/workspace/schematic/symbol/delete",
|
|
122
114
|
{ keys: array.toArray(keys) },
|
|
123
115
|
deleteReqZ,
|
|
124
116
|
emptyResZ,
|
|
@@ -128,7 +120,7 @@ export class Client {
|
|
|
128
120
|
async retrieveGroup(): Promise<group.Group> {
|
|
129
121
|
const res = await sendRequired(
|
|
130
122
|
this.client,
|
|
131
|
-
|
|
123
|
+
"/workspace/schematic/symbol/retrieve_group",
|
|
132
124
|
{},
|
|
133
125
|
retrieveGroupReqZ,
|
|
134
126
|
retrieveGroupResZ,
|
|
@@ -137,7 +129,4 @@ export class Client {
|
|
|
137
129
|
}
|
|
138
130
|
}
|
|
139
131
|
|
|
140
|
-
export const ontologyID =
|
|
141
|
-
type: "schematic_symbol",
|
|
142
|
-
key,
|
|
143
|
-
});
|
|
132
|
+
export const ontologyID = ontology.createIDFactory<Key>("schematic_symbol");
|
|
@@ -59,7 +59,7 @@ export interface Spec extends z.infer<typeof specZ> {}
|
|
|
59
59
|
|
|
60
60
|
export const symbolZ = z.object({
|
|
61
61
|
key: keyZ,
|
|
62
|
-
version: z.literal(1).
|
|
62
|
+
version: z.literal(1).default(1),
|
|
63
63
|
name: z.string().min(1, "Name is required"),
|
|
64
64
|
data: specZ,
|
|
65
65
|
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
+
// licenses/BSL.txt.
|
|
5
|
+
//
|
|
6
|
+
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
+
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
+
// included in the file licenses/APL.txt.
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
|
|
12
|
+
import { AuthError, NotFoundError } from "@/errors";
|
|
13
|
+
import { createTestClientWithPolicy } from "@/testutil/access";
|
|
14
|
+
import { createTestClient } from "@/testutil/client";
|
|
15
|
+
import { table } from "@/workspace/table";
|
|
16
|
+
|
|
17
|
+
const client = createTestClient();
|
|
18
|
+
|
|
19
|
+
describe("table", () => {
|
|
20
|
+
describe("access control", () => {
|
|
21
|
+
it("should deny access when no retrieve policy exists", async () => {
|
|
22
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
23
|
+
name: "test",
|
|
24
|
+
objects: [],
|
|
25
|
+
actions: [],
|
|
26
|
+
});
|
|
27
|
+
const ws = await client.workspaces.create({
|
|
28
|
+
name: "test",
|
|
29
|
+
layout: {},
|
|
30
|
+
});
|
|
31
|
+
const randomTable = await client.workspaces.tables.create(ws.key, {
|
|
32
|
+
name: "test",
|
|
33
|
+
data: {},
|
|
34
|
+
});
|
|
35
|
+
await expect(
|
|
36
|
+
userClient.workspaces.tables.retrieve({ key: randomTable.key }),
|
|
37
|
+
).rejects.toThrow(AuthError);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should allow the caller to retrieve tables with the correct policy", async () => {
|
|
41
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
42
|
+
name: "test",
|
|
43
|
+
objects: [table.ontologyID("")],
|
|
44
|
+
actions: ["retrieve"],
|
|
45
|
+
});
|
|
46
|
+
const ws = await client.workspaces.create({
|
|
47
|
+
name: "test",
|
|
48
|
+
layout: {},
|
|
49
|
+
});
|
|
50
|
+
const randomTable = await client.workspaces.tables.create(ws.key, {
|
|
51
|
+
name: "test",
|
|
52
|
+
data: {},
|
|
53
|
+
});
|
|
54
|
+
const retrieved = await userClient.workspaces.tables.retrieve({
|
|
55
|
+
key: randomTable.key,
|
|
56
|
+
});
|
|
57
|
+
expect(retrieved.key).toBe(randomTable.key);
|
|
58
|
+
expect(retrieved.name).toBe(randomTable.name);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should allow the caller to create tables with the correct policy", async () => {
|
|
62
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
63
|
+
name: "test",
|
|
64
|
+
objects: [table.ontologyID("")],
|
|
65
|
+
actions: ["create"],
|
|
66
|
+
});
|
|
67
|
+
const ws = await client.workspaces.create({
|
|
68
|
+
name: "test",
|
|
69
|
+
layout: {},
|
|
70
|
+
});
|
|
71
|
+
await userClient.workspaces.tables.create(ws.key, {
|
|
72
|
+
name: "test",
|
|
73
|
+
data: {},
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should deny access when no create policy exists", async () => {
|
|
78
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
79
|
+
name: "test",
|
|
80
|
+
objects: [table.ontologyID("")],
|
|
81
|
+
actions: [],
|
|
82
|
+
});
|
|
83
|
+
const ws = await client.workspaces.create({
|
|
84
|
+
name: "test",
|
|
85
|
+
layout: {},
|
|
86
|
+
});
|
|
87
|
+
await expect(
|
|
88
|
+
userClient.workspaces.tables.create(ws.key, {
|
|
89
|
+
name: "test",
|
|
90
|
+
data: {},
|
|
91
|
+
}),
|
|
92
|
+
).rejects.toThrow(AuthError);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("should allow the caller to delete tables with the correct policy", async () => {
|
|
96
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
97
|
+
name: "test",
|
|
98
|
+
objects: [table.ontologyID("")],
|
|
99
|
+
actions: ["delete", "retrieve"],
|
|
100
|
+
});
|
|
101
|
+
const ws = await client.workspaces.create({
|
|
102
|
+
name: "test",
|
|
103
|
+
layout: {},
|
|
104
|
+
});
|
|
105
|
+
const randomTable = await client.workspaces.tables.create(ws.key, {
|
|
106
|
+
name: "test",
|
|
107
|
+
data: {},
|
|
108
|
+
});
|
|
109
|
+
await userClient.workspaces.tables.delete(randomTable.key);
|
|
110
|
+
await expect(
|
|
111
|
+
userClient.workspaces.tables.retrieve({ key: randomTable.key }),
|
|
112
|
+
).rejects.toThrow(NotFoundError);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("should deny access when no delete policy exists", async () => {
|
|
116
|
+
const userClient = await createTestClientWithPolicy(client, {
|
|
117
|
+
name: "test",
|
|
118
|
+
objects: [table.ontologyID("")],
|
|
119
|
+
actions: [],
|
|
120
|
+
});
|
|
121
|
+
const ws = await client.workspaces.create({
|
|
122
|
+
name: "test",
|
|
123
|
+
layout: {},
|
|
124
|
+
});
|
|
125
|
+
const randomTable = await client.workspaces.tables.create(ws.key, {
|
|
126
|
+
name: "test",
|
|
127
|
+
data: {},
|
|
128
|
+
});
|
|
129
|
+
await expect(
|
|
130
|
+
userClient.workspaces.tables.delete(randomTable.key),
|
|
131
|
+
).rejects.toThrow(AuthError);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|