@casual-simulation/aux-records 3.4.6-alpha.14601027727 → 3.5.0-alpha.15117651144

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 (211) hide show
  1. package/AIController.js +835 -890
  2. package/AIController.js.map +1 -1
  3. package/AIHumeInterface.js +43 -54
  4. package/AIHumeInterface.js.map +1 -1
  5. package/AIOpenAIRealtimeInterface.js +60 -71
  6. package/AIOpenAIRealtimeInterface.js.map +1 -1
  7. package/AnthropicAIChatInterface.js +96 -142
  8. package/AnthropicAIChatInterface.js.map +1 -1
  9. package/AuthController.d.ts +3 -2
  10. package/AuthController.js +1907 -1933
  11. package/AuthController.js.map +1 -1
  12. package/AuthStore.d.ts +1 -10
  13. package/BlockadeLabsGenerateSkyboxInterface.js +57 -72
  14. package/BlockadeLabsGenerateSkyboxInterface.js.map +1 -1
  15. package/CachingConfigStore.js +30 -45
  16. package/CachingConfigStore.js.map +1 -1
  17. package/CachingPolicyStore.d.ts +8 -2
  18. package/CachingPolicyStore.js +108 -135
  19. package/CachingPolicyStore.js.map +1 -1
  20. package/ComIdConfig.d.ts +18 -18
  21. package/ComIdConfig.js.map +1 -1
  22. package/ConsoleAuthMessenger.js +7 -20
  23. package/ConsoleAuthMessenger.js.map +1 -1
  24. package/DataRecordsController.d.ts +2 -2
  25. package/DataRecordsController.js +369 -377
  26. package/DataRecordsController.js.map +1 -1
  27. package/DataRecordsStore.d.ts +1 -1
  28. package/DataRecordsStore.js +1 -1
  29. package/DataRecordsStore.js.map +1 -1
  30. package/EventRecordsController.js +226 -240
  31. package/EventRecordsController.js.map +1 -1
  32. package/FileRecordsController.d.ts +13 -2
  33. package/FileRecordsController.js +458 -450
  34. package/FileRecordsController.js.map +1 -1
  35. package/GoogleAIChatInterface.js +133 -179
  36. package/GoogleAIChatInterface.js.map +1 -1
  37. package/LivekitController.js +43 -54
  38. package/LivekitController.js.map +1 -1
  39. package/LoomController.js +64 -75
  40. package/LoomController.js.map +1 -1
  41. package/MemoryAuthMessenger.js +10 -23
  42. package/MemoryAuthMessenger.js.map +1 -1
  43. package/MemoryCache.js +18 -35
  44. package/MemoryCache.js.map +1 -1
  45. package/MemoryFileRecordsLookup.js +105 -125
  46. package/MemoryFileRecordsLookup.js.map +1 -1
  47. package/MemoryModerationJobProvider.js +17 -30
  48. package/MemoryModerationJobProvider.js.map +1 -1
  49. package/MemoryRateLimiter.js +12 -27
  50. package/MemoryRateLimiter.js.map +1 -1
  51. package/MemoryStore.d.ts +18 -6
  52. package/MemoryStore.js +1879 -1997
  53. package/MemoryStore.js.map +1 -1
  54. package/MetricsStore.d.ts +2 -2
  55. package/ModerationController.js +186 -200
  56. package/ModerationController.js.map +1 -1
  57. package/OpenAIChatInterface.js +105 -135
  58. package/OpenAIChatInterface.js.map +1 -1
  59. package/OpenAIImageInterface.js +57 -51
  60. package/OpenAIImageInterface.js.map +1 -1
  61. package/PolicyController.d.ts +150 -10
  62. package/PolicyController.js +1546 -1299
  63. package/PolicyController.js.map +1 -1
  64. package/PolicyStore.d.ts +110 -2
  65. package/PolicyStore.js +36 -1
  66. package/PolicyStore.js.map +1 -1
  67. package/PrivoClient.js +398 -435
  68. package/PrivoClient.js.map +1 -1
  69. package/RateLimitController.js +25 -36
  70. package/RateLimitController.js.map +1 -1
  71. package/RecordsClient.js +51 -74
  72. package/RecordsClient.js.map +1 -1
  73. package/RecordsController.d.ts +2 -42
  74. package/RecordsController.js +1026 -1182
  75. package/RecordsController.js.map +1 -1
  76. package/RecordsServer.d.ts +196 -27
  77. package/RecordsServer.js +1701 -1343
  78. package/RecordsServer.js.map +1 -1
  79. package/RecordsStore.d.ts +1 -10
  80. package/RecordsStore.js.map +1 -1
  81. package/ServerConfig.d.ts +339 -195
  82. package/ServerConfig.js +13 -0
  83. package/ServerConfig.js.map +1 -1
  84. package/SloydInterface.js +62 -75
  85. package/SloydInterface.js.map +1 -1
  86. package/StabilityAIImageInterface.js +150 -167
  87. package/StabilityAIImageInterface.js.map +1 -1
  88. package/SubscriptionConfigBuilder.d.ts +6 -1
  89. package/SubscriptionConfigBuilder.js +22 -0
  90. package/SubscriptionConfigBuilder.js.map +1 -1
  91. package/SubscriptionConfiguration.d.ts +266 -169
  92. package/SubscriptionConfiguration.js +101 -79
  93. package/SubscriptionConfiguration.js.map +1 -1
  94. package/SubscriptionController.d.ts +2 -1
  95. package/SubscriptionController.js +643 -650
  96. package/SubscriptionController.js.map +1 -1
  97. package/SystemNotificationMessenger.d.ts +21 -4
  98. package/SystemNotificationMessenger.js +36 -30
  99. package/SystemNotificationMessenger.js.map +1 -1
  100. package/TestUtils.d.ts +9 -1
  101. package/TestUtils.js +105 -129
  102. package/TestUtils.js.map +1 -1
  103. package/Utils.d.ts +2 -16
  104. package/Utils.js +21 -22
  105. package/Utils.js.map +1 -1
  106. package/crud/CrudHelpers.js +17 -26
  107. package/crud/CrudHelpers.js.map +1 -1
  108. package/crud/CrudRecordsController.d.ts +1 -1
  109. package/crud/CrudRecordsController.js +259 -267
  110. package/crud/CrudRecordsController.js.map +1 -1
  111. package/crud/CrudRecordsControllerTests.js +174 -185
  112. package/crud/CrudRecordsControllerTests.js.map +1 -1
  113. package/crud/CrudRecordsStore.d.ts +7 -3
  114. package/crud/MemoryCrudRecordsStore.d.ts +4 -4
  115. package/crud/MemoryCrudRecordsStore.js +98 -118
  116. package/crud/MemoryCrudRecordsStore.js.map +1 -1
  117. package/crud/sub/MemorySubCrudRecordsStore.d.ts +24 -0
  118. package/crud/sub/MemorySubCrudRecordsStore.js +146 -0
  119. package/crud/sub/MemorySubCrudRecordsStore.js.map +1 -0
  120. package/crud/sub/SubCrudRecordsController.d.ts +182 -0
  121. package/crud/sub/SubCrudRecordsController.js +360 -0
  122. package/crud/sub/SubCrudRecordsController.js.map +1 -0
  123. package/crud/sub/SubCrudRecordsControllerTests.d.ts +39 -0
  124. package/crud/sub/SubCrudRecordsControllerTests.js +821 -0
  125. package/crud/sub/SubCrudRecordsControllerTests.js.map +1 -0
  126. package/crud/sub/SubCrudRecordsStore.d.ts +95 -0
  127. package/{forms/index.js → crud/sub/SubCrudRecordsStore.js} +2 -2
  128. package/crud/sub/SubCrudRecordsStore.js.map +1 -0
  129. package/crud/sub/index.d.ts +3 -0
  130. package/crud/sub/index.js +20 -0
  131. package/{forms → crud/sub}/index.js.map +1 -1
  132. package/index.d.ts +1 -1
  133. package/index.js +1 -1
  134. package/index.js.map +1 -1
  135. package/notifications/MemoryNotificationRecordsStore.js +189 -198
  136. package/notifications/MemoryNotificationRecordsStore.js.map +1 -1
  137. package/notifications/NotificationRecordsController.js +438 -460
  138. package/notifications/NotificationRecordsController.js.map +1 -1
  139. package/notifications/NotificationRecordsStore.d.ts +2 -1
  140. package/notifications/WebPushInterface.d.ts +0 -1
  141. package/notifications/WebPushInterface.js +0 -1
  142. package/notifications/WebPushInterface.js.map +1 -1
  143. package/package.json +6 -6
  144. package/packages/MemoryPackageRecordsStore.d.ts +10 -0
  145. package/packages/MemoryPackageRecordsStore.js +38 -0
  146. package/packages/MemoryPackageRecordsStore.js.map +1 -0
  147. package/packages/PackageRecordsController.d.ts +26 -0
  148. package/packages/PackageRecordsController.js +49 -0
  149. package/packages/PackageRecordsController.js.map +1 -0
  150. package/packages/PackageRecordsStore.d.ts +32 -0
  151. package/packages/PackageRecordsStore.js +19 -0
  152. package/packages/PackageRecordsStore.js.map +1 -0
  153. package/packages/index.d.ts +4 -0
  154. package/packages/index.js +21 -0
  155. package/packages/index.js.map +1 -0
  156. package/packages/version/MemoryPackageVersionRecordsStore.d.ts +21 -0
  157. package/packages/version/MemoryPackageVersionRecordsStore.js +177 -0
  158. package/packages/version/MemoryPackageVersionRecordsStore.js.map +1 -0
  159. package/packages/version/PackageVersionRecordsController.d.ts +144 -0
  160. package/packages/version/PackageVersionRecordsController.js +656 -0
  161. package/packages/version/PackageVersionRecordsController.js.map +1 -0
  162. package/packages/version/PackageVersionRecordsStore.d.ts +342 -0
  163. package/packages/version/PackageVersionRecordsStore.js +126 -0
  164. package/packages/version/PackageVersionRecordsStore.js.map +1 -0
  165. package/packages/version/index.d.ts +4 -0
  166. package/packages/version/index.js +21 -0
  167. package/packages/version/index.js.map +1 -0
  168. package/tracing/TracingDecorators.js +31 -40
  169. package/tracing/TracingDecorators.js.map +1 -1
  170. package/webhooks/MemoryWebhookRecordsStore.js +56 -72
  171. package/webhooks/MemoryWebhookRecordsStore.js.map +1 -1
  172. package/webhooks/WebhookEnvironment.d.ts +3 -3
  173. package/webhooks/WebhookRecordsController.d.ts +2 -1
  174. package/webhooks/WebhookRecordsController.js +389 -382
  175. package/webhooks/WebhookRecordsController.js.map +1 -1
  176. package/webhooks/WebhookRecordsStore.d.ts +2 -1
  177. package/websockets/InstRecordsStore.d.ts +50 -0
  178. package/websockets/InstRecordsStore.js +17 -0
  179. package/websockets/InstRecordsStore.js.map +1 -1
  180. package/websockets/MemoryTempInstRecordsStore.d.ts +5 -0
  181. package/websockets/MemoryTempInstRecordsStore.js +168 -179
  182. package/websockets/MemoryTempInstRecordsStore.js.map +1 -1
  183. package/websockets/MemoryWebsocketConnectionStore.js +98 -135
  184. package/websockets/MemoryWebsocketConnectionStore.js.map +1 -1
  185. package/websockets/MemoryWebsocketMessenger.js +29 -48
  186. package/websockets/MemoryWebsocketMessenger.js.map +1 -1
  187. package/websockets/SplitInstRecordsStore.d.ts +4 -1
  188. package/websockets/SplitInstRecordsStore.js +167 -185
  189. package/websockets/SplitInstRecordsStore.js.map +1 -1
  190. package/websockets/TemporaryInstRecordsStore.d.ts +19 -1
  191. package/websockets/TemporaryInstRecordsStore.js +17 -0
  192. package/websockets/TemporaryInstRecordsStore.js.map +1 -1
  193. package/websockets/WebsocketController.d.ts +147 -3
  194. package/websockets/WebsocketController.js +1735 -1391
  195. package/websockets/WebsocketController.js.map +1 -1
  196. package/websockets/index.d.ts +0 -1
  197. package/websockets/index.js +0 -1
  198. package/websockets/index.js.map +1 -1
  199. package/AAGUID.d.ts +0 -11
  200. package/AAGUID.js +0 -116
  201. package/AAGUID.js.map +0 -1
  202. package/AuthUtils.d.ts +0 -162
  203. package/AuthUtils.js +0 -327
  204. package/AuthUtils.js.map +0 -1
  205. package/forms/FormError.d.ts +0 -43
  206. package/forms/FormError.js +0 -56
  207. package/forms/FormError.js.map +0 -1
  208. package/forms/index.d.ts +0 -2
  209. package/websockets/Utils.d.ts +0 -33
  210. package/websockets/Utils.js +0 -82
  211. package/websockets/Utils.js.map +0 -1
@@ -0,0 +1,821 @@
1
+ import { createTestControllers, createTestRecordKey, createTestUser, } from '../../TestUtils';
2
+ import { PRIVATE_MARKER, PUBLIC_READ_MARKER, } from '@casual-simulation/aux-common';
3
+ /**
4
+ * Creates a new test context that can be used to test a CRUD records controller.
5
+ * @param storeFactory The factory function that creates the store.
6
+ * @param controllerFactory The factory function that creates the controller.
7
+ */
8
+ export async function setupTestContext(recordStoreFactory, storeFactory, controllerFactory) {
9
+ const services = createTestControllers();
10
+ const store = services.store;
11
+ const recordItemsStore = recordStoreFactory(services);
12
+ const itemsStore = storeFactory(services, recordItemsStore);
13
+ const policies = services.policies;
14
+ const recordName = 'testRecord';
15
+ const manager = controllerFactory({
16
+ policies,
17
+ store: itemsStore,
18
+ recordItemStore: recordItemsStore,
19
+ config: store,
20
+ }, services);
21
+ const user = await createTestUser(services, 'test@example.com');
22
+ const userId = user.userId;
23
+ const sessionKey = user.sessionKey;
24
+ const connectionKey = user.connectionKey;
25
+ const testRecordKey = await createTestRecordKey(services, userId, recordName, 'subjectfull');
26
+ const key = testRecordKey.recordKey;
27
+ const subjectlessRecordKey = await createTestRecordKey(services, userId, recordName, 'subjectless');
28
+ const subjectlessKey = subjectlessRecordKey.recordKey;
29
+ const otherUserId = 'otherUserId';
30
+ await store.saveUser({
31
+ id: otherUserId,
32
+ allSessionRevokeTimeMs: null,
33
+ currentLoginRequestId: null,
34
+ email: 'other@example.com',
35
+ phoneNumber: null,
36
+ });
37
+ return {
38
+ services,
39
+ key,
40
+ manager,
41
+ otherUserId,
42
+ sessionKey,
43
+ store,
44
+ itemsStore,
45
+ recordItemsStore,
46
+ subjectlessKey,
47
+ userId,
48
+ recordName,
49
+ connectionKey,
50
+ };
51
+ }
52
+ /**
53
+ * Runs all of the common tests for a CRUD records controller.
54
+ * @param allowRecordKeys Whether record keys can be used to access the resources.
55
+ * @param resourceKind The resource kind that should be expected.
56
+ * @param storeFactory The factory function that creates the store.
57
+ * @param controllerFactory The factory function that creates the controller.
58
+ * @param createTestItem The factory function that creates a test item.
59
+ * @param configureEnvironment An optional function that can be used to configure the environment before the tests are run.
60
+ */
61
+ export function testCrudRecordsController(allowRecordKeys, resourceKind, recordStoreFactory, storeFactory, controllerFactory, createKey, createTestItem, createRecordItem, configureEnvironment, allowedActions = [
62
+ 'create',
63
+ 'read',
64
+ 'update',
65
+ 'delete',
66
+ 'list',
67
+ ]) {
68
+ let context;
69
+ let services;
70
+ let store;
71
+ let itemsStore;
72
+ let recordItemsStore;
73
+ let records;
74
+ let policies;
75
+ let manager;
76
+ let key;
77
+ let subjectlessKey;
78
+ let userId;
79
+ let sessionKey;
80
+ let otherUserId;
81
+ let recordName;
82
+ beforeEach(async () => {
83
+ context = await setupTestContext(recordStoreFactory, storeFactory, controllerFactory);
84
+ services = context.services;
85
+ store = context.store;
86
+ itemsStore = context.itemsStore;
87
+ recordItemsStore = context.recordItemsStore;
88
+ records = services.records;
89
+ policies = services.policies;
90
+ manager = context.manager;
91
+ key = context.key;
92
+ subjectlessKey = context.subjectlessKey;
93
+ userId = context.userId;
94
+ sessionKey = context.sessionKey;
95
+ otherUserId = context.otherUserId;
96
+ recordName = context.recordName;
97
+ if (configureEnvironment) {
98
+ await configureEnvironment(context);
99
+ }
100
+ });
101
+ if (allowedActions.includes('create') ||
102
+ allowedActions.includes('update')) {
103
+ describe('recordItem()', () => {
104
+ if (allowedActions.includes('create')) {
105
+ describe('create', () => {
106
+ beforeEach(async () => {
107
+ await recordItemsStore.createItem(recordName, createRecordItem({
108
+ address: 'address',
109
+ markers: [PUBLIC_READ_MARKER],
110
+ }));
111
+ });
112
+ it('should store the item in the store', async () => {
113
+ const item = createTestItem({
114
+ address: 'address',
115
+ key: createKey(0),
116
+ });
117
+ const result = (await manager.recordItem({
118
+ recordKeyOrRecordName: recordName,
119
+ userId,
120
+ item,
121
+ instances: [],
122
+ }));
123
+ expect(result).toEqual({
124
+ success: true,
125
+ recordName: recordName,
126
+ address: 'address',
127
+ });
128
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
129
+ item,
130
+ parentMarkers: [PUBLIC_READ_MARKER],
131
+ });
132
+ });
133
+ it('should return data_not_found if the record item doesnt exist', async () => {
134
+ const item = createTestItem({
135
+ address: 'missing',
136
+ key: createKey(0),
137
+ });
138
+ const result = (await manager.recordItem({
139
+ recordKeyOrRecordName: recordName,
140
+ userId,
141
+ item,
142
+ instances: [],
143
+ }));
144
+ expect(result).toEqual({
145
+ success: false,
146
+ errorCode: 'data_not_found',
147
+ errorMessage: expect.any(String),
148
+ });
149
+ await expect(itemsStore.getItemByKey(recordName, 'missing', createKey(0))).resolves.toMatchObject({
150
+ item: null,
151
+ parentMarkers: null,
152
+ });
153
+ });
154
+ it('should reject the request if given an invalid key', async () => {
155
+ const result = (await manager.recordItem({
156
+ recordKeyOrRecordName: 'not_a_key',
157
+ userId,
158
+ item: createTestItem({
159
+ address: 'address',
160
+ key: createKey(0),
161
+ }),
162
+ instances: [],
163
+ }));
164
+ expect(result).toEqual({
165
+ success: false,
166
+ errorCode: 'record_not_found',
167
+ errorMessage: expect.any(String),
168
+ });
169
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
170
+ item: null,
171
+ parentMarkers: [PUBLIC_READ_MARKER],
172
+ });
173
+ });
174
+ if (allowRecordKeys) {
175
+ it('should support using a record key', async () => {
176
+ const result = (await manager.recordItem({
177
+ recordKeyOrRecordName: key,
178
+ userId: otherUserId,
179
+ item: createTestItem({
180
+ address: 'address',
181
+ key: createKey(0),
182
+ }),
183
+ instances: [],
184
+ }));
185
+ expect(result).toEqual({
186
+ success: true,
187
+ recordName: recordName,
188
+ address: 'address',
189
+ });
190
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toEqual({
191
+ item: {
192
+ address: 'address',
193
+ key: createKey(0),
194
+ },
195
+ parentMarkers: [PUBLIC_READ_MARKER],
196
+ });
197
+ });
198
+ it('should be able to use subjectless keys', async () => {
199
+ const result = (await manager.recordItem({
200
+ recordKeyOrRecordName: subjectlessKey,
201
+ userId: otherUserId,
202
+ item: createTestItem({
203
+ address: 'address',
204
+ key: createKey(0),
205
+ }),
206
+ instances: [],
207
+ }));
208
+ expect(result).toEqual({
209
+ success: true,
210
+ recordName: recordName,
211
+ address: 'address',
212
+ });
213
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toEqual({
214
+ item: {
215
+ address: 'address',
216
+ key: createKey(0),
217
+ },
218
+ parentMarkers: [PUBLIC_READ_MARKER],
219
+ });
220
+ });
221
+ }
222
+ else {
223
+ it('should reject the request if record keys are not allowed', async () => {
224
+ const result = (await manager.recordItem({
225
+ recordKeyOrRecordName: key,
226
+ userId: otherUserId,
227
+ item: createTestItem({
228
+ address: 'address',
229
+ key: createKey(0),
230
+ }),
231
+ instances: [],
232
+ }));
233
+ expect(result).toEqual({
234
+ success: false,
235
+ errorCode: 'not_authorized',
236
+ errorMessage: expect.any(String),
237
+ reason: {
238
+ type: 'missing_permission',
239
+ recordName,
240
+ action: 'create',
241
+ resourceKind,
242
+ resourceId: 'address',
243
+ subjectType: 'user',
244
+ subjectId: otherUserId,
245
+ },
246
+ });
247
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
248
+ item: null,
249
+ parentMarkers: [PUBLIC_READ_MARKER],
250
+ });
251
+ });
252
+ it('should reject the request if subjectless keys are not allowed', async () => {
253
+ const result = (await manager.recordItem({
254
+ recordKeyOrRecordName: subjectlessKey,
255
+ userId: otherUserId,
256
+ item: createTestItem({
257
+ address: 'address',
258
+ key: createKey(0),
259
+ }),
260
+ instances: [],
261
+ }));
262
+ expect(result).toEqual({
263
+ success: false,
264
+ errorCode: 'not_authorized',
265
+ errorMessage: expect.any(String),
266
+ reason: {
267
+ type: 'missing_permission',
268
+ recordName,
269
+ action: 'create',
270
+ resourceKind,
271
+ resourceId: 'address',
272
+ subjectType: 'user',
273
+ subjectId: otherUserId,
274
+ },
275
+ });
276
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
277
+ item: null,
278
+ parentMarkers: [PUBLIC_READ_MARKER],
279
+ });
280
+ });
281
+ }
282
+ });
283
+ }
284
+ if (allowedActions.includes('update')) {
285
+ describe('update', () => {
286
+ beforeEach(async () => {
287
+ await recordItemsStore.createItem(recordName, createRecordItem({
288
+ address: 'address',
289
+ markers: [PUBLIC_READ_MARKER],
290
+ }));
291
+ await itemsStore.createItem(recordName, createTestItem({
292
+ address: 'address',
293
+ key: createKey(0),
294
+ }));
295
+ });
296
+ it('should update the markers in the store', async () => {
297
+ const item = createTestItem({
298
+ address: 'address',
299
+ key: createKey(0),
300
+ });
301
+ const result = (await manager.recordItem({
302
+ recordKeyOrRecordName: recordName,
303
+ userId,
304
+ item,
305
+ instances: [],
306
+ }));
307
+ expect(result).toEqual({
308
+ success: true,
309
+ recordName: recordName,
310
+ address: 'address',
311
+ });
312
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
313
+ item,
314
+ parentMarkers: [PUBLIC_READ_MARKER],
315
+ });
316
+ });
317
+ it('should reject the request if given an invalid key', async () => {
318
+ const item = createTestItem({
319
+ address: 'address',
320
+ key: createKey(0),
321
+ });
322
+ const result = (await manager.recordItem({
323
+ recordKeyOrRecordName: 'not_a_key',
324
+ userId,
325
+ item,
326
+ instances: [],
327
+ }));
328
+ expect(result).toEqual({
329
+ success: false,
330
+ errorCode: 'record_not_found',
331
+ errorMessage: expect.any(String),
332
+ });
333
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
334
+ item,
335
+ parentMarkers: [PUBLIC_READ_MARKER],
336
+ });
337
+ });
338
+ if (allowRecordKeys) {
339
+ it('should support using a record key', async () => {
340
+ const item = createTestItem({
341
+ address: 'address',
342
+ key: createKey(0),
343
+ });
344
+ const result = (await manager.recordItem({
345
+ recordKeyOrRecordName: key,
346
+ userId,
347
+ item,
348
+ instances: [],
349
+ }));
350
+ expect(result).toEqual({
351
+ success: true,
352
+ recordName: recordName,
353
+ address: 'address',
354
+ });
355
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
356
+ item,
357
+ parentMarkers: [PUBLIC_READ_MARKER],
358
+ });
359
+ });
360
+ it('should be able to use subjectless keys', async () => {
361
+ const item = createTestItem({
362
+ address: 'address',
363
+ key: createKey(0),
364
+ });
365
+ const result = (await manager.recordItem({
366
+ recordKeyOrRecordName: subjectlessKey,
367
+ userId,
368
+ item,
369
+ instances: [],
370
+ }));
371
+ expect(result).toEqual({
372
+ success: true,
373
+ recordName: recordName,
374
+ address: 'address',
375
+ });
376
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
377
+ item,
378
+ parentMarkers: [PUBLIC_READ_MARKER],
379
+ });
380
+ });
381
+ }
382
+ else {
383
+ it('should reject the request if record keys are not allowed', async () => {
384
+ const item = createTestItem({
385
+ address: 'address',
386
+ key: createKey(0),
387
+ });
388
+ const result = (await manager.recordItem({
389
+ recordKeyOrRecordName: key,
390
+ userId: otherUserId,
391
+ item,
392
+ instances: [],
393
+ }));
394
+ expect(result).toEqual({
395
+ success: false,
396
+ errorCode: 'not_authorized',
397
+ errorMessage: expect.any(String),
398
+ reason: {
399
+ type: 'missing_permission',
400
+ recordName,
401
+ action: 'update',
402
+ resourceKind,
403
+ resourceId: 'address',
404
+ subjectType: 'user',
405
+ subjectId: otherUserId,
406
+ },
407
+ });
408
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
409
+ item: createTestItem({
410
+ address: 'address',
411
+ key: createKey(0),
412
+ }),
413
+ parentMarkers: [PUBLIC_READ_MARKER],
414
+ });
415
+ });
416
+ it('should reject the request if subjectless keys are not allowed', async () => {
417
+ const item = createTestItem({
418
+ address: 'address',
419
+ key: createKey(0),
420
+ });
421
+ const result = (await manager.recordItem({
422
+ recordKeyOrRecordName: subjectlessKey,
423
+ userId: otherUserId,
424
+ item,
425
+ instances: [],
426
+ }));
427
+ expect(result).toEqual({
428
+ success: false,
429
+ errorCode: 'not_authorized',
430
+ errorMessage: expect.any(String),
431
+ reason: {
432
+ type: 'missing_permission',
433
+ recordName,
434
+ action: 'update',
435
+ resourceKind,
436
+ resourceId: 'address',
437
+ subjectType: 'user',
438
+ subjectId: otherUserId,
439
+ },
440
+ });
441
+ await expect(itemsStore.getItemByKey(recordName, 'address', createKey(0))).resolves.toMatchObject({
442
+ item: createTestItem({
443
+ address: 'address',
444
+ key: createKey(0),
445
+ }),
446
+ parentMarkers: [PUBLIC_READ_MARKER],
447
+ });
448
+ });
449
+ }
450
+ });
451
+ }
452
+ });
453
+ }
454
+ if (allowedActions.includes('read')) {
455
+ describe('getItem()', () => {
456
+ beforeEach(async () => {
457
+ await recordItemsStore.createItem(recordName, createRecordItem({
458
+ address: 'address',
459
+ markers: [PUBLIC_READ_MARKER],
460
+ }));
461
+ await recordItemsStore.createItem(recordName, createRecordItem({
462
+ address: 'address2',
463
+ markers: [PRIVATE_MARKER],
464
+ }));
465
+ await recordItemsStore.createItem(recordName, createRecordItem({
466
+ address: 'address3',
467
+ markers: [PRIVATE_MARKER],
468
+ }));
469
+ await itemsStore.createItem(recordName, createTestItem({
470
+ address: 'address',
471
+ key: createKey(1),
472
+ }));
473
+ await itemsStore.createItem(recordName, createTestItem({
474
+ address: 'address2',
475
+ key: createKey(2),
476
+ }));
477
+ await itemsStore.createItem(recordName, createTestItem({
478
+ address: 'address3',
479
+ key: createKey(3),
480
+ }));
481
+ });
482
+ it('should return the item if the user has access', async () => {
483
+ const result = await manager.getItem({
484
+ recordName: recordName,
485
+ userId,
486
+ address: 'address2',
487
+ key: createKey(2),
488
+ instances: [],
489
+ });
490
+ expect(result).toMatchObject({
491
+ success: true,
492
+ item: createTestItem({
493
+ address: 'address2',
494
+ key: createKey(2),
495
+ }),
496
+ });
497
+ });
498
+ it('should return data_not_found if the item was not found', async () => {
499
+ const result = await manager.getItem({
500
+ recordName: recordName,
501
+ userId,
502
+ address: 'missing',
503
+ key: createKey(0),
504
+ instances: [],
505
+ });
506
+ expect(result).toEqual({
507
+ success: false,
508
+ errorCode: 'data_not_found',
509
+ errorMessage: expect.any(String),
510
+ });
511
+ });
512
+ it('should return record_not_found if the record doesnt exist', async () => {
513
+ const result = await manager.getItem({
514
+ recordName: 'missing',
515
+ userId,
516
+ address: 'address',
517
+ key: createKey(1),
518
+ instances: [],
519
+ });
520
+ expect(result).toEqual({
521
+ success: false,
522
+ errorCode: 'record_not_found',
523
+ errorMessage: expect.any(String),
524
+ });
525
+ });
526
+ if (allowRecordKeys) {
527
+ it('should be able to use a record key to access the item', async () => {
528
+ const result = await manager.getItem({
529
+ recordName: key,
530
+ userId,
531
+ address: 'address2',
532
+ key: createKey(2),
533
+ instances: [],
534
+ });
535
+ expect(result).toEqual({
536
+ success: true,
537
+ item: createTestItem({
538
+ address: 'address2',
539
+ key: createKey(2),
540
+ }),
541
+ });
542
+ });
543
+ }
544
+ else {
545
+ it('should return not_authorized if record keys are not allowed', async () => {
546
+ const result = await manager.getItem({
547
+ recordName: key,
548
+ userId: otherUserId,
549
+ address: 'address2',
550
+ key: createKey(2),
551
+ instances: [],
552
+ });
553
+ expect(result).toEqual({
554
+ success: false,
555
+ errorCode: 'not_authorized',
556
+ errorMessage: expect.any(String),
557
+ reason: {
558
+ type: 'missing_permission',
559
+ recordName,
560
+ action: 'read',
561
+ resourceKind,
562
+ resourceId: 'address2',
563
+ subjectType: 'user',
564
+ subjectId: otherUserId,
565
+ },
566
+ });
567
+ });
568
+ }
569
+ });
570
+ }
571
+ if (allowedActions.includes('delete')) {
572
+ describe('eraseItem()', () => {
573
+ beforeEach(async () => {
574
+ await recordItemsStore.createItem(recordName, createRecordItem({
575
+ address: 'address',
576
+ markers: [PUBLIC_READ_MARKER],
577
+ }));
578
+ await itemsStore.createItem(recordName, createTestItem({
579
+ address: 'address',
580
+ key: createKey(1),
581
+ }));
582
+ await recordItemsStore.createItem(recordName, createRecordItem({
583
+ address: 'address2',
584
+ markers: [PRIVATE_MARKER],
585
+ }));
586
+ await itemsStore.createItem(recordName, createTestItem({
587
+ address: 'address2',
588
+ key: createKey(2),
589
+ }));
590
+ await recordItemsStore.createItem(recordName, createRecordItem({
591
+ address: 'address3',
592
+ markers: [PUBLIC_READ_MARKER],
593
+ }));
594
+ await itemsStore.createItem(recordName, createTestItem({
595
+ address: 'address3',
596
+ key: createKey(3),
597
+ }));
598
+ });
599
+ it('should erase the item if the user has access', async () => {
600
+ const result = await manager.eraseItem({
601
+ recordName: recordName,
602
+ userId,
603
+ address: 'address2',
604
+ key: createKey(2),
605
+ instances: [],
606
+ });
607
+ expect(result).toEqual({
608
+ success: true,
609
+ });
610
+ await expect(itemsStore.getItemByKey(recordName, 'address2', createKey(2))).resolves.toMatchObject({
611
+ item: null,
612
+ parentMarkers: [PRIVATE_MARKER],
613
+ });
614
+ });
615
+ it('should return data_not_found if the record item doesnt exist', async () => {
616
+ const result = await manager.eraseItem({
617
+ recordName: recordName,
618
+ userId,
619
+ address: 'missing',
620
+ key: createKey(2),
621
+ instances: [],
622
+ });
623
+ expect(result).toEqual({
624
+ success: false,
625
+ errorCode: 'data_not_found',
626
+ errorMessage: 'The item was not found.',
627
+ });
628
+ });
629
+ it('should return data_not_found if the item doesnt exist', async () => {
630
+ const result = await manager.eraseItem({
631
+ recordName: recordName,
632
+ userId,
633
+ address: 'address',
634
+ key: createKey(99),
635
+ instances: [],
636
+ });
637
+ expect(result).toEqual({
638
+ success: false,
639
+ errorCode: 'data_not_found',
640
+ errorMessage: 'The item was not found.',
641
+ });
642
+ });
643
+ if (allowRecordKeys) {
644
+ it('should erase the item if the record key has access', async () => {
645
+ const result = await manager.eraseItem({
646
+ recordName: key,
647
+ userId: otherUserId,
648
+ address: 'address2',
649
+ key: createKey(2),
650
+ instances: [],
651
+ });
652
+ expect(result).toEqual({
653
+ success: true,
654
+ });
655
+ await expect(itemsStore.getItemByKey(recordName, 'address2', createKey(2))).resolves.toMatchObject({
656
+ item: null,
657
+ parentMarkers: [PRIVATE_MARKER],
658
+ });
659
+ });
660
+ }
661
+ else {
662
+ it('should return not_authorized if the controller doesnt allow record keys', async () => {
663
+ const result = await manager.eraseItem({
664
+ recordName: key,
665
+ userId: otherUserId,
666
+ address: 'address2',
667
+ key: createKey(2),
668
+ instances: [],
669
+ });
670
+ expect(result).toEqual({
671
+ success: false,
672
+ errorCode: 'not_authorized',
673
+ errorMessage: expect.any(String),
674
+ reason: {
675
+ type: 'missing_permission',
676
+ recordName,
677
+ action: 'delete',
678
+ resourceKind,
679
+ resourceId: 'address2',
680
+ subjectType: 'user',
681
+ subjectId: otherUserId,
682
+ },
683
+ });
684
+ await expect(itemsStore.getItemByKey(recordName, 'address2', createKey(2))).resolves.toBeTruthy();
685
+ });
686
+ }
687
+ it('should return record_not_found if the record doesnt exist', async () => {
688
+ const result = await manager.eraseItem({
689
+ recordName: 'missing',
690
+ userId,
691
+ address: 'address2',
692
+ key: createKey(2),
693
+ instances: [],
694
+ });
695
+ expect(result).toEqual({
696
+ success: false,
697
+ errorCode: 'record_not_found',
698
+ errorMessage: expect.any(String),
699
+ });
700
+ await expect(itemsStore.getItemByKey(recordName, 'address2', createKey(2))).resolves.toBeTruthy();
701
+ });
702
+ });
703
+ }
704
+ if (allowedActions.includes('list')) {
705
+ describe('listItems()', () => {
706
+ let items;
707
+ beforeEach(async () => {
708
+ items = [];
709
+ await recordItemsStore.createItem(recordName, createRecordItem({
710
+ address: 'address',
711
+ markers: [PUBLIC_READ_MARKER],
712
+ }));
713
+ for (let i = 0; i < 20; i++) {
714
+ const item = createTestItem({
715
+ address: 'address',
716
+ key: createKey(i),
717
+ });
718
+ await itemsStore.createItem(recordName, item);
719
+ items.push(item);
720
+ }
721
+ });
722
+ it('should return a list of items', async () => {
723
+ const result = await manager.listItems({
724
+ recordName: recordName,
725
+ userId: otherUserId,
726
+ address: 'address',
727
+ instances: [],
728
+ });
729
+ expect(result).toEqual({
730
+ success: true,
731
+ recordName: recordName,
732
+ items: items,
733
+ totalCount: 20,
734
+ });
735
+ });
736
+ if (allowRecordKeys) {
737
+ it('should be able to use a record key', async () => {
738
+ await recordItemsStore.updateItem(recordName, createRecordItem({
739
+ address: 'address',
740
+ markers: [PRIVATE_MARKER],
741
+ }));
742
+ const result = await manager.listItems({
743
+ recordName: key,
744
+ userId: otherUserId,
745
+ address: 'address',
746
+ instances: [],
747
+ });
748
+ expect(result).toEqual({
749
+ success: true,
750
+ recordName: recordName,
751
+ items: items,
752
+ totalCount: 20,
753
+ });
754
+ });
755
+ }
756
+ else {
757
+ it('should return not_authorized if record keys are not allowed', async () => {
758
+ await recordItemsStore.updateItem(recordName, createRecordItem({
759
+ address: 'address',
760
+ markers: [PRIVATE_MARKER],
761
+ }));
762
+ const result = await manager.listItems({
763
+ recordName: key,
764
+ userId: otherUserId,
765
+ address: 'address',
766
+ instances: [],
767
+ });
768
+ expect(result).toEqual({
769
+ success: false,
770
+ errorCode: 'not_authorized',
771
+ errorMessage: expect.any(String),
772
+ reason: {
773
+ type: 'missing_permission',
774
+ recordName,
775
+ action: 'list',
776
+ resourceKind,
777
+ subjectType: 'user',
778
+ subjectId: otherUserId,
779
+ },
780
+ });
781
+ });
782
+ }
783
+ it('should return not_authorized if the user does not have access to the record item marker', async () => {
784
+ items = [];
785
+ await recordItemsStore.createItem(recordName, createRecordItem({
786
+ address: 'address2',
787
+ markers: [PRIVATE_MARKER],
788
+ }));
789
+ for (let i = 0; i < 20; i++) {
790
+ const item = createTestItem({
791
+ address: 'address2',
792
+ key: createKey(i),
793
+ });
794
+ await itemsStore.createItem(recordName, item);
795
+ items.push(item);
796
+ }
797
+ const result = await manager.listItems({
798
+ recordName: recordName,
799
+ userId: otherUserId,
800
+ address: 'address2',
801
+ instances: [],
802
+ });
803
+ expect(result).toEqual({
804
+ success: false,
805
+ errorCode: 'not_authorized',
806
+ errorMessage: expect.any(String),
807
+ reason: {
808
+ action: 'list',
809
+ recordName: recordName,
810
+ resourceId: undefined,
811
+ resourceKind: resourceKind,
812
+ subjectId: otherUserId,
813
+ subjectType: 'user',
814
+ type: 'missing_permission',
815
+ },
816
+ });
817
+ });
818
+ });
819
+ }
820
+ }
821
+ //# sourceMappingURL=SubCrudRecordsControllerTests.js.map