camstreamerlib 4.0.33-dfd8bbb → 4.0.34

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.
@@ -14,7 +14,6 @@ export declare class CamOverlayAPI<Client extends IClient<TResponse, any>> exten
14
14
  }[]>;
15
15
  wsAuthorization(options?: THttpRequestOptions): Promise<string>;
16
16
  getMjpegStreamImage(mjpegUrl: string, options?: THttpRequestOptions): Promise<ReturnType<Awaited<ReturnType<Client["get"]>>["blob"]>>;
17
- isViewerPassValid(pass: string, options?: THttpRequestOptions): Promise<boolean>;
18
17
  listFiles<T extends TFileType>(fileType: T, options?: THttpRequestOptions): Promise<TFileList<T>>;
19
18
  uploadFile<T extends TFileType>(fileType: T, formData: Parameters<Client['post']>[0]['data'], storage: TFileStorageType<T>, options?: THttpRequestOptions): Promise<void>;
20
19
  removeFile<T extends TFileType>(fileType: T, fileParams: TFile<T>, options?: THttpRequestOptions): Promise<void>;
@@ -29,13 +29,6 @@ class CamOverlayAPI extends BasicAPI_1.BasicAPI {
29
29
  async getMjpegStreamImage(mjpegUrl, options) {
30
30
  return await this._getBlob(`${BASE_PATH}/fetch_mjpeg_image.cgi`, { mjpeg_url: decodeURIComponent(mjpegUrl) }, options);
31
31
  }
32
- async isViewerPassValid(pass, options) {
33
- const res = await this._getJson(`${BASE_PATH}/check_pass.cgi`, { pass }, options);
34
- if (res.status !== 200) {
35
- throw new Error(res.message);
36
- }
37
- return res.data === '1';
38
- }
39
32
  async listFiles(fileType, options) {
40
33
  const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'list' }, options);
41
34
  return (0, CamOverlayAPI_1.getFileListSchema)(fileType).parse(res.list);
package/cjs/VapixAPI.js CHANGED
@@ -93,7 +93,7 @@ class VapixAPI extends BasicAPI_1.BasicAPI {
93
93
  };
94
94
  await this._postJsonEncoded('/axis-cgi/opticscontrol.cgi', data, undefined, options);
95
95
  }
96
- catch (err) {
96
+ catch {
97
97
  await this._postUrlEncoded('/axis-cgi/opticssetup.cgi', {
98
98
  autofocus: 'perform',
99
99
  source: '1',
package/cjs/helpers.js CHANGED
@@ -13,7 +13,7 @@ const jsonParseCameraParam = (param, paramName) => {
13
13
  try {
14
14
  return JSON.parse(decodeURIComponent(param.replaceAll('\\', '')));
15
15
  }
16
- catch (e) {
16
+ catch {
17
17
  throw new errors_1.JsonParseError(paramName, param);
18
18
  }
19
19
  }
@@ -32,12 +32,15 @@ class HttpRequestSender {
32
32
  options.headers ??= {};
33
33
  options.headers['Authorization'] = authorization;
34
34
  }
35
- const req = new undici_1.Request(url, { body: postData, method: options.method, headers: options.headers });
36
- const res = await (0, undici_1.fetch)(req, { signal: AbortSignal.timeout(options.timeout), dispatcher: this.agent });
37
- if (!res.ok) {
38
- this.invalidateAuthorization();
39
- }
35
+ const res = await (0, undici_1.fetch)(url, {
36
+ method: options.method,
37
+ headers: options.headers,
38
+ body: postData,
39
+ signal: AbortSignal.timeout(options.timeout),
40
+ dispatcher: this.agent,
41
+ });
40
42
  if (res.status === 401) {
43
+ this.invalidateAuthorization();
41
44
  const authenticateHeader = res.headers.get('www-authenticate');
42
45
  if (authenticateHeader !== null &&
43
46
  authenticateHeader.indexOf('Digest') !== -1 &&
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const http = __importStar(require("http"));
27
+ const undici_1 = require("undici");
28
+ const globals_1 = require("@jest/globals");
29
+ const HttpRequestSender_1 = require("./HttpRequestSender");
30
+ const DIGEST_CHALLENGE = 'Digest realm="test", qop="auth", nonce="abc123", opaque="xyz"';
31
+ const okHandler = (_req, res) => {
32
+ res.end('ok');
33
+ };
34
+ const digestHandler = (req, res) => {
35
+ if (req.headers.authorization?.startsWith('Digest ') !== true) {
36
+ res.writeHead(401, { 'WWW-Authenticate': DIGEST_CHALLENGE });
37
+ res.end();
38
+ return;
39
+ }
40
+ res.end('ok');
41
+ };
42
+ (0, globals_1.describe)('HttpRequestSender', () => {
43
+ let server;
44
+ let received;
45
+ let handler;
46
+ const options = (overrides = {}) => ({
47
+ protocol: 'http:',
48
+ host: '127.0.0.1',
49
+ port: server.address().port,
50
+ path: '/test.cgi',
51
+ user: 'root',
52
+ pass: 'pass',
53
+ ...overrides,
54
+ });
55
+ (0, globals_1.beforeEach)(async () => {
56
+ received = [];
57
+ handler = okHandler;
58
+ server = http.createServer((req, res) => {
59
+ let body = '';
60
+ req.on('data', (chunk) => {
61
+ body += chunk.toString();
62
+ });
63
+ req.on('end', () => {
64
+ received.push({
65
+ method: req.method,
66
+ url: req.url,
67
+ authorization: req.headers.authorization,
68
+ contentType: req.headers['content-type'],
69
+ body,
70
+ });
71
+ handler(req, res);
72
+ });
73
+ });
74
+ await new Promise((resolve) => {
75
+ server.listen(0, '127.0.0.1', resolve);
76
+ });
77
+ });
78
+ (0, globals_1.afterEach)(async () => {
79
+ server.closeAllConnections();
80
+ await new Promise((resolve) => {
81
+ server.close(() => resolve());
82
+ });
83
+ });
84
+ (0, globals_1.test)('sends basic auth when the server accepts it', async () => {
85
+ const res = await new HttpRequestSender_1.HttpRequestSender().sendRequest(options());
86
+ (0, globals_1.expect)(res.status).toBe(200);
87
+ (0, globals_1.expect)(await res.text()).toBe('ok');
88
+ (0, globals_1.expect)(received).toHaveLength(1);
89
+ (0, globals_1.expect)(received[0]?.authorization).toBe(`Basic ${Buffer.from('root:pass').toString('base64')}`);
90
+ });
91
+ (0, globals_1.test)('sends no authorization without credentials', async () => {
92
+ await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ user: undefined, pass: undefined }));
93
+ (0, globals_1.expect)(received[0]?.authorization).toBeUndefined();
94
+ });
95
+ (0, globals_1.test)('retries with digest auth on a digest 401 and reuses it for later requests', async () => {
96
+ handler = digestHandler;
97
+ const sender = new HttpRequestSender_1.HttpRequestSender();
98
+ const first = await sender.sendRequest(options());
99
+ const second = await sender.sendRequest(options());
100
+ (0, globals_1.expect)(first.status).toBe(200);
101
+ (0, globals_1.expect)(second.status).toBe(200);
102
+ (0, globals_1.expect)(received.map((r) => r.authorization?.split(' ')[0])).toEqual(['Basic', 'Digest', 'Digest']);
103
+ });
104
+ (0, globals_1.test)('keeps digest auth after a non-401 error response', async () => {
105
+ const sender = new HttpRequestSender_1.HttpRequestSender();
106
+ handler = digestHandler;
107
+ await sender.sendRequest(options());
108
+ handler = (_req, res) => {
109
+ res.writeHead(500);
110
+ res.end();
111
+ };
112
+ await sender.sendRequest(options());
113
+ handler = digestHandler;
114
+ const res = await sender.sendRequest(options());
115
+ (0, globals_1.expect)(res.status).toBe(200);
116
+ (0, globals_1.expect)(received.map((r) => r.authorization?.split(' ')[0])).toEqual(['Basic', 'Digest', 'Digest', 'Digest']);
117
+ });
118
+ (0, globals_1.test)('retries a digest 401 only once', async () => {
119
+ handler = (_req, res) => {
120
+ res.writeHead(401, { 'WWW-Authenticate': DIGEST_CHALLENGE });
121
+ res.end();
122
+ };
123
+ const res = await new HttpRequestSender_1.HttpRequestSender().sendRequest(options());
124
+ (0, globals_1.expect)(res.status).toBe(401);
125
+ (0, globals_1.expect)(received).toHaveLength(2);
126
+ });
127
+ (0, globals_1.test)('rejects when the response does not arrive within the timeout', async () => {
128
+ handler = () => undefined;
129
+ await (0, globals_1.expect)(new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ timeout: 200 }))).rejects.toThrow();
130
+ });
131
+ (0, globals_1.test)('sends a url-encoded POST body', async () => {
132
+ const res = await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }), 'action=settext&text=hello');
133
+ (0, globals_1.expect)(res.ok).toBe(true);
134
+ (0, globals_1.expect)(received[0]).toMatchObject({
135
+ method: 'POST',
136
+ contentType: 'application/x-www-form-urlencoded',
137
+ body: 'action=settext&text=hello',
138
+ });
139
+ });
140
+ (0, globals_1.test)('sends a JSON POST body', async () => {
141
+ const payload = JSON.stringify({ text: 'hello', index: 1 });
142
+ await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ method: 'POST', headers: { 'Content-Type': 'application/json' } }), payload);
143
+ (0, globals_1.expect)(received[0]).toMatchObject({ method: 'POST', contentType: 'application/json', body: payload });
144
+ });
145
+ (0, globals_1.test)('sends a Buffer POST body', async () => {
146
+ await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ method: 'POST' }), Buffer.from('binary-data'));
147
+ (0, globals_1.expect)(received[0]?.body).toBe('binary-data');
148
+ });
149
+ (0, globals_1.test)('sends a FormData POST body as multipart', async () => {
150
+ const formData = new undici_1.FormData();
151
+ formData.append('field', 'value');
152
+ await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ method: 'POST' }), formData);
153
+ (0, globals_1.expect)(received[0]?.contentType).toMatch(/^multipart\/form-data; boundary=/);
154
+ (0, globals_1.expect)(received[0]?.body).toContain('value');
155
+ });
156
+ (0, globals_1.test)('resends the POST body on the digest retry', async () => {
157
+ handler = digestHandler;
158
+ await new HttpRequestSender_1.HttpRequestSender().sendRequest(options({ method: 'POST' }), 'payload');
159
+ (0, globals_1.expect)(received.map((r) => r.body)).toEqual(['payload', 'payload']);
160
+ });
161
+ });
@@ -26,13 +26,6 @@ export class CamOverlayAPI extends BasicAPI {
26
26
  async getMjpegStreamImage(mjpegUrl, options) {
27
27
  return await this._getBlob(`${BASE_PATH}/fetch_mjpeg_image.cgi`, { mjpeg_url: decodeURIComponent(mjpegUrl) }, options);
28
28
  }
29
- async isViewerPassValid(pass, options) {
30
- const res = await this._getJson(`${BASE_PATH}/check_pass.cgi`, { pass }, options);
31
- if (res.status !== 200) {
32
- throw new Error(res.message);
33
- }
34
- return res.data === '1';
35
- }
36
29
  async listFiles(fileType, options) {
37
30
  const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'list' }, options);
38
31
  return getFileListSchema(fileType).parse(res.list);
package/esm/VapixAPI.js CHANGED
@@ -90,7 +90,7 @@ export class VapixAPI extends BasicAPI {
90
90
  };
91
91
  await this._postJsonEncoded('/axis-cgi/opticscontrol.cgi', data, undefined, options);
92
92
  }
93
- catch (err) {
93
+ catch {
94
94
  await this._postUrlEncoded('/axis-cgi/opticssetup.cgi', {
95
95
  autofocus: 'perform',
96
96
  source: '1',
package/esm/helpers.js CHANGED
@@ -10,7 +10,7 @@ export const jsonParseCameraParam = (param, paramName) => {
10
10
  try {
11
11
  return JSON.parse(decodeURIComponent(param.replaceAll('\\', '')));
12
12
  }
13
- catch (e) {
13
+ catch {
14
14
  throw new JsonParseError(paramName, param);
15
15
  }
16
16
  }
@@ -1,5 +1,5 @@
1
1
  import { Digest } from './Digest';
2
- import { Agent, fetch as undiciFetch, Request as UndiciRequest, } from 'undici';
2
+ import { Agent, fetch as undiciFetch } from 'undici';
3
3
  export class HttpRequestSender {
4
4
  agent;
5
5
  authData;
@@ -29,12 +29,15 @@ export class HttpRequestSender {
29
29
  options.headers ??= {};
30
30
  options.headers['Authorization'] = authorization;
31
31
  }
32
- const req = new UndiciRequest(url, { body: postData, method: options.method, headers: options.headers });
33
- const res = await undiciFetch(req, { signal: AbortSignal.timeout(options.timeout), dispatcher: this.agent });
34
- if (!res.ok) {
35
- this.invalidateAuthorization();
36
- }
32
+ const res = await undiciFetch(url, {
33
+ method: options.method,
34
+ headers: options.headers,
35
+ body: postData,
36
+ signal: AbortSignal.timeout(options.timeout),
37
+ dispatcher: this.agent,
38
+ });
37
39
  if (res.status === 401) {
40
+ this.invalidateAuthorization();
38
41
  const authenticateHeader = res.headers.get('www-authenticate');
39
42
  if (authenticateHeader !== null &&
40
43
  authenticateHeader.indexOf('Digest') !== -1 &&
@@ -0,0 +1,136 @@
1
+ import * as http from 'http';
2
+ import { FormData } from 'undici';
3
+ import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';
4
+ import { HttpRequestSender } from './HttpRequestSender';
5
+ const DIGEST_CHALLENGE = 'Digest realm="test", qop="auth", nonce="abc123", opaque="xyz"';
6
+ const okHandler = (_req, res) => {
7
+ res.end('ok');
8
+ };
9
+ const digestHandler = (req, res) => {
10
+ if (req.headers.authorization?.startsWith('Digest ') !== true) {
11
+ res.writeHead(401, { 'WWW-Authenticate': DIGEST_CHALLENGE });
12
+ res.end();
13
+ return;
14
+ }
15
+ res.end('ok');
16
+ };
17
+ describe('HttpRequestSender', () => {
18
+ let server;
19
+ let received;
20
+ let handler;
21
+ const options = (overrides = {}) => ({
22
+ protocol: 'http:',
23
+ host: '127.0.0.1',
24
+ port: server.address().port,
25
+ path: '/test.cgi',
26
+ user: 'root',
27
+ pass: 'pass',
28
+ ...overrides,
29
+ });
30
+ beforeEach(async () => {
31
+ received = [];
32
+ handler = okHandler;
33
+ server = http.createServer((req, res) => {
34
+ let body = '';
35
+ req.on('data', (chunk) => {
36
+ body += chunk.toString();
37
+ });
38
+ req.on('end', () => {
39
+ received.push({
40
+ method: req.method,
41
+ url: req.url,
42
+ authorization: req.headers.authorization,
43
+ contentType: req.headers['content-type'],
44
+ body,
45
+ });
46
+ handler(req, res);
47
+ });
48
+ });
49
+ await new Promise((resolve) => {
50
+ server.listen(0, '127.0.0.1', resolve);
51
+ });
52
+ });
53
+ afterEach(async () => {
54
+ server.closeAllConnections();
55
+ await new Promise((resolve) => {
56
+ server.close(() => resolve());
57
+ });
58
+ });
59
+ test('sends basic auth when the server accepts it', async () => {
60
+ const res = await new HttpRequestSender().sendRequest(options());
61
+ expect(res.status).toBe(200);
62
+ expect(await res.text()).toBe('ok');
63
+ expect(received).toHaveLength(1);
64
+ expect(received[0]?.authorization).toBe(`Basic ${Buffer.from('root:pass').toString('base64')}`);
65
+ });
66
+ test('sends no authorization without credentials', async () => {
67
+ await new HttpRequestSender().sendRequest(options({ user: undefined, pass: undefined }));
68
+ expect(received[0]?.authorization).toBeUndefined();
69
+ });
70
+ test('retries with digest auth on a digest 401 and reuses it for later requests', async () => {
71
+ handler = digestHandler;
72
+ const sender = new HttpRequestSender();
73
+ const first = await sender.sendRequest(options());
74
+ const second = await sender.sendRequest(options());
75
+ expect(first.status).toBe(200);
76
+ expect(second.status).toBe(200);
77
+ expect(received.map((r) => r.authorization?.split(' ')[0])).toEqual(['Basic', 'Digest', 'Digest']);
78
+ });
79
+ test('keeps digest auth after a non-401 error response', async () => {
80
+ const sender = new HttpRequestSender();
81
+ handler = digestHandler;
82
+ await sender.sendRequest(options());
83
+ handler = (_req, res) => {
84
+ res.writeHead(500);
85
+ res.end();
86
+ };
87
+ await sender.sendRequest(options());
88
+ handler = digestHandler;
89
+ const res = await sender.sendRequest(options());
90
+ expect(res.status).toBe(200);
91
+ expect(received.map((r) => r.authorization?.split(' ')[0])).toEqual(['Basic', 'Digest', 'Digest', 'Digest']);
92
+ });
93
+ test('retries a digest 401 only once', async () => {
94
+ handler = (_req, res) => {
95
+ res.writeHead(401, { 'WWW-Authenticate': DIGEST_CHALLENGE });
96
+ res.end();
97
+ };
98
+ const res = await new HttpRequestSender().sendRequest(options());
99
+ expect(res.status).toBe(401);
100
+ expect(received).toHaveLength(2);
101
+ });
102
+ test('rejects when the response does not arrive within the timeout', async () => {
103
+ handler = () => undefined;
104
+ await expect(new HttpRequestSender().sendRequest(options({ timeout: 200 }))).rejects.toThrow();
105
+ });
106
+ test('sends a url-encoded POST body', async () => {
107
+ const res = await new HttpRequestSender().sendRequest(options({ method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }), 'action=settext&text=hello');
108
+ expect(res.ok).toBe(true);
109
+ expect(received[0]).toMatchObject({
110
+ method: 'POST',
111
+ contentType: 'application/x-www-form-urlencoded',
112
+ body: 'action=settext&text=hello',
113
+ });
114
+ });
115
+ test('sends a JSON POST body', async () => {
116
+ const payload = JSON.stringify({ text: 'hello', index: 1 });
117
+ await new HttpRequestSender().sendRequest(options({ method: 'POST', headers: { 'Content-Type': 'application/json' } }), payload);
118
+ expect(received[0]).toMatchObject({ method: 'POST', contentType: 'application/json', body: payload });
119
+ });
120
+ test('sends a Buffer POST body', async () => {
121
+ await new HttpRequestSender().sendRequest(options({ method: 'POST' }), Buffer.from('binary-data'));
122
+ expect(received[0]?.body).toBe('binary-data');
123
+ });
124
+ test('sends a FormData POST body as multipart', async () => {
125
+ const formData = new FormData();
126
+ formData.append('field', 'value');
127
+ await new HttpRequestSender().sendRequest(options({ method: 'POST' }), formData);
128
+ expect(received[0]?.contentType).toMatch(/^multipart\/form-data; boundary=/);
129
+ expect(received[0]?.body).toContain('value');
130
+ });
131
+ test('resends the POST body on the digest retry', async () => {
132
+ handler = digestHandler;
133
+ await new HttpRequestSender().sendRequest(options({ method: 'POST' }), 'payload');
134
+ expect(received.map((r) => r.body)).toEqual(['payload', 'payload']);
135
+ });
136
+ });
package/package.json CHANGED
@@ -1,114 +1,117 @@
1
1
  {
2
- "name": "camstreamerlib",
3
- "version": "4.0.33-dfd8bbb",
4
- "description": "Helper library for CamStreamer ACAP applications.",
5
- "prettier": "@camstreamer/prettier-config",
6
- "engine": {
7
- "node": ">=18.0.0"
8
- },
9
- "dependencies": {
10
- "adm-zip": "^0.6.0",
11
- "eventemitter2": "^5.0.1",
12
- "fast-xml-parser": "^5.3.6",
13
- "type-fest": "^4.41.0",
14
- "undici": "^6.28.0",
15
- "ws": "^8.18.0",
16
- "zod": "^3.25.76"
17
- },
18
- "devDependencies": {
19
- "@camstreamer/eslint-config": "^1.0.2",
20
- "@camstreamer/prettier-config": "^2.0.4",
21
- "@types/adm-zip": "^0.5.5",
22
- "@types/jest": "^28.0.0",
23
- "@types/node": "^18.19.127",
24
- "@types/ws": "^8.5.10",
25
- "@typescript-eslint/eslint-plugin": "^6.8.0",
26
- "@typescript-eslint/parser": "^6.8.0",
27
- "esbuild": "^0.28.2",
28
- "eslint": "^8.51.0",
29
- "eslint-plugin-deprecation": "^2.0.0",
30
- "eslint-plugin-unused-imports": "^3.0.0",
31
- "jest": "^28.1.3",
32
- "npm-run-all": "^4.1.5",
33
- "prettier": "^2.7.1",
34
- "ts-jest": "^28.0.0",
35
- "ts-node": "^10.7.0",
36
- "typescript": "5.3.3"
37
- },
38
- "overrides": {
39
- "js-yaml": "^4.3.2",
40
- "browserslist": "^4.28.7"
41
- },
42
- "scripts": {
43
- "clean": "rimraf dist/*",
44
- "build": "npm-run-all clean build:cjs build:esm copyPackage",
45
- "build:cjs": "tsc --project tsconfig.cjs.json",
46
- "build:esm": "tsc --project tsconfig.esm.json",
47
- "build:browser": "esbuild src/browser.index.ts --bundle --format=esm --platform=browser --target=es2022 --outfile=examples/camstreamerlib.js",
48
- "copyPackage": "cp -f LICENSE dist/ && cp -f README.md dist/ && cp -f package.json dist/ && cp -r -f examples dist/",
49
- "publishPackage": "./publish.sh",
50
- "lint": "eslint \"src/**/*.ts\"",
51
- "lint:fix": "eslint \"src/**/*.ts\" --fix",
52
- "pretty": "prettier --write \"./{{src,doc}/**/*.{ts,tsx,md},README.md}\"",
53
- "pretty:check": "prettier --check \"./{{src,doc}/**/*.{ts,tsx,md},README.md}\"",
54
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
55
- "audit": "npm audit --audit-level=high"
56
- },
57
- "files": [
58
- "/**/*.js",
59
- "/**/*.ts",
60
- "/examples/**/*"
61
- ],
62
- "main": "./cjs/index.js",
63
- "module": "./esm/index.js",
64
- "types": "types/index.d.ts",
65
- "exports": {
66
- ".": {
67
- "import": "./esm/index.js",
68
- "require": "./cjs/index.js",
69
- "types": "./types/index.d.ts"
2
+ "name": "camstreamerlib",
3
+ "version": "4.0.34",
4
+ "description": "Helper library for CamStreamer ACAP applications.",
5
+ "prettier": "@camstreamer/prettier-config",
6
+ "engine": {
7
+ "node": ">=18.0.0"
70
8
  },
71
- "./web": {
72
- "import": "./esm/web/index.js",
73
- "require": "./cjs/web/index.js",
74
- "types": "./types/web/index.d.ts"
9
+ "dependencies": {
10
+ "adm-zip": "^0.6.0",
11
+ "eventemitter2": "^5.0.1",
12
+ "fast-xml-parser": "^5.3.6",
13
+ "type-fest": "^4.41.0",
14
+ "undici": "^6.28.1",
15
+ "ws": "^8.18.0",
16
+ "zod": "^3.25.76"
75
17
  },
76
- "./node": {
77
- "import": "./esm/node/index.js",
78
- "require": "./cjs/node/index.js",
79
- "types": "./types/node/index.d.ts"
18
+ "devDependencies": {
19
+ "@camstreamer/eslint-config": "^1.0.2",
20
+ "@camstreamer/prettier-config": "^2.0.4",
21
+ "@types/adm-zip": "^0.5.5",
22
+ "@types/jest": "^30.0.0",
23
+ "@types/node": "^18.19.127",
24
+ "@types/ws": "^8.5.10",
25
+ "@typescript-eslint/eslint-plugin": "^8.71.1",
26
+ "@typescript-eslint/parser": "^8.71.1",
27
+ "esbuild": "^0.28.2",
28
+ "eslint": "^8.51.0",
29
+ "eslint-plugin-deprecation": "^2.0.0",
30
+ "eslint-plugin-unused-imports": "^4.4.1",
31
+ "jest": "^30.5.2",
32
+ "npm-run-all": "^4.1.5",
33
+ "prettier": "^2.7.1",
34
+ "ts-jest": "^29.4.14",
35
+ "ts-node": "^10.7.0",
36
+ "typescript": "5.3.3"
80
37
  },
81
- "./cjs/index": {
82
- "import": "./esm/index.js",
83
- "require": "./cjs/index.js",
84
- "types": "./types/index.d.ts"
38
+ "overrides": {
39
+ "js-yaml": "^4.3.2",
40
+ "browserslist": "^4.28.7",
41
+ "eslint-plugin-deprecation": {
42
+ "@typescript-eslint/utils": "^8.71.1"
43
+ }
85
44
  },
86
- "./cjs/node": {
87
- "import": "./esm/node/index.js",
88
- "require": "./cjs/node/index.js",
89
- "types": "./types/node/index.js"
45
+ "scripts": {
46
+ "clean": "rimraf dist/*",
47
+ "build": "npm-run-all clean build:cjs build:esm copyPackage",
48
+ "build:cjs": "tsc --project tsconfig.cjs.json",
49
+ "build:esm": "tsc --project tsconfig.esm.json",
50
+ "build:browser": "esbuild src/browser.index.ts --bundle --format=esm --platform=browser --target=es2022 --outfile=examples/camstreamerlib.js",
51
+ "copyPackage": "cp -f LICENSE dist/ && cp -f README.md dist/ && cp -f package.json dist/ && cp -r -f examples dist/",
52
+ "publishPackage": "./publish.sh",
53
+ "lint": "eslint \"src/**/*.ts\"",
54
+ "lint:fix": "eslint \"src/**/*.ts\" --fix",
55
+ "pretty": "prettier --write \"./{{src,doc}/**/*.{ts,tsx,md},README.md}\"",
56
+ "pretty:check": "prettier --check \"./{{src,doc}/**/*.{ts,tsx,md},README.md}\"",
57
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
58
+ "audit": "npm audit --audit-level=high"
90
59
  },
91
- "./cjs/node/index": {
92
- "import": "./esm/node/index.js",
93
- "require": "./cjs/node/index.js",
94
- "types": "./types/node/index.js"
95
- }
96
- },
97
- "repository": {
98
- "type": "git",
99
- "url": "git+https://github.com/CamStreamer/CamStreamerLib.git"
100
- },
101
- "keywords": [
102
- "CamStreamer",
103
- "CamOverlay",
104
- "CamScripter",
105
- "Camera",
106
- "Axis"
107
- ],
108
- "author": "CamStreamer s.r.o",
109
- "license": "ISC",
110
- "bugs": {
111
- "url": "https://github.com/CamStreamer/CamStreamerLib/issues"
112
- },
113
- "homepage": "https://github.com/CamStreamer/CamStreamerLib#readme"
60
+ "files": [
61
+ "/**/*.js",
62
+ "/**/*.ts",
63
+ "/examples/**/*"
64
+ ],
65
+ "main": "./cjs/index.js",
66
+ "module": "./esm/index.js",
67
+ "types": "types/index.d.ts",
68
+ "exports": {
69
+ ".": {
70
+ "import": "./esm/index.js",
71
+ "require": "./cjs/index.js",
72
+ "types": "./types/index.d.ts"
73
+ },
74
+ "./web": {
75
+ "import": "./esm/web/index.js",
76
+ "require": "./cjs/web/index.js",
77
+ "types": "./types/web/index.d.ts"
78
+ },
79
+ "./node": {
80
+ "import": "./esm/node/index.js",
81
+ "require": "./cjs/node/index.js",
82
+ "types": "./types/node/index.d.ts"
83
+ },
84
+ "./cjs/index": {
85
+ "import": "./esm/index.js",
86
+ "require": "./cjs/index.js",
87
+ "types": "./types/index.d.ts"
88
+ },
89
+ "./cjs/node": {
90
+ "import": "./esm/node/index.js",
91
+ "require": "./cjs/node/index.js",
92
+ "types": "./types/node/index.js"
93
+ },
94
+ "./cjs/node/index": {
95
+ "import": "./esm/node/index.js",
96
+ "require": "./cjs/node/index.js",
97
+ "types": "./types/node/index.js"
98
+ }
99
+ },
100
+ "repository": {
101
+ "type": "git",
102
+ "url": "git+https://github.com/CamStreamer/CamStreamerLib.git"
103
+ },
104
+ "keywords": [
105
+ "CamStreamer",
106
+ "CamOverlay",
107
+ "CamScripter",
108
+ "Camera",
109
+ "Axis"
110
+ ],
111
+ "author": "CamStreamer s.r.o",
112
+ "license": "ISC",
113
+ "bugs": {
114
+ "url": "https://github.com/CamStreamer/CamStreamerLib/issues"
115
+ },
116
+ "homepage": "https://github.com/CamStreamer/CamStreamerLib#readme"
114
117
  }
@@ -14,7 +14,6 @@ export declare class CamOverlayAPI<Client extends IClient<TResponse, any>> exten
14
14
  }[]>;
15
15
  wsAuthorization(options?: THttpRequestOptions): Promise<string>;
16
16
  getMjpegStreamImage(mjpegUrl: string, options?: THttpRequestOptions): Promise<ReturnType<Awaited<ReturnType<Client["get"]>>["blob"]>>;
17
- isViewerPassValid(pass: string, options?: THttpRequestOptions): Promise<boolean>;
18
17
  listFiles<T extends TFileType>(fileType: T, options?: THttpRequestOptions): Promise<TFileList<T>>;
19
18
  uploadFile<T extends TFileType>(fileType: T, formData: Parameters<Client['post']>[0]['data'], storage: TFileStorageType<T>, options?: THttpRequestOptions): Promise<void>;
20
19
  removeFile<T extends TFileType>(fileType: T, fileParams: TFile<T>, options?: THttpRequestOptions): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};