@oino-ts/common 0.17.3 → 0.17.4

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.
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OINOHeaders = void 0;
4
+ /**
5
+ * Type for HTTP style headers that just guarantees keys are normalized to lowercase.
6
+ *
7
+ */
8
+ class OINOHeaders {
9
+ constructor(init) {
10
+ this.setHeaders(init ?? {});
11
+ }
12
+ get(key) {
13
+ return this[key.toLowerCase()];
14
+ }
15
+ set(key, value) {
16
+ this[key.toLowerCase()] = value;
17
+ }
18
+ setHeaders(init) {
19
+ if (init instanceof OINOHeaders) {
20
+ for (const key of Object.keys(init)) {
21
+ this.set(key, init.get(key));
22
+ }
23
+ }
24
+ else if (init instanceof Map) {
25
+ for (const [key, value] of init.entries()) {
26
+ this.set(key, value);
27
+ }
28
+ }
29
+ else if (Array.isArray(init)) {
30
+ for (const [key, value] of init) {
31
+ this.set(key, value);
32
+ }
33
+ }
34
+ else if (init && typeof init === "object") {
35
+ for (const key in init) {
36
+ this.set(key, init[key]);
37
+ }
38
+ }
39
+ }
40
+ clear() {
41
+ for (const key of Object.keys(this)) {
42
+ delete this[key];
43
+ }
44
+ }
45
+ }
46
+ exports.OINOHeaders = OINOHeaders;
@@ -6,8 +6,8 @@
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.OINOHttpRequest = exports.OINORequest = void 0;
9
+ const node_buffer_1 = require("node:buffer");
9
10
  const _1 = require(".");
10
- const index_js_1 = require("./index.js");
11
11
  /**
12
12
  * OINO API request result object with returned data and/or http status code/message and
13
13
  * error / warning messages.
@@ -50,18 +50,7 @@ class OINOHttpRequest extends OINORequest {
50
50
  super(init);
51
51
  this.url = init.url;
52
52
  this.method = init.method ?? "GET";
53
- if (init.headers && init.headers) {
54
- this.headers = init.headers;
55
- }
56
- else if (init.headers && init.headers) {
57
- this.headers = {};
58
- for (const key in init.headers) {
59
- this.headers[key.toLowerCase()] = init.headers[key];
60
- }
61
- }
62
- else {
63
- this.headers = {};
64
- }
53
+ this.headers = new _1.OINOHeaders(init.headers);
65
54
  this.data = init.data ?? "";
66
55
  this.multipartBoundary = "";
67
56
  this.lastModified = init.lastModified;
@@ -72,7 +61,7 @@ class OINOHttpRequest extends OINORequest {
72
61
  this.requestType = init.requestType;
73
62
  }
74
63
  else {
75
- const request_type_param = this.url?.searchParams.get(index_js_1.OINO_REQUEST_TYPE_PARAM) || this.headers["content-type"]; // content-type header can be overridden by query parameter
64
+ const request_type_param = this.url?.searchParams.get(_1.OINO_REQUEST_TYPE_PARAM) || this.headers.get("content-type"); // content-type header can be overridden by query parameter
76
65
  if (request_type_param == _1.OINOContentType.csv) {
77
66
  this.requestType = _1.OINOContentType.csv;
78
67
  }
@@ -93,7 +82,7 @@ class OINOHttpRequest extends OINORequest {
93
82
  this.responseType = init.responseType;
94
83
  }
95
84
  else {
96
- const response_type_param = this.url?.searchParams.get(index_js_1.OINO_RESPONSE_TYPE_PARAM) || this.headers["accept"]; // accept header can be overridden by query parameter
85
+ const response_type_param = this.url?.searchParams.get(_1.OINO_RESPONSE_TYPE_PARAM) || this.headers.get("accept"); // accept header can be overridden by query parameter
97
86
  const accept_types = response_type_param?.split(', ') || [];
98
87
  let response_type = undefined;
99
88
  for (let i = 0; i < accept_types.length; i++) {
@@ -104,11 +93,11 @@ class OINOHttpRequest extends OINORequest {
104
93
  }
105
94
  this.responseType = response_type ?? _1.OINOContentType.json;
106
95
  }
107
- const last_modified = this.headers["if-modified-since"];
96
+ const last_modified = this.headers.get("if-modified-since");
108
97
  if (last_modified) {
109
98
  this.lastModified = new Date(last_modified).getTime();
110
99
  }
111
- const etags = this.headers["if-none-match"]?.split(',').map(e => e.trim());
100
+ const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim());
112
101
  if (etags) {
113
102
  this.etags = etags;
114
103
  }
@@ -119,7 +108,7 @@ class OINOHttpRequest extends OINORequest {
119
108
  url: new URL(request.url),
120
109
  method: request.method,
121
110
  headers: Object.fromEntries(request.headers),
122
- data: Buffer.from(body),
111
+ data: node_buffer_1.Buffer.from(body),
123
112
  });
124
113
  }
125
114
  dataAsText() {
@@ -141,19 +130,19 @@ class OINOHttpRequest extends OINORequest {
141
130
  }
142
131
  dataAsBuffer() {
143
132
  if (this.data === null) {
144
- return Buffer.alloc(0);
133
+ return node_buffer_1.Buffer.alloc(0);
145
134
  }
146
- else if (this.data instanceof Buffer) {
135
+ else if (this.data instanceof node_buffer_1.Buffer) {
147
136
  return this.data;
148
137
  }
149
138
  else if (this.data instanceof Uint8Array) {
150
- return Buffer.from(this.data);
139
+ return node_buffer_1.Buffer.from(this.data);
151
140
  }
152
141
  else if (this.data instanceof Object) {
153
- return Buffer.from(JSON.stringify(this.data), "utf-8");
142
+ return node_buffer_1.Buffer.from(JSON.stringify(this.data), "utf-8");
154
143
  }
155
144
  else {
156
- return Buffer.from(this.data, "utf-8");
145
+ return node_buffer_1.Buffer.from(this.data, "utf-8");
157
146
  }
158
147
  }
159
148
  }
@@ -133,19 +133,19 @@ class OINOResult {
133
133
  for (let i = 0; i < this.messages.length; i++) {
134
134
  const message = this.messages[i].replaceAll("\r", " ").replaceAll("\n", " ");
135
135
  if (copyErrors && message.startsWith(_1.OINO_ERROR_PREFIX)) {
136
- headers.append('X-OINO-MESSAGE-' + j, message);
136
+ headers.set('X-OINO-MESSAGE-' + j, message);
137
137
  j++;
138
138
  }
139
139
  if (copyWarnings && message.startsWith(_1.OINO_WARNING_PREFIX)) {
140
- headers.append('X-OINO-MESSAGE-' + j, message);
140
+ headers.set('X-OINO-MESSAGE-' + j, message);
141
141
  j++;
142
142
  }
143
143
  if (copyInfos && message.startsWith(_1.OINO_INFO_PREFIX)) {
144
- headers.append('X-OINO-MESSAGE-' + j, message);
144
+ headers.set('X-OINO-MESSAGE-' + j, message);
145
145
  j++;
146
146
  }
147
147
  if (copyDebug && message.startsWith(_1.OINO_DEBUG_PREFIX)) {
148
- headers.append('X-OINO-MESSAGE-' + j, message);
148
+ headers.set('X-OINO-MESSAGE-' + j, message);
149
149
  j++;
150
150
  }
151
151
  }
@@ -183,7 +183,7 @@ class OINOHttpResult extends OINOResult {
183
183
  constructor(init) {
184
184
  super(init);
185
185
  this.body = init?.body ?? "";
186
- this.headers = init?.headers ?? {};
186
+ this.headers = new _1.OINOHeaders(init?.headers);
187
187
  this.expires = init?.expires ?? 0;
188
188
  this.lastModified = init?.lastModified ?? 0;
189
189
  this._etag = "";
@@ -205,7 +205,10 @@ class OINOHttpResult extends OINOResult {
205
205
  * @param headers HTTP headers (overrides existing values)
206
206
  */
207
207
  getFetchResponse(headers) {
208
- const merged_headers = { ...this.headers, ...headers };
208
+ const merged_headers = new _1.OINOHeaders(this.headers);
209
+ if (headers) {
210
+ merged_headers.setHeaders(headers);
211
+ }
209
212
  const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
210
213
  result.headers.set('Content-Length', this.body.length.toString());
211
214
  if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OINOContentType = exports.OINO_RESPONSE_TYPE_PARAM = exports.OINO_REQUEST_TYPE_PARAM = exports.OINO_DEBUG_PREFIX = exports.OINO_INFO_PREFIX = exports.OINO_WARNING_PREFIX = exports.OINO_ERROR_PREFIX = exports.OINO_EMPTY_FORMATTER = exports.OINOFormatter = exports.OINOHtmlTemplate = exports.OINOStr = exports.OINOHttpRequest = exports.OINORequest = exports.OINOHttpResult = exports.OINOResult = exports.OINOConsoleLog = exports.OINOLogLevel = exports.OINOLog = exports.OINOMemoryBenchmark = exports.OINOBenchmark = void 0;
3
+ exports.OINOContentType = exports.OINO_RESPONSE_TYPE_PARAM = exports.OINO_REQUEST_TYPE_PARAM = exports.OINO_DEBUG_PREFIX = exports.OINO_INFO_PREFIX = exports.OINO_WARNING_PREFIX = exports.OINO_ERROR_PREFIX = exports.OINOHeaders = exports.OINO_EMPTY_FORMATTER = exports.OINOFormatter = exports.OINOHtmlTemplate = exports.OINOStr = exports.OINOHttpRequest = exports.OINORequest = exports.OINOHttpResult = exports.OINOResult = exports.OINOConsoleLog = exports.OINOLogLevel = exports.OINOLog = exports.OINOMemoryBenchmark = exports.OINOBenchmark = void 0;
4
4
  var OINOBenchmark_js_1 = require("./OINOBenchmark.js");
5
5
  Object.defineProperty(exports, "OINOBenchmark", { enumerable: true, get: function () { return OINOBenchmark_js_1.OINOBenchmark; } });
6
6
  Object.defineProperty(exports, "OINOMemoryBenchmark", { enumerable: true, get: function () { return OINOBenchmark_js_1.OINOMemoryBenchmark; } });
@@ -21,6 +21,8 @@ Object.defineProperty(exports, "OINOHtmlTemplate", { enumerable: true, get: func
21
21
  var OINOFormatter_js_1 = require("./OINOFormatter.js");
22
22
  Object.defineProperty(exports, "OINOFormatter", { enumerable: true, get: function () { return OINOFormatter_js_1.OINOFormatter; } });
23
23
  Object.defineProperty(exports, "OINO_EMPTY_FORMATTER", { enumerable: true, get: function () { return OINOFormatter_js_1.OINO_EMPTY_FORMATTER; } });
24
+ var OINOHeaders_js_1 = require("./OINOHeaders.js");
25
+ Object.defineProperty(exports, "OINOHeaders", { enumerable: true, get: function () { return OINOHeaders_js_1.OINOHeaders; } });
24
26
  /** OINO error message prefix */
25
27
  exports.OINO_ERROR_PREFIX = "OINO ERROR";
26
28
  /** OINO warning message prefix */
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Type for HTTP style headers that just guarantees keys are normalized to lowercase.
3
+ *
4
+ */
5
+ export class OINOHeaders {
6
+ constructor(init) {
7
+ this.setHeaders(init ?? {});
8
+ }
9
+ get(key) {
10
+ return this[key.toLowerCase()];
11
+ }
12
+ set(key, value) {
13
+ this[key.toLowerCase()] = value;
14
+ }
15
+ setHeaders(init) {
16
+ if (init instanceof OINOHeaders) {
17
+ for (const key of Object.keys(init)) {
18
+ this.set(key, init.get(key));
19
+ }
20
+ }
21
+ else if (init instanceof Map) {
22
+ for (const [key, value] of init.entries()) {
23
+ this.set(key, value);
24
+ }
25
+ }
26
+ else if (Array.isArray(init)) {
27
+ for (const [key, value] of init) {
28
+ this.set(key, value);
29
+ }
30
+ }
31
+ else if (init && typeof init === "object") {
32
+ for (const key in init) {
33
+ this.set(key, init[key]);
34
+ }
35
+ }
36
+ }
37
+ clear() {
38
+ for (const key of Object.keys(this)) {
39
+ delete this[key];
40
+ }
41
+ }
42
+ }
@@ -3,8 +3,8 @@
3
3
  * License, v. 2.0. If a copy of the MPL was not distributed with this
4
4
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
- import { OINOContentType } from ".";
7
- import { OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM } from "./index.js";
6
+ import { Buffer } from "node:buffer";
7
+ import { OINOContentType, OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM, OINOHeaders } from ".";
8
8
  /**
9
9
  * OINO API request result object with returned data and/or http status code/message and
10
10
  * error / warning messages.
@@ -46,18 +46,7 @@ export class OINOHttpRequest extends OINORequest {
46
46
  super(init);
47
47
  this.url = init.url;
48
48
  this.method = init.method ?? "GET";
49
- if (init.headers && init.headers) {
50
- this.headers = init.headers;
51
- }
52
- else if (init.headers && init.headers) {
53
- this.headers = {};
54
- for (const key in init.headers) {
55
- this.headers[key.toLowerCase()] = init.headers[key];
56
- }
57
- }
58
- else {
59
- this.headers = {};
60
- }
49
+ this.headers = new OINOHeaders(init.headers);
61
50
  this.data = init.data ?? "";
62
51
  this.multipartBoundary = "";
63
52
  this.lastModified = init.lastModified;
@@ -68,7 +57,7 @@ export class OINOHttpRequest extends OINORequest {
68
57
  this.requestType = init.requestType;
69
58
  }
70
59
  else {
71
- const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers["content-type"]; // content-type header can be overridden by query parameter
60
+ const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers.get("content-type"); // content-type header can be overridden by query parameter
72
61
  if (request_type_param == OINOContentType.csv) {
73
62
  this.requestType = OINOContentType.csv;
74
63
  }
@@ -89,7 +78,7 @@ export class OINOHttpRequest extends OINORequest {
89
78
  this.responseType = init.responseType;
90
79
  }
91
80
  else {
92
- const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers["accept"]; // accept header can be overridden by query parameter
81
+ const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers.get("accept"); // accept header can be overridden by query parameter
93
82
  const accept_types = response_type_param?.split(', ') || [];
94
83
  let response_type = undefined;
95
84
  for (let i = 0; i < accept_types.length; i++) {
@@ -100,11 +89,11 @@ export class OINOHttpRequest extends OINORequest {
100
89
  }
101
90
  this.responseType = response_type ?? OINOContentType.json;
102
91
  }
103
- const last_modified = this.headers["if-modified-since"];
92
+ const last_modified = this.headers.get("if-modified-since");
104
93
  if (last_modified) {
105
94
  this.lastModified = new Date(last_modified).getTime();
106
95
  }
107
- const etags = this.headers["if-none-match"]?.split(',').map(e => e.trim());
96
+ const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim());
108
97
  if (etags) {
109
98
  this.etags = etags;
110
99
  }
@@ -4,7 +4,7 @@
4
4
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
6
  import { createHash } from "node:crypto";
7
- import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX } from ".";
7
+ import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX, OINOHeaders } from ".";
8
8
  /**
9
9
  * OINO API request result object with returned data and/or http status code/message and
10
10
  * error / warning messages.
@@ -130,19 +130,19 @@ export class OINOResult {
130
130
  for (let i = 0; i < this.messages.length; i++) {
131
131
  const message = this.messages[i].replaceAll("\r", " ").replaceAll("\n", " ");
132
132
  if (copyErrors && message.startsWith(OINO_ERROR_PREFIX)) {
133
- headers.append('X-OINO-MESSAGE-' + j, message);
133
+ headers.set('X-OINO-MESSAGE-' + j, message);
134
134
  j++;
135
135
  }
136
136
  if (copyWarnings && message.startsWith(OINO_WARNING_PREFIX)) {
137
- headers.append('X-OINO-MESSAGE-' + j, message);
137
+ headers.set('X-OINO-MESSAGE-' + j, message);
138
138
  j++;
139
139
  }
140
140
  if (copyInfos && message.startsWith(OINO_INFO_PREFIX)) {
141
- headers.append('X-OINO-MESSAGE-' + j, message);
141
+ headers.set('X-OINO-MESSAGE-' + j, message);
142
142
  j++;
143
143
  }
144
144
  if (copyDebug && message.startsWith(OINO_DEBUG_PREFIX)) {
145
- headers.append('X-OINO-MESSAGE-' + j, message);
145
+ headers.set('X-OINO-MESSAGE-' + j, message);
146
146
  j++;
147
147
  }
148
148
  }
@@ -179,7 +179,7 @@ export class OINOHttpResult extends OINOResult {
179
179
  constructor(init) {
180
180
  super(init);
181
181
  this.body = init?.body ?? "";
182
- this.headers = init?.headers ?? {};
182
+ this.headers = new OINOHeaders(init?.headers);
183
183
  this.expires = init?.expires ?? 0;
184
184
  this.lastModified = init?.lastModified ?? 0;
185
185
  this._etag = "";
@@ -201,7 +201,10 @@ export class OINOHttpResult extends OINOResult {
201
201
  * @param headers HTTP headers (overrides existing values)
202
202
  */
203
203
  getFetchResponse(headers) {
204
- const merged_headers = { ...this.headers, ...headers };
204
+ const merged_headers = new OINOHeaders(this.headers);
205
+ if (headers) {
206
+ merged_headers.setHeaders(headers);
207
+ }
205
208
  const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
206
209
  result.headers.set('Content-Length', this.body.length.toString());
207
210
  if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
package/dist/esm/index.js CHANGED
@@ -5,6 +5,7 @@ export { OINORequest, OINOHttpRequest } from "./OINORequest.js";
5
5
  export { OINOStr } from "./OINOStr.js";
6
6
  export { OINOHtmlTemplate } from "./OINOHtmlTemplate.js";
7
7
  export { OINOFormatter, OINO_EMPTY_FORMATTER } from "./OINOFormatter.js";
8
+ export { OINOHeaders } from "./OINOHeaders.js";
8
9
  /** OINO error message prefix */
9
10
  export const OINO_ERROR_PREFIX = "OINO ERROR";
10
11
  /** OINO warning message prefix */
@@ -0,0 +1,13 @@
1
+ export type OINOHeadersInit = OINOHeaders | Record<string, string> | [string, string][] | Map<string, string>;
2
+ /**
3
+ * Type for HTTP style headers that just guarantees keys are normalized to lowercase.
4
+ *
5
+ */
6
+ export declare class OINOHeaders {
7
+ [key: string]: any;
8
+ constructor(init?: OINOHeadersInit);
9
+ get(key: string): string | undefined;
10
+ set(key: string, value: string): void;
11
+ setHeaders(init?: OINOHeadersInit): void;
12
+ clear(): void;
13
+ }
@@ -1,4 +1,5 @@
1
- import { OINOContentType } from ".";
1
+ import { Buffer } from "node:buffer";
2
+ import { OINOContentType, OINOHeaders, OINOHeadersInit } from ".";
2
3
  export interface OINORequestInit {
3
4
  params?: Record<string, string>;
4
5
  }
@@ -18,15 +19,10 @@ export declare class OINORequest {
18
19
  */
19
20
  constructor(init?: OINORequestInit);
20
21
  }
21
- /**
22
- * Type for HTTP headers that just guarantees keys are normalized to lowercase.
23
- *
24
- */
25
- export type OINOHttpHeaders = Record<string, string>;
26
22
  export interface OINOHttpRequestInit extends OINORequestInit {
27
23
  url?: URL;
28
24
  method?: string;
29
- headers?: OINOHttpHeaders | Record<string, string>;
25
+ headers?: OINOHeadersInit;
30
26
  data?: string | Buffer | Uint8Array | object | null;
31
27
  requestType?: OINOContentType;
32
28
  responseType?: OINOContentType;
@@ -39,7 +35,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
39
35
  export declare class OINOHttpRequest extends OINORequest {
40
36
  readonly url?: URL;
41
37
  readonly method: string;
42
- readonly headers: OINOHttpHeaders;
38
+ readonly headers: OINOHeaders;
43
39
  readonly data: string | Buffer | Uint8Array | object | null;
44
40
  readonly requestType: OINOContentType;
45
41
  readonly responseType: OINOContentType;
@@ -1,3 +1,4 @@
1
+ import { OINOHeaders, OINOHeadersInit } from ".";
1
2
  export interface OINOResultInit {
2
3
  success?: boolean;
3
4
  status?: number;
@@ -79,7 +80,7 @@ export declare class OINOResult {
79
80
  * @param copyDebug wether debug messages should be copied (default false)
80
81
  *
81
82
  */
82
- copyMessagesToHeaders(headers: Headers, copyErrors?: boolean, copyWarnings?: boolean, copyInfos?: boolean, copyDebug?: boolean): void;
83
+ copyMessagesToHeaders(headers: OINOHeaders, copyErrors?: boolean, copyWarnings?: boolean, copyInfos?: boolean, copyDebug?: boolean): void;
83
84
  /**
84
85
  * Print result for logging.
85
86
  *
@@ -88,7 +89,7 @@ export declare class OINOResult {
88
89
  }
89
90
  export interface OINOHttpResultInit extends OINOResultInit {
90
91
  body?: string;
91
- headers?: Record<string, string>;
92
+ headers?: OINOHeadersInit;
92
93
  expires?: number;
93
94
  lastModified?: number;
94
95
  }
@@ -100,7 +101,7 @@ export declare class OINOHttpResult extends OINOResult {
100
101
  /** HTTP body data */
101
102
  readonly body: string;
102
103
  /** HTTP headers */
103
- readonly headers?: Record<string, string>;
104
+ readonly headers: OINOHeaders;
104
105
  /** HTTP cache expiration value
105
106
  * Note: default 0 means no expiration and 'Pragma: no-cache' is set.
106
107
  */
@@ -124,5 +125,5 @@ export declare class OINOHttpResult extends OINOResult {
124
125
  *
125
126
  * @param headers HTTP headers (overrides existing values)
126
127
  */
127
- getFetchResponse(headers?: Record<string, string>): Response;
128
+ getFetchResponse(headers?: OINOHeadersInit): Response;
128
129
  }
@@ -5,6 +5,7 @@ export { OINORequest, OINOHttpRequest, type OINORequestInit, type OINOHttpReques
5
5
  export { OINOStr } from "./OINOStr.js";
6
6
  export { OINOHtmlTemplate } from "./OINOHtmlTemplate.js";
7
7
  export { OINOFormatter, OINO_EMPTY_FORMATTER } from "./OINOFormatter.js";
8
+ export { OINOHeaders, type OINOHeadersInit } from "./OINOHeaders.js";
8
9
  /** OINO error message prefix */
9
10
  export declare const OINO_ERROR_PREFIX = "OINO ERROR";
10
11
  /** OINO warning message prefix */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/common",
3
- "version": "0.17.3",
3
+ "version": "0.17.4",
4
4
  "description": "OINO TS package for common classes.",
5
5
  "author": "Matias Kiviniemi (pragmatta)",
6
6
  "license": "MPL-2.0",
@@ -19,7 +19,7 @@
19
19
  "dependencies": {
20
20
  },
21
21
  "devDependencies": {
22
- "@oino-ts/types": "0.17.3",
22
+ "@oino-ts/types": "0.17.4",
23
23
  "@types/node": "^22.0.0",
24
24
  "typescript": "~5.9.0"
25
25
  },
@@ -0,0 +1,51 @@
1
+ export type OINOHeadersInit = OINOHeaders | Record<string, string> | [string, string][] | Map<string, string>;
2
+
3
+ /**
4
+ * Type for HTTP style headers that just guarantees keys are normalized to lowercase.
5
+ *
6
+ */
7
+
8
+ export class OINOHeaders {
9
+ [key: string]: any
10
+
11
+ constructor(init?: OINOHeadersInit) {
12
+ this.setHeaders(init ?? {})
13
+ }
14
+
15
+ get(key: string): string | undefined {
16
+ return this[key.toLowerCase()]
17
+ }
18
+
19
+ set(key: string, value: string): void {
20
+ this[key.toLowerCase()] = value
21
+ }
22
+
23
+ setHeaders(init?: OINOHeadersInit): void {
24
+ if (init instanceof OINOHeaders) {
25
+ for (const key of Object.keys(init)) {
26
+ this.set(key, init.get(key)!)
27
+ }
28
+
29
+ } else if (init instanceof Map) {
30
+ for (const [key, value] of init.entries()) {
31
+ this.set(key, value)
32
+ }
33
+
34
+ } else if (Array.isArray(init)) {
35
+ for (const [key, value] of init) {
36
+ this.set(key, value)
37
+ }
38
+
39
+ } else if (init && typeof init === "object") {
40
+ for (const key in init as Record<string, string>) {
41
+ this.set(key, init[key])
42
+ }
43
+ }
44
+ }
45
+
46
+ clear(): void {
47
+ for (const key of Object.keys(this)) {
48
+ delete this[key]
49
+ }
50
+ }
51
+ }
@@ -4,8 +4,9 @@
4
4
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
6
 
7
- import { OINOContentType } from "."
8
- import { OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM } from "./index.js"
7
+ import { Buffer } from "node:buffer"
8
+
9
+ import { OINOContentType, OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM, OINOHeaders, OINOHeadersInit } from "."
9
10
 
10
11
  export interface OINORequestInit {
11
12
  params?: Record<string, string>
@@ -31,16 +32,10 @@ export class OINORequest {
31
32
  }
32
33
  }
33
34
 
34
- /**
35
- * Type for HTTP headers that just guarantees keys are normalized to lowercase.
36
- *
37
- */
38
- export type OINOHttpHeaders = Record<string, string>
39
-
40
35
  export interface OINOHttpRequestInit extends OINORequestInit {
41
36
  url?: URL
42
37
  method?: string
43
- headers?: OINOHttpHeaders|Record<string, string>
38
+ headers?: OINOHeadersInit
44
39
  data?: string|Buffer|Uint8Array|object|null
45
40
  requestType?:OINOContentType
46
41
  responseType?:OINOContentType
@@ -54,7 +49,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
54
49
  export class OINOHttpRequest extends OINORequest {
55
50
  readonly url?: URL
56
51
  readonly method: string
57
- readonly headers: OINOHttpHeaders
52
+ readonly headers: OINOHeaders
58
53
  readonly data: string|Buffer|Uint8Array|object|null
59
54
  readonly requestType:OINOContentType
60
55
  readonly responseType:OINOContentType
@@ -72,18 +67,7 @@ export class OINOHttpRequest extends OINORequest {
72
67
  super(init)
73
68
  this.url = init.url
74
69
  this.method = init.method ?? "GET"
75
- if (init.headers && init.headers satisfies OINOHttpHeaders) {
76
- this.headers = init.headers as OINOHttpHeaders
77
-
78
- } else if (init.headers && init.headers satisfies Record<string, string>) {
79
- this.headers = {}
80
- for (const key in init.headers) {
81
- this.headers[key.toLowerCase()] = init.headers[key]
82
- }
83
- } else {
84
- this.headers = {}
85
- }
86
-
70
+ this.headers = new OINOHeaders(init.headers)
87
71
  this.data = init.data ?? ""
88
72
  this.multipartBoundary = ""
89
73
  this.lastModified = init.lastModified
@@ -94,7 +78,7 @@ export class OINOHttpRequest extends OINORequest {
94
78
  if (init.requestType) {
95
79
  this.requestType = init.requestType
96
80
  } else {
97
- const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers["content-type"] // content-type header can be overridden by query parameter
81
+ const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers.get("content-type") // content-type header can be overridden by query parameter
98
82
  if (request_type_param == OINOContentType.csv) {
99
83
  this.requestType = OINOContentType.csv
100
84
 
@@ -113,7 +97,7 @@ export class OINOHttpRequest extends OINORequest {
113
97
  if (init.responseType) {
114
98
  this.responseType = init.responseType
115
99
  } else {
116
- const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers["accept"] // accept header can be overridden by query parameter
100
+ const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers.get("accept") // accept header can be overridden by query parameter
117
101
  const accept_types = response_type_param?.split(', ') || []
118
102
  let response_type:OINOContentType|undefined = undefined
119
103
  for (let i=0; i<accept_types.length; i++) {
@@ -124,11 +108,11 @@ export class OINOHttpRequest extends OINORequest {
124
108
  }
125
109
  this.responseType = response_type ?? OINOContentType.json
126
110
  }
127
- const last_modified = this.headers["if-modified-since"]
111
+ const last_modified = this.headers.get("if-modified-since")
128
112
  if (last_modified) {
129
113
  this.lastModified = new Date(last_modified).getTime()
130
114
  }
131
- const etags = this.headers["if-none-match"]?.split(',').map(e => e.trim())
115
+ const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim())
132
116
  if (etags) {
133
117
  this.etags = etags
134
118
  }
package/src/OINOResult.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { createHash, Hash } from "node:crypto";
8
- import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX } from ".";
8
+ import { OINO_DEBUG_PREFIX, OINO_ERROR_PREFIX, OINO_INFO_PREFIX, OINO_WARNING_PREFIX, OINOHeaders, OINOHeadersInit } from ".";
9
9
 
10
10
  export interface OINOResultInit {
11
11
  success?: boolean
@@ -144,24 +144,24 @@ export class OINOResult {
144
144
  * @param copyDebug wether debug messages should be copied (default false)
145
145
  *
146
146
  */
147
- copyMessagesToHeaders(headers:Headers, copyErrors:boolean = true, copyWarnings:boolean = false, copyInfos:boolean = false, copyDebug:boolean = false) {
147
+ copyMessagesToHeaders(headers:OINOHeaders, copyErrors:boolean = true, copyWarnings:boolean = false, copyInfos:boolean = false, copyDebug:boolean = false) {
148
148
  let j=1
149
149
  for(let i=0; i<this.messages.length; i++) {
150
150
  const message = this.messages[i].replaceAll("\r", " ").replaceAll("\n", " ")
151
151
  if (copyErrors && message.startsWith(OINO_ERROR_PREFIX)) {
152
- headers.append('X-OINO-MESSAGE-'+j, message)
152
+ headers.set('X-OINO-MESSAGE-'+j, message)
153
153
  j++
154
154
  }
155
155
  if (copyWarnings && message.startsWith(OINO_WARNING_PREFIX)) {
156
- headers.append('X-OINO-MESSAGE-'+j, message)
156
+ headers.set('X-OINO-MESSAGE-'+j, message)
157
157
  j++
158
158
  }
159
159
  if (copyInfos && message.startsWith(OINO_INFO_PREFIX)) {
160
- headers.append('X-OINO-MESSAGE-'+j, message)
160
+ headers.set('X-OINO-MESSAGE-'+j, message)
161
161
  j++
162
162
  }
163
163
  if (copyDebug && message.startsWith(OINO_DEBUG_PREFIX)) {
164
- headers.append('X-OINO-MESSAGE-'+j, message)
164
+ headers.set('X-OINO-MESSAGE-'+j, message)
165
165
  j++
166
166
  }
167
167
  }
@@ -178,7 +178,7 @@ export class OINOResult {
178
178
 
179
179
  export interface OINOHttpResultInit extends OINOResultInit {
180
180
  body?: string
181
- headers?: Record<string, string>
181
+ headers?: OINOHeadersInit
182
182
  expires?: number
183
183
  lastModified?: number
184
184
  }
@@ -193,7 +193,7 @@ export class OINOHttpResult extends OINOResult {
193
193
  readonly body: string
194
194
 
195
195
  /** HTTP headers */
196
- readonly headers?: Record<string, string>
196
+ readonly headers: OINOHeaders
197
197
 
198
198
  /** HTTP cache expiration value
199
199
  * Note: default 0 means no expiration and 'Pragma: no-cache' is set.
@@ -212,7 +212,7 @@ export class OINOHttpResult extends OINOResult {
212
212
  constructor(init?: OINOHttpResultInit) {
213
213
  super(init)
214
214
  this.body = init?.body ?? ""
215
- this.headers = init?.headers ?? {}
215
+ this.headers = new OINOHeaders(init?.headers)
216
216
  this.expires = init?.expires ?? 0
217
217
  this.lastModified = init?.lastModified ?? 0
218
218
  this._etag = ""
@@ -235,8 +235,11 @@ export class OINOHttpResult extends OINOResult {
235
235
  *
236
236
  * @param headers HTTP headers (overrides existing values)
237
237
  */
238
- getFetchResponse(headers?:Record<string, string>):Response {
239
- const merged_headers = { ...this.headers, ...headers }
238
+ getFetchResponse(headers?:OINOHeadersInit):Response {
239
+ const merged_headers = new OINOHeaders(this.headers)
240
+ if (headers) {
241
+ merged_headers.setHeaders(headers)
242
+ }
240
243
  const result: Response = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers })
241
244
  result.headers.set('Content-Length', this.body.length.toString())
242
245
  if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ export { OINORequest, OINOHttpRequest, type OINORequestInit, type OINOHttpReques
5
5
  export { OINOStr } from "./OINOStr.js"
6
6
  export { OINOHtmlTemplate } from "./OINOHtmlTemplate.js"
7
7
  export { OINOFormatter, OINO_EMPTY_FORMATTER } from "./OINOFormatter.js"
8
+ export { OINOHeaders, type OINOHeadersInit } from "./OINOHeaders.js"
8
9
 
9
10
  /** OINO error message prefix */
10
11
  export const OINO_ERROR_PREFIX = "OINO ERROR"