@casual-simulation/aux-records 3.2.11 → 3.2.12

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/RecordsServer.js CHANGED
@@ -26,6 +26,7 @@ import { AVAILABLE_PERMISSIONS_VALIDATION } from '@casual-simulation/aux-common'
26
26
  import { AI_CHAT_MESSAGE_SCHEMA } from './AIChatInterface';
27
27
  import { WebsocketEventTypes, websocketEventSchema, websocketRequestMessageSchema, } from '@casual-simulation/aux-common/websockets/WebsocketEvents';
28
28
  import { DEFAULT_BRANCH_NAME } from '@casual-simulation/aux-common';
29
+ import { COM_ID_CONFIG_SCHEMA, COM_ID_PLAYER_CONFIG } from './ComIdConfig';
29
30
  const NOT_LOGGED_IN_RESULT = {
30
31
  success: false,
31
32
  errorCode: 'not_logged_in',
@@ -93,7 +94,8 @@ const ADDRESS_VALIDATION = z
93
94
  invalid_type_error: 'address must be a string.',
94
95
  required_error: 'address is required.',
95
96
  })
96
- .nonempty('address must not be empty.');
97
+ .min(1)
98
+ .max(512);
97
99
  /**
98
100
  * The Zod validation for event names.
99
101
  */
@@ -102,7 +104,29 @@ const EVENT_NAME_VALIDATION = z
102
104
  invalid_type_error: 'eventName must be a string.',
103
105
  required_error: 'eventName is required.',
104
106
  })
105
- .nonempty('eventName must not be empty.');
107
+ .min(1)
108
+ .max(128);
109
+ const STUDIO_ID_VALIDATION = z
110
+ .string({
111
+ invalid_type_error: 'studioId must be a string.',
112
+ required_error: 'studioId is required.',
113
+ })
114
+ .min(1)
115
+ .max(128);
116
+ const COM_ID_VALIDATION = z
117
+ .string({
118
+ invalid_type_error: 'comId must be a string.',
119
+ required_error: 'comId is required.',
120
+ })
121
+ .min(1)
122
+ .max(128);
123
+ const STUDIO_DISPLAY_NAME_VALIDATION = z
124
+ .string({
125
+ invalid_type_error: 'displayName must be a string.',
126
+ required_error: 'displayName is required.',
127
+ })
128
+ .min(1)
129
+ .max(128);
106
130
  /**
107
131
  * The Zod validation for markers.
108
132
  */
@@ -112,11 +136,13 @@ const MARKERS_VALIDATION = z
112
136
  invalid_type_error: 'individual markers must be strings.',
113
137
  required_error: 'invidiaul markers must not be null or empty.',
114
138
  })
115
- .nonempty('invidiaul markers must not be null or empty.'), {
139
+ .min(1)
140
+ .max(128), {
116
141
  invalid_type_error: 'markers must be an array of strings.',
117
142
  required_error: 'markers is required.',
118
143
  })
119
- .nonempty('markers must not be empty.');
144
+ .nonempty('markers must not be empty.')
145
+ .max(10, 'markers must not contain more than 10 markers.');
120
146
  const NO_WHITESPACE_MESSAGE = 'The value cannot not contain spaces.';
121
147
  const NO_WHITESPACE_REGEX = /^\S*$/g;
122
148
  const NO_SPECIAL_CHARACTERS_MESSAGE = 'The value cannot not contain special characters.';
@@ -125,14 +151,31 @@ const DISPLAY_NAME_VALIDATION = z
125
151
  .string()
126
152
  .trim()
127
153
  .min(1)
154
+ .max(128)
128
155
  .regex(NO_WHITESPACE_REGEX, NO_WHITESPACE_MESSAGE)
129
156
  .regex(NO_SPECIAL_CHARACTERS_REGEX, NO_SPECIAL_CHARACTERS_MESSAGE);
130
157
  const NAME_VALIDATION = z
131
158
  .string()
132
159
  .trim()
133
160
  .min(1)
161
+ .max(128)
134
162
  .regex(NO_WHITESPACE_REGEX, NO_WHITESPACE_MESSAGE)
135
163
  .regex(NO_SPECIAL_CHARACTERS_REGEX, NO_SPECIAL_CHARACTERS_MESSAGE);
164
+ const RECORD_NAME_VALIDATION = z
165
+ .string({
166
+ required_error: 'recordName is required.',
167
+ invalid_type_error: 'recordName must be a string.',
168
+ })
169
+ .trim()
170
+ .min(1)
171
+ .max(128);
172
+ const INSTANCE_VALIDATION = z.string().min(1).max(128);
173
+ const INSTANCES_ARRAY_VALIDATION = z.array(INSTANCE_VALIDATION).min(1).max(3);
174
+ const INSTANCES_QUERY_VALIDATION = z
175
+ .string()
176
+ .min(1)
177
+ .max(128 * 3)
178
+ .transform((value) => parseInstancesList(value));
136
179
  /**
137
180
  * Defines a class that represents a generic HTTP server suitable for Records HTTP Requests.
138
181
  */
@@ -393,10 +436,22 @@ export class RecordsServer {
393
436
  request.path === '/api/v2/ai/image') {
394
437
  return formatResponse(request, yield this._aiGenerateImage(request), this._allowedApiOrigins);
395
438
  }
439
+ else if (request.method === 'GET' &&
440
+ request.path === '/api/v2/studios') {
441
+ return formatResponse(request, yield this._getStudio(request), this._allowedAccountOrigins);
442
+ }
396
443
  else if (request.method === 'POST' &&
397
444
  request.path === '/api/v2/studios') {
398
445
  return formatResponse(request, yield this._postStudio(request), this._allowedAccountOrigins);
399
446
  }
447
+ else if (request.method === 'PUT' &&
448
+ request.path === '/api/v2/studios') {
449
+ return formatResponse(request, yield this._updateStudio(request), this._allowedAccountOrigins);
450
+ }
451
+ else if (request.method === 'POST' &&
452
+ request.path === '/api/v2/studios/requestComId') {
453
+ return formatResponse(request, yield this._requestComId(request), this._allowedAccountOrigins);
454
+ }
400
455
  else if (request.method === 'GET' &&
401
456
  request.path === '/api/v2/studios/list') {
402
457
  return formatResponse(request, yield this._listStudios(request), this._allowedApiOrigins);
@@ -413,6 +468,10 @@ export class RecordsServer {
413
468
  request.path === '/api/v2/studios/members') {
414
469
  return formatResponse(request, yield this._removeStudioMember(request), this._allowedAccountOrigins);
415
470
  }
471
+ else if (request.method === 'GET' &&
472
+ request.path === '/api/v2/player/config') {
473
+ return formatResponse(request, yield this._getPlayerConfig(request), this._allowedApiOrigins);
474
+ }
416
475
  else if (request.method === 'GET' &&
417
476
  request.path === '/api/v2/subscriptions') {
418
477
  return formatResponse(request, yield this._getSubscriptionInfoV2(request), this._allowedAccountOrigins);
@@ -748,12 +807,7 @@ export class RecordsServer {
748
807
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
749
808
  }
750
809
  const schema = z.object({
751
- recordName: z
752
- .string({
753
- invalid_type_error: 'recordName must be a string.',
754
- required_error: 'recordName is required.',
755
- })
756
- .nonempty('recordName must not be empty.'),
810
+ recordName: RECORD_NAME_VALIDATION,
757
811
  ownerId: z
758
812
  .string({
759
813
  invalid_type_error: 'ownerId must be a string.',
@@ -810,10 +864,7 @@ export class RecordsServer {
810
864
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
811
865
  }
812
866
  const schema = z.object({
813
- recordName: z.string({
814
- invalid_type_error: 'recordName must be a string.',
815
- required_error: 'recordName is required.',
816
- }),
867
+ recordName: RECORD_NAME_VALIDATION,
817
868
  policy: z.string({
818
869
  invalid_type_error: 'policy must be a string.',
819
870
  required_error: 'policy is required.',
@@ -855,12 +906,7 @@ export class RecordsServer {
855
906
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
856
907
  }
857
908
  const schema = z.object({
858
- recordName: z
859
- .string({
860
- invalid_type_error: 'recordName must be a string.',
861
- required_error: 'recordName is required.',
862
- })
863
- .nonempty('recordName must not be empty'),
909
+ recordName: RECORD_NAME_VALIDATION,
864
910
  marker: z
865
911
  .string({
866
912
  invalid_type_error: 'marker must be a string.',
@@ -868,7 +914,7 @@ export class RecordsServer {
868
914
  })
869
915
  .nonempty('marker must not be empty'),
870
916
  permission: AVAILABLE_PERMISSIONS_VALIDATION,
871
- instances: z.array(z.string()).nonempty().optional(),
917
+ instances: INSTANCES_ARRAY_VALIDATION.nonempty().optional(),
872
918
  });
873
919
  const parseResult = schema.safeParse(jsonResult.value);
874
920
  if (parseResult.success === false) {
@@ -918,12 +964,7 @@ export class RecordsServer {
918
964
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
919
965
  }
920
966
  const schema = z.object({
921
- recordName: z
922
- .string({
923
- invalid_type_error: 'recordName must be a string.',
924
- required_error: 'recordName is required.',
925
- })
926
- .nonempty('recordName must not be empty'),
967
+ recordName: RECORD_NAME_VALIDATION,
927
968
  marker: z
928
969
  .string({
929
970
  invalid_type_error: 'marker must be a string.',
@@ -931,7 +972,7 @@ export class RecordsServer {
931
972
  })
932
973
  .nonempty('marker must not be empty'),
933
974
  permission: AVAILABLE_PERMISSIONS_VALIDATION,
934
- instances: z.array(z.string()).nonempty().optional(),
975
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
935
976
  });
936
977
  const parseResult = schema.safeParse(jsonResult.value);
937
978
  if (parseResult.success === false) {
@@ -961,12 +1002,7 @@ export class RecordsServer {
961
1002
  return returnResult(INVALID_ORIGIN_RESULT);
962
1003
  }
963
1004
  const schema = z.object({
964
- recordName: z
965
- .string({
966
- invalid_type_error: 'recordName must be a string.',
967
- required_error: 'recordName is required.',
968
- })
969
- .nonempty('recordName must not be empty'),
1005
+ recordName: RECORD_NAME_VALIDATION,
970
1006
  marker: z
971
1007
  .string({
972
1008
  invalid_type_error: 'marker must be a string.',
@@ -996,12 +1032,7 @@ export class RecordsServer {
996
1032
  return returnResult(INVALID_ORIGIN_RESULT);
997
1033
  }
998
1034
  const schema = z.object({
999
- recordName: z
1000
- .string({
1001
- invalid_type_error: 'recordName must be a string.',
1002
- required_error: 'recordName is required.',
1003
- })
1004
- .nonempty('recordName must not be empty'),
1035
+ recordName: RECORD_NAME_VALIDATION,
1005
1036
  startingMarker: z
1006
1037
  .string({
1007
1038
  invalid_type_error: 'startingMarker must be a string.',
@@ -1032,26 +1063,14 @@ export class RecordsServer {
1032
1063
  return returnResult(INVALID_ORIGIN_RESULT);
1033
1064
  }
1034
1065
  const schema = z.object({
1035
- recordName: z
1036
- .string({
1037
- invalid_type_error: 'recordName must be a string.',
1038
- required_error: 'recordName is required.',
1039
- })
1040
- .nonempty('recordName must not be empty'),
1066
+ recordName: RECORD_NAME_VALIDATION,
1041
1067
  userId: z
1042
1068
  .string({
1043
1069
  invalid_type_error: 'userId must be a string.',
1044
1070
  required_error: 'userId is required.',
1045
1071
  })
1046
1072
  .nonempty('userId must not be empty'),
1047
- instances: z
1048
- .string({
1049
- invalid_type_error: 'instances must be a string.',
1050
- required_error: 'instances is required.',
1051
- })
1052
- .nonempty('instances must not be empty')
1053
- .optional()
1054
- .transform((value) => parseInstancesList(value)),
1073
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1055
1074
  });
1056
1075
  const parseResult = schema.safeParse(request.query);
1057
1076
  if (parseResult.success === false) {
@@ -1075,26 +1094,14 @@ export class RecordsServer {
1075
1094
  return returnResult(INVALID_ORIGIN_RESULT);
1076
1095
  }
1077
1096
  const schema = z.object({
1078
- recordName: z
1079
- .string({
1080
- invalid_type_error: 'recordName must be a string.',
1081
- required_error: 'recordName is required.',
1082
- })
1083
- .nonempty('recordName must not be empty'),
1097
+ recordName: RECORD_NAME_VALIDATION,
1084
1098
  inst: z
1085
1099
  .string({
1086
1100
  invalid_type_error: 'inst must be a string.',
1087
1101
  required_error: 'inst is required.',
1088
1102
  })
1089
1103
  .nonempty('inst must not be empty'),
1090
- instances: z
1091
- .string({
1092
- invalid_type_error: 'instances must be a string.',
1093
- required_error: 'instances is required.',
1094
- })
1095
- .nonempty('instances must not be empty')
1096
- .optional()
1097
- .transform((value) => parseInstancesList(value)),
1104
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1098
1105
  });
1099
1106
  const parseResult = schema.safeParse(request.query);
1100
1107
  if (parseResult.success === false) {
@@ -1118,12 +1125,7 @@ export class RecordsServer {
1118
1125
  return returnResult(INVALID_ORIGIN_RESULT);
1119
1126
  }
1120
1127
  const schema = z.object({
1121
- recordName: z
1122
- .string({
1123
- invalid_type_error: 'recordName must be a string.',
1124
- required_error: 'recordName is required.',
1125
- })
1126
- .nonempty('recordName must not be empty'),
1128
+ recordName: RECORD_NAME_VALIDATION,
1127
1129
  startingRole: z
1128
1130
  .string({
1129
1131
  invalid_type_error: 'startingRole must be a string.',
@@ -1138,14 +1140,7 @@ export class RecordsServer {
1138
1140
  })
1139
1141
  .nonempty('role must not be empty')
1140
1142
  .optional(),
1141
- instances: z
1142
- .string({
1143
- invalid_type_error: 'instances must be a string.',
1144
- required_error: 'instances is required.',
1145
- })
1146
- .nonempty('instances must not be empty')
1147
- .optional()
1148
- .transform((value) => parseInstancesList(value)),
1143
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1149
1144
  });
1150
1145
  const parseResult = schema.safeParse(request.query);
1151
1146
  if (parseResult.success === false) {
@@ -1182,12 +1177,7 @@ export class RecordsServer {
1182
1177
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1183
1178
  }
1184
1179
  const schema = z.object({
1185
- recordName: z
1186
- .string({
1187
- invalid_type_error: 'recordName must be a string.',
1188
- required_error: 'recordName is required.',
1189
- })
1190
- .nonempty('recordName must not be empty'),
1180
+ recordName: RECORD_NAME_VALIDATION,
1191
1181
  userId: z
1192
1182
  .string({
1193
1183
  invalid_type_error: 'userId must be a string.',
@@ -1215,7 +1205,7 @@ export class RecordsServer {
1215
1205
  })
1216
1206
  .positive('expireTimeMs must be positive')
1217
1207
  .optional(),
1218
- instances: z.array(z.string()).nonempty().optional(),
1208
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1219
1209
  });
1220
1210
  const parseResult = schema.safeParse(jsonResult.value);
1221
1211
  if (parseResult.success === false) {
@@ -1251,12 +1241,7 @@ export class RecordsServer {
1251
1241
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1252
1242
  }
1253
1243
  const schema = z.object({
1254
- recordName: z
1255
- .string({
1256
- invalid_type_error: 'recordName must be a string.',
1257
- required_error: 'recordName is required.',
1258
- })
1259
- .nonempty('recordName must not be empty'),
1244
+ recordName: RECORD_NAME_VALIDATION,
1260
1245
  userId: z
1261
1246
  .string({
1262
1247
  invalid_type_error: 'userId must be a string.',
@@ -1277,7 +1262,7 @@ export class RecordsServer {
1277
1262
  required_error: 'role is required.',
1278
1263
  })
1279
1264
  .nonempty('role must not be empty'),
1280
- instances: z.array(z.string()).nonempty().optional(),
1265
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1281
1266
  });
1282
1267
  const parseResult = schema.safeParse(jsonResult.value);
1283
1268
  if (parseResult.success === false) {
@@ -1317,7 +1302,7 @@ export class RecordsServer {
1317
1302
  const schema = z.object({
1318
1303
  model: z.string().nonempty().optional(),
1319
1304
  messages: z.array(AI_CHAT_MESSAGE_SCHEMA).nonempty(),
1320
- instances: z.array(z.string()).nonempty().optional(),
1305
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1321
1306
  temperature: z.number().min(0).max(2).optional(),
1322
1307
  topP: z.number().optional(),
1323
1308
  presencePenalty: z.number().min(-2).max(2).optional(),
@@ -1356,8 +1341,8 @@ export class RecordsServer {
1356
1341
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1357
1342
  }
1358
1343
  const schema = z.object({
1359
- prompt: z.string().nonempty(),
1360
- negativePrompt: z.string().nonempty().optional(),
1344
+ prompt: z.string().nonempty().max(600),
1345
+ negativePrompt: z.string().nonempty().max(600).optional(),
1361
1346
  blockadeLabs: z
1362
1347
  .object({
1363
1348
  skyboxStyleId: z.number().optional(),
@@ -1365,7 +1350,7 @@ export class RecordsServer {
1365
1350
  seed: z.number().optional(),
1366
1351
  })
1367
1352
  .optional(),
1368
- instances: z.array(z.string()).nonempty().optional(),
1353
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1369
1354
  });
1370
1355
  const parseResult = schema.safeParse(jsonResult.value);
1371
1356
  if (parseResult.success === false) {
@@ -1404,14 +1389,7 @@ export class RecordsServer {
1404
1389
  required_error: 'skyboxId is required.',
1405
1390
  })
1406
1391
  .nonempty('skyboxId must not be empty'),
1407
- instances: z
1408
- .string({
1409
- invalid_type_error: 'instances must be a string.',
1410
- required_error: 'instances is required.',
1411
- })
1412
- .nonempty('instances must not be empty')
1413
- .optional()
1414
- .transform((value) => parseInstancesList(value)),
1392
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1415
1393
  });
1416
1394
  const parseResult = schema.safeParse(request.query);
1417
1395
  if (parseResult.success === false) {
@@ -1472,7 +1450,7 @@ export class RecordsServer {
1472
1450
  cfgScale: z.number().min(0).int().optional(),
1473
1451
  clipGuidancePreset: z.string().nonempty().optional(),
1474
1452
  stylePreset: z.string().nonempty().optional(),
1475
- instances: z.array(z.string().nonempty()).optional(),
1453
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1476
1454
  });
1477
1455
  const parseResult = schema.safeParse(jsonResult.value);
1478
1456
  if (parseResult.success === false) {
@@ -1506,6 +1484,30 @@ export class RecordsServer {
1506
1484
  return returnResult(result);
1507
1485
  });
1508
1486
  }
1487
+ _getStudio(request) {
1488
+ return __awaiter(this, void 0, void 0, function* () {
1489
+ if (!validateOrigin(request, this._allowedAccountOrigins)) {
1490
+ return returnResult(INVALID_ORIGIN_RESULT);
1491
+ }
1492
+ const schema = z.object({
1493
+ studioId: STUDIO_ID_VALIDATION,
1494
+ });
1495
+ const parseResult = schema.safeParse(request.query);
1496
+ if (parseResult.success === false) {
1497
+ return returnZodError(parseResult.error);
1498
+ }
1499
+ const { studioId } = parseResult.data;
1500
+ const sessionKeyValidation = yield this._validateSessionKey(request);
1501
+ if (sessionKeyValidation.success === false) {
1502
+ if (sessionKeyValidation.errorCode === 'no_session_key') {
1503
+ return returnResult(NOT_LOGGED_IN_RESULT);
1504
+ }
1505
+ return returnResult(sessionKeyValidation);
1506
+ }
1507
+ const result = yield this._records.getStudio(studioId, sessionKeyValidation.userId);
1508
+ return returnResult(result);
1509
+ });
1510
+ }
1509
1511
  _postStudio(request) {
1510
1512
  return __awaiter(this, void 0, void 0, function* () {
1511
1513
  if (!validateOrigin(request, this._allowedAccountOrigins)) {
@@ -1519,18 +1521,71 @@ export class RecordsServer {
1519
1521
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1520
1522
  }
1521
1523
  const schema = z.object({
1522
- displayName: z
1524
+ displayName: STUDIO_DISPLAY_NAME_VALIDATION,
1525
+ ownerStudioComId: z
1526
+ .string({
1527
+ invalid_type_error: 'ownerStudioComId must be a string.',
1528
+ required_error: 'ownerStudioComId is required.',
1529
+ })
1530
+ .nonempty('ownerStudioComId must not be empty')
1531
+ .nullable()
1532
+ .optional(),
1533
+ });
1534
+ const parseResult = schema.safeParse(jsonResult.value);
1535
+ if (parseResult.success === false) {
1536
+ return returnZodError(parseResult.error);
1537
+ }
1538
+ const { displayName, ownerStudioComId } = parseResult.data;
1539
+ const sessionKeyValidation = yield this._validateSessionKey(request);
1540
+ if (sessionKeyValidation.success === false) {
1541
+ if (sessionKeyValidation.errorCode === 'no_session_key') {
1542
+ return returnResult(NOT_LOGGED_IN_RESULT);
1543
+ }
1544
+ return returnResult(sessionKeyValidation);
1545
+ }
1546
+ if (!ownerStudioComId) {
1547
+ const result = yield this._records.createStudio(displayName, sessionKeyValidation.userId);
1548
+ return returnResult(result);
1549
+ }
1550
+ else {
1551
+ const result = yield this._records.createStudioInComId(displayName, sessionKeyValidation.userId, ownerStudioComId);
1552
+ return returnResult(result);
1553
+ }
1554
+ });
1555
+ }
1556
+ _updateStudio(request) {
1557
+ return __awaiter(this, void 0, void 0, function* () {
1558
+ if (!validateOrigin(request, this._allowedAccountOrigins)) {
1559
+ return returnResult(INVALID_ORIGIN_RESULT);
1560
+ }
1561
+ if (typeof request.body !== 'string') {
1562
+ return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1563
+ }
1564
+ const jsonResult = tryParseJson(request.body);
1565
+ if (!jsonResult.success || typeof jsonResult.value !== 'object') {
1566
+ return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1567
+ }
1568
+ const schema = z.object({
1569
+ id: STUDIO_ID_VALIDATION,
1570
+ displayName: STUDIO_DISPLAY_NAME_VALIDATION.optional(),
1571
+ logoUrl: z
1523
1572
  .string({
1524
- invalid_type_error: 'displayName must be a string.',
1525
- required_error: 'displayName is required.',
1573
+ invalid_type_error: 'logoUrl must be a string.',
1574
+ required_error: 'logoUrl is required.',
1526
1575
  })
1527
- .nonempty('displayName must not be empty'),
1576
+ .url()
1577
+ .min(1)
1578
+ .max(512)
1579
+ .nullable()
1580
+ .optional(),
1581
+ comIdConfig: COM_ID_CONFIG_SCHEMA.optional(),
1582
+ playerConfig: COM_ID_PLAYER_CONFIG.optional(),
1528
1583
  });
1529
1584
  const parseResult = schema.safeParse(jsonResult.value);
1530
1585
  if (parseResult.success === false) {
1531
1586
  return returnZodError(parseResult.error);
1532
1587
  }
1533
- const { displayName } = parseResult.data;
1588
+ const { id, displayName, logoUrl, comIdConfig, playerConfig } = parseResult.data;
1534
1589
  const sessionKeyValidation = yield this._validateSessionKey(request);
1535
1590
  if (sessionKeyValidation.success === false) {
1536
1591
  if (sessionKeyValidation.errorCode === 'no_session_key') {
@@ -1538,7 +1593,53 @@ export class RecordsServer {
1538
1593
  }
1539
1594
  return returnResult(sessionKeyValidation);
1540
1595
  }
1541
- const result = yield this._records.createStudio(displayName, sessionKeyValidation.userId);
1596
+ const result = yield this._records.updateStudio({
1597
+ userId: sessionKeyValidation.userId,
1598
+ studio: {
1599
+ id,
1600
+ displayName,
1601
+ logoUrl,
1602
+ comIdConfig,
1603
+ playerConfig,
1604
+ },
1605
+ });
1606
+ return returnResult(result);
1607
+ });
1608
+ }
1609
+ _requestComId(request) {
1610
+ return __awaiter(this, void 0, void 0, function* () {
1611
+ if (!validateOrigin(request, this._allowedAccountOrigins)) {
1612
+ return returnResult(INVALID_ORIGIN_RESULT);
1613
+ }
1614
+ if (typeof request.body !== 'string') {
1615
+ return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1616
+ }
1617
+ const jsonResult = tryParseJson(request.body);
1618
+ if (!jsonResult.success || typeof jsonResult.value !== 'object') {
1619
+ return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1620
+ }
1621
+ const schema = z.object({
1622
+ studioId: STUDIO_ID_VALIDATION,
1623
+ comId: COM_ID_VALIDATION,
1624
+ });
1625
+ const parseResult = schema.safeParse(jsonResult.value);
1626
+ if (parseResult.success === false) {
1627
+ return returnZodError(parseResult.error);
1628
+ }
1629
+ const { studioId, comId } = parseResult.data;
1630
+ const sessionKeyValidation = yield this._validateSessionKey(request);
1631
+ if (sessionKeyValidation.success === false) {
1632
+ if (sessionKeyValidation.errorCode === 'no_session_key') {
1633
+ return returnResult(NOT_LOGGED_IN_RESULT);
1634
+ }
1635
+ return returnResult(sessionKeyValidation);
1636
+ }
1637
+ const result = yield this._records.requestComId({
1638
+ studioId,
1639
+ userId: sessionKeyValidation.userId,
1640
+ requestedComId: comId,
1641
+ ipAddress: request.ipAddress,
1642
+ });
1542
1643
  return returnResult(result);
1543
1644
  });
1544
1645
  }
@@ -1547,12 +1648,14 @@ export class RecordsServer {
1547
1648
  if (!validateOrigin(request, this._allowedApiOrigins)) {
1548
1649
  return returnResult(INVALID_ORIGIN_RESULT);
1549
1650
  }
1550
- const schema = z.object({});
1651
+ const schema = z.object({
1652
+ comId: z.string().nonempty().optional(),
1653
+ });
1551
1654
  const parseResult = schema.safeParse(request.query);
1552
1655
  if (parseResult.success === false) {
1553
1656
  return returnZodError(parseResult.error);
1554
1657
  }
1555
- const {} = parseResult.data;
1658
+ const { comId } = parseResult.data;
1556
1659
  const sessionKeyValidation = yield this._validateSessionKey(request);
1557
1660
  if (sessionKeyValidation.success === false) {
1558
1661
  if (sessionKeyValidation.errorCode === 'no_session_key') {
@@ -1560,8 +1663,14 @@ export class RecordsServer {
1560
1663
  }
1561
1664
  return returnResult(sessionKeyValidation);
1562
1665
  }
1563
- const result = yield this._records.listStudios(sessionKeyValidation.userId);
1564
- return returnResult(result);
1666
+ if (comId) {
1667
+ const result = yield this._records.listStudiosByComId(sessionKeyValidation.userId, comId);
1668
+ return returnResult(result);
1669
+ }
1670
+ else {
1671
+ const result = yield this._records.listStudios(sessionKeyValidation.userId);
1672
+ return returnResult(result);
1673
+ }
1565
1674
  });
1566
1675
  }
1567
1676
  _listStudioMembers(request) {
@@ -1570,12 +1679,7 @@ export class RecordsServer {
1570
1679
  return returnResult(INVALID_ORIGIN_RESULT);
1571
1680
  }
1572
1681
  const schema = z.object({
1573
- studioId: z
1574
- .string({
1575
- invalid_type_error: 'studioId must be a string.',
1576
- required_error: 'studioId is required.',
1577
- })
1578
- .nonempty('studioId must not be empty'),
1682
+ studioId: STUDIO_ID_VALIDATION,
1579
1683
  });
1580
1684
  const parseResult = schema.safeParse(request.query);
1581
1685
  if (parseResult.success === false) {
@@ -1606,12 +1710,7 @@ export class RecordsServer {
1606
1710
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1607
1711
  }
1608
1712
  const schema = z.object({
1609
- studioId: z
1610
- .string({
1611
- invalid_type_error: 'studioId must be a string.',
1612
- required_error: 'studioId is required.',
1613
- })
1614
- .nonempty('studioId must not be empty'),
1713
+ studioId: STUDIO_ID_VALIDATION,
1615
1714
  addedUserId: z
1616
1715
  .string({
1617
1716
  invalid_type_error: 'addedUserId must be a string.',
@@ -1671,12 +1770,7 @@ export class RecordsServer {
1671
1770
  return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
1672
1771
  }
1673
1772
  const schema = z.object({
1674
- studioId: z
1675
- .string({
1676
- invalid_type_error: 'studioId must be a string.',
1677
- required_error: 'studioId is required.',
1678
- })
1679
- .nonempty('studioId must not be empty'),
1773
+ studioId: STUDIO_ID_VALIDATION,
1680
1774
  removedUserId: z
1681
1775
  .string({
1682
1776
  invalid_type_error: 'removedUserId must be a string.',
@@ -1705,24 +1799,29 @@ export class RecordsServer {
1705
1799
  return returnResult(result);
1706
1800
  });
1707
1801
  }
1802
+ _getPlayerConfig(request) {
1803
+ return __awaiter(this, void 0, void 0, function* () {
1804
+ if (!validateOrigin(request, this._allowedApiOrigins)) {
1805
+ return returnResult(INVALID_ORIGIN_RESULT);
1806
+ }
1807
+ const schema = z.object({
1808
+ comId: z.string().nonempty(),
1809
+ });
1810
+ const parseResult = schema.safeParse(request.query);
1811
+ if (parseResult.success === false) {
1812
+ return returnZodError(parseResult.error);
1813
+ }
1814
+ const { comId } = parseResult.data;
1815
+ const result = yield this._records.getPlayerConfig(comId);
1816
+ return returnResult(result);
1817
+ });
1818
+ }
1708
1819
  _listData(request) {
1709
1820
  return __awaiter(this, void 0, void 0, function* () {
1710
1821
  const schema = z.object({
1711
- recordName: z
1712
- .string({
1713
- required_error: 'recordName is required.',
1714
- invalid_type_error: 'recordName must be a string.',
1715
- })
1716
- .nonempty('recordName must not be empty'),
1717
- address: z.union([z.string(), z.null()]).optional(),
1718
- instances: z
1719
- .string({
1720
- invalid_type_error: 'instances must be a string.',
1721
- required_error: 'instances is required.',
1722
- })
1723
- .nonempty('instances must not be empty')
1724
- .optional()
1725
- .transform((value) => parseInstancesList(value)),
1822
+ recordName: RECORD_NAME_VALIDATION,
1823
+ address: ADDRESS_VALIDATION.nullable().optional(),
1824
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1726
1825
  });
1727
1826
  const parseResult = schema.safeParse(request.query || {});
1728
1827
  if (parseResult.success === false) {
@@ -1794,6 +1893,8 @@ export class RecordsServer {
1794
1893
  invalid_type_error: 'fileSha256Hex must be a string.',
1795
1894
  required_error: 'fileSha256Hex is required.',
1796
1895
  })
1896
+ .min(1)
1897
+ .max(128)
1797
1898
  .nonempty('fileSha256Hex must be non-empty.'),
1798
1899
  fileByteLength: z
1799
1900
  .number({
@@ -1802,15 +1903,20 @@ export class RecordsServer {
1802
1903
  })
1803
1904
  .positive('fileByteLength must be a positive integer number.')
1804
1905
  .int('fileByteLength must be a positive integer number.'),
1805
- fileMimeType: z.string({
1906
+ fileMimeType: z
1907
+ .string({
1806
1908
  invalid_type_error: 'fileMimeType must be a string.',
1807
1909
  required_error: 'fileMimeType is required.',
1808
- }),
1910
+ })
1911
+ .min(1)
1912
+ .max(128),
1809
1913
  fileDescription: z
1810
1914
  .string({
1811
1915
  invalid_type_error: 'fileDescription must be a string.',
1812
1916
  required_error: 'fileDescription is required.',
1813
1917
  })
1918
+ .min(1)
1919
+ .max(128)
1814
1920
  .optional(),
1815
1921
  markers: z
1816
1922
  .array(z.string(), {
@@ -1819,7 +1925,7 @@ export class RecordsServer {
1819
1925
  })
1820
1926
  .nonempty('markers must be non-empty.')
1821
1927
  .optional(),
1822
- instances: z.array(z.string()).nonempty().optional(),
1928
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1823
1929
  });
1824
1930
  const parseResult = schema.safeParse(jsonResult.value);
1825
1931
  if (parseResult.success === false) {
@@ -1905,7 +2011,7 @@ export class RecordsServer {
1905
2011
  required_error: 'markers is required.',
1906
2012
  })
1907
2013
  .nonempty('markers must be non-empty.'),
1908
- instances: z.array(z.string()).nonempty().optional(),
2014
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
1909
2015
  });
1910
2016
  const parseResult = schema.safeParse(jsonResult.value);
1911
2017
  if (parseResult.success === false) {
@@ -1928,13 +2034,7 @@ export class RecordsServer {
1928
2034
  _readFile(request) {
1929
2035
  return __awaiter(this, void 0, void 0, function* () {
1930
2036
  const schema = z.object({
1931
- recordName: z
1932
- .string({
1933
- invalid_type_error: 'recordName must be a string.',
1934
- required_error: 'recordName is required.',
1935
- })
1936
- .nonempty('recordName must be non-empty.')
1937
- .optional(),
2037
+ recordName: RECORD_NAME_VALIDATION.optional(),
1938
2038
  fileName: z
1939
2039
  .string({
1940
2040
  invalid_type_error: 'fileName must be a string.',
@@ -1949,11 +2049,7 @@ export class RecordsServer {
1949
2049
  })
1950
2050
  .nonempty('fileUrl must be non-empty.')
1951
2051
  .optional(),
1952
- instances: z
1953
- .string()
1954
- .nonempty()
1955
- .optional()
1956
- .transform((value) => parseInstancesList(value)),
2052
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
1957
2053
  });
1958
2054
  const parseResult = schema.safeParse(request.query || {});
1959
2055
  if (parseResult.success === false) {
@@ -2020,12 +2116,7 @@ export class RecordsServer {
2020
2116
  _listFiles(request) {
2021
2117
  return __awaiter(this, void 0, void 0, function* () {
2022
2118
  const schema = z.object({
2023
- recordName: z
2024
- .string({
2025
- invalid_type_error: 'recordName must be a string.',
2026
- required_error: 'recordName is required.',
2027
- })
2028
- .nonempty('recordName must be non-empty.'),
2119
+ recordName: RECORD_NAME_VALIDATION,
2029
2120
  fileName: z
2030
2121
  .string({
2031
2122
  invalid_type_error: 'fileName must be a string.',
@@ -2033,11 +2124,7 @@ export class RecordsServer {
2033
2124
  })
2034
2125
  .nonempty('fileName must be non-empty.')
2035
2126
  .optional(),
2036
- instances: z
2037
- .string()
2038
- .nonempty()
2039
- .optional()
2040
- .transform((value) => parseInstancesList(value)),
2127
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
2041
2128
  });
2042
2129
  const parseResult = schema.safeParse(request.query || {});
2043
2130
  if (parseResult.success === false) {
@@ -2086,7 +2173,7 @@ export class RecordsServer {
2086
2173
  invalid_type_error: 'fileUrl must be a string.',
2087
2174
  required_error: 'fileUrl is required.',
2088
2175
  }),
2089
- instances: z.array(z.string()).nonempty().optional(),
2176
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
2090
2177
  });
2091
2178
  const parseResult = schema.safeParse(jsonResult.value);
2092
2179
  if (parseResult.success === false) {
@@ -2148,7 +2235,7 @@ export class RecordsServer {
2148
2235
  })
2149
2236
  .optional(),
2150
2237
  markers: MARKERS_VALIDATION.optional(),
2151
- instances: z.array(z.string()).nonempty().optional(),
2238
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
2152
2239
  });
2153
2240
  const parseResult = schema.safeParse(jsonResult.value);
2154
2241
  if (parseResult.success === false) {
@@ -2197,26 +2284,14 @@ export class RecordsServer {
2197
2284
  _baseGetRecordData(request, controller) {
2198
2285
  return __awaiter(this, void 0, void 0, function* () {
2199
2286
  const schema = z.object({
2200
- recordName: z
2201
- .string({
2202
- required_error: 'recordName is required.',
2203
- invalid_type_error: 'recordName must be a string.',
2204
- })
2205
- .nonempty('recordName must not be empty'),
2287
+ recordName: RECORD_NAME_VALIDATION,
2206
2288
  address: z
2207
2289
  .string({
2208
2290
  required_error: 'address is required.',
2209
2291
  invalid_type_error: 'address must be a string.',
2210
2292
  })
2211
2293
  .nonempty('address must not be empty'),
2212
- instances: z
2213
- .string({
2214
- invalid_type_error: 'instances must be a string.',
2215
- required_error: 'instances is required.',
2216
- })
2217
- .nonempty('instances must not be empty')
2218
- .optional()
2219
- .transform((value) => parseInstancesList(value)),
2294
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
2220
2295
  });
2221
2296
  const parseResult = schema.safeParse(request.query || {});
2222
2297
  if (parseResult.success === false) {
@@ -2267,7 +2342,7 @@ export class RecordsServer {
2267
2342
  const schema = z.object({
2268
2343
  recordKey: RECORD_KEY_VALIDATION,
2269
2344
  address: ADDRESS_VALIDATION,
2270
- instances: z.array(z.string()).nonempty().optional(),
2345
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
2271
2346
  });
2272
2347
  const parseResult = schema.safeParse(jsonResult.value);
2273
2348
  if (parseResult.success === false) {
@@ -2310,23 +2385,14 @@ export class RecordsServer {
2310
2385
  return returnResult(INVALID_ORIGIN_RESULT);
2311
2386
  }
2312
2387
  const schema = z.object({
2313
- recordName: z
2314
- .string({
2315
- required_error: 'recordName is required.',
2316
- invalid_type_error: 'recordName must be a string.',
2317
- })
2318
- .nonempty('recordName must not be empty'),
2388
+ recordName: RECORD_NAME_VALIDATION,
2319
2389
  eventName: z
2320
2390
  .string({
2321
2391
  required_error: 'eventName is required.',
2322
2392
  invalid_type_error: 'eventName must be a string.',
2323
2393
  })
2324
2394
  .nonempty('eventName must not be empty'),
2325
- instances: z
2326
- .string()
2327
- .nonempty()
2328
- .optional()
2329
- .transform((value) => parseInstancesList(value)),
2395
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
2330
2396
  });
2331
2397
  const parseResult = schema.safeParse(request.query || {});
2332
2398
  if (parseResult.success === false) {
@@ -2376,7 +2442,7 @@ export class RecordsServer {
2376
2442
  invalid_type_error: 'count must be a number.',
2377
2443
  required_error: 'count is required.',
2378
2444
  }),
2379
- instances: z.array(z.string()).nonempty().optional(),
2445
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
2380
2446
  });
2381
2447
  const parseResult = schema.safeParse(jsonResult.value);
2382
2448
  if (parseResult.success === false) {
@@ -2417,12 +2483,7 @@ export class RecordsServer {
2417
2483
  _listEvents(request) {
2418
2484
  return __awaiter(this, void 0, void 0, function* () {
2419
2485
  const schema = z.object({
2420
- recordName: z
2421
- .string({
2422
- invalid_type_error: 'recordName must be a string.',
2423
- required_error: 'recordName is required.',
2424
- })
2425
- .nonempty('recordName must be non-empty.'),
2486
+ recordName: RECORD_NAME_VALIDATION,
2426
2487
  eventName: z
2427
2488
  .string({
2428
2489
  invalid_type_error: 'eventName must be a string.',
@@ -2430,11 +2491,7 @@ export class RecordsServer {
2430
2491
  })
2431
2492
  .nonempty('eventName must be non-empty.')
2432
2493
  .optional(),
2433
- instances: z
2434
- .string()
2435
- .nonempty()
2436
- .optional()
2437
- .transform((value) => parseInstancesList(value)),
2494
+ instances: INSTANCES_QUERY_VALIDATION.optional(),
2438
2495
  });
2439
2496
  const parseResult = schema.safeParse(request.query || {});
2440
2497
  if (parseResult.success === false) {
@@ -2482,7 +2539,7 @@ export class RecordsServer {
2482
2539
  eventName: EVENT_NAME_VALIDATION,
2483
2540
  count: z.number().optional(),
2484
2541
  markers: MARKERS_VALIDATION.optional(),
2485
- instances: z.array(z.string()).nonempty().optional(),
2542
+ instances: INSTANCES_ARRAY_VALIDATION.optional(),
2486
2543
  });
2487
2544
  const parseResult = schema.safeParse(jsonResult.value);
2488
2545
  if (parseResult.success === false) {
@@ -3092,7 +3149,7 @@ export class RecordsServer {
3092
3149
  return returnResult(NOT_LOGGED_IN_RESULT);
3093
3150
  }
3094
3151
  const schema = z.object({
3095
- recordName: z.string().nonempty().optional(),
3152
+ recordName: RECORD_NAME_VALIDATION.optional(),
3096
3153
  inst: z.string().optional(),
3097
3154
  });
3098
3155
  const parseResult = schema.safeParse(request.query || {});
@@ -3122,8 +3179,8 @@ export class RecordsServer {
3122
3179
  return returnResult(NOT_LOGGED_IN_RESULT);
3123
3180
  }
3124
3181
  const schema = z.object({
3125
- recordKey: z.string().nonempty().optional(),
3126
- recordName: z.string().nonempty().optional(),
3182
+ recordKey: RECORD_KEY_VALIDATION.optional(),
3183
+ recordName: RECORD_NAME_VALIDATION.optional(),
3127
3184
  inst: z.string().optional(),
3128
3185
  });
3129
3186
  if (typeof request.body !== 'string') {
@@ -3155,7 +3212,7 @@ export class RecordsServer {
3155
3212
  return returnResult(MODERATION_NOT_SUPPORTED_RESULT);
3156
3213
  }
3157
3214
  const schema = z.object({
3158
- recordName: z.string().nonempty().nullable(),
3215
+ recordName: RECORD_NAME_VALIDATION.nullable(),
3159
3216
  inst: z.string().nonempty(),
3160
3217
  automaticReport: z.boolean(),
3161
3218
  reportReason: z.union([
@@ -3219,7 +3276,7 @@ export class RecordsServer {
3219
3276
  userId = validation.userId;
3220
3277
  }
3221
3278
  const schema = z.object({
3222
- recordName: z.string().nonempty().nullable().optional(),
3279
+ recordName: RECORD_NAME_VALIDATION.nullable().optional(),
3223
3280
  inst: z.string().nonempty(),
3224
3281
  branch: z.string().nonempty().default(DEFAULT_BRANCH_NAME),
3225
3282
  });