@pallasoft/ps-utilities 2.14.0 → 2.16.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.
Files changed (50) hide show
  1. package/dist/client/http-service.js +16 -12
  2. package/dist/common/base64-service.d.ts +4 -0
  3. package/dist/common/base64-service.js +24 -0
  4. package/dist/common/constants/http-auth-scheme.d.ts +3 -0
  5. package/dist/common/constants/http-auth-scheme.js +6 -0
  6. package/dist/common/constants/http-content-type.d.ts +8 -0
  7. package/dist/common/constants/http-content-type.js +11 -0
  8. package/dist/common/constants/http-header.d.ts +23 -0
  9. package/dist/common/constants/http-header.js +26 -0
  10. package/dist/common/constants/http-method.d.ts +9 -0
  11. package/dist/common/constants/http-method.js +13 -0
  12. package/dist/common/constants/index.d.ts +6 -0
  13. package/dist/common/constants/index.js +6 -0
  14. package/dist/common/constants/relative-time-config.d.ts +21 -0
  15. package/dist/common/constants/relative-time-config.js +14 -0
  16. package/dist/common/constants/request-client-config.d.ts +5 -0
  17. package/dist/common/constants/request-client-config.js +9 -0
  18. package/dist/common/crypto-service.d.ts +0 -2
  19. package/dist/common/crypto-service.js +13 -27
  20. package/dist/common/date-service.d.ts +3 -0
  21. package/dist/common/date-service.js +9 -0
  22. package/dist/common/error-response-service.d.ts +2 -0
  23. package/dist/common/error-response-service.js +3 -0
  24. package/dist/common/index.d.ts +4 -0
  25. package/dist/common/index.js +4 -0
  26. package/dist/common/json-service.d.ts +5 -0
  27. package/dist/common/json-service.js +23 -0
  28. package/dist/common/relative-time-service.d.ts +4 -0
  29. package/dist/common/relative-time-service.js +25 -0
  30. package/dist/common/request-client-service.d.ts +6 -0
  31. package/dist/common/request-client-service.js +28 -0
  32. package/dist/common/signed-token-service.d.ts +0 -2
  33. package/dist/common/signed-token-service.js +7 -21
  34. package/dist/index.d.ts +6 -0
  35. package/dist/index.js +3 -1
  36. package/dist/models/coded-error-data.d.ts +3 -0
  37. package/dist/models/coded-error-data.js +2 -0
  38. package/dist/models/json-value-guard.d.ts +1 -0
  39. package/dist/models/json-value-guard.js +2 -0
  40. package/dist/models/relative-time-options.d.ts +5 -0
  41. package/dist/models/relative-time-options.js +2 -0
  42. package/dist/models/request-client-data.d.ts +4 -0
  43. package/dist/models/request-client-data.js +2 -0
  44. package/dist/models/request-client-options.d.ts +4 -0
  45. package/dist/models/request-client-options.js +2 -0
  46. package/dist/server/index.d.ts +1 -0
  47. package/dist/server/index.js +1 -0
  48. package/dist/server/timing-safe-service.d.ts +3 -0
  49. package/dist/server/timing-safe-service.js +15 -0
  50. package/package.json +5 -3
@@ -37,6 +37,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.HttpService = void 0;
40
+ var http_content_type_1 = require("../common/constants/http-content-type");
41
+ var http_header_1 = require("../common/constants/http-header");
42
+ var http_method_1 = require("../common/constants/http-method");
40
43
  var isBinaryBody = function (data) {
41
44
  return data instanceof FormData ||
42
45
  data instanceof Blob ||
@@ -49,17 +52,18 @@ var HttpService = /** @class */ (function () {
49
52
  HttpService.createApiClient = function (options) {
50
53
  var _this = this;
51
54
  if (options === void 0) { options = {}; }
52
- var apiKey = options.apiKey, _a = options.apiKeyHeader, apiKeyHeader = _a === void 0 ? 'X-API-Key' : _a, baseURL = options.baseURL, defaultHeaders = options.headers;
55
+ var apiKey = options.apiKey, _a = options.apiKeyHeader, apiKeyHeader = _a === void 0 ? http_header_1.HttpHeader.apiKey : _a, baseURL = options.baseURL, defaultHeaders = options.headers;
53
56
  var request = function (method, url, data, config) { return __awaiter(_this, void 0, void 0, function () {
54
57
  var fullUrl, sendsBinaryBody, headers, body, response, responseData, error;
55
- return __generator(this, function (_a) {
56
- switch (_a.label) {
58
+ var _a;
59
+ return __generator(this, function (_b) {
60
+ switch (_b.label) {
57
61
  case 0:
58
62
  fullUrl = baseURL ? "".concat(baseURL).concat(url) : url;
59
63
  sendsBinaryBody = isBinaryBody(data);
60
64
  headers = sendsBinaryBody
61
65
  ? {}
62
- : { 'Content-Type': 'application/json' };
66
+ : (_a = {}, _a[http_header_1.HttpHeader.contentType] = http_content_type_1.HttpContentType.json, _a);
63
67
  if (defaultHeaders)
64
68
  Object.assign(headers, defaultHeaders);
65
69
  if (apiKey)
@@ -69,18 +73,18 @@ var HttpService = /** @class */ (function () {
69
73
  body = data === undefined ? undefined : sendsBinaryBody ? data : JSON.stringify(data);
70
74
  return [4 /*yield*/, fetch(fullUrl, { method: method, headers: headers, body: body })];
71
75
  case 1:
72
- response = _a.sent();
76
+ response = _b.sent();
73
77
  return [4 /*yield*/, ((config === null || config === void 0 ? void 0 : config.responseType) === 'arraybuffer'
74
78
  ? response.arrayBuffer()
75
79
  : (config === null || config === void 0 ? void 0 : config.responseType) === 'text'
76
80
  ? response.text()
77
81
  : (config === null || config === void 0 ? void 0 : config.responseType) === 'json'
78
82
  ? response.json()
79
- : String(response.headers.get('content-type')).includes('application/json')
83
+ : String(response.headers.get(http_header_1.HttpHeader.contentType)).includes(http_content_type_1.HttpContentType.json)
80
84
  ? response.json()
81
85
  : response.text())];
82
86
  case 2:
83
- responseData = _a.sent();
87
+ responseData = _b.sent();
84
88
  if (!response.ok) {
85
89
  error = new Error("Request failed with status ".concat(response.status));
86
90
  error.response = { data: responseData, status: response.status };
@@ -92,19 +96,19 @@ var HttpService = /** @class */ (function () {
92
96
  }); };
93
97
  return {
94
98
  get: function (url, config) {
95
- return request('GET', url, undefined, config);
99
+ return request(http_method_1.HttpMethod.Get, url, undefined, config);
96
100
  },
97
101
  post: function (url, data, config) {
98
- return request('POST', url, data, config);
102
+ return request(http_method_1.HttpMethod.Post, url, data, config);
99
103
  },
100
104
  put: function (url, data, config) {
101
- return request('PUT', url, data, config);
105
+ return request(http_method_1.HttpMethod.Put, url, data, config);
102
106
  },
103
107
  patch: function (url, data, config) {
104
- return request('PATCH', url, data, config);
108
+ return request(http_method_1.HttpMethod.Patch, url, data, config);
105
109
  },
106
110
  delete: function (url, config) {
107
- return request('DELETE', url, undefined, config);
111
+ return request(http_method_1.HttpMethod.Delete, url, undefined, config);
108
112
  },
109
113
  };
110
114
  };
@@ -0,0 +1,4 @@
1
+ export declare class Base64Service {
2
+ static encode(bytes: Uint8Array): string;
3
+ static decode(value: string): Uint8Array<ArrayBuffer>;
4
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Base64Service = void 0;
4
+ var Base64Service = /** @class */ (function () {
5
+ function Base64Service() {
6
+ }
7
+ Base64Service.encode = function (bytes) {
8
+ var binary = '';
9
+ for (var index = 0; index < bytes.length; index += 1) {
10
+ binary += String.fromCharCode(bytes[index]);
11
+ }
12
+ return btoa(binary);
13
+ };
14
+ Base64Service.decode = function (value) {
15
+ var binary = atob(value.trim());
16
+ var bytes = new Uint8Array(new ArrayBuffer(binary.length));
17
+ for (var index = 0; index < binary.length; index += 1) {
18
+ bytes[index] = binary.charCodeAt(index);
19
+ }
20
+ return bytes;
21
+ };
22
+ return Base64Service;
23
+ }());
24
+ exports.Base64Service = Base64Service;
@@ -0,0 +1,3 @@
1
+ export declare const HttpAuthScheme: {
2
+ readonly bearerPrefix: "Bearer ";
3
+ };
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpAuthScheme = void 0;
4
+ exports.HttpAuthScheme = {
5
+ bearerPrefix: 'Bearer ',
6
+ };
@@ -0,0 +1,8 @@
1
+ export declare const HttpContentType: {
2
+ readonly formUrlEncoded: "application/x-www-form-urlencoded";
3
+ readonly html: "text/html";
4
+ readonly json: "application/json";
5
+ readonly multipartFormData: "multipart/form-data";
6
+ readonly octetStream: "application/octet-stream";
7
+ readonly plainText: "text/plain";
8
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpContentType = void 0;
4
+ exports.HttpContentType = {
5
+ formUrlEncoded: 'application/x-www-form-urlencoded',
6
+ html: 'text/html',
7
+ json: 'application/json',
8
+ multipartFormData: 'multipart/form-data',
9
+ octetStream: 'application/octet-stream',
10
+ plainText: 'text/plain',
11
+ };
@@ -0,0 +1,23 @@
1
+ export declare const HttpHeader: {
2
+ readonly accept: "Accept";
3
+ readonly apiKey: "X-API-Key";
4
+ readonly authorization: "Authorization";
5
+ readonly cacheControl: "Cache-Control";
6
+ readonly cfConnectingIp: "CF-Connecting-IP";
7
+ readonly contentDisposition: "Content-Disposition";
8
+ readonly contentSecurityPolicy: "Content-Security-Policy";
9
+ readonly contentType: "Content-Type";
10
+ readonly contentTypeOptions: "X-Content-Type-Options";
11
+ readonly cookie: "Cookie";
12
+ readonly forwardedFor: "X-Forwarded-For";
13
+ readonly frameOptions: "X-Frame-Options";
14
+ readonly idempotencyKey: "Idempotency-Key";
15
+ readonly location: "Location";
16
+ readonly prefer: "Prefer";
17
+ readonly realIp: "X-Real-IP";
18
+ readonly retryAfter: "Retry-After";
19
+ readonly robotsTag: "X-Robots-Tag";
20
+ readonly setCookie: "Set-Cookie";
21
+ readonly strictTransportSecurity: "Strict-Transport-Security";
22
+ readonly userAgent: "User-Agent";
23
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpHeader = void 0;
4
+ exports.HttpHeader = {
5
+ accept: 'Accept',
6
+ apiKey: 'X-API-Key',
7
+ authorization: 'Authorization',
8
+ cacheControl: 'Cache-Control',
9
+ cfConnectingIp: 'CF-Connecting-IP',
10
+ contentDisposition: 'Content-Disposition',
11
+ contentSecurityPolicy: 'Content-Security-Policy',
12
+ contentType: 'Content-Type',
13
+ contentTypeOptions: 'X-Content-Type-Options',
14
+ cookie: 'Cookie',
15
+ forwardedFor: 'X-Forwarded-For',
16
+ frameOptions: 'X-Frame-Options',
17
+ idempotencyKey: 'Idempotency-Key',
18
+ location: 'Location',
19
+ prefer: 'Prefer',
20
+ realIp: 'X-Real-IP',
21
+ retryAfter: 'Retry-After',
22
+ robotsTag: 'X-Robots-Tag',
23
+ setCookie: 'Set-Cookie',
24
+ strictTransportSecurity: 'Strict-Transport-Security',
25
+ userAgent: 'User-Agent',
26
+ };
@@ -0,0 +1,9 @@
1
+ export declare enum HttpMethod {
2
+ Delete = "DELETE",
3
+ Get = "GET",
4
+ Head = "HEAD",
5
+ Options = "OPTIONS",
6
+ Patch = "PATCH",
7
+ Post = "POST",
8
+ Put = "PUT"
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpMethod = void 0;
4
+ var HttpMethod;
5
+ (function (HttpMethod) {
6
+ HttpMethod["Delete"] = "DELETE";
7
+ HttpMethod["Get"] = "GET";
8
+ HttpMethod["Head"] = "HEAD";
9
+ HttpMethod["Options"] = "OPTIONS";
10
+ HttpMethod["Patch"] = "PATCH";
11
+ HttpMethod["Post"] = "POST";
12
+ HttpMethod["Put"] = "PUT";
13
+ })(HttpMethod || (exports.HttpMethod = HttpMethod = {}));
@@ -10,3 +10,9 @@ export * from './socket-token-config';
10
10
  export * from './user-agent-config';
11
11
  export * from './amount-direction';
12
12
  export * from './error-response-config';
13
+ export * from './http-auth-scheme';
14
+ export * from './http-content-type';
15
+ export * from './http-header';
16
+ export * from './http-method';
17
+ export * from './relative-time-config';
18
+ export * from './request-client-config';
@@ -26,3 +26,9 @@ __exportStar(require("./socket-token-config"), exports);
26
26
  __exportStar(require("./user-agent-config"), exports);
27
27
  __exportStar(require("./amount-direction"), exports);
28
28
  __exportStar(require("./error-response-config"), exports);
29
+ __exportStar(require("./http-auth-scheme"), exports);
30
+ __exportStar(require("./http-content-type"), exports);
31
+ __exportStar(require("./http-header"), exports);
32
+ __exportStar(require("./http-method"), exports);
33
+ __exportStar(require("./relative-time-config"), exports);
34
+ __exportStar(require("./request-client-config"), exports);
@@ -0,0 +1,21 @@
1
+ export declare const RelativeTimeConfig: {
2
+ readonly futureToleranceSeconds: 300;
3
+ readonly justNowSeconds: 45;
4
+ readonly millisecondsPerSecond: 1000;
5
+ readonly format: {
6
+ readonly numeric: "auto";
7
+ };
8
+ readonly units: readonly [{
9
+ readonly limitSeconds: 3600;
10
+ readonly seconds: 60;
11
+ readonly unit: "minute";
12
+ }, {
13
+ readonly limitSeconds: 86400;
14
+ readonly seconds: 3600;
15
+ readonly unit: "hour";
16
+ }, {
17
+ readonly limitSeconds: 604800;
18
+ readonly seconds: 86400;
19
+ readonly unit: "day";
20
+ }];
21
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RelativeTimeConfig = void 0;
4
+ exports.RelativeTimeConfig = {
5
+ futureToleranceSeconds: 300,
6
+ justNowSeconds: 45,
7
+ millisecondsPerSecond: 1000,
8
+ format: { numeric: 'auto' },
9
+ units: [
10
+ { limitSeconds: 3600, seconds: 60, unit: 'minute' },
11
+ { limitSeconds: 86400, seconds: 3600, unit: 'hour' },
12
+ { limitSeconds: 604800, seconds: 86400, unit: 'day' },
13
+ ],
14
+ };
@@ -0,0 +1,5 @@
1
+ export declare const RequestClientConfig: {
2
+ readonly addressHeaders: readonly ["CF-Connecting-IP", "X-Real-IP", "X-Forwarded-For"];
3
+ readonly agentHeader: "User-Agent";
4
+ readonly listSeparator: ",";
5
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestClientConfig = void 0;
4
+ var http_header_1 = require("./http-header");
5
+ exports.RequestClientConfig = {
6
+ addressHeaders: [http_header_1.HttpHeader.cfConnectingIp, http_header_1.HttpHeader.realIp, http_header_1.HttpHeader.forwardedFor],
7
+ agentHeader: http_header_1.HttpHeader.userAgent,
8
+ listSeparator: ',',
9
+ };
@@ -11,8 +11,6 @@ export declare class CryptoService {
11
11
  private static _dataKeyLength;
12
12
  private static _payloadAlgorithm;
13
13
  private static _aad;
14
- private static _toBase64;
15
- private static _fromBase64;
16
14
  private static _getAdditionalData;
17
15
  private static _parsePayload;
18
16
  private static _deriveKey;
@@ -37,24 +37,10 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.CryptoService = void 0;
40
+ var base64_service_1 = require("./base64-service");
40
41
  var CryptoService = /** @class */ (function () {
41
42
  function CryptoService() {
42
43
  }
43
- CryptoService._toBase64 = function (bytes) {
44
- var binary = '';
45
- for (var index = 0; index < bytes.length; index += 1) {
46
- binary += String.fromCharCode(bytes[index]);
47
- }
48
- return btoa(binary);
49
- };
50
- CryptoService._fromBase64 = function (value) {
51
- var binary = atob(value);
52
- var bytes = new Uint8Array(binary.length);
53
- for (var index = 0; index < binary.length; index += 1) {
54
- bytes[index] = binary.charCodeAt(index);
55
- }
56
- return bytes;
57
- };
58
44
  CryptoService._getAdditionalData = function () {
59
45
  return this._textEncoder.encode(this._aad);
60
46
  };
@@ -113,9 +99,9 @@ var CryptoService = /** @class */ (function () {
113
99
  serializedPayload = {
114
100
  v: this._payloadVersion,
115
101
  alg: this._payloadAlgorithm,
116
- iv: this._toBase64(iv),
117
- salt: this._toBase64(salt),
118
- ciphertext: this._toBase64(new Uint8Array(encryptedBuffer)),
102
+ iv: base64_service_1.Base64Service.encode(iv),
103
+ salt: base64_service_1.Base64Service.encode(salt),
104
+ ciphertext: base64_service_1.Base64Service.encode(new Uint8Array(encryptedBuffer)),
119
105
  };
120
106
  return [2 /*return*/, JSON.stringify(serializedPayload)];
121
107
  }
@@ -126,14 +112,14 @@ var CryptoService = /** @class */ (function () {
126
112
  return __awaiter(this, void 0, void 0, function () {
127
113
  return __generator(this, function (_a) {
128
114
  switch (_a.label) {
129
- case 0: return [4 /*yield*/, crypto.subtle.importKey('raw', this._fromBase64(dataKey), { name: this._algorithm, length: this._keyLength }, false, ['encrypt', 'decrypt'])];
115
+ case 0: return [4 /*yield*/, crypto.subtle.importKey('raw', base64_service_1.Base64Service.decode(dataKey), { name: this._algorithm, length: this._keyLength }, false, ['encrypt', 'decrypt'])];
130
116
  case 1: return [2 /*return*/, _a.sent()];
131
117
  }
132
118
  });
133
119
  });
134
120
  };
135
121
  CryptoService.generateDataKey = function () {
136
- return this._toBase64(crypto.getRandomValues(new Uint8Array(this._dataKeyLength)));
122
+ return base64_service_1.Base64Service.encode(crypto.getRandomValues(new Uint8Array(this._dataKeyLength)));
137
123
  };
138
124
  CryptoService.encryptPayloadWithDataKey = function (payload, dataKey) {
139
125
  return __awaiter(this, void 0, void 0, function () {
@@ -151,8 +137,8 @@ var CryptoService = /** @class */ (function () {
151
137
  return [2 /*return*/, JSON.stringify({
152
138
  v: this._dataKeyPayloadVersion,
153
139
  alg: this._payloadAlgorithm,
154
- iv: this._toBase64(iv),
155
- ciphertext: this._toBase64(new Uint8Array(encryptedBuffer)),
140
+ iv: base64_service_1.Base64Service.encode(iv),
141
+ ciphertext: base64_service_1.Base64Service.encode(new Uint8Array(encryptedBuffer)),
156
142
  })];
157
143
  }
158
144
  });
@@ -168,11 +154,11 @@ var CryptoService = /** @class */ (function () {
168
154
  _b = (_a = crypto.subtle).decrypt;
169
155
  _c = [{
170
156
  name: this._algorithm,
171
- iv: this._fromBase64(payload.iv),
157
+ iv: base64_service_1.Base64Service.decode(payload.iv),
172
158
  additionalData: this._getAdditionalData(),
173
159
  }];
174
160
  return [4 /*yield*/, this._importDataKey(dataKey)];
175
- case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent(), this._fromBase64(payload.ciphertext)]))];
161
+ case 1: return [4 /*yield*/, _b.apply(_a, _c.concat([_d.sent(), base64_service_1.Base64Service.decode(payload.ciphertext)]))];
176
162
  case 2:
177
163
  decryptedBuffer = _d.sent();
178
164
  return [2 /*return*/, JSON.parse(this._textDecoder.decode(decryptedBuffer))];
@@ -242,14 +228,14 @@ var CryptoService = /** @class */ (function () {
242
228
  switch (_a.label) {
243
229
  case 0:
244
230
  payload = this._parsePayload(encryptedPayload);
245
- return [4 /*yield*/, this._deriveKey(cryptoKey, this._fromBase64(payload.salt))];
231
+ return [4 /*yield*/, this._deriveKey(cryptoKey, base64_service_1.Base64Service.decode(payload.salt))];
246
232
  case 1:
247
233
  key = _a.sent();
248
234
  return [4 /*yield*/, crypto.subtle.decrypt({
249
235
  name: this._algorithm,
250
- iv: this._fromBase64(payload.iv),
236
+ iv: base64_service_1.Base64Service.decode(payload.iv),
251
237
  additionalData: this._getAdditionalData(),
252
- }, key, this._fromBase64(payload.ciphertext))];
238
+ }, key, base64_service_1.Base64Service.decode(payload.ciphertext))];
253
239
  case 2:
254
240
  decryptedBuffer = _a.sent();
255
241
  return [2 /*return*/, JSON.parse(this._textDecoder.decode(decryptedBuffer))];
@@ -19,4 +19,7 @@ export declare class DateService {
19
19
  static nowUnixSeconds(): number;
20
20
  static fromParts(year: number, monthIndex: number, day: number): Dayjs;
21
21
  static isValid(date: string | number): boolean;
22
+ static addDays(date: string, days: number): string;
23
+ static addDaysToInstant(instant: Date, days: number): Date;
24
+ static startOfUtcDay(instant: Date): Date;
22
25
  }
@@ -97,6 +97,15 @@ var DateService = /** @class */ (function () {
97
97
  DateService.isValid = function (date) {
98
98
  return (0, dayjs_1.default)(date).isValid();
99
99
  };
100
+ DateService.addDays = function (date, days) {
101
+ return dayjs_1.default.utc(date).add(days, 'day').format('YYYY-MM-DD');
102
+ };
103
+ DateService.addDaysToInstant = function (instant, days) {
104
+ return dayjs_1.default.utc(instant).add(days, 'day').toDate();
105
+ };
106
+ DateService.startOfUtcDay = function (instant) {
107
+ return dayjs_1.default.utc(instant).startOf('day').toDate();
108
+ };
100
109
  return DateService;
101
110
  }());
102
111
  exports.DateService = DateService;
@@ -1,4 +1,6 @@
1
+ import type { CodedErrorData } from '../models/coded-error-data';
1
2
  export declare class ErrorResponseService {
3
+ static create(message: string, code: number): CodedErrorData;
2
4
  static code(error: unknown): number | null;
3
5
  static isClientError(status: number): boolean;
4
6
  static pageContent<Content extends {
@@ -16,6 +16,9 @@ var error_response_config_1 = require("./constants/error-response-config");
16
16
  var ErrorResponseService = /** @class */ (function () {
17
17
  function ErrorResponseService() {
18
18
  }
19
+ ErrorResponseService.create = function (message, code) {
20
+ return Object.assign(new Error(message), { code: code });
21
+ };
19
22
  ErrorResponseService.code = function (error) {
20
23
  if (typeof error !== 'object' || error === null || !('code' in error))
21
24
  return null;
@@ -1,4 +1,5 @@
1
1
  export * from './amount-service';
2
+ export * from './base64-service';
2
3
  export * from './color-service';
3
4
  export * from './constants';
4
5
  export * from './crypto-service';
@@ -20,3 +21,6 @@ export * from './user-agent-service';
20
21
  export * from './user-token-service';
21
22
  export * from './validation-service';
22
23
  export * from './error-response-service';
24
+ export * from './relative-time-service';
25
+ export * from './request-client-service';
26
+ export * from './json-service';
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./amount-service"), exports);
18
+ __exportStar(require("./base64-service"), exports);
18
19
  __exportStar(require("./color-service"), exports);
19
20
  __exportStar(require("./constants"), exports);
20
21
  __exportStar(require("./crypto-service"), exports);
@@ -36,3 +37,6 @@ __exportStar(require("./user-agent-service"), exports);
36
37
  __exportStar(require("./user-token-service"), exports);
37
38
  __exportStar(require("./validation-service"), exports);
38
39
  __exportStar(require("./error-response-service"), exports);
40
+ __exportStar(require("./relative-time-service"), exports);
41
+ __exportStar(require("./request-client-service"), exports);
42
+ __exportStar(require("./json-service"), exports);
@@ -0,0 +1,5 @@
1
+ import type { JsonValueGuard } from '../models/json-value-guard';
2
+ export declare class JsonService {
3
+ static read(text: string | null | undefined): unknown;
4
+ static parse<Value>(text: string | null | undefined, guard: JsonValueGuard<Value>): Value | null;
5
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonService = void 0;
4
+ var JsonService = /** @class */ (function () {
5
+ function JsonService() {
6
+ }
7
+ JsonService.read = function (text) {
8
+ if (typeof text !== 'string')
9
+ return undefined;
10
+ try {
11
+ return JSON.parse(text);
12
+ }
13
+ catch (_a) {
14
+ return undefined;
15
+ }
16
+ };
17
+ JsonService.parse = function (text, guard) {
18
+ var value = this.read(text);
19
+ return value !== undefined && guard(value) ? value : null;
20
+ };
21
+ return JsonService;
22
+ }());
23
+ exports.JsonService = JsonService;
@@ -0,0 +1,4 @@
1
+ import type { RelativeTimeOptions } from '../models/relative-time-options';
2
+ export declare class RelativeTimeService {
3
+ static format(value: string, now: Date, options: RelativeTimeOptions): string;
4
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RelativeTimeService = void 0;
4
+ var relative_time_config_1 = require("./constants/relative-time-config");
5
+ var date_service_1 = require("./date-service");
6
+ var RelativeTimeService = /** @class */ (function () {
7
+ function RelativeTimeService() {
8
+ }
9
+ RelativeTimeService.format = function (value, now, options) {
10
+ if (!date_service_1.DateService.isValid(value))
11
+ return value;
12
+ var seconds = (now.getTime() - date_service_1.DateService.getDate(value).valueOf()) /
13
+ relative_time_config_1.RelativeTimeConfig.millisecondsPerSecond;
14
+ if (seconds < -relative_time_config_1.RelativeTimeConfig.futureToleranceSeconds)
15
+ return options.formatDate(value);
16
+ if (seconds < relative_time_config_1.RelativeTimeConfig.justNowSeconds)
17
+ return options.justNow;
18
+ var step = relative_time_config_1.RelativeTimeConfig.units.find(function (unit) { return seconds < unit.limitSeconds; });
19
+ return step === undefined
20
+ ? options.formatDate(value)
21
+ : new Intl.RelativeTimeFormat(options.locale, relative_time_config_1.RelativeTimeConfig.format).format(-Math.max(1, Math.round(seconds / step.seconds)), step.unit);
22
+ };
23
+ return RelativeTimeService;
24
+ }());
25
+ exports.RelativeTimeService = RelativeTimeService;
@@ -0,0 +1,6 @@
1
+ import type { RequestClientData } from '../models/request-client-data';
2
+ import type { RequestClientOptions } from '../models/request-client-options';
3
+ export declare class RequestClientService {
4
+ static from(headers: Headers, options?: RequestClientOptions): RequestClientData;
5
+ private static _limit;
6
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestClientService = void 0;
4
+ var request_client_config_1 = require("./constants/request-client-config");
5
+ var RequestClientService = /** @class */ (function () {
6
+ function RequestClientService() {
7
+ }
8
+ RequestClientService.from = function (headers, options) {
9
+ if (options === void 0) { options = {}; }
10
+ var address = request_client_config_1.RequestClientConfig.addressHeaders
11
+ .map(function (name) { return headers.get(name); })
12
+ .find(function (value) { return value !== null && value.trim() !== ''; });
13
+ var agent = headers.get(request_client_config_1.RequestClientConfig.agentHeader);
14
+ return {
15
+ ipAddress: address === undefined
16
+ ? null
17
+ : this._limit(address.split(request_client_config_1.RequestClientConfig.listSeparator)[0].trim(), options.ipAddressMaxLength),
18
+ userAgent: agent === null || agent.trim() === ''
19
+ ? null
20
+ : this._limit(agent.trim(), options.userAgentMaxLength),
21
+ };
22
+ };
23
+ RequestClientService._limit = function (value, maxLength) {
24
+ return typeof maxLength === 'number' ? value.slice(0, maxLength) : value;
25
+ };
26
+ return RequestClientService;
27
+ }());
28
+ exports.RequestClientService = RequestClientService;
@@ -12,8 +12,6 @@ export declare class SignedTokenService {
12
12
  private static _remember;
13
13
  private static _encodeJson;
14
14
  private static _decodeJson;
15
- private static _toBase64;
16
- private static _fromBase64;
17
15
  private static _toBase64Url;
18
16
  private static _fromBase64Url;
19
17
  }
@@ -37,6 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.SignedTokenService = void 0;
40
+ var base64_service_1 = require("./base64-service");
40
41
  var signed_token_config_1 = require("./constants/signed-token-config");
41
42
  var SignedTokenService = /** @class */ (function () {
42
43
  function SignedTokenService() {
@@ -59,8 +60,8 @@ var SignedTokenService = /** @class */ (function () {
59
60
  case 3:
60
61
  publicKey = _a.sent();
61
62
  return [2 /*return*/, {
62
- privateKey: this._toBase64(new Uint8Array(privateKey)),
63
- publicKey: this._toBase64(new Uint8Array(publicKey)),
63
+ privateKey: base64_service_1.Base64Service.encode(new Uint8Array(privateKey)),
64
+ publicKey: base64_service_1.Base64Service.encode(new Uint8Array(publicKey)),
64
65
  }];
65
66
  }
66
67
  });
@@ -142,7 +143,7 @@ var SignedTokenService = /** @class */ (function () {
142
143
  cached = this._privateKeys.get(privateKey);
143
144
  if (cached !== undefined)
144
145
  return [2 /*return*/, cached];
145
- return [4 /*yield*/, crypto.subtle.importKey(signed_token_config_1.SignedTokenConfig.privateKeyFormat, this._fromBase64(privateKey), signed_token_config_1.SignedTokenConfig.keyAlgorithm, false, ['sign'])];
146
+ return [4 /*yield*/, crypto.subtle.importKey(signed_token_config_1.SignedTokenConfig.privateKeyFormat, base64_service_1.Base64Service.decode(privateKey), signed_token_config_1.SignedTokenConfig.keyAlgorithm, false, ['sign'])];
146
147
  case 1:
147
148
  key = _a.sent();
148
149
  this._remember(this._privateKeys, privateKey, key);
@@ -160,7 +161,7 @@ var SignedTokenService = /** @class */ (function () {
160
161
  cached = this._publicKeys.get(publicKey);
161
162
  if (cached !== undefined)
162
163
  return [2 /*return*/, cached];
163
- return [4 /*yield*/, crypto.subtle.importKey(signed_token_config_1.SignedTokenConfig.publicKeyFormat, this._fromBase64(publicKey), signed_token_config_1.SignedTokenConfig.keyAlgorithm, false, ['verify'])];
164
+ return [4 /*yield*/, crypto.subtle.importKey(signed_token_config_1.SignedTokenConfig.publicKeyFormat, base64_service_1.Base64Service.decode(publicKey), signed_token_config_1.SignedTokenConfig.keyAlgorithm, false, ['verify'])];
164
165
  case 1:
165
166
  key = _a.sent();
166
167
  this._remember(this._publicKeys, publicKey, key);
@@ -194,23 +195,8 @@ var SignedTokenService = /** @class */ (function () {
194
195
  return null;
195
196
  }
196
197
  };
197
- SignedTokenService._toBase64 = function (bytes) {
198
- var binary = '';
199
- for (var index = 0; index < bytes.length; index += 1) {
200
- binary += String.fromCharCode(bytes[index]);
201
- }
202
- return btoa(binary);
203
- };
204
- SignedTokenService._fromBase64 = function (value) {
205
- var binary = atob(value.trim());
206
- var bytes = new Uint8Array(binary.length);
207
- for (var index = 0; index < binary.length; index += 1) {
208
- bytes[index] = binary.charCodeAt(index);
209
- }
210
- return bytes;
211
- };
212
198
  SignedTokenService._toBase64Url = function (bytes) {
213
- return this._toBase64(bytes).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
199
+ return base64_service_1.Base64Service.encode(bytes).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
214
200
  };
215
201
  SignedTokenService._fromBase64Url = function (value) {
216
202
  if (!/^[A-Za-z0-9_-]*$/.test(value))
@@ -218,7 +204,7 @@ var SignedTokenService = /** @class */ (function () {
218
204
  var base64 = value.replace(/-/g, '+').replace(/_/g, '/');
219
205
  var padding = base64.length % 4 === 0 ? '' : '='.repeat(4 - (base64.length % 4));
220
206
  try {
221
- return this._fromBase64("".concat(base64).concat(padding));
207
+ return base64_service_1.Base64Service.decode("".concat(base64).concat(padding));
222
208
  }
223
209
  catch (_a) {
224
210
  return null;
package/dist/index.d.ts CHANGED
@@ -3,8 +3,11 @@ import * as CommonNamespace from './common';
3
3
  export declare const Common: typeof CommonNamespace;
4
4
  export declare const Client: typeof ClientNamespace;
5
5
  export { AmountDirection } from './common/constants/amount-direction';
6
+ export { HttpMethod } from './common/constants/http-method';
7
+ export type { CodedErrorData } from './models/coded-error-data';
6
8
  export type { DeviceData } from './models/device-data';
7
9
  export type { EmailPreviewInput } from './models/email-preview-input';
10
+ export type { JsonValueGuard } from './models/json-value-guard';
8
11
  export type { SignedTokenHeader } from './models/signed-token-header';
9
12
  export type { SignedTokenKeyPair } from './models/signed-token-key-pair';
10
13
  export type { SocketTokenClaims } from './models/socket-token-claims';
@@ -18,3 +21,6 @@ export type { DataKeyPair } from './common/envelope-crypto-service';
18
21
  export type { PhoneCountryData } from './models/phone-country-data';
19
22
  export type { PhoneDisplayData } from './models/phone-display-data';
20
23
  export type { PostalCodeFormatData } from './models/postal-code-format-data';
24
+ export type { RelativeTimeOptions } from './models/relative-time-options';
25
+ export type { RequestClientData } from './models/request-client-data';
26
+ export type { RequestClientOptions } from './models/request-client-options';
package/dist/index.js CHANGED
@@ -33,10 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.AmountDirection = exports.Client = exports.Common = void 0;
36
+ exports.HttpMethod = exports.AmountDirection = exports.Client = exports.Common = void 0;
37
37
  var ClientNamespace = __importStar(require("./client"));
38
38
  var CommonNamespace = __importStar(require("./common"));
39
39
  exports.Common = CommonNamespace;
40
40
  exports.Client = ClientNamespace;
41
41
  var amount_direction_1 = require("./common/constants/amount-direction");
42
42
  Object.defineProperty(exports, "AmountDirection", { enumerable: true, get: function () { return amount_direction_1.AmountDirection; } });
43
+ var http_method_1 = require("./common/constants/http-method");
44
+ Object.defineProperty(exports, "HttpMethod", { enumerable: true, get: function () { return http_method_1.HttpMethod; } });
@@ -0,0 +1,3 @@
1
+ export interface CodedErrorData extends Error {
2
+ code: number;
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export type JsonValueGuard<Value> = (value: unknown) => value is Value;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export interface RelativeTimeOptions {
2
+ locale: string;
3
+ justNow: string;
4
+ formatDate: (value: string) => string;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface RequestClientData {
2
+ ipAddress: string | null;
3
+ userAgent: string | null;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface RequestClientOptions {
2
+ ipAddressMaxLength?: number;
3
+ userAgentMaxLength?: number;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1,2 @@
1
1
  export * from './file-service';
2
+ export * from './timing-safe-service';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./file-service"), exports);
18
+ __exportStar(require("./timing-safe-service"), exports);
@@ -0,0 +1,3 @@
1
+ export declare class TimingSafeService {
2
+ static equals(candidate: string, secret: string): boolean;
3
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimingSafeService = void 0;
4
+ var node_crypto_1 = require("node:crypto");
5
+ var TimingSafeService = /** @class */ (function () {
6
+ function TimingSafeService() {
7
+ }
8
+ TimingSafeService.equals = function (candidate, secret) {
9
+ var candidateBytes = Buffer.from(candidate);
10
+ var secretBytes = Buffer.from(secret);
11
+ return (candidateBytes.length === secretBytes.length && (0, node_crypto_1.timingSafeEqual)(candidateBytes, secretBytes));
12
+ };
13
+ return TimingSafeService;
14
+ }());
15
+ exports.TimingSafeService = TimingSafeService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pallasoft/ps-utilities",
3
- "version": "2.14.0",
3
+ "version": "2.16.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -39,7 +39,8 @@
39
39
  "format:prettier": "npx prettier --write \"**/*.{js,ts,json,md}\"",
40
40
  "lint:eslint": "npx eslint \"**/*.{js,ts}\"",
41
41
  "lint:eslint:fix": "npx eslint --fix \"**/*.{js,ts}\"",
42
- "release": "semantic-release"
42
+ "release": "semantic-release",
43
+ "test": "vitest run"
43
44
  },
44
45
  "devDependencies": {
45
46
  "@commitlint/cli": "^20.1.0",
@@ -65,9 +66,10 @@
65
66
  "lint-staged": "^16.2.7",
66
67
  "prettier": "^3.6.2",
67
68
  "semantic-release": "^24.2.0",
69
+ "socket.io-client": "^4.8.3",
68
70
  "ts-node": "^10.9.2",
69
71
  "typescript": "^5.9.3",
70
- "socket.io-client": "^4.8.3"
72
+ "vitest": "^3.2.7"
71
73
  },
72
74
  "peerDependencies": {
73
75
  "hono": "^4.0.0",