@darco2903/altv-web-api 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,7 @@ const internalError = {
11
11
  500: apiError(z.literal("INTERNAL_SERVER_ERROR"), z.string()),
12
12
  };
13
13
  const noTrack = apiError(z.literal("NO_TRACK"), z.literal("The room has no track"));
14
+ const queueItemNotFound = apiError(z.literal("QUEUE_ITEM_NOT_FOUND"), z.literal("The queue doesn't have this track"));
14
15
  const invalidVideoId = apiError(z.literal("INVALID_VIDEO_ID"), z.literal("The provided video ID is invalid"));
15
16
  export default c.router({
16
17
  create: {
@@ -94,10 +95,66 @@ export default c.router({
94
95
  ...internalError,
95
96
  },
96
97
  },
98
+ queueAdd: {
99
+ method: "POST",
100
+ path: "/room/:roomId/queue",
101
+ description: "Add a YouTube video to the queue of a room, it plays right away if the room has nothing to play. Listeners get the queue through the roomQueue socket event",
102
+ body: z.object({
103
+ videoId: z.string(),
104
+ }),
105
+ responses: {
106
+ 200: c.noBody(),
107
+ 400: z.union([ZodErrorSchema, invalidVideoId]),
108
+ ...authResponses,
109
+ ...notFound,
110
+ 409: apiError(z.literal("QUEUE_FULL"), z.literal("The queue of this room is full")),
111
+ ...internalError,
112
+ },
113
+ },
114
+ queueRemove: {
115
+ method: "DELETE",
116
+ path: "/room/:roomId/queue/:itemId",
117
+ description: "Remove a track from the queue of a room",
118
+ body: z.undefined(),
119
+ responses: {
120
+ 200: c.noBody(),
121
+ ...authResponses,
122
+ 404: z.union([notFound[404], queueItemNotFound]),
123
+ ...internalError,
124
+ },
125
+ },
126
+ queueMove: {
127
+ method: "POST",
128
+ path: "/room/:roomId/queue/:itemId/move",
129
+ description: "Move a track of the queue of a room to a new index",
130
+ body: z.object({
131
+ index: z.number().int().min(0),
132
+ }),
133
+ responses: {
134
+ 200: c.noBody(),
135
+ 400: ZodErrorSchema,
136
+ ...authResponses,
137
+ 404: z.union([notFound[404], queueItemNotFound]),
138
+ ...internalError,
139
+ },
140
+ },
141
+ next: {
142
+ method: "POST",
143
+ path: "/room/:roomId/next",
144
+ description: "Skip to the next track of the queue of a room",
145
+ body: z.undefined(),
146
+ responses: {
147
+ 200: c.noBody(),
148
+ 400: apiError(z.literal("QUEUE_EMPTY"), z.literal("The queue of this room is empty")),
149
+ ...authResponses,
150
+ ...notFound,
151
+ ...internalError,
152
+ },
153
+ },
97
154
  play: {
98
155
  method: "POST",
99
156
  path: "/room/:roomId/play",
100
- description: "Play the track of a room, from its position. A room without a stream starts a new one",
157
+ description: "Play the track of a room, from its position, or the next one of its queue if it has none. A room without a stream starts a new one",
101
158
  body: z.undefined(),
102
159
  responses: {
103
160
  200: c.noBody(),
@@ -1,4 +1,4 @@
1
- import type { RoomState } from "../types/room.js";
1
+ import type { RoomQueueItem, RoomState } from "../types/room.js";
2
2
  import type { MediaStreamScene } from "../types/scene.js";
3
3
  export interface SocketClientToServerRoom {
4
4
  /** Calls back with the state of the room, null if it doesn't exist */
@@ -20,6 +20,10 @@ export interface SocketServerToClientRoom {
20
20
  roomTrack: (roomId: string, state: RoomState) => void;
21
21
  /** The stream is gone, its url now returns 404. The room stays, with this state. */
22
22
  roomEnd: (roomId: string, reason: RoomEndReason, state: RoomState) => void;
23
+ /** The queue changed, the whole new queue */
24
+ roomQueue: (roomId: string, queue: RoomQueueItem[]) => void;
25
+ /** A track of the queue couldn't be played */
26
+ roomTrackFailed: (roomId: string, title: string) => void;
23
27
  /** The scene changed, the whole new scene */
24
28
  roomScene: (roomId: string, scene: MediaStreamScene) => void;
25
29
  roomName: (roomId: string, name: string | null) => void;
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const ROOM_ID_PATTERN: RegExp;
3
3
  export declare const ROOM_NAME_MAX_LENGTH = 64;
4
+ export declare const ROOM_QUEUE_MAX_LENGTH = 100;
4
5
  export declare const roomNameSchema: z.ZodString;
5
6
  export declare const roomTrackSchema: z.ZodObject<{
6
7
  videoId: z.ZodString;
@@ -16,6 +17,24 @@ export declare const roomTrackSchema: z.ZodObject<{
16
17
  title: string;
17
18
  duration: number;
18
19
  }>;
20
+ export declare const roomQueueItemSchema: z.ZodObject<{
21
+ videoId: z.ZodString;
22
+ title: z.ZodString;
23
+ /** seconds */
24
+ duration: z.ZodNumber;
25
+ } & {
26
+ id: z.ZodString;
27
+ }, "strip", z.ZodTypeAny, {
28
+ videoId: string;
29
+ title: string;
30
+ duration: number;
31
+ id: string;
32
+ }, {
33
+ videoId: string;
34
+ title: string;
35
+ duration: number;
36
+ id: string;
37
+ }>;
19
38
  export declare const roomStateSchema: z.ZodObject<{
20
39
  roomId: z.ZodString;
21
40
  name: z.ZodNullable<z.ZodString>;
@@ -35,6 +54,25 @@ export declare const roomStateSchema: z.ZodObject<{
35
54
  title: string;
36
55
  duration: number;
37
56
  }>>;
57
+ /** Tracks after the current one, the next one first */
58
+ queue: z.ZodArray<z.ZodObject<{
59
+ videoId: z.ZodString;
60
+ title: z.ZodString;
61
+ /** seconds */
62
+ duration: z.ZodNumber;
63
+ } & {
64
+ id: z.ZodString;
65
+ }, "strip", z.ZodTypeAny, {
66
+ videoId: string;
67
+ title: string;
68
+ duration: number;
69
+ id: string;
70
+ }, {
71
+ videoId: string;
72
+ title: string;
73
+ duration: number;
74
+ id: string;
75
+ }>, "many">;
38
76
  /** Audio of the current track, null while the room has no stream: nothing is playing, or it was paused for long */
39
77
  url: z.ZodNullable<z.ZodString>;
40
78
  paused: z.ZodBoolean;
@@ -141,6 +179,12 @@ export declare const roomStateSchema: z.ZodObject<{
141
179
  title: string;
142
180
  duration: number;
143
181
  } | null;
182
+ queue: {
183
+ videoId: string;
184
+ title: string;
185
+ duration: number;
186
+ id: string;
187
+ }[];
144
188
  url: string | null;
145
189
  paused: boolean;
146
190
  startTime: number;
@@ -174,6 +218,12 @@ export declare const roomStateSchema: z.ZodObject<{
174
218
  title: string;
175
219
  duration: number;
176
220
  } | null;
221
+ queue: {
222
+ videoId: string;
223
+ title: string;
224
+ duration: number;
225
+ id: string;
226
+ }[];
177
227
  url: string | null;
178
228
  paused: boolean;
179
229
  startTime: number;
@@ -237,5 +287,6 @@ export declare const roomSummarySchema: z.ZodObject<{
237
287
  paused: boolean;
238
288
  }>;
239
289
  export type RoomTrack = z.infer<typeof roomTrackSchema>;
290
+ export type RoomQueueItem = z.infer<typeof roomQueueItemSchema>;
240
291
  export type RoomState = z.infer<typeof roomStateSchema>;
241
292
  export type RoomSummary = z.infer<typeof roomSummarySchema>;
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { mediaStreamSceneSchema } from "./scene.js";
3
3
  export const ROOM_ID_PATTERN = /^[a-zA-Z0-9]{8}$/;
4
4
  export const ROOM_NAME_MAX_LENGTH = 64;
5
+ export const ROOM_QUEUE_MAX_LENGTH = 100;
5
6
  export const roomNameSchema = z
6
7
  .string()
7
8
  .trim()
@@ -13,12 +14,17 @@ export const roomTrackSchema = z.object({
13
14
  /** seconds */
14
15
  duration: z.number(),
15
16
  });
17
+ export const roomQueueItemSchema = roomTrackSchema.extend({
18
+ id: z.string(),
19
+ });
16
20
  export const roomStateSchema = z.object({
17
21
  roomId: z.string(),
18
22
  name: z.string().nullable(),
19
23
  /** public_id of the owner */
20
24
  ownerId: z.string(),
21
25
  track: roomTrackSchema.nullable(),
26
+ /** Tracks after the current one, the next one first */
27
+ queue: z.array(roomQueueItemSchema),
22
28
  /** Audio of the current track, null while the room has no stream: nothing is playing, or it was paused for long */
23
29
  url: z.string().nullable(),
24
30
  paused: z.boolean(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darco2903/altv-web-api",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "keywords": [],