]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - shared/extra-utils/shared/abstract-command.ts
Introduce server commands
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / shared / abstract-command.ts
1 import { isAbsolute, join } from 'path'
2 import { HttpStatusCode } from '@shared/core-utils'
3 import { root } from '../miscs/tests'
4 import {
5 makeDeleteRequest,
6 makeGetRequest,
7 makePostBodyRequest,
8 makePutBodyRequest,
9 makeUploadRequest,
10 unwrapBody,
11 unwrapText
12 } from '../requests/requests'
13 import { ServerInfo } from '../server/servers'
14
15 export interface OverrideCommandOptions {
16 token?: string
17 expectedStatus?: number
18 }
19
20 interface InternalCommonCommandOptions extends OverrideCommandOptions {
21 // Default to server.url
22 url?: string
23
24 path: string
25 // If we automatically send the server token if the token is not provided
26 implicitToken: boolean
27 defaultExpectedStatus: number
28 }
29
30 interface InternalGetCommandOptions extends InternalCommonCommandOptions {
31 query?: { [ id: string ]: any }
32 contentType?: string
33 accept?: string
34 redirects?: number
35 range?: string
36 }
37
38 abstract class AbstractCommand {
39
40 private expectedStatus: HttpStatusCode
41
42 constructor (
43 protected server: ServerInfo
44 ) {
45
46 }
47
48 setServer (server: ServerInfo) {
49 this.server = server
50 }
51
52 setExpectedStatus (status: HttpStatusCode) {
53 this.expectedStatus = status
54 }
55
56 protected getRequestBody <T> (options: InternalGetCommandOptions) {
57 return unwrapBody<T>(this.getRequest(options))
58 }
59
60 protected getRequestText (options: InternalGetCommandOptions) {
61 return unwrapText(this.getRequest(options))
62 }
63
64 protected getRawRequest (options: Omit<InternalGetCommandOptions, 'path'>) {
65 const { url, range } = options
66 const { host, protocol, pathname } = new URL(url)
67
68 return this.getRequest({
69 ...options,
70
71 token: this.buildCommonRequestToken(options),
72 defaultExpectedStatus: this.buildStatusCodeExpected(options),
73
74 url: `${protocol}//${host}`,
75 path: pathname,
76 range
77 })
78 }
79
80 protected getRequest (options: InternalGetCommandOptions) {
81 const { redirects, query, contentType, accept, range } = options
82
83 return makeGetRequest({
84 ...this.buildCommonRequestOptions(options),
85
86 redirects,
87 query,
88 contentType,
89 range,
90 accept
91 })
92 }
93
94 protected deleteRequest (options: InternalCommonCommandOptions) {
95 return makeDeleteRequest(this.buildCommonRequestOptions(options))
96 }
97
98 protected putBodyRequest (options: InternalCommonCommandOptions & {
99 fields?: { [ fieldName: string ]: any }
100 }) {
101 const { fields } = options
102
103 return makePutBodyRequest({
104 ...this.buildCommonRequestOptions(options),
105
106 fields
107 })
108 }
109
110 protected postBodyRequest (options: InternalCommonCommandOptions & {
111 fields?: { [ fieldName: string ]: any }
112 }) {
113 const { fields } = options
114
115 return makePostBodyRequest({
116 ...this.buildCommonRequestOptions(options),
117
118 fields
119 })
120 }
121
122 protected postUploadRequest (options: InternalCommonCommandOptions & {
123 fields?: { [ fieldName: string ]: any }
124 attaches?: any
125 }) {
126 const { fields, attaches } = options
127
128 return makeUploadRequest({
129 ...this.buildCommonRequestOptions(options),
130
131 method: 'POST',
132 fields,
133 attaches
134 })
135 }
136
137 protected putUploadRequest (options: InternalCommonCommandOptions & {
138 fields?: { [ fieldName: string ]: any }
139 attaches?: any
140 }) {
141 const { fields, attaches } = options
142
143 return makeUploadRequest({
144 ...this.buildCommonRequestOptions(options),
145
146 method: 'PUT',
147 fields,
148 attaches
149 })
150 }
151
152 protected updateImageRequest (options: InternalCommonCommandOptions & {
153 fixture: string
154 fieldname: string
155 }) {
156 let filePath = ''
157 if (isAbsolute(options.fixture)) {
158 filePath = options.fixture
159 } else {
160 filePath = join(root(), 'server', 'tests', 'fixtures', options.fixture)
161 }
162
163 return this.postUploadRequest({
164 ...options,
165
166 fields: {},
167 attaches: { [options.fieldname]: filePath }
168 })
169 }
170
171 private buildCommonRequestOptions (options: InternalCommonCommandOptions) {
172 const { url, path } = options
173
174 return {
175 url: url ?? this.server.url,
176 path,
177
178 token: this.buildCommonRequestToken(options),
179 statusCodeExpected: this.buildStatusCodeExpected(options)
180 }
181 }
182
183 private buildCommonRequestToken (options: Pick<InternalCommonCommandOptions, 'token' | 'implicitToken'>) {
184 const { token } = options
185
186 const fallbackToken = options.implicitToken
187 ? this.server.accessToken
188 : undefined
189
190 return token !== undefined ? token : fallbackToken
191 }
192
193 private buildStatusCodeExpected (options: Pick<InternalCommonCommandOptions, 'expectedStatus' | 'defaultExpectedStatus'>) {
194 const { expectedStatus, defaultExpectedStatus } = options
195
196 return expectedStatus ?? this.expectedStatus ?? defaultExpectedStatus
197 }
198 }
199
200 export {
201 AbstractCommand
202 }