@synnaxlabs/client 0.48.0 → 0.49.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.
Files changed (300) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/dist/client.cjs +33 -31
  3. package/dist/client.js +6522 -6167
  4. package/dist/src/access/client.d.ts +3 -1
  5. package/dist/src/access/client.d.ts.map +1 -1
  6. package/dist/src/access/enforce.d.ts +35 -0
  7. package/dist/src/access/enforce.d.ts.map +1 -0
  8. package/dist/src/access/enforce.spec.d.ts +2 -0
  9. package/dist/src/access/enforce.spec.d.ts.map +1 -0
  10. package/dist/src/access/external.d.ts +3 -0
  11. package/dist/src/access/external.d.ts.map +1 -1
  12. package/dist/src/access/payload.d.ts +0 -6
  13. package/dist/src/access/payload.d.ts.map +1 -1
  14. package/dist/src/access/policy/access.spec.d.ts +2 -0
  15. package/dist/src/access/policy/access.spec.d.ts.map +1 -0
  16. package/dist/src/access/policy/client.d.ts +485 -31
  17. package/dist/src/access/policy/client.d.ts.map +1 -1
  18. package/dist/src/access/policy/payload.d.ts +36 -113
  19. package/dist/src/access/policy/payload.d.ts.map +1 -1
  20. package/dist/src/access/role/client.d.ts +135 -0
  21. package/dist/src/access/role/client.d.ts.map +1 -0
  22. package/dist/src/access/role/external.d.ts.map +1 -0
  23. package/dist/src/access/role/index.d.ts +2 -0
  24. package/dist/src/access/role/index.d.ts.map +1 -0
  25. package/dist/src/access/role/payload.d.ts +27 -0
  26. package/dist/src/access/role/payload.d.ts.map +1 -0
  27. package/dist/src/access/role/role.spec.d.ts +2 -0
  28. package/dist/src/access/role/role.spec.d.ts.map +1 -0
  29. package/dist/src/arc/access.spec.d.ts +2 -0
  30. package/dist/src/arc/access.spec.d.ts.map +1 -0
  31. package/dist/src/arc/client.d.ts +5 -14
  32. package/dist/src/arc/client.d.ts.map +1 -1
  33. package/dist/src/arc/payload.d.ts +11 -2
  34. package/dist/src/arc/payload.d.ts.map +1 -1
  35. package/dist/src/auth/auth.d.ts +5 -3
  36. package/dist/src/auth/auth.d.ts.map +1 -1
  37. package/dist/src/channel/access.spec.d.ts +2 -0
  38. package/dist/src/channel/access.spec.d.ts.map +1 -0
  39. package/dist/src/channel/client.d.ts +0 -1
  40. package/dist/src/channel/client.d.ts.map +1 -1
  41. package/dist/src/channel/payload.d.ts +18 -8
  42. package/dist/src/channel/payload.d.ts.map +1 -1
  43. package/dist/src/channel/payload.spec.d.ts +2 -0
  44. package/dist/src/channel/payload.spec.d.ts.map +1 -0
  45. package/dist/src/channel/retriever.d.ts +4 -6
  46. package/dist/src/channel/retriever.d.ts.map +1 -1
  47. package/dist/src/channel/writer.d.ts.map +1 -1
  48. package/dist/src/client.d.ts +9 -5
  49. package/dist/src/client.d.ts.map +1 -1
  50. package/dist/src/device/access.spec.d.ts +2 -0
  51. package/dist/src/device/access.spec.d.ts.map +1 -0
  52. package/dist/src/{hardware/device → device}/client.d.ts +14 -7
  53. package/dist/src/device/client.d.ts.map +1 -0
  54. package/dist/src/device/device.spec.d.ts.map +1 -0
  55. package/dist/src/device/external.d.ts.map +1 -0
  56. package/dist/src/device/index.d.ts.map +1 -0
  57. package/dist/src/{hardware/device → device}/payload.d.ts +1 -1
  58. package/dist/src/device/payload.d.ts.map +1 -0
  59. package/dist/src/errors.d.ts +3 -0
  60. package/dist/src/errors.d.ts.map +1 -1
  61. package/dist/src/framer/client.d.ts +11 -1
  62. package/dist/src/framer/client.d.ts.map +1 -1
  63. package/dist/src/framer/frame.d.ts +10 -5
  64. package/dist/src/framer/frame.d.ts.map +1 -1
  65. package/dist/src/framer/iterator.d.ts +3 -3
  66. package/dist/src/framer/reader.d.ts +16 -0
  67. package/dist/src/framer/reader.d.ts.map +1 -0
  68. package/dist/src/framer/reader.spec.d.ts +2 -0
  69. package/dist/src/framer/reader.spec.d.ts.map +1 -0
  70. package/dist/src/framer/streamer.d.ts +24 -21
  71. package/dist/src/framer/streamer.d.ts.map +1 -1
  72. package/dist/src/framer/writer.d.ts +13 -13
  73. package/dist/src/index.d.ts +4 -5
  74. package/dist/src/index.d.ts.map +1 -1
  75. package/dist/src/label/access.spec.d.ts +2 -0
  76. package/dist/src/label/access.spec.d.ts.map +1 -0
  77. package/dist/src/label/client.d.ts +20 -11
  78. package/dist/src/label/client.d.ts.map +1 -1
  79. package/dist/src/ontology/client.d.ts +6 -6
  80. package/dist/src/ontology/client.d.ts.map +1 -1
  81. package/dist/src/ontology/group/access.spec.d.ts +2 -0
  82. package/dist/src/ontology/group/access.spec.d.ts.map +1 -0
  83. package/dist/src/ontology/group/client.d.ts +2 -2
  84. package/dist/src/ontology/group/client.d.ts.map +1 -1
  85. package/dist/src/ontology/group/payload.d.ts +1 -2
  86. package/dist/src/ontology/group/payload.d.ts.map +1 -1
  87. package/dist/src/ontology/payload.d.ts +23 -17
  88. package/dist/src/ontology/payload.d.ts.map +1 -1
  89. package/dist/src/ontology/writer.d.ts +10 -10
  90. package/dist/src/ontology/writer.d.ts.map +1 -1
  91. package/dist/src/rack/access.spec.d.ts +2 -0
  92. package/dist/src/rack/access.spec.d.ts.map +1 -0
  93. package/dist/src/{hardware/rack → rack}/client.d.ts +15 -8
  94. package/dist/src/rack/client.d.ts.map +1 -0
  95. package/dist/src/rack/external.d.ts.map +1 -0
  96. package/dist/src/rack/index.d.ts.map +1 -0
  97. package/dist/src/{hardware/rack → rack}/payload.d.ts +1 -1
  98. package/dist/src/rack/payload.d.ts.map +1 -0
  99. package/dist/src/rack/rack.spec.d.ts.map +1 -0
  100. package/dist/src/ranger/access.spec.d.ts +2 -0
  101. package/dist/src/ranger/access.spec.d.ts.map +1 -0
  102. package/dist/src/ranger/alias.d.ts +1 -8
  103. package/dist/src/ranger/alias.d.ts.map +1 -1
  104. package/dist/src/ranger/client.d.ts +12 -5
  105. package/dist/src/ranger/client.d.ts.map +1 -1
  106. package/dist/src/ranger/kv.d.ts +0 -3
  107. package/dist/src/ranger/kv.d.ts.map +1 -1
  108. package/dist/src/ranger/writer.d.ts +2 -2
  109. package/dist/src/ranger/writer.d.ts.map +1 -1
  110. package/dist/src/status/access.spec.d.ts +2 -0
  111. package/dist/src/status/access.spec.d.ts.map +1 -0
  112. package/dist/src/status/client.d.ts +4 -4
  113. package/dist/src/status/client.d.ts.map +1 -1
  114. package/dist/src/status/payload.d.ts +9 -2
  115. package/dist/src/status/payload.d.ts.map +1 -1
  116. package/dist/src/task/access.spec.d.ts +2 -0
  117. package/dist/src/task/access.spec.d.ts.map +1 -0
  118. package/dist/src/{hardware/task → task}/client.d.ts +26 -15
  119. package/dist/src/task/client.d.ts.map +1 -0
  120. package/dist/src/task/external.d.ts +3 -0
  121. package/dist/src/task/external.d.ts.map +1 -0
  122. package/dist/src/task/index.d.ts.map +1 -0
  123. package/dist/src/{hardware/task → task}/payload.d.ts +45 -6
  124. package/dist/src/task/payload.d.ts.map +1 -0
  125. package/dist/src/task/task.spec.d.ts.map +1 -0
  126. package/dist/src/testutil/access.d.ts +4 -0
  127. package/dist/src/testutil/access.d.ts.map +1 -0
  128. package/dist/src/transport.d.ts.map +1 -1
  129. package/dist/src/user/access.spec.d.ts +2 -0
  130. package/dist/src/user/access.spec.d.ts.map +1 -0
  131. package/dist/src/user/client.d.ts +10 -1
  132. package/dist/src/user/client.d.ts.map +1 -1
  133. package/dist/src/user/external.d.ts +1 -1
  134. package/dist/src/user/external.d.ts.map +1 -1
  135. package/dist/src/user/payload.d.ts.map +1 -1
  136. package/dist/src/workspace/access.spec.d.ts +2 -0
  137. package/dist/src/workspace/access.spec.d.ts.map +1 -0
  138. package/dist/src/workspace/client.d.ts +10 -5
  139. package/dist/src/workspace/client.d.ts.map +1 -1
  140. package/dist/src/workspace/lineplot/access.spec.d.ts +2 -0
  141. package/dist/src/workspace/lineplot/access.spec.d.ts.map +1 -0
  142. package/dist/src/workspace/lineplot/client.d.ts +8 -1
  143. package/dist/src/workspace/lineplot/client.d.ts.map +1 -1
  144. package/dist/src/workspace/log/access.spec.d.ts +2 -0
  145. package/dist/src/workspace/log/access.spec.d.ts.map +1 -0
  146. package/dist/src/workspace/log/client.d.ts +8 -1
  147. package/dist/src/workspace/log/client.d.ts.map +1 -1
  148. package/dist/src/workspace/schematic/access.spec.d.ts +2 -0
  149. package/dist/src/workspace/schematic/access.spec.d.ts.map +1 -0
  150. package/dist/src/workspace/schematic/client.d.ts +8 -1
  151. package/dist/src/workspace/schematic/client.d.ts.map +1 -1
  152. package/dist/src/workspace/schematic/symbol/access.spec.d.ts +2 -0
  153. package/dist/src/workspace/schematic/symbol/access.spec.d.ts.map +1 -0
  154. package/dist/src/workspace/schematic/symbol/client.d.ts +1 -5
  155. package/dist/src/workspace/schematic/symbol/client.d.ts.map +1 -1
  156. package/dist/src/workspace/schematic/symbol/payload.d.ts +2 -2
  157. package/dist/src/workspace/table/access.spec.d.ts +2 -0
  158. package/dist/src/workspace/table/access.spec.d.ts.map +1 -0
  159. package/dist/src/workspace/table/client.d.ts +8 -1
  160. package/dist/src/workspace/table/client.d.ts.map +1 -1
  161. package/package.json +3 -3
  162. package/src/access/client.ts +5 -2
  163. package/src/access/enforce.spec.ts +189 -0
  164. package/src/access/enforce.ts +84 -0
  165. package/src/access/external.ts +3 -0
  166. package/src/access/payload.ts +1 -13
  167. package/src/access/policy/access.spec.ts +147 -0
  168. package/src/access/policy/client.ts +21 -25
  169. package/src/access/policy/payload.ts +9 -5
  170. package/src/access/role/client.ts +135 -0
  171. package/src/access/role/external.ts +11 -0
  172. package/src/{hardware → access/role}/index.ts +1 -1
  173. package/src/access/role/payload.ts +32 -0
  174. package/src/access/role/role.spec.ts +95 -0
  175. package/src/arc/access.spec.ts +143 -0
  176. package/src/arc/client.ts +7 -31
  177. package/src/arc/payload.ts +4 -0
  178. package/src/auth/auth.ts +33 -11
  179. package/src/channel/access.spec.ts +116 -0
  180. package/src/channel/channel.spec.ts +63 -73
  181. package/src/channel/client.ts +2 -8
  182. package/src/channel/payload.spec.ts +171 -0
  183. package/src/channel/payload.ts +35 -7
  184. package/src/channel/retriever.ts +10 -11
  185. package/src/channel/writer.ts +3 -7
  186. package/src/client.ts +14 -18
  187. package/src/device/access.spec.ts +159 -0
  188. package/src/{hardware/device → device}/client.ts +12 -21
  189. package/src/{hardware/device → device}/device.spec.ts +70 -34
  190. package/src/device/external.ts +11 -0
  191. package/src/{hardware/rack → device}/index.ts +1 -1
  192. package/src/{hardware/device → device}/payload.ts +3 -3
  193. package/src/errors.ts +2 -0
  194. package/src/framer/adapter.spec.ts +14 -14
  195. package/src/framer/client.spec.ts +14 -20
  196. package/src/framer/client.ts +15 -20
  197. package/src/framer/deleter.spec.ts +1 -1
  198. package/src/framer/frame.spec.ts +131 -0
  199. package/src/framer/frame.ts +10 -2
  200. package/src/framer/iterator.ts +3 -3
  201. package/src/framer/reader.spec.ts +736 -0
  202. package/src/framer/reader.ts +265 -0
  203. package/src/framer/streamer.spec.ts +100 -12
  204. package/src/framer/streamer.ts +29 -9
  205. package/src/framer/writer.spec.ts +5 -5
  206. package/src/index.ts +4 -5
  207. package/src/label/access.spec.ts +109 -0
  208. package/src/label/client.ts +10 -14
  209. package/src/ontology/client.ts +4 -6
  210. package/src/ontology/group/access.spec.ts +77 -0
  211. package/src/ontology/group/client.ts +3 -7
  212. package/src/ontology/group/group.spec.ts +18 -0
  213. package/src/ontology/group/payload.ts +2 -2
  214. package/src/ontology/ontology.spec.ts +2 -0
  215. package/src/ontology/payload.ts +18 -2
  216. package/src/ontology/writer.ts +3 -7
  217. package/src/rack/access.spec.ts +102 -0
  218. package/src/{hardware/rack → rack}/client.ts +14 -19
  219. package/src/{hardware/device/index.ts → rack/external.ts} +2 -1
  220. package/src/{hardware/external.ts → rack/index.ts} +1 -1
  221. package/src/{hardware/rack → rack}/payload.ts +2 -2
  222. package/src/{hardware/rack → rack}/rack.spec.ts +43 -17
  223. package/src/ranger/access.spec.ts +115 -0
  224. package/src/ranger/alias.ts +6 -14
  225. package/src/ranger/client.ts +13 -14
  226. package/src/ranger/kv.ts +7 -9
  227. package/src/ranger/ranger.spec.ts +4 -4
  228. package/src/ranger/writer.ts +3 -7
  229. package/src/status/access.spec.ts +129 -0
  230. package/src/status/client.ts +5 -9
  231. package/src/status/payload.ts +3 -2
  232. package/src/task/access.spec.ts +131 -0
  233. package/src/{hardware/task → task}/client.ts +50 -25
  234. package/src/task/external.ts +11 -0
  235. package/src/{hardware/task → task}/index.ts +1 -1
  236. package/src/{hardware/task → task}/payload.ts +22 -3
  237. package/src/{hardware/task → task}/task.spec.ts +197 -34
  238. package/src/testutil/access.ts +34 -0
  239. package/src/testutil/channels.ts +3 -3
  240. package/src/transport.ts +1 -3
  241. package/src/user/access.spec.ts +107 -0
  242. package/src/user/client.ts +10 -12
  243. package/src/user/external.ts +12 -1
  244. package/src/user/payload.ts +3 -5
  245. package/src/workspace/access.spec.ts +108 -0
  246. package/src/workspace/client.ts +11 -27
  247. package/src/workspace/lineplot/access.spec.ts +134 -0
  248. package/src/workspace/lineplot/client.ts +8 -13
  249. package/src/workspace/log/access.spec.ts +134 -0
  250. package/src/workspace/log/client.ts +8 -13
  251. package/src/workspace/schematic/access.spec.ts +134 -0
  252. package/src/workspace/schematic/client.ts +9 -18
  253. package/src/workspace/schematic/symbol/access.spec.ts +172 -0
  254. package/src/workspace/schematic/symbol/client.ts +6 -17
  255. package/src/workspace/schematic/symbol/payload.ts +1 -1
  256. package/src/workspace/table/access.spec.ts +134 -0
  257. package/src/workspace/table/client.ts +8 -13
  258. package/dist/src/access/policy/policy.spec.d.ts +0 -2
  259. package/dist/src/access/policy/policy.spec.d.ts.map +0 -1
  260. package/dist/src/hardware/client.d.ts +0 -10
  261. package/dist/src/hardware/client.d.ts.map +0 -1
  262. package/dist/src/hardware/device/client.d.ts.map +0 -1
  263. package/dist/src/hardware/device/device.spec.d.ts.map +0 -1
  264. package/dist/src/hardware/device/external.d.ts.map +0 -1
  265. package/dist/src/hardware/device/index.d.ts.map +0 -1
  266. package/dist/src/hardware/device/payload.d.ts.map +0 -1
  267. package/dist/src/hardware/external.d.ts +0 -2
  268. package/dist/src/hardware/external.d.ts.map +0 -1
  269. package/dist/src/hardware/index.d.ts +0 -2
  270. package/dist/src/hardware/index.d.ts.map +0 -1
  271. package/dist/src/hardware/rack/client.d.ts.map +0 -1
  272. package/dist/src/hardware/rack/external.d.ts.map +0 -1
  273. package/dist/src/hardware/rack/index.d.ts.map +0 -1
  274. package/dist/src/hardware/rack/payload.d.ts.map +0 -1
  275. package/dist/src/hardware/rack/rack.spec.d.ts.map +0 -1
  276. package/dist/src/hardware/task/client.d.ts.map +0 -1
  277. package/dist/src/hardware/task/external.d.ts.map +0 -1
  278. package/dist/src/hardware/task/index.d.ts.map +0 -1
  279. package/dist/src/hardware/task/payload.d.ts.map +0 -1
  280. package/dist/src/hardware/task/task.spec.d.ts.map +0 -1
  281. package/dist/src/user/retriever.d.ts +0 -16
  282. package/dist/src/user/retriever.d.ts.map +0 -1
  283. package/dist/src/user/writer.d.ts +0 -11
  284. package/dist/src/user/writer.d.ts.map +0 -1
  285. package/src/access/policy/policy.spec.ts +0 -329
  286. package/src/hardware/client.ts +0 -24
  287. package/src/hardware/device/external.ts +0 -11
  288. package/src/hardware/rack/external.ts +0 -11
  289. package/src/hardware/task/external.ts +0 -11
  290. package/src/user/retriever.ts +0 -41
  291. package/src/user/writer.ts +0 -84
  292. /package/dist/src/{hardware/device → access/role}/external.d.ts +0 -0
  293. /package/dist/src/{hardware/device → device}/device.spec.d.ts +0 -0
  294. /package/dist/src/{hardware/rack → device}/external.d.ts +0 -0
  295. /package/dist/src/{hardware/device → device}/index.d.ts +0 -0
  296. /package/dist/src/{hardware/task → rack}/external.d.ts +0 -0
  297. /package/dist/src/{hardware/rack → rack}/index.d.ts +0 -0
  298. /package/dist/src/{hardware/rack → rack}/rack.spec.d.ts +0 -0
  299. /package/dist/src/{hardware/task → task}/index.d.ts +0 -0
  300. /package/dist/src/{hardware/task → task}/task.spec.d.ts +0 -0
@@ -12,7 +12,7 @@ import { array } from "@synnaxlabs/x";
12
12
  import { z } from "zod";
13
13
 
14
14
  import { MultipleFoundError, NotFoundError } from "@/errors";
15
- import { type ontology } from "@/ontology";
15
+ import { ontology } from "@/ontology";
16
16
  import { type Key, keyZ, type New, newZ, type User, userZ } from "@/user/payload";
17
17
 
18
18
  const retrieveRequestZ = z.object({
@@ -68,11 +68,8 @@ const renameResZ = z.object({});
68
68
  const deleteReqZ = z.object({ keys: keyZ.array() });
69
69
  const deleteResZ = z.object({});
70
70
 
71
- const RETRIEVE_ENDPOINT = "/user/retrieve";
72
- const CREATE_ENDPOINT = "/user/create";
73
- const CHANGE_USERNAME_ENDPOINT = "/user/change-username";
74
- const RENAME_ENDPOINT = "/user/rename";
75
- const DELETE_ENDPOINT = "/user/delete";
71
+ export const SET_CHANNEL_NAME = "sy_user_set";
72
+ export const DELETE_CHANNEL_NAME = "sy_user_delete";
76
73
 
77
74
  export class Client {
78
75
  private readonly client: UnaryClient;
@@ -87,7 +84,7 @@ export class Client {
87
84
  const isMany = Array.isArray(users);
88
85
  const res = await sendRequired<typeof createReqZ, typeof createResZ>(
89
86
  this.client,
90
- CREATE_ENDPOINT,
87
+ "/user/create",
91
88
  { users: array.toArray(users) },
92
89
  createReqZ,
93
90
  createResZ,
@@ -98,7 +95,7 @@ export class Client {
98
95
  async changeUsername(key: Key, newUsername: string): Promise<void> {
99
96
  await sendRequired<typeof changeUsernameReqZ, typeof changeUsernameResZ>(
100
97
  this.client,
101
- CHANGE_USERNAME_ENDPOINT,
98
+ "/user/change-username",
102
99
  { key, username: newUsername },
103
100
  changeUsernameReqZ,
104
101
  changeUsernameResZ,
@@ -112,7 +109,7 @@ export class Client {
112
109
  const isSingle = "key" in args || "username" in args;
113
110
  const res = await sendRequired<typeof retrieveArgsZ, typeof retrieveResZ>(
114
111
  this.client,
115
- RETRIEVE_ENDPOINT,
112
+ "/user/retrieve",
116
113
  args,
117
114
  retrieveArgsZ,
118
115
  retrieveResZ,
@@ -136,7 +133,7 @@ export class Client {
136
133
  async rename(key: Key, firstName?: string, lastName?: string): Promise<void> {
137
134
  await sendRequired<typeof renameReqZ, typeof renameResZ>(
138
135
  this.client,
139
- RENAME_ENDPOINT,
136
+ "/user/rename",
140
137
  { key, firstName, lastName },
141
138
  renameReqZ,
142
139
  renameResZ,
@@ -148,7 +145,7 @@ export class Client {
148
145
  async delete(keys: Key | Key[]): Promise<void> {
149
146
  await sendRequired<typeof deleteReqZ, typeof deleteResZ>(
150
147
  this.client,
151
- DELETE_ENDPOINT,
148
+ "/user/delete",
152
149
  { keys: array.toArray(keys) },
153
150
  deleteReqZ,
154
151
  deleteResZ,
@@ -156,4 +153,5 @@ export class Client {
156
153
  }
157
154
  }
158
155
 
159
- export const ontologyID = (key: Key): ontology.ID => ({ type: "user", key });
156
+ export const ontologyID = ontology.createIDFactory<Key>("user");
157
+ export const TYPE_ONTOLOGY_ID = ontologyID("");
@@ -7,5 +7,16 @@
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 * from "@/user/client";
10
+ export {
11
+ Client,
12
+ DELETE_CHANNEL_NAME,
13
+ type KeyRetrieveRequest,
14
+ ontologyID,
15
+ type RetrieveArgs,
16
+ type RetrieveRequest,
17
+ SET_CHANNEL_NAME,
18
+ TYPE_ONTOLOGY_ID,
19
+ type UsernameRetrieveRequest,
20
+ type UsernamesRetrieveRequest,
21
+ } from "@/user/client";
11
22
  export * from "@/user/payload";
@@ -15,17 +15,15 @@ export type Key = z.infer<typeof keyZ>;
15
15
  export const userZ = z.object({
16
16
  key: keyZ,
17
17
  username: z.string().min(1, "Username is required"),
18
- // defaults for firstName, lastName, and rootUser are done to give compatibility with
19
- // servers running v0.30.x and earlier. These defaults should be removed in a future
20
- // release.
21
18
  firstName: z.string().default(""),
22
19
  lastName: z.string().default(""),
23
- rootUser: z.boolean().default(true),
20
+ rootUser: z.boolean().default(false),
24
21
  });
22
+
25
23
  export interface User extends z.infer<typeof userZ> {}
26
24
 
27
25
  export const newZ = userZ
28
- .partial({ key: true, firstName: true, lastName: true })
29
26
  .omit({ rootUser: true })
27
+ .partial({ key: true, firstName: true, lastName: true })
30
28
  .extend({ password: z.string().min(1) });
31
29
  export interface New extends z.infer<typeof newZ> {}
@@ -0,0 +1,108 @@
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 { workspace } from "@/workspace";
16
+
17
+ const client = createTestClient();
18
+
19
+ describe("workspace", () => {
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 randomWorkspace = await client.workspaces.create({
28
+ name: "test",
29
+ layout: {},
30
+ });
31
+ await expect(userClient.workspaces.retrieve(randomWorkspace.key)).rejects.toThrow(
32
+ AuthError,
33
+ );
34
+ });
35
+
36
+ it("should allow the caller to retrieve workspaces with the correct policy", async () => {
37
+ const userClient = await createTestClientWithPolicy(client, {
38
+ name: "test",
39
+ objects: [workspace.ontologyID("")],
40
+ actions: ["retrieve"],
41
+ });
42
+ const randomWorkspace = await client.workspaces.create({
43
+ name: "test",
44
+ layout: {},
45
+ });
46
+ const retrieved = await userClient.workspaces.retrieve(randomWorkspace.key);
47
+ expect(retrieved.key).toBe(randomWorkspace.key);
48
+ expect(retrieved.name).toBe(randomWorkspace.name);
49
+ });
50
+
51
+ it("should allow the caller to create workspaces with the correct policy", async () => {
52
+ const userClient = await createTestClientWithPolicy(client, {
53
+ name: "test",
54
+ objects: [workspace.ontologyID("")],
55
+ actions: ["create"],
56
+ });
57
+ await userClient.workspaces.create({
58
+ name: "test",
59
+ layout: {},
60
+ });
61
+ });
62
+
63
+ it("should deny access when no create policy exists", async () => {
64
+ const userClient = await createTestClientWithPolicy(client, {
65
+ name: "test",
66
+ objects: [workspace.ontologyID("")],
67
+ actions: [],
68
+ });
69
+ await expect(
70
+ userClient.workspaces.create({
71
+ name: "test",
72
+ layout: {},
73
+ }),
74
+ ).rejects.toThrow(AuthError);
75
+ });
76
+
77
+ it("should allow the caller to delete workspaces with the correct policy", async () => {
78
+ const userClient = await createTestClientWithPolicy(client, {
79
+ name: "test",
80
+ objects: [workspace.ontologyID("")],
81
+ actions: ["delete"],
82
+ });
83
+ const randomWorkspace = await client.workspaces.create({
84
+ name: "test",
85
+ layout: {},
86
+ });
87
+ await userClient.workspaces.delete(randomWorkspace.key);
88
+ await expect(userClient.workspaces.retrieve(randomWorkspace.key)).rejects.toThrow(
89
+ NotFoundError,
90
+ );
91
+ });
92
+
93
+ it("should deny access when no delete policy exists", async () => {
94
+ const userClient = await createTestClientWithPolicy(client, {
95
+ name: "test",
96
+ objects: [workspace.ontologyID("")],
97
+ actions: [],
98
+ });
99
+ const randomWorkspace = await client.workspaces.create({
100
+ name: "test",
101
+ layout: {},
102
+ });
103
+ await expect(userClient.workspaces.delete(randomWorkspace.key)).rejects.toThrow(
104
+ AuthError,
105
+ );
106
+ });
107
+ });
108
+ });
@@ -11,8 +11,8 @@ import { sendRequired, type UnaryClient } from "@synnaxlabs/freighter";
11
11
  import { array, record } from "@synnaxlabs/x";
12
12
  import { z } from "zod";
13
13
 
14
- import { type ontology } from "@/ontology";
15
- import { type Key as UserKey, keyZ as userKeyZ } from "@/user/payload";
14
+ import { ontology } from "@/ontology";
15
+ import { keyZ as userKeyZ } from "@/user/payload";
16
16
  import { lineplot } from "@/workspace/lineplot";
17
17
  import { log } from "@/workspace/log";
18
18
  import {
@@ -28,18 +28,12 @@ import {
28
28
  import { schematic } from "@/workspace/schematic";
29
29
  import { table } from "@/workspace/table";
30
30
 
31
- const RETRIEVE_ENDPOINT = "/workspace/retrieve";
32
- const CREATE_ENDPOINT = "/workspace/create";
33
- const RENAME_ENDPOINT = "/workspace/rename";
34
- const SET_LAYOUT_ENDPOINT = "/workspace/set-layout";
35
- const DELETE_ENDPOINT = "/workspace/delete";
36
-
37
31
  const retrieveReqZ = z.object({
38
32
  keys: keyZ.array().optional(),
39
33
  searchTerm: z.string().optional(),
40
34
  author: userKeyZ.optional(),
41
- offset: z.number().optional(),
42
- limit: z.number().optional(),
35
+ offset: z.int().optional(),
36
+ limit: z.int().optional(),
43
37
  });
44
38
  export interface RetrieveRequest extends z.infer<typeof retrieveReqZ> {}
45
39
  const createReqZ = z.object({ workspaces: newZ.array() });
@@ -80,7 +74,7 @@ export class Client {
80
74
  const isMany = Array.isArray(workspaces);
81
75
  const res = await sendRequired(
82
76
  this.client,
83
- CREATE_ENDPOINT,
77
+ "/workspace/create",
84
78
  { workspaces: array.toArray(workspaces) },
85
79
  createReqZ,
86
80
  createResZ,
@@ -91,7 +85,7 @@ export class Client {
91
85
  async rename(key: Key, name: string): Promise<void> {
92
86
  await sendRequired(
93
87
  this.client,
94
- RENAME_ENDPOINT,
88
+ "/workspace/rename",
95
89
  { key, name },
96
90
  renameReqZ,
97
91
  emptyResZ,
@@ -101,7 +95,7 @@ export class Client {
101
95
  async setLayout(key: Key, layout: record.Unknown): Promise<void> {
102
96
  await sendRequired(
103
97
  this.client,
104
- SET_LAYOUT_ENDPOINT,
98
+ "/workspace/set-layout",
105
99
  { key, layout },
106
100
  setLayoutReqZ,
107
101
  emptyResZ,
@@ -119,7 +113,7 @@ export class Client {
119
113
  else req = keys;
120
114
  const res = await sendRequired(
121
115
  this.client,
122
- RETRIEVE_ENDPOINT,
116
+ "/workspace/retrieve",
123
117
  req,
124
118
  retrieveReqZ,
125
119
  retrieveResZ,
@@ -127,23 +121,12 @@ export class Client {
127
121
  return isMany ? res.workspaces : res.workspaces[0];
128
122
  }
129
123
 
130
- async retrieveByAuthor(author: UserKey): Promise<Workspace[]> {
131
- const res = await sendRequired(
132
- this.client,
133
- RETRIEVE_ENDPOINT,
134
- { author },
135
- retrieveReqZ,
136
- retrieveResZ,
137
- );
138
- return res.workspaces;
139
- }
140
-
141
124
  async delete(key: Key): Promise<void>;
142
125
  async delete(keys: Key[]): Promise<void>;
143
126
  async delete(keys: Params): Promise<void> {
144
127
  await sendRequired(
145
128
  this.client,
146
- DELETE_ENDPOINT,
129
+ "/workspace/delete",
147
130
  { keys: array.toArray(keys) },
148
131
  deleteReqZ,
149
132
  emptyResZ,
@@ -151,4 +134,5 @@ export class Client {
151
134
  }
152
135
  }
153
136
 
154
- export const ontologyID = (key: Key): ontology.ID => ({ type: "workspace", key });
137
+ export const ontologyID = ontology.createIDFactory<Key>("workspace");
138
+ 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 { lineplot } from "@/workspace/lineplot";
16
+
17
+ const client = createTestClient();
18
+
19
+ describe("lineplot", () => {
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 randomLinePlot = await client.workspaces.lineplots.create(ws.key, {
32
+ name: "test",
33
+ data: {},
34
+ });
35
+ await expect(
36
+ userClient.workspaces.lineplots.retrieve({ key: randomLinePlot.key }),
37
+ ).rejects.toThrow(AuthError);
38
+ });
39
+
40
+ it("should allow the caller to retrieve lineplots with the correct policy", async () => {
41
+ const userClient = await createTestClientWithPolicy(client, {
42
+ name: "test",
43
+ objects: [lineplot.ontologyID("")],
44
+ actions: ["retrieve"],
45
+ });
46
+ const ws = await client.workspaces.create({
47
+ name: "test",
48
+ layout: {},
49
+ });
50
+ const randomLinePlot = await client.workspaces.lineplots.create(ws.key, {
51
+ name: "test",
52
+ data: {},
53
+ });
54
+ const retrieved = await userClient.workspaces.lineplots.retrieve({
55
+ key: randomLinePlot.key,
56
+ });
57
+ expect(retrieved.key).toBe(randomLinePlot.key);
58
+ expect(retrieved.name).toBe(randomLinePlot.name);
59
+ });
60
+
61
+ it("should allow the caller to create lineplots with the correct policy", async () => {
62
+ const userClient = await createTestClientWithPolicy(client, {
63
+ name: "test",
64
+ objects: [lineplot.ontologyID("")],
65
+ actions: ["create"],
66
+ });
67
+ const ws = await client.workspaces.create({
68
+ name: "test",
69
+ layout: {},
70
+ });
71
+ await userClient.workspaces.lineplots.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: [lineplot.ontologyID("")],
81
+ actions: [],
82
+ });
83
+ const ws = await client.workspaces.create({
84
+ name: "test",
85
+ layout: {},
86
+ });
87
+ await expect(
88
+ userClient.workspaces.lineplots.create(ws.key, {
89
+ name: "test",
90
+ data: {},
91
+ }),
92
+ ).rejects.toThrow(AuthError);
93
+ });
94
+
95
+ it("should allow the caller to delete lineplots with the correct policy", async () => {
96
+ const userClient = await createTestClientWithPolicy(client, {
97
+ name: "test",
98
+ objects: [lineplot.ontologyID("")],
99
+ actions: ["delete", "retrieve"],
100
+ });
101
+ const ws = await client.workspaces.create({
102
+ name: "test",
103
+ layout: {},
104
+ });
105
+ const randomLinePlot = await client.workspaces.lineplots.create(ws.key, {
106
+ name: "test",
107
+ data: {},
108
+ });
109
+ await userClient.workspaces.lineplots.delete(randomLinePlot.key);
110
+ await expect(
111
+ userClient.workspaces.lineplots.retrieve({ key: randomLinePlot.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: [lineplot.ontologyID("")],
119
+ actions: [],
120
+ });
121
+ const ws = await client.workspaces.create({
122
+ name: "test",
123
+ layout: {},
124
+ });
125
+ const randomLinePlot = await client.workspaces.lineplots.create(ws.key, {
126
+ name: "test",
127
+ data: {},
128
+ });
129
+ await expect(
130
+ userClient.workspaces.lineplots.delete(randomLinePlot.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 { type ontology } from "@/ontology";
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/lineplot/payload";
25
25
  import { type Key as WorkspaceKey, keyZ as workspaceKeyZ } from "@/workspace/payload";
26
26
 
27
- const RETRIEVE_ENDPOINT = "/workspace/lineplot/retrieve";
28
- const CREATE_ENDPOINT = "/workspace/lineplot/create";
29
- const RENAME_ENDPOINT = "/workspace/lineplot/rename";
30
- const SET_DATA_ENDPOINT = "/workspace/lineplot/set-data";
31
- const DELETE_ENDPOINT = "/workspace/lineplot/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() });
@@ -68,7 +62,7 @@ export class Client {
68
62
  const isMany = Array.isArray(linePlots);
69
63
  const res = await sendRequired(
70
64
  this.client,
71
- CREATE_ENDPOINT,
65
+ "/workspace/lineplot/create",
72
66
  { workspace, linePlots: array.toArray(linePlots) },
73
67
  createReqZ,
74
68
  createResZ,
@@ -79,7 +73,7 @@ export class Client {
79
73
  async rename(key: Key, name: string): Promise<void> {
80
74
  await sendRequired(
81
75
  this.client,
82
- RENAME_ENDPOINT,
76
+ "/workspace/lineplot/rename",
83
77
  { key, name },
84
78
  renameReqZ,
85
79
  emptyResZ,
@@ -89,7 +83,7 @@ export class Client {
89
83
  async setData(key: Key, data: record.Unknown): Promise<void> {
90
84
  await sendRequired(
91
85
  this.client,
92
- SET_DATA_ENDPOINT,
86
+ "/workspace/lineplot/set-data",
93
87
  { key, data: JSON.stringify(data) },
94
88
  setDataReqZ,
95
89
  emptyResZ,
@@ -104,7 +98,7 @@ export class Client {
104
98
  const isSingle = singleRetrieveArgsZ.safeParse(args).success;
105
99
  const res = await sendRequired(
106
100
  this.client,
107
- RETRIEVE_ENDPOINT,
101
+ "/workspace/lineplot/retrieve",
108
102
  args,
109
103
  retrieveArgsZ,
110
104
  retrieveResZ,
@@ -116,7 +110,7 @@ export class Client {
116
110
  async delete(keys: Params): Promise<void> {
117
111
  await sendRequired(
118
112
  this.client,
119
- DELETE_ENDPOINT,
113
+ "/workspace/lineplot/delete",
120
114
  { keys: array.toArray(keys) },
121
115
  deleteReqZ,
122
116
  emptyResZ,
@@ -124,4 +118,5 @@ export class Client {
124
118
  }
125
119
  }
126
120
 
127
- export const ontologyID = (key: Key): ontology.ID => ({ type: "lineplot", key });
121
+ export const ontologyID = ontology.createIDFactory<Key>("lineplot");
122
+ 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 { log } from "@/workspace/log";
16
+
17
+ const client = createTestClient();
18
+
19
+ describe("log", () => {
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 randomLog = await client.workspaces.logs.create(ws.key, {
32
+ name: "test",
33
+ data: {},
34
+ });
35
+ await expect(
36
+ userClient.workspaces.logs.retrieve({ key: randomLog.key }),
37
+ ).rejects.toThrow(AuthError);
38
+ });
39
+
40
+ it("should allow the caller to retrieve logs with the correct policy", async () => {
41
+ const userClient = await createTestClientWithPolicy(client, {
42
+ name: "test",
43
+ objects: [log.ontologyID("")],
44
+ actions: ["retrieve"],
45
+ });
46
+ const ws = await client.workspaces.create({
47
+ name: "test",
48
+ layout: {},
49
+ });
50
+ const randomLog = await client.workspaces.logs.create(ws.key, {
51
+ name: "test",
52
+ data: {},
53
+ });
54
+ const retrieved = await userClient.workspaces.logs.retrieve({
55
+ key: randomLog.key,
56
+ });
57
+ expect(retrieved.key).toBe(randomLog.key);
58
+ expect(retrieved.name).toBe(randomLog.name);
59
+ });
60
+
61
+ it("should allow the caller to create logs with the correct policy", async () => {
62
+ const userClient = await createTestClientWithPolicy(client, {
63
+ name: "test",
64
+ objects: [log.ontologyID("")],
65
+ actions: ["create"],
66
+ });
67
+ const ws = await client.workspaces.create({
68
+ name: "test",
69
+ layout: {},
70
+ });
71
+ await userClient.workspaces.logs.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: [log.ontologyID("")],
81
+ actions: [],
82
+ });
83
+ const ws = await client.workspaces.create({
84
+ name: "test",
85
+ layout: {},
86
+ });
87
+ await expect(
88
+ userClient.workspaces.logs.create(ws.key, {
89
+ name: "test",
90
+ data: {},
91
+ }),
92
+ ).rejects.toThrow(AuthError);
93
+ });
94
+
95
+ it("should allow the caller to delete logs with the correct policy", async () => {
96
+ const userClient = await createTestClientWithPolicy(client, {
97
+ name: "test",
98
+ objects: [log.ontologyID("")],
99
+ actions: ["delete", "retrieve"],
100
+ });
101
+ const ws = await client.workspaces.create({
102
+ name: "test",
103
+ layout: {},
104
+ });
105
+ const randomLog = await client.workspaces.logs.create(ws.key, {
106
+ name: "test",
107
+ data: {},
108
+ });
109
+ await userClient.workspaces.logs.delete(randomLog.key);
110
+ await expect(
111
+ userClient.workspaces.logs.retrieve({ key: randomLog.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: [log.ontologyID("")],
119
+ actions: [],
120
+ });
121
+ const ws = await client.workspaces.create({
122
+ name: "test",
123
+ layout: {},
124
+ });
125
+ const randomLog = await client.workspaces.logs.create(ws.key, {
126
+ name: "test",
127
+ data: {},
128
+ });
129
+ await expect(userClient.workspaces.logs.delete(randomLog.key)).rejects.toThrow(
130
+ AuthError,
131
+ );
132
+ });
133
+ });
134
+ });