tering-serieuze-sdk 1.2.2 → 2.0.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.
- package/dist/index.mjs +120 -34
- package/dist/index.mjs.map +2 -2
- package/package.json +5 -5
- package/src/api/auth.ts +6 -0
- package/src/api/jingle.ts +6 -6
- package/src/api/user.ts +12 -2
- package/src/index.ts +107 -23
- package/test/api/base.test.ts +13 -4
- package/test/api/jingle.test.ts +9 -7
- package/tsconfig.json +4 -2
- package/types/environment.d.ts +13 -0
package/dist/index.mjs
CHANGED
|
@@ -36,17 +36,17 @@ var CookieCache = class extends AbstractCache {
|
|
|
36
36
|
throw new Error("Not implemented, use get() and set()");
|
|
37
37
|
}
|
|
38
38
|
async get(key) {
|
|
39
|
-
if (document.cookie.includes(
|
|
40
|
-
return document.cookie.split(
|
|
39
|
+
if (document.cookie.includes(`${key}=`)) {
|
|
40
|
+
return document.cookie.split(`${key}=`)[1]?.split(";")[0];
|
|
41
41
|
}
|
|
42
42
|
return void 0;
|
|
43
43
|
}
|
|
44
44
|
set(key, value, lifetime) {
|
|
45
45
|
const expires = lifetime ? new Date(Date.now() + lifetime).toUTCString() : "";
|
|
46
|
-
document.cookie =
|
|
46
|
+
document.cookie = `${key}=${value}; expires=${expires}; path=/; samesite=strict; secure`;
|
|
47
47
|
}
|
|
48
48
|
remove(key) {
|
|
49
|
-
document.cookie =
|
|
49
|
+
document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
|
50
50
|
}
|
|
51
51
|
clear() {
|
|
52
52
|
throw new Error("Not implemented, use remove()");
|
|
@@ -185,8 +185,12 @@ var _AuthModule = class extends BaseModule {
|
|
|
185
185
|
async getToken() {
|
|
186
186
|
return this.cache.get(_AuthModule.cacheKey);
|
|
187
187
|
}
|
|
188
|
-
async setToken(token) {
|
|
189
|
-
return this.cache.set(_AuthModule.cacheKey, token);
|
|
188
|
+
async setToken(token, lifetime) {
|
|
189
|
+
return this.cache.set(_AuthModule.cacheKey, token, lifetime);
|
|
190
|
+
}
|
|
191
|
+
async setCode(code) {
|
|
192
|
+
const { accessToken } = await this.api.post(`auth/setCode?code=${code}`, {});
|
|
193
|
+
return accessToken;
|
|
190
194
|
}
|
|
191
195
|
async removeToken() {
|
|
192
196
|
return this.cache.remove(_AuthModule.cacheKey);
|
|
@@ -200,7 +204,7 @@ var JingleModule = class extends BaseModule {
|
|
|
200
204
|
async getGrouped() {
|
|
201
205
|
return this.cache.cacheOrGet(
|
|
202
206
|
() => {
|
|
203
|
-
return this.api.
|
|
207
|
+
return this.api.get("jingle/grouped");
|
|
204
208
|
},
|
|
205
209
|
"getGrouped",
|
|
206
210
|
604800 /* Week */
|
|
@@ -209,15 +213,15 @@ var JingleModule = class extends BaseModule {
|
|
|
209
213
|
async getAll() {
|
|
210
214
|
return this.cache.cacheOrGet(
|
|
211
215
|
() => {
|
|
212
|
-
return this.api.
|
|
216
|
+
return this.api.get("jingle");
|
|
213
217
|
},
|
|
214
218
|
"getAll",
|
|
215
219
|
604800 /* Week */
|
|
216
220
|
);
|
|
217
221
|
}
|
|
218
|
-
async play(
|
|
219
|
-
console.log(`Playing jingle ${folder}/${file}`);
|
|
220
|
-
return this.api.post("jingle/play",
|
|
222
|
+
async play(playJingleDto) {
|
|
223
|
+
console.log(`Playing jingle ${playJingleDto.folder}/${playJingleDto.file}`);
|
|
224
|
+
return this.api.post("jingle/play", playJingleDto);
|
|
221
225
|
}
|
|
222
226
|
};
|
|
223
227
|
|
|
@@ -226,9 +230,17 @@ var UserModule = class extends BaseModule {
|
|
|
226
230
|
async get(userId) {
|
|
227
231
|
return this.cache.cacheOrGet(() => {
|
|
228
232
|
const userIdParam = userId ? `/${userId}` : "";
|
|
229
|
-
return this.api.
|
|
233
|
+
return this.api.get(`user${userIdParam}`);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
async getAll() {
|
|
237
|
+
return this.cache.cacheOrGet(() => {
|
|
238
|
+
return this.api.get("user/all");
|
|
230
239
|
});
|
|
231
240
|
}
|
|
241
|
+
async setWindowState(setWindowStateDto) {
|
|
242
|
+
return this.api.put("user/windowState", setWindowStateDto);
|
|
243
|
+
}
|
|
232
244
|
};
|
|
233
245
|
|
|
234
246
|
// src/index.ts
|
|
@@ -237,7 +249,23 @@ import {
|
|
|
237
249
|
ForbiddenException,
|
|
238
250
|
NotFoundException,
|
|
239
251
|
UnauthorizedException,
|
|
240
|
-
UnprocessableEntityException
|
|
252
|
+
UnprocessableEntityException,
|
|
253
|
+
InternalServerErrorException,
|
|
254
|
+
GatewayTimeoutException,
|
|
255
|
+
BadGatewayException,
|
|
256
|
+
ConflictException,
|
|
257
|
+
GoneException,
|
|
258
|
+
HttpVersionNotSupportedException,
|
|
259
|
+
ImATeapotException,
|
|
260
|
+
MethodNotAllowedException,
|
|
261
|
+
MisdirectedException,
|
|
262
|
+
NotAcceptableException,
|
|
263
|
+
NotImplementedException,
|
|
264
|
+
PayloadTooLargeException,
|
|
265
|
+
PreconditionFailedException,
|
|
266
|
+
RequestTimeoutException,
|
|
267
|
+
ServiceUnavailableException,
|
|
268
|
+
UnsupportedMediaTypeException
|
|
241
269
|
} from "@nestjs/common";
|
|
242
270
|
var CacheType = /* @__PURE__ */ ((CacheType2) => {
|
|
243
271
|
CacheType2["jingle"] = "jingle";
|
|
@@ -246,16 +274,15 @@ var CacheType = /* @__PURE__ */ ((CacheType2) => {
|
|
|
246
274
|
return CacheType2;
|
|
247
275
|
})(CacheType || {});
|
|
248
276
|
var TssApi = class {
|
|
249
|
-
apiConfiguration;
|
|
250
|
-
auth;
|
|
251
|
-
jingle;
|
|
252
|
-
user;
|
|
253
277
|
constructor(apiConfiguration, cacheConfiguration) {
|
|
254
278
|
this.apiConfiguration = apiConfiguration;
|
|
255
279
|
this.jingle = new JingleModule(this, cacheConfiguration?.jingle ?? new NullCache("jingle"));
|
|
256
280
|
this.auth = new AuthModule(this, cacheConfiguration?.auth ?? new NullCache("auth"));
|
|
257
281
|
this.user = new UserModule(this, cacheConfiguration?.user ?? new NullCache("user"));
|
|
258
282
|
}
|
|
283
|
+
auth;
|
|
284
|
+
jingle;
|
|
285
|
+
user;
|
|
259
286
|
async fetch(url, config = {}) {
|
|
260
287
|
config.method = config.method ?? "GET";
|
|
261
288
|
config.headers = {
|
|
@@ -264,26 +291,85 @@ var TssApi = class {
|
|
|
264
291
|
Authorization: `Bearer ${await this.auth.getToken()}`
|
|
265
292
|
};
|
|
266
293
|
const apiPrefix = this.apiConfiguration.API_URL;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
case 400:
|
|
270
|
-
throw new BadRequestException(response.statusText);
|
|
271
|
-
case 401:
|
|
272
|
-
throw new UnauthorizedException(response.statusText);
|
|
273
|
-
case 403:
|
|
274
|
-
throw new ForbiddenException(response.statusText);
|
|
275
|
-
case 404:
|
|
276
|
-
throw new NotFoundException(response.statusText);
|
|
277
|
-
case 422:
|
|
278
|
-
throw new UnprocessableEntityException(response.statusText);
|
|
294
|
+
if (apiPrefix.match(/^https?:\/\/localhost/) !== null && typeof process !== "undefined" && process.env) {
|
|
295
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
|
|
279
296
|
}
|
|
280
|
-
|
|
297
|
+
const fullUrl = `${apiPrefix}/api/${url}`;
|
|
298
|
+
console.log("Fetching url", fullUrl);
|
|
299
|
+
let response;
|
|
300
|
+
try {
|
|
301
|
+
response = await fetch(fullUrl, config);
|
|
302
|
+
} catch (e) {
|
|
303
|
+
throw new GatewayTimeoutException("API erg dood");
|
|
304
|
+
}
|
|
305
|
+
if (response.status >= 400) {
|
|
306
|
+
const error = await response.json();
|
|
307
|
+
switch (response.status) {
|
|
308
|
+
case 400:
|
|
309
|
+
throw new BadRequestException(error);
|
|
310
|
+
case 401:
|
|
311
|
+
throw new UnauthorizedException(error);
|
|
312
|
+
case 403:
|
|
313
|
+
throw new ForbiddenException(error);
|
|
314
|
+
case 404:
|
|
315
|
+
throw new NotFoundException(error);
|
|
316
|
+
case 405:
|
|
317
|
+
throw new MethodNotAllowedException(error);
|
|
318
|
+
case 406:
|
|
319
|
+
throw new NotAcceptableException(error);
|
|
320
|
+
case 408:
|
|
321
|
+
throw new RequestTimeoutException(error);
|
|
322
|
+
case 409:
|
|
323
|
+
throw new ConflictException(error);
|
|
324
|
+
case 410:
|
|
325
|
+
throw new GoneException(error);
|
|
326
|
+
case 412:
|
|
327
|
+
throw new PreconditionFailedException(error);
|
|
328
|
+
case 413:
|
|
329
|
+
throw new PayloadTooLargeException(error);
|
|
330
|
+
case 415:
|
|
331
|
+
throw new UnsupportedMediaTypeException(error);
|
|
332
|
+
case 418:
|
|
333
|
+
throw new ImATeapotException(error);
|
|
334
|
+
case 421:
|
|
335
|
+
throw new MisdirectedException(error);
|
|
336
|
+
case 422:
|
|
337
|
+
throw new UnprocessableEntityException(error);
|
|
338
|
+
case 500:
|
|
339
|
+
throw new InternalServerErrorException(error);
|
|
340
|
+
case 501:
|
|
341
|
+
throw new NotImplementedException(error);
|
|
342
|
+
case 502:
|
|
343
|
+
throw new BadGatewayException(error);
|
|
344
|
+
case 503:
|
|
345
|
+
throw new ServiceUnavailableException(error);
|
|
346
|
+
case 504:
|
|
347
|
+
throw new GatewayTimeoutException(error);
|
|
348
|
+
case 505:
|
|
349
|
+
throw new HttpVersionNotSupportedException(error);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return response;
|
|
281
353
|
}
|
|
282
|
-
async
|
|
283
|
-
|
|
284
|
-
method
|
|
285
|
-
body: JSON.stringify(
|
|
354
|
+
async fetchPossibleEmptyResponse(method, url, dto) {
|
|
355
|
+
const response = await this.fetch(url, {
|
|
356
|
+
method,
|
|
357
|
+
body: JSON.stringify(dto)
|
|
286
358
|
});
|
|
359
|
+
if (response.status === 204) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
return response.json();
|
|
363
|
+
}
|
|
364
|
+
async get(url) {
|
|
365
|
+
const response = await this.fetch(url);
|
|
366
|
+
return response.json();
|
|
367
|
+
}
|
|
368
|
+
async post(url, dto) {
|
|
369
|
+
return this.fetchPossibleEmptyResponse("POST", url, dto);
|
|
370
|
+
}
|
|
371
|
+
async put(url, dto) {
|
|
372
|
+
return this.fetchPossibleEmptyResponse("PUT", url, dto);
|
|
287
373
|
}
|
|
288
374
|
};
|
|
289
375
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cache/abstractCache.ts", "../src/cache/cookieCache.ts", "../src/cache/filesystemCache.ts", "../src/cache/nullCache.ts", "../src/cache/onePasswordCache.ts", "../src/api/base.ts", "../src/api/auth.ts", "../src/api/jingle.ts", "../src/api/user.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { get } from \"stack-trace\";\n\nexport enum CacheLifetime {\n Day = 60 * 60 * 24,\n Week = 60 * 60 * 24 * 7,\n}\n\nexport abstract class AbstractCache {\n constructor(protected cacheName: string) {}\n\n public abstract cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T>;\n\n public abstract get<T>(key: string): Promise<T | undefined>;\n\n public abstract set<T>(key: string, value: T, lifetime?: number): void;\n\n public abstract remove(key: string): void;\n\n public abstract clear(): void;\n\n public getCacheKey(): string {\n const errorMessage = \"Could not determine cache key. Please provide a key manually.\";\n const trace = get();\n if (trace.length < 3) {\n throw new Error(errorMessage);\n }\n\n const functionName = get()[2].getFunctionName();\n if (!functionName) {\n throw new Error(errorMessage);\n }\n\n return functionName;\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\n\nexport class CookieCache extends AbstractCache {\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n throw new Error(\"Not implemented, use get() and set()\");\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n if (document.cookie.includes(\"auth=\")) {\n return document.cookie.split(\"auth=\")[1]?.split(\";\")[0] as T;\n }\n\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {\n const expires = lifetime ? new Date(Date.now() + lifetime).toUTCString() : \"\";\n document.cookie = `auth=${value}; expires=${expires}; path=/; samesite=strict; secure`;\n }\n\n public remove(key: string): void {\n document.cookie = \"auth=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;\";\n }\n\n public clear(): void {\n throw new Error(\"Not implemented, use remove()\");\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\ntype CacheItem = {\n value: any;\n expiresAt?: number;\n};\n\nexport class FilesystemCache extends AbstractCache {\n protected initialized = false;\n\n protected state: { [key: string]: CacheItem } = {};\n\n public async cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n key = key ?? this.getCacheKey();\n\n const cachedValue = await this.get<T>(key);\n if (cachedValue) {\n return cachedValue;\n }\n\n const result = await callbackWhenEmpty();\n this.set(key, result, lifetime);\n return result;\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n if (!this.initialized) {\n await this._initialize();\n }\n\n const expires = this.state[key]?.expiresAt;\n if (Object.keys(this.state).includes(key) && (expires === undefined || expires > Date.now())) {\n return this.state[key].value;\n }\n\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {\n const expiresAt = lifetime ? Date.now() + lifetime : undefined;\n const content: CacheItem = { value };\n if (expiresAt) {\n content.expiresAt = expiresAt;\n }\n this.state[key] = content;\n this.writeState();\n }\n\n public remove(key: string): void {\n delete this.state[key];\n this.writeState();\n }\n\n public clear(): void {\n this.state = {};\n unlinkSync(this.getFilePath());\n }\n\n public getFilePath() {\n return path.join(os.homedir(), \".tss\", `${this.cacheName}.json`);\n }\n\n protected _initialize() {\n this.initialized = true;\n if (existsSync(this.getFilePath())) {\n this.state = JSON.parse(readFileSync(this.getFilePath(), \"utf8\"));\n }\n }\n\n protected writeState() {\n if (!existsSync(path.dirname(this.getFilePath()))) {\n mkdirSync(path.dirname(this.getFilePath()));\n }\n\n writeFileSync(this.getFilePath(), JSON.stringify(this.state));\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\n\nexport class NullCache extends AbstractCache {\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n return callbackWhenEmpty();\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {}\n\n public remove(key: string): void {}\n\n public clear(): void {}\n}\n", "import { AbstractCache } from \"./abstractCache\";\nimport { promisify } from \"util\";\nimport { exec } from \"child_process\";\n\n// TODO error handling en lifetime\nexport class OnePasswordCache extends AbstractCache {\n protected asyncExec = promisify(exec);\n\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n throw new Error(\"Not implemented, use get() and set()\");\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n const { stdout, stderr } = await this.asyncExec(`op item get \"${key}\" --fields label=credential --format json`);\n\n if (stderr) {\n console.log(stderr);\n throw new Error(\"ERROR\");\n }\n\n return JSON.parse(stdout).value;\n }\n\n public async set<T>(key: string, value: T, lifetime?: number): Promise<void> {\n let action = `op item edit '${key}' 'credential=${value}'`;\n\n try {\n const t = await this.get(key);\n } catch (e) {\n action = `op item create --category=\"API Credential\" --title ${key} 'credential=${value}'`;\n }\n\n const { stdout, stderr } = await this.asyncExec(action);\n\n if (stderr) {\n console.log(stderr);\n throw new Error(\"ERROR\");\n }\n }\n\n public async remove(key: string): Promise<void> {\n await this.asyncExec(`op item delete '${key}'`);\n }\n\n public clear(): void {\n // Loopje maken en heel 1password leeg maken?\n }\n}\n", "import { AbstractCache } from \"../cache\";\nimport { TssApi } from \"../index\";\n\nexport class BaseModule {\n constructor(protected api: TssApi, protected cache: AbstractCache) {}\n\n public getCache() {\n return this.cache;\n }\n\n public setCache(cache: AbstractCache) {\n this.cache = cache;\n }\n}\n", "import { BaseModule } from \"./base\";\n\nexport class AuthModule extends BaseModule {\n protected static cacheKey = \"TSS-TOKEN\";\n\n async getToken(): Promise<string | undefined> {\n return this.cache.get(AuthModule.cacheKey);\n }\n\n async setToken(token: string) {\n return this.cache.set(AuthModule.cacheKey, token);\n }\n\n async removeToken() {\n return this.cache.remove(AuthModule.cacheKey);\n }\n}\n", "import { JingleFolder, Jingle } from \"tering-serieuze-types\";\nimport { BaseModule } from \"./base\";\nimport { CacheLifetime } from \"../cache\";\n\nexport class JingleModule extends BaseModule {\n async getGrouped() {\n return this.cache.cacheOrGet(\n () => {\n return this.api.fetch<JingleFolder[]>(\"jingle/grouped\");\n },\n \"getGrouped\",\n CacheLifetime.Week\n );\n }\n\n async getAll() {\n return this.cache.cacheOrGet(\n () => {\n return this.api.fetch<Jingle[]>(\"jingle\");\n },\n \"getAll\",\n CacheLifetime.Week\n );\n }\n\n async play(folder: string, file: string) {\n console.log(`Playing jingle ${folder}/${file}`);\n return this.api.post(\"jingle/play\", { folder, file });\n }\n}\n", "import { BaseModule } from \"./base\";\nimport { User } from \"tering-serieuze-types\";\n\nexport class UserModule extends BaseModule {\n async get(userId?: string) {\n return this.cache.cacheOrGet(() => {\n const userIdParam = userId ? `/${userId}` : \"\";\n return this.api.fetch<User>(`user${userIdParam}`);\n });\n }\n}\n", "import { AbstractCache, NullCache } from \"./cache\";\nimport { AuthModule, JingleModule, UserModule } from \"./api\";\nimport {\n BadRequestException,\n ForbiddenException,\n NotFoundException,\n UnauthorizedException,\n UnprocessableEntityException,\n} from \"@nestjs/common\";\n\nexport * from \"./api\";\nexport * from \"./cache\";\n\nexport interface SDKRequestInit extends RequestInit {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n}\n\nexport enum CacheType {\n jingle = \"jingle\",\n auth = \"auth\",\n user = \"user\",\n}\n\nexport type ApiConfiguration = {\n API_URL: string;\n};\n\nexport type CacheConfiguration = {\n [key in keyof typeof CacheType]?: AbstractCache;\n};\n\nexport class TssApi {\n apiConfiguration: ApiConfiguration;\n\n auth: AuthModule;\n\n jingle: JingleModule;\n\n user: UserModule;\n\n constructor(apiConfiguration: ApiConfiguration, cacheConfiguration?: CacheConfiguration) {\n this.apiConfiguration = apiConfiguration;\n this.jingle = new JingleModule(this, cacheConfiguration?.jingle ?? new NullCache(\"jingle\"));\n this.auth = new AuthModule(this, cacheConfiguration?.auth ?? new NullCache(\"auth\"));\n this.user = new UserModule(this, cacheConfiguration?.user ?? new NullCache(\"user\"));\n }\n\n async fetch<T>(url: string, config: SDKRequestInit = {}) {\n config.method = config.method ?? \"GET\";\n config.headers = {\n ...config.headers,\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${await this.auth.getToken()}`,\n };\n\n const apiPrefix = this.apiConfiguration.API_URL;\n const response = await fetch(apiPrefix + \"/api/\" + url, config);\n switch (response.status) {\n case 400:\n throw new BadRequestException(response.statusText);\n case 401:\n throw new UnauthorizedException(response.statusText);\n case 403:\n throw new ForbiddenException(response.statusText);\n case 404:\n throw new NotFoundException(response.statusText);\n case 422:\n throw new UnprocessableEntityException(response.statusText);\n }\n\n return response.json() as Promise<T>;\n }\n\n async post<T>(url: string, body: any) {\n return this.fetch<T>(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;AAAA,SAAS,WAAW;AAEb,IAAK,gBAAL,kBAAKA,mBAAL;AACH,EAAAA,8BAAA,SAAM,SAAN;AACA,EAAAA,8BAAA,UAAO,UAAP;AAFQ,SAAAA;AAAA,GAAA;AAKL,IAAe,gBAAf,MAA6B;AAAA,EAChC,YAAsB,WAAmB;AAAnB;AAAA,EAAoB;AAAA,EAYnC,cAAsB;AACzB,UAAM,eAAe;AACrB,UAAM,QAAQ,IAAI;AAClB,QAAI,MAAM,SAAS,GAAG;AAClB,YAAM,IAAI,MAAM,YAAY;AAAA,IAChC;AAEA,UAAM,eAAe,IAAI,EAAE,CAAC,EAAE,gBAAgB;AAC9C,QAAI,CAAC,cAAc;AACf,YAAM,IAAI,MAAM,YAAY;AAAA,IAChC;AAEA,WAAO;AAAA,EACX;AACJ;;;AChCO,IAAM,cAAN,cAA0B,cAAc;AAAA,EACpC,WAAc,mBAAqC,KAAc,UAA+B;AACnG,UAAM,IAAI,MAAM,sCAAsC;AAAA,EAC1D;AAAA,EAEA,MAAa,IAAO,KAAqC;AACrD,QAAI,SAAS,OAAO,SAAS,
|
|
4
|
+
"sourcesContent": ["import { get } from \"stack-trace\";\n\nexport enum CacheLifetime {\n Day = 60 * 60 * 24,\n Week = 60 * 60 * 24 * 7,\n}\n\nexport abstract class AbstractCache {\n constructor(protected cacheName: string) {}\n\n public abstract cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T>;\n\n public abstract get<T>(key: string): Promise<T | undefined>;\n\n public abstract set<T>(key: string, value: T, lifetime?: number): void;\n\n public abstract remove(key: string): void;\n\n public abstract clear(): void;\n\n public getCacheKey(): string {\n const errorMessage = \"Could not determine cache key. Please provide a key manually.\";\n const trace = get();\n if (trace.length < 3) {\n throw new Error(errorMessage);\n }\n\n const functionName = get()[2].getFunctionName();\n if (!functionName) {\n throw new Error(errorMessage);\n }\n\n return functionName;\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\n\nexport class CookieCache extends AbstractCache {\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n throw new Error(\"Not implemented, use get() and set()\");\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n if (document.cookie.includes(`${key}=`)) {\n return document.cookie.split(`${key}=`)[1]?.split(\";\")[0] as T;\n }\n\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {\n const expires = lifetime ? new Date(Date.now() + lifetime).toUTCString() : \"\";\n document.cookie = `${key}=${value}; expires=${expires}; path=/; samesite=strict; secure`;\n }\n\n public remove(key: string): void {\n document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n }\n\n public clear(): void {\n throw new Error(\"Not implemented, use remove()\");\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\ntype CacheItem = {\n value: any;\n expiresAt?: number;\n};\n\nexport class FilesystemCache extends AbstractCache {\n protected initialized = false;\n\n protected state: { [key: string]: CacheItem } = {};\n\n public async cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n key = key ?? this.getCacheKey();\n\n const cachedValue = await this.get<T>(key);\n if (cachedValue) {\n return cachedValue;\n }\n\n const result = await callbackWhenEmpty();\n this.set(key, result, lifetime);\n return result;\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n // TODO iets met # (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)\n if (!this.initialized) {\n await this._initialize();\n }\n\n const expires = this.state[key]?.expiresAt;\n if (Object.keys(this.state).includes(key) && (expires === undefined || expires > Date.now())) {\n return this.state[key].value;\n }\n\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {\n const expiresAt = lifetime ? Date.now() + lifetime : undefined;\n const content: CacheItem = { value };\n if (expiresAt) {\n content.expiresAt = expiresAt;\n }\n this.state[key] = content;\n this.writeState();\n }\n\n public remove(key: string): void {\n delete this.state[key];\n this.writeState();\n }\n\n public clear(): void {\n this.state = {};\n unlinkSync(this.getFilePath());\n }\n\n public getFilePath() {\n return path.join(os.homedir(), \".tss\", `${this.cacheName}.json`);\n }\n\n protected _initialize() {\n this.initialized = true;\n if (existsSync(this.getFilePath())) {\n this.state = JSON.parse(readFileSync(this.getFilePath(), \"utf8\"));\n }\n }\n\n protected writeState() {\n if (!existsSync(path.dirname(this.getFilePath()))) {\n mkdirSync(path.dirname(this.getFilePath()));\n }\n\n writeFileSync(this.getFilePath(), JSON.stringify(this.state));\n }\n}\n", "import { AbstractCache } from \"./abstractCache\";\n\nexport class NullCache extends AbstractCache {\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n return callbackWhenEmpty();\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n return undefined;\n }\n\n public set<T>(key: string, value: T, lifetime?: number): void {}\n\n public remove(key: string): void {}\n\n public clear(): void {}\n}\n", "import { AbstractCache } from \"./abstractCache\";\nimport { promisify } from \"util\";\nimport { exec } from \"child_process\";\n\n// TODO error handling en lifetime\nexport class OnePasswordCache extends AbstractCache {\n protected asyncExec = promisify(exec);\n\n public cacheOrGet<T>(callbackWhenEmpty: () => Promise<T>, key?: string, lifetime?: number): Promise<T> {\n throw new Error(\"Not implemented, use get() and set()\");\n }\n\n public async get<T>(key: string): Promise<T | undefined> {\n const { stdout, stderr } = await this.asyncExec(`op item get \"${key}\" --fields label=credential --format json`);\n\n if (stderr) {\n console.log(stderr);\n throw new Error(\"ERROR\");\n }\n\n return JSON.parse(stdout).value;\n }\n\n public async set<T>(key: string, value: T, lifetime?: number): Promise<void> {\n let action = `op item edit '${key}' 'credential=${value}'`;\n\n try {\n const t = await this.get(key);\n } catch (e) {\n action = `op item create --category=\"API Credential\" --title ${key} 'credential=${value}'`;\n }\n\n const { stdout, stderr } = await this.asyncExec(action);\n\n if (stderr) {\n console.log(stderr);\n throw new Error(\"ERROR\");\n }\n }\n\n public async remove(key: string): Promise<void> {\n await this.asyncExec(`op item delete '${key}'`);\n }\n\n public clear(): void {\n // Loopje maken en heel 1password leeg maken?\n }\n}\n", "import { AbstractCache } from \"../cache\";\nimport { TssApi } from \"../index\";\n\nexport class BaseModule {\n constructor(protected api: TssApi, protected cache: AbstractCache) {}\n\n public getCache() {\n return this.cache;\n }\n\n public setCache(cache: AbstractCache) {\n this.cache = cache;\n }\n}\n", "import { BaseModule } from \"./base\";\n\nexport class AuthModule extends BaseModule {\n public static cacheKey = \"TSS-TOKEN\";\n\n async getToken(): Promise<string | undefined> {\n return this.cache.get(AuthModule.cacheKey);\n }\n\n async setToken(token: string, lifetime?: number) {\n return this.cache.set(AuthModule.cacheKey, token, lifetime);\n }\n\n async setCode(code: string) {\n // TODO any ?!\n const { accessToken } = await this.api.post<any>(`auth/setCode?code=${code}`, {});\n return accessToken;\n }\n\n async removeToken() {\n return this.cache.remove(AuthModule.cacheKey);\n }\n}\n", "import { JingleFolder, Jingle, PlayJingleDto } from \"tering-serieuze-types\";\nimport { BaseModule } from \"./base\";\nimport { CacheLifetime } from \"../cache\";\n\nexport class JingleModule extends BaseModule {\n async getGrouped() {\n return this.cache.cacheOrGet(\n () => {\n return this.api.get<JingleFolder[]>(\"jingle/grouped\");\n },\n \"getGrouped\",\n CacheLifetime.Week\n );\n }\n\n async getAll() {\n return this.cache.cacheOrGet(\n () => {\n return this.api.get<Jingle[]>(\"jingle\");\n },\n \"getAll\",\n CacheLifetime.Week\n );\n }\n\n async play(playJingleDto: PlayJingleDto) {\n console.log(`Playing jingle ${playJingleDto.folder}/${playJingleDto.file}`);\n return this.api.post(\"jingle/play\", playJingleDto);\n }\n}\n", "import { BaseModule } from \"./base\";\nimport { SetWindowStateDto, User } from \"tering-serieuze-types\";\n\nexport class UserModule extends BaseModule {\n async get(userId?: string) {\n return this.cache.cacheOrGet(() => {\n const userIdParam = userId ? `/${userId}` : \"\";\n return this.api.get<User>(`user${userIdParam}`);\n });\n }\n\n async getAll() {\n return this.cache.cacheOrGet(() => {\n return this.api.get<User[]>(\"user/all\");\n });\n }\n\n async setWindowState(setWindowStateDto: SetWindowStateDto) {\n return this.api.put(\"user/windowState\", setWindowStateDto);\n }\n}\n", "import { AbstractCache, NullCache } from \"./cache\";\nimport { AuthModule, JingleModule, UserModule } from \"./api\";\nimport {\n BadRequestException,\n ForbiddenException,\n NotFoundException,\n UnauthorizedException,\n UnprocessableEntityException,\n InternalServerErrorException,\n GatewayTimeoutException,\n BadGatewayException,\n ConflictException,\n GoneException,\n HttpVersionNotSupportedException,\n ImATeapotException,\n MethodNotAllowedException,\n MisdirectedException,\n NotAcceptableException,\n NotImplementedException,\n PayloadTooLargeException,\n PreconditionFailedException,\n RequestTimeoutException,\n ServiceUnavailableException,\n UnsupportedMediaTypeException,\n} from \"@nestjs/common\";\nimport { Dto } from \"tering-serieuze-types\";\n\nexport * from \"./api\";\nexport * from \"./cache\";\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\nexport interface SDKRequestInit extends RequestInit {\n method?: HttpMethod;\n}\n\nexport enum CacheType {\n jingle = \"jingle\",\n auth = \"auth\",\n user = \"user\",\n}\n\nexport type ApiConfiguration = {\n API_URL: string;\n};\n\nexport type CacheConfiguration = {\n [key in keyof typeof CacheType]?: AbstractCache;\n};\n\nexport class TssApi {\n auth: AuthModule;\n\n jingle: JingleModule;\n\n user: UserModule;\n\n constructor(protected readonly apiConfiguration: ApiConfiguration, cacheConfiguration?: CacheConfiguration) {\n this.jingle = new JingleModule(this, cacheConfiguration?.jingle ?? new NullCache(\"jingle\"));\n this.auth = new AuthModule(this, cacheConfiguration?.auth ?? new NullCache(\"auth\"));\n this.user = new UserModule(this, cacheConfiguration?.user ?? new NullCache(\"user\"));\n }\n\n async fetch(url: string, config: SDKRequestInit = {}) {\n config.method = config.method ?? \"GET\";\n config.headers = {\n ...config.headers,\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${await this.auth.getToken()}`,\n };\n\n const apiPrefix = this.apiConfiguration.API_URL;\n\n if (apiPrefix.match(/^https?:\\/\\/localhost/) !== null && typeof process !== \"undefined\" && process.env) {\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;\n }\n\n const fullUrl = `${apiPrefix}/api/${url}`;\n console.log(\"Fetching url\", fullUrl);\n\n let response;\n try {\n response = await fetch(fullUrl, config);\n } catch (e) {\n throw new GatewayTimeoutException(\"API erg dood\");\n }\n\n if (response.status >= 400) {\n const error = await response.json();\n switch (response.status) {\n case 400:\n throw new BadRequestException(error);\n case 401:\n throw new UnauthorizedException(error);\n case 403:\n throw new ForbiddenException(error);\n case 404:\n throw new NotFoundException(error);\n case 405:\n throw new MethodNotAllowedException(error);\n case 406:\n throw new NotAcceptableException(error);\n case 408:\n throw new RequestTimeoutException(error);\n case 409:\n throw new ConflictException(error);\n case 410:\n throw new GoneException(error);\n case 412:\n throw new PreconditionFailedException(error);\n case 413:\n throw new PayloadTooLargeException(error);\n case 415:\n throw new UnsupportedMediaTypeException(error);\n case 418:\n throw new ImATeapotException(error);\n case 421:\n throw new MisdirectedException(error);\n case 422:\n throw new UnprocessableEntityException(error);\n case 500:\n throw new InternalServerErrorException(error);\n case 501:\n throw new NotImplementedException(error);\n case 502:\n throw new BadGatewayException(error);\n case 503:\n throw new ServiceUnavailableException(error);\n case 504:\n throw new GatewayTimeoutException(error);\n case 505:\n throw new HttpVersionNotSupportedException(error);\n }\n }\n\n return response;\n }\n\n protected async fetchPossibleEmptyResponse<T>(method: HttpMethod, url: string, dto: Dto) {\n const response = await this.fetch(url, {\n method,\n body: JSON.stringify(dto),\n });\n\n if (response.status === 204) {\n return;\n }\n\n return response.json() as Promise<T>;\n }\n\n async get<T>(url: string) {\n const response = await this.fetch(url);\n return response.json() as Promise<T>;\n }\n\n async post<T>(url: string, dto: Dto) {\n return this.fetchPossibleEmptyResponse<T>(\"POST\", url, dto);\n }\n\n async put<T>(url: string, dto: Dto) {\n return this.fetchPossibleEmptyResponse<T>(\"PUT\", url, dto);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["CacheLifetime", "CacheType"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tering-serieuze-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Teringserieuze sdk",
|
|
5
5
|
"author": "Frank",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
7
7
|
"types": "index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "vitest",
|
|
10
|
+
"test": "API_URL=https://localhost:8081 vitest",
|
|
11
11
|
"coverage": "vitest run --coverage",
|
|
12
12
|
"dev": "esbuild src/index.ts --bundle --platform=node --outfile=dist/index.mjs --packages=external --sourcemap=external --format=esm --watch",
|
|
13
13
|
"build": "esbuild src/index.ts --bundle --platform=node --outfile=dist/index.mjs --packages=external --sourcemap=external --format=esm",
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"homepage": "https://gitlab.com/tering-serieuze-shit/tering-serieuze-sdk#readme",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@nestjs/common": "^9.3.9",
|
|
27
|
-
"@types/node": "^18.11.18",
|
|
28
27
|
"stack-trace": "^1.0.0-pre2",
|
|
29
|
-
"tering-serieuze-types": "^1.
|
|
28
|
+
"tering-serieuze-types": "^1.9.0"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
31
|
+
"@types/node": "^18.15.3",
|
|
32
32
|
"@types/stack-trace": "^0.0.30",
|
|
33
33
|
"@vitest/coverage-c8": "^0.28.5",
|
|
34
|
-
"esbuild": "^0.
|
|
34
|
+
"esbuild": "^0.17.12",
|
|
35
35
|
"prettier": "^2.8.1",
|
|
36
36
|
"vitest": "^0.28.5"
|
|
37
37
|
}
|
package/src/api/auth.ts
CHANGED
|
@@ -11,6 +11,12 @@ export class AuthModule extends BaseModule {
|
|
|
11
11
|
return this.cache.set(AuthModule.cacheKey, token, lifetime);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
async setCode(code: string) {
|
|
15
|
+
// TODO any ?!
|
|
16
|
+
const { accessToken } = await this.api.post<any>(`auth/setCode?code=${code}`, {});
|
|
17
|
+
return accessToken;
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
async removeToken() {
|
|
15
21
|
return this.cache.remove(AuthModule.cacheKey);
|
|
16
22
|
}
|
package/src/api/jingle.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JingleFolder, Jingle } from "tering-serieuze-types";
|
|
1
|
+
import { JingleFolder, Jingle, PlayJingleDto } from "tering-serieuze-types";
|
|
2
2
|
import { BaseModule } from "./base";
|
|
3
3
|
import { CacheLifetime } from "../cache";
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ export class JingleModule extends BaseModule {
|
|
|
6
6
|
async getGrouped() {
|
|
7
7
|
return this.cache.cacheOrGet(
|
|
8
8
|
() => {
|
|
9
|
-
return this.api.
|
|
9
|
+
return this.api.get<JingleFolder[]>("jingle/grouped");
|
|
10
10
|
},
|
|
11
11
|
"getGrouped",
|
|
12
12
|
CacheLifetime.Week
|
|
@@ -16,15 +16,15 @@ export class JingleModule extends BaseModule {
|
|
|
16
16
|
async getAll() {
|
|
17
17
|
return this.cache.cacheOrGet(
|
|
18
18
|
() => {
|
|
19
|
-
return this.api.
|
|
19
|
+
return this.api.get<Jingle[]>("jingle");
|
|
20
20
|
},
|
|
21
21
|
"getAll",
|
|
22
22
|
CacheLifetime.Week
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
async play(
|
|
27
|
-
console.log(`Playing jingle ${folder}/${file}`);
|
|
28
|
-
return this.api.post("jingle/play",
|
|
26
|
+
async play(playJingleDto: PlayJingleDto) {
|
|
27
|
+
console.log(`Playing jingle ${playJingleDto.folder}/${playJingleDto.file}`);
|
|
28
|
+
return this.api.post("jingle/play", playJingleDto);
|
|
29
29
|
}
|
|
30
30
|
}
|
package/src/api/user.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { BaseModule } from "./base";
|
|
2
|
-
import { User } from "tering-serieuze-types";
|
|
2
|
+
import { SetWindowStateDto, User } from "tering-serieuze-types";
|
|
3
3
|
|
|
4
4
|
export class UserModule extends BaseModule {
|
|
5
5
|
async get(userId?: string) {
|
|
6
6
|
return this.cache.cacheOrGet(() => {
|
|
7
7
|
const userIdParam = userId ? `/${userId}` : "";
|
|
8
|
-
return this.api.
|
|
8
|
+
return this.api.get<User>(`user${userIdParam}`);
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
async getAll() {
|
|
13
|
+
return this.cache.cacheOrGet(() => {
|
|
14
|
+
return this.api.get<User[]>("user/all");
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async setWindowState(setWindowStateDto: SetWindowStateDto) {
|
|
19
|
+
return this.api.put("user/windowState", setWindowStateDto);
|
|
20
|
+
}
|
|
11
21
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,13 +6,32 @@ import {
|
|
|
6
6
|
NotFoundException,
|
|
7
7
|
UnauthorizedException,
|
|
8
8
|
UnprocessableEntityException,
|
|
9
|
+
InternalServerErrorException,
|
|
10
|
+
GatewayTimeoutException,
|
|
11
|
+
BadGatewayException,
|
|
12
|
+
ConflictException,
|
|
13
|
+
GoneException,
|
|
14
|
+
HttpVersionNotSupportedException,
|
|
15
|
+
ImATeapotException,
|
|
16
|
+
MethodNotAllowedException,
|
|
17
|
+
MisdirectedException,
|
|
18
|
+
NotAcceptableException,
|
|
19
|
+
NotImplementedException,
|
|
20
|
+
PayloadTooLargeException,
|
|
21
|
+
PreconditionFailedException,
|
|
22
|
+
RequestTimeoutException,
|
|
23
|
+
ServiceUnavailableException,
|
|
24
|
+
UnsupportedMediaTypeException,
|
|
9
25
|
} from "@nestjs/common";
|
|
26
|
+
import { Dto } from "tering-serieuze-types";
|
|
10
27
|
|
|
11
28
|
export * from "./api";
|
|
12
29
|
export * from "./cache";
|
|
13
30
|
|
|
31
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
32
|
+
|
|
14
33
|
export interface SDKRequestInit extends RequestInit {
|
|
15
|
-
method?:
|
|
34
|
+
method?: HttpMethod;
|
|
16
35
|
}
|
|
17
36
|
|
|
18
37
|
export enum CacheType {
|
|
@@ -30,22 +49,19 @@ export type CacheConfiguration = {
|
|
|
30
49
|
};
|
|
31
50
|
|
|
32
51
|
export class TssApi {
|
|
33
|
-
apiConfiguration: ApiConfiguration;
|
|
34
|
-
|
|
35
52
|
auth: AuthModule;
|
|
36
53
|
|
|
37
54
|
jingle: JingleModule;
|
|
38
55
|
|
|
39
56
|
user: UserModule;
|
|
40
57
|
|
|
41
|
-
constructor(apiConfiguration: ApiConfiguration, cacheConfiguration?: CacheConfiguration) {
|
|
42
|
-
this.apiConfiguration = apiConfiguration;
|
|
58
|
+
constructor(protected readonly apiConfiguration: ApiConfiguration, cacheConfiguration?: CacheConfiguration) {
|
|
43
59
|
this.jingle = new JingleModule(this, cacheConfiguration?.jingle ?? new NullCache("jingle"));
|
|
44
60
|
this.auth = new AuthModule(this, cacheConfiguration?.auth ?? new NullCache("auth"));
|
|
45
61
|
this.user = new UserModule(this, cacheConfiguration?.user ?? new NullCache("user"));
|
|
46
62
|
}
|
|
47
63
|
|
|
48
|
-
async fetch
|
|
64
|
+
async fetch(url: string, config: SDKRequestInit = {}) {
|
|
49
65
|
config.method = config.method ?? "GET";
|
|
50
66
|
config.headers = {
|
|
51
67
|
...config.headers,
|
|
@@ -54,27 +70,95 @@ export class TssApi {
|
|
|
54
70
|
};
|
|
55
71
|
|
|
56
72
|
const apiPrefix = this.apiConfiguration.API_URL;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new BadRequestException(response.statusText);
|
|
61
|
-
case 401:
|
|
62
|
-
throw new UnauthorizedException(response.statusText);
|
|
63
|
-
case 403:
|
|
64
|
-
throw new ForbiddenException(response.statusText);
|
|
65
|
-
case 404:
|
|
66
|
-
throw new NotFoundException(response.statusText);
|
|
67
|
-
case 422:
|
|
68
|
-
throw new UnprocessableEntityException(response.statusText);
|
|
73
|
+
|
|
74
|
+
if (apiPrefix.match(/^https?:\/\/localhost/) !== null && typeof process !== "undefined" && process.env) {
|
|
75
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
const fullUrl = `${apiPrefix}/api/${url}`;
|
|
79
|
+
console.log("Fetching url", fullUrl);
|
|
80
|
+
|
|
81
|
+
let response;
|
|
82
|
+
try {
|
|
83
|
+
response = await fetch(fullUrl, config);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
throw new GatewayTimeoutException("API erg dood");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (response.status >= 400) {
|
|
89
|
+
const error = await response.json();
|
|
90
|
+
switch (response.status) {
|
|
91
|
+
case 400:
|
|
92
|
+
throw new BadRequestException(error);
|
|
93
|
+
case 401:
|
|
94
|
+
throw new UnauthorizedException(error);
|
|
95
|
+
case 403:
|
|
96
|
+
throw new ForbiddenException(error);
|
|
97
|
+
case 404:
|
|
98
|
+
throw new NotFoundException(error);
|
|
99
|
+
case 405:
|
|
100
|
+
throw new MethodNotAllowedException(error);
|
|
101
|
+
case 406:
|
|
102
|
+
throw new NotAcceptableException(error);
|
|
103
|
+
case 408:
|
|
104
|
+
throw new RequestTimeoutException(error);
|
|
105
|
+
case 409:
|
|
106
|
+
throw new ConflictException(error);
|
|
107
|
+
case 410:
|
|
108
|
+
throw new GoneException(error);
|
|
109
|
+
case 412:
|
|
110
|
+
throw new PreconditionFailedException(error);
|
|
111
|
+
case 413:
|
|
112
|
+
throw new PayloadTooLargeException(error);
|
|
113
|
+
case 415:
|
|
114
|
+
throw new UnsupportedMediaTypeException(error);
|
|
115
|
+
case 418:
|
|
116
|
+
throw new ImATeapotException(error);
|
|
117
|
+
case 421:
|
|
118
|
+
throw new MisdirectedException(error);
|
|
119
|
+
case 422:
|
|
120
|
+
throw new UnprocessableEntityException(error);
|
|
121
|
+
case 500:
|
|
122
|
+
throw new InternalServerErrorException(error);
|
|
123
|
+
case 501:
|
|
124
|
+
throw new NotImplementedException(error);
|
|
125
|
+
case 502:
|
|
126
|
+
throw new BadGatewayException(error);
|
|
127
|
+
case 503:
|
|
128
|
+
throw new ServiceUnavailableException(error);
|
|
129
|
+
case 504:
|
|
130
|
+
throw new GatewayTimeoutException(error);
|
|
131
|
+
case 505:
|
|
132
|
+
throw new HttpVersionNotSupportedException(error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return response;
|
|
72
137
|
}
|
|
73
138
|
|
|
74
|
-
async
|
|
75
|
-
|
|
76
|
-
method
|
|
77
|
-
body: JSON.stringify(
|
|
139
|
+
protected async fetchPossibleEmptyResponse<T>(method: HttpMethod, url: string, dto: Dto) {
|
|
140
|
+
const response = await this.fetch(url, {
|
|
141
|
+
method,
|
|
142
|
+
body: JSON.stringify(dto),
|
|
78
143
|
});
|
|
144
|
+
|
|
145
|
+
if (response.status === 204) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return response.json() as Promise<T>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async get<T>(url: string) {
|
|
153
|
+
const response = await this.fetch(url);
|
|
154
|
+
return response.json() as Promise<T>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async post<T>(url: string, dto: Dto) {
|
|
158
|
+
return this.fetchPossibleEmptyResponse<T>("POST", url, dto);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async put<T>(url: string, dto: Dto) {
|
|
162
|
+
return this.fetchPossibleEmptyResponse<T>("PUT", url, dto);
|
|
79
163
|
}
|
|
80
164
|
}
|
package/test/api/base.test.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { BaseModule } from "../../src/api/base";
|
|
3
|
-
import { NullCache } from "../../src
|
|
4
|
-
import { TssApi } from "../../src/index";
|
|
3
|
+
import { TssApi, NullCache } from "../../src";
|
|
5
4
|
|
|
6
5
|
describe("Base module", () => {
|
|
7
6
|
it("returns the cache", () => {
|
|
8
7
|
const cache = new NullCache("base");
|
|
9
|
-
const base = new BaseModule(
|
|
8
|
+
const base = new BaseModule(
|
|
9
|
+
new TssApi({
|
|
10
|
+
API_URL: process.env.API_URL,
|
|
11
|
+
}),
|
|
12
|
+
cache
|
|
13
|
+
);
|
|
10
14
|
expect(base.getCache()).toBe(cache);
|
|
11
15
|
});
|
|
12
16
|
|
|
13
17
|
it("sets the cache", () => {
|
|
14
18
|
const cache = new NullCache("base");
|
|
15
|
-
const base = new BaseModule(
|
|
19
|
+
const base = new BaseModule(
|
|
20
|
+
new TssApi({
|
|
21
|
+
API_URL: process.env.API_URL,
|
|
22
|
+
}),
|
|
23
|
+
cache
|
|
24
|
+
);
|
|
16
25
|
const newCache = new NullCache("base");
|
|
17
26
|
base.setCache(newCache);
|
|
18
27
|
expect(base.getCache()).toBe(newCache);
|
package/test/api/jingle.test.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { TssApi } from "../../src";
|
|
3
|
-
import { NullCache, OnePasswordCache } from "../../src/cache";
|
|
2
|
+
import { TssApi, NullCache, OnePasswordCache } from "../../src";
|
|
4
3
|
|
|
5
4
|
describe("Jingle API", () => {
|
|
6
|
-
const api = new TssApi(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const api = new TssApi(
|
|
6
|
+
{ API_URL: process.env.API_URL },
|
|
7
|
+
{
|
|
8
|
+
jingle: new NullCache("jingle"),
|
|
9
|
+
auth: new OnePasswordCache("TSS-TOKEN"),
|
|
10
|
+
}
|
|
11
|
+
);
|
|
10
12
|
|
|
11
13
|
it("Retrieves jingles when calling getGrouped", async () => {
|
|
12
14
|
const items = await api.jingle.getGrouped();
|
|
@@ -26,7 +28,7 @@ describe("Jingle API", () => {
|
|
|
26
28
|
});
|
|
27
29
|
|
|
28
30
|
it("Plays a jingle", async () => {
|
|
29
|
-
const result = await api.jingle.play("keeskankerkachel", "aan.mp3");
|
|
31
|
+
const result = await api.jingle.play({ folder: "keeskankerkachel", file: "aan.mp3" });
|
|
30
32
|
// TODO fix dit
|
|
31
33
|
expect(result.success).toBe(true);
|
|
32
34
|
});
|
package/tsconfig.json
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
"module": "ES2022",
|
|
8
8
|
"sourceMap": true,
|
|
9
9
|
"esModuleInterop": true,
|
|
10
|
-
"moduleResolution": "
|
|
10
|
+
"moduleResolution": "node",
|
|
11
11
|
"strictNullChecks": true,
|
|
12
|
-
"noImplicitAny": true
|
|
12
|
+
"noImplicitAny": true,
|
|
13
|
+
"experimentalDecorators": true,
|
|
14
|
+
"strictPropertyInitialization": false
|
|
13
15
|
}
|
|
14
16
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
namespace NodeJS {
|
|
3
|
+
interface ProcessEnv {
|
|
4
|
+
NODE_ENV: "development" | "production";
|
|
5
|
+
API_URL: string;
|
|
6
|
+
NODE_TLS_REJECT_UNAUTHORIZED: number;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// If this file has no import/export statements (i.e. is a script)
|
|
12
|
+
// convert it into a module by adding an empty export statement.
|
|
13
|
+
export {};
|