@oino-ts/common 0.17.2 → 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.
- package/dist/cjs/OINOHeaders.js +46 -0
- package/dist/cjs/OINORequest.js +42 -16
- package/dist/cjs/OINOResult.js +16 -9
- package/dist/cjs/index.js +3 -1
- package/dist/esm/OINOHeaders.js +42 -0
- package/dist/esm/OINORequest.js +42 -16
- package/dist/esm/OINOResult.js +17 -10
- package/dist/esm/index.js +1 -0
- package/dist/types/OINOHeaders.d.ts +13 -0
- package/dist/types/OINORequest.d.ts +9 -10
- package/dist/types/OINOResult.d.ts +6 -2
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/OINOHeaders.ts +51 -0
- package/src/OINORequest.ts +49 -19
- package/src/OINOResult.ts +20 -11
- package/src/index.ts +1 -0
|
@@ -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;
|
package/dist/cjs/OINORequest.js
CHANGED
|
@@ -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.
|
|
@@ -25,14 +25,6 @@ class OINORequest {
|
|
|
25
25
|
constructor(init) {
|
|
26
26
|
this.params = init?.params ?? {};
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Copy values from different result.
|
|
30
|
-
*
|
|
31
|
-
* @param request source value
|
|
32
|
-
*/
|
|
33
|
-
copy(request) {
|
|
34
|
-
this.params = { ...request.params };
|
|
35
|
-
}
|
|
36
28
|
}
|
|
37
29
|
exports.OINORequest = OINORequest;
|
|
38
30
|
/**
|
|
@@ -58,7 +50,7 @@ class OINOHttpRequest extends OINORequest {
|
|
|
58
50
|
super(init);
|
|
59
51
|
this.url = init.url;
|
|
60
52
|
this.method = init.method ?? "GET";
|
|
61
|
-
this.headers = init.headers
|
|
53
|
+
this.headers = new _1.OINOHeaders(init.headers);
|
|
62
54
|
this.data = init.data ?? "";
|
|
63
55
|
this.multipartBoundary = "";
|
|
64
56
|
this.lastModified = init.lastModified;
|
|
@@ -69,7 +61,7 @@ class OINOHttpRequest extends OINORequest {
|
|
|
69
61
|
this.requestType = init.requestType;
|
|
70
62
|
}
|
|
71
63
|
else {
|
|
72
|
-
const request_type_param = this.url?.searchParams.get(
|
|
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
|
|
73
65
|
if (request_type_param == _1.OINOContentType.csv) {
|
|
74
66
|
this.requestType = _1.OINOContentType.csv;
|
|
75
67
|
}
|
|
@@ -90,7 +82,7 @@ class OINOHttpRequest extends OINORequest {
|
|
|
90
82
|
this.responseType = init.responseType;
|
|
91
83
|
}
|
|
92
84
|
else {
|
|
93
|
-
const response_type_param = this.url?.searchParams.get(
|
|
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
|
|
94
86
|
const accept_types = response_type_param?.split(', ') || [];
|
|
95
87
|
let response_type = undefined;
|
|
96
88
|
for (let i = 0; i < accept_types.length; i++) {
|
|
@@ -101,23 +93,57 @@ class OINOHttpRequest extends OINORequest {
|
|
|
101
93
|
}
|
|
102
94
|
this.responseType = response_type ?? _1.OINOContentType.json;
|
|
103
95
|
}
|
|
104
|
-
const last_modified = this.headers
|
|
96
|
+
const last_modified = this.headers.get("if-modified-since");
|
|
105
97
|
if (last_modified) {
|
|
106
98
|
this.lastModified = new Date(last_modified).getTime();
|
|
107
99
|
}
|
|
108
|
-
const etags = this.headers
|
|
100
|
+
const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim());
|
|
109
101
|
if (etags) {
|
|
110
102
|
this.etags = etags;
|
|
111
103
|
}
|
|
112
104
|
}
|
|
113
|
-
static async
|
|
105
|
+
static async fromFetchRequest(request) {
|
|
114
106
|
const body = await request.arrayBuffer();
|
|
115
107
|
return new OINOHttpRequest({
|
|
116
108
|
url: new URL(request.url),
|
|
117
109
|
method: request.method,
|
|
118
110
|
headers: Object.fromEntries(request.headers),
|
|
119
|
-
data: Buffer.from(body),
|
|
111
|
+
data: node_buffer_1.Buffer.from(body),
|
|
120
112
|
});
|
|
121
113
|
}
|
|
114
|
+
dataAsText() {
|
|
115
|
+
if (this.data instanceof Uint8Array) {
|
|
116
|
+
return new TextDecoder().decode(this.data);
|
|
117
|
+
}
|
|
118
|
+
else if (this.data instanceof Object) {
|
|
119
|
+
return JSON.stringify(this.data);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return this.data?.toString() || "";
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
dataAsParsedJson() {
|
|
126
|
+
return this.data ? JSON.parse(this.dataAsText()) : {};
|
|
127
|
+
}
|
|
128
|
+
dataAsFormData() {
|
|
129
|
+
return new URLSearchParams(this.dataAsText() || "");
|
|
130
|
+
}
|
|
131
|
+
dataAsBuffer() {
|
|
132
|
+
if (this.data === null) {
|
|
133
|
+
return node_buffer_1.Buffer.alloc(0);
|
|
134
|
+
}
|
|
135
|
+
else if (this.data instanceof node_buffer_1.Buffer) {
|
|
136
|
+
return this.data;
|
|
137
|
+
}
|
|
138
|
+
else if (this.data instanceof Uint8Array) {
|
|
139
|
+
return node_buffer_1.Buffer.from(this.data);
|
|
140
|
+
}
|
|
141
|
+
else if (this.data instanceof Object) {
|
|
142
|
+
return node_buffer_1.Buffer.from(JSON.stringify(this.data), "utf-8");
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return node_buffer_1.Buffer.from(this.data, "utf-8");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
122
148
|
}
|
|
123
149
|
exports.OINOHttpRequest = OINOHttpRequest;
|
package/dist/cjs/OINOResult.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
148
|
+
headers.set('X-OINO-MESSAGE-' + j, message);
|
|
149
149
|
j++;
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -166,6 +166,8 @@ class OINOHttpResult extends OINOResult {
|
|
|
166
166
|
_etag;
|
|
167
167
|
/** HTTP body data */
|
|
168
168
|
body;
|
|
169
|
+
/** HTTP headers */
|
|
170
|
+
headers;
|
|
169
171
|
/** HTTP cache expiration value
|
|
170
172
|
* Note: default 0 means no expiration and 'Pragma: no-cache' is set.
|
|
171
173
|
*/
|
|
@@ -181,6 +183,7 @@ class OINOHttpResult extends OINOResult {
|
|
|
181
183
|
constructor(init) {
|
|
182
184
|
super(init);
|
|
183
185
|
this.body = init?.body ?? "";
|
|
186
|
+
this.headers = new _1.OINOHeaders(init?.headers);
|
|
184
187
|
this.expires = init?.expires ?? 0;
|
|
185
188
|
this.lastModified = init?.lastModified ?? 0;
|
|
186
189
|
this._etag = "";
|
|
@@ -201,14 +204,18 @@ class OINOHttpResult extends OINOResult {
|
|
|
201
204
|
*
|
|
202
205
|
* @param headers HTTP headers (overrides existing values)
|
|
203
206
|
*/
|
|
204
|
-
|
|
205
|
-
const
|
|
207
|
+
getFetchResponse(headers) {
|
|
208
|
+
const merged_headers = new _1.OINOHeaders(this.headers);
|
|
209
|
+
if (headers) {
|
|
210
|
+
merged_headers.setHeaders(headers);
|
|
211
|
+
}
|
|
212
|
+
const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
|
|
206
213
|
result.headers.set('Content-Length', this.body.length.toString());
|
|
207
|
-
if (this.lastModified > 0) {
|
|
214
|
+
if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
|
|
208
215
|
result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString());
|
|
209
216
|
}
|
|
210
|
-
if (this.expires >= 0) {
|
|
211
|
-
result.headers.set('Expires', Math.round(this.expires).
|
|
217
|
+
if (merged_headers['Expires'] === undefined && this.expires >= 0) {
|
|
218
|
+
result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString());
|
|
212
219
|
if (this.expires == 0) {
|
|
213
220
|
result.headers.set('Pragma', 'no-cache');
|
|
214
221
|
}
|
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
|
+
}
|
package/dist/esm/OINORequest.js
CHANGED
|
@@ -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 {
|
|
7
|
-
import { OINO_REQUEST_TYPE_PARAM, OINO_RESPONSE_TYPE_PARAM } from "
|
|
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.
|
|
@@ -22,14 +22,6 @@ export class OINORequest {
|
|
|
22
22
|
constructor(init) {
|
|
23
23
|
this.params = init?.params ?? {};
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Copy values from different result.
|
|
27
|
-
*
|
|
28
|
-
* @param request source value
|
|
29
|
-
*/
|
|
30
|
-
copy(request) {
|
|
31
|
-
this.params = { ...request.params };
|
|
32
|
-
}
|
|
33
25
|
}
|
|
34
26
|
/**
|
|
35
27
|
* Specialized result for HTTP responses.
|
|
@@ -54,7 +46,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
54
46
|
super(init);
|
|
55
47
|
this.url = init.url;
|
|
56
48
|
this.method = init.method ?? "GET";
|
|
57
|
-
this.headers = init.headers
|
|
49
|
+
this.headers = new OINOHeaders(init.headers);
|
|
58
50
|
this.data = init.data ?? "";
|
|
59
51
|
this.multipartBoundary = "";
|
|
60
52
|
this.lastModified = init.lastModified;
|
|
@@ -65,7 +57,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
65
57
|
this.requestType = init.requestType;
|
|
66
58
|
}
|
|
67
59
|
else {
|
|
68
|
-
const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers
|
|
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
|
|
69
61
|
if (request_type_param == OINOContentType.csv) {
|
|
70
62
|
this.requestType = OINOContentType.csv;
|
|
71
63
|
}
|
|
@@ -86,7 +78,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
86
78
|
this.responseType = init.responseType;
|
|
87
79
|
}
|
|
88
80
|
else {
|
|
89
|
-
const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers
|
|
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
|
|
90
82
|
const accept_types = response_type_param?.split(', ') || [];
|
|
91
83
|
let response_type = undefined;
|
|
92
84
|
for (let i = 0; i < accept_types.length; i++) {
|
|
@@ -97,16 +89,16 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
97
89
|
}
|
|
98
90
|
this.responseType = response_type ?? OINOContentType.json;
|
|
99
91
|
}
|
|
100
|
-
const last_modified = this.headers
|
|
92
|
+
const last_modified = this.headers.get("if-modified-since");
|
|
101
93
|
if (last_modified) {
|
|
102
94
|
this.lastModified = new Date(last_modified).getTime();
|
|
103
95
|
}
|
|
104
|
-
const etags = this.headers
|
|
96
|
+
const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim());
|
|
105
97
|
if (etags) {
|
|
106
98
|
this.etags = etags;
|
|
107
99
|
}
|
|
108
100
|
}
|
|
109
|
-
static async
|
|
101
|
+
static async fromFetchRequest(request) {
|
|
110
102
|
const body = await request.arrayBuffer();
|
|
111
103
|
return new OINOHttpRequest({
|
|
112
104
|
url: new URL(request.url),
|
|
@@ -115,4 +107,38 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
115
107
|
data: Buffer.from(body),
|
|
116
108
|
});
|
|
117
109
|
}
|
|
110
|
+
dataAsText() {
|
|
111
|
+
if (this.data instanceof Uint8Array) {
|
|
112
|
+
return new TextDecoder().decode(this.data);
|
|
113
|
+
}
|
|
114
|
+
else if (this.data instanceof Object) {
|
|
115
|
+
return JSON.stringify(this.data);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
return this.data?.toString() || "";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
dataAsParsedJson() {
|
|
122
|
+
return this.data ? JSON.parse(this.dataAsText()) : {};
|
|
123
|
+
}
|
|
124
|
+
dataAsFormData() {
|
|
125
|
+
return new URLSearchParams(this.dataAsText() || "");
|
|
126
|
+
}
|
|
127
|
+
dataAsBuffer() {
|
|
128
|
+
if (this.data === null) {
|
|
129
|
+
return Buffer.alloc(0);
|
|
130
|
+
}
|
|
131
|
+
else if (this.data instanceof Buffer) {
|
|
132
|
+
return this.data;
|
|
133
|
+
}
|
|
134
|
+
else if (this.data instanceof Uint8Array) {
|
|
135
|
+
return Buffer.from(this.data);
|
|
136
|
+
}
|
|
137
|
+
else if (this.data instanceof Object) {
|
|
138
|
+
return Buffer.from(JSON.stringify(this.data), "utf-8");
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return Buffer.from(this.data, "utf-8");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
118
144
|
}
|
package/dist/esm/OINOResult.js
CHANGED
|
@@ -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.
|
|
133
|
+
headers.set('X-OINO-MESSAGE-' + j, message);
|
|
134
134
|
j++;
|
|
135
135
|
}
|
|
136
136
|
if (copyWarnings && message.startsWith(OINO_WARNING_PREFIX)) {
|
|
137
|
-
headers.
|
|
137
|
+
headers.set('X-OINO-MESSAGE-' + j, message);
|
|
138
138
|
j++;
|
|
139
139
|
}
|
|
140
140
|
if (copyInfos && message.startsWith(OINO_INFO_PREFIX)) {
|
|
141
|
-
headers.
|
|
141
|
+
headers.set('X-OINO-MESSAGE-' + j, message);
|
|
142
142
|
j++;
|
|
143
143
|
}
|
|
144
144
|
if (copyDebug && message.startsWith(OINO_DEBUG_PREFIX)) {
|
|
145
|
-
headers.
|
|
145
|
+
headers.set('X-OINO-MESSAGE-' + j, message);
|
|
146
146
|
j++;
|
|
147
147
|
}
|
|
148
148
|
}
|
|
@@ -162,6 +162,8 @@ export class OINOHttpResult extends OINOResult {
|
|
|
162
162
|
_etag;
|
|
163
163
|
/** HTTP body data */
|
|
164
164
|
body;
|
|
165
|
+
/** HTTP headers */
|
|
166
|
+
headers;
|
|
165
167
|
/** HTTP cache expiration value
|
|
166
168
|
* Note: default 0 means no expiration and 'Pragma: no-cache' is set.
|
|
167
169
|
*/
|
|
@@ -177,6 +179,7 @@ export class OINOHttpResult extends OINOResult {
|
|
|
177
179
|
constructor(init) {
|
|
178
180
|
super(init);
|
|
179
181
|
this.body = init?.body ?? "";
|
|
182
|
+
this.headers = new OINOHeaders(init?.headers);
|
|
180
183
|
this.expires = init?.expires ?? 0;
|
|
181
184
|
this.lastModified = init?.lastModified ?? 0;
|
|
182
185
|
this._etag = "";
|
|
@@ -197,14 +200,18 @@ export class OINOHttpResult extends OINOResult {
|
|
|
197
200
|
*
|
|
198
201
|
* @param headers HTTP headers (overrides existing values)
|
|
199
202
|
*/
|
|
200
|
-
|
|
201
|
-
const
|
|
203
|
+
getFetchResponse(headers) {
|
|
204
|
+
const merged_headers = new OINOHeaders(this.headers);
|
|
205
|
+
if (headers) {
|
|
206
|
+
merged_headers.setHeaders(headers);
|
|
207
|
+
}
|
|
208
|
+
const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
|
|
202
209
|
result.headers.set('Content-Length', this.body.length.toString());
|
|
203
|
-
if (this.lastModified > 0) {
|
|
210
|
+
if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
|
|
204
211
|
result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString());
|
|
205
212
|
}
|
|
206
|
-
if (this.expires >= 0) {
|
|
207
|
-
result.headers.set('Expires', Math.round(this.expires).
|
|
213
|
+
if (merged_headers['Expires'] === undefined && this.expires >= 0) {
|
|
214
|
+
result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString());
|
|
208
215
|
if (this.expires == 0) {
|
|
209
216
|
result.headers.set('Pragma', 'no-cache');
|
|
210
217
|
}
|
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 {
|
|
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
|
}
|
|
@@ -17,17 +18,11 @@ export declare class OINORequest {
|
|
|
17
18
|
*
|
|
18
19
|
*/
|
|
19
20
|
constructor(init?: OINORequestInit);
|
|
20
|
-
/**
|
|
21
|
-
* Copy values from different result.
|
|
22
|
-
*
|
|
23
|
-
* @param request source value
|
|
24
|
-
*/
|
|
25
|
-
copy(request: OINORequest): void;
|
|
26
21
|
}
|
|
27
22
|
export interface OINOHttpRequestInit extends OINORequestInit {
|
|
28
23
|
url?: URL;
|
|
29
24
|
method?: string;
|
|
30
|
-
headers?:
|
|
25
|
+
headers?: OINOHeadersInit;
|
|
31
26
|
data?: string | Buffer | Uint8Array | object | null;
|
|
32
27
|
requestType?: OINOContentType;
|
|
33
28
|
responseType?: OINOContentType;
|
|
@@ -40,7 +35,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
|
|
|
40
35
|
export declare class OINOHttpRequest extends OINORequest {
|
|
41
36
|
readonly url?: URL;
|
|
42
37
|
readonly method: string;
|
|
43
|
-
readonly headers:
|
|
38
|
+
readonly headers: OINOHeaders;
|
|
44
39
|
readonly data: string | Buffer | Uint8Array | object | null;
|
|
45
40
|
readonly requestType: OINOContentType;
|
|
46
41
|
readonly responseType: OINOContentType;
|
|
@@ -54,5 +49,9 @@ export declare class OINOHttpRequest extends OINORequest {
|
|
|
54
49
|
*
|
|
55
50
|
*/
|
|
56
51
|
constructor(init: OINOHttpRequestInit);
|
|
57
|
-
static
|
|
52
|
+
static fromFetchRequest(request: Request): Promise<OINOHttpRequest>;
|
|
53
|
+
dataAsText(): string;
|
|
54
|
+
dataAsParsedJson(): any;
|
|
55
|
+
dataAsFormData(): URLSearchParams;
|
|
56
|
+
dataAsBuffer(): Buffer;
|
|
58
57
|
}
|
|
@@ -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:
|
|
83
|
+
copyMessagesToHeaders(headers: OINOHeaders, copyErrors?: boolean, copyWarnings?: boolean, copyInfos?: boolean, copyDebug?: boolean): void;
|
|
83
84
|
/**
|
|
84
85
|
* Print result for logging.
|
|
85
86
|
*
|
|
@@ -88,6 +89,7 @@ export declare class OINOResult {
|
|
|
88
89
|
}
|
|
89
90
|
export interface OINOHttpResultInit extends OINOResultInit {
|
|
90
91
|
body?: string;
|
|
92
|
+
headers?: OINOHeadersInit;
|
|
91
93
|
expires?: number;
|
|
92
94
|
lastModified?: number;
|
|
93
95
|
}
|
|
@@ -98,6 +100,8 @@ export declare class OINOHttpResult extends OINOResult {
|
|
|
98
100
|
private _etag;
|
|
99
101
|
/** HTTP body data */
|
|
100
102
|
readonly body: string;
|
|
103
|
+
/** HTTP headers */
|
|
104
|
+
readonly headers: OINOHeaders;
|
|
101
105
|
/** HTTP cache expiration value
|
|
102
106
|
* Note: default 0 means no expiration and 'Pragma: no-cache' is set.
|
|
103
107
|
*/
|
|
@@ -121,5 +125,5 @@ export declare class OINOHttpResult extends OINOResult {
|
|
|
121
125
|
*
|
|
122
126
|
* @param headers HTTP headers (overrides existing values)
|
|
123
127
|
*/
|
|
124
|
-
|
|
128
|
+
getFetchResponse(headers?: OINOHeadersInit): Response;
|
|
125
129
|
}
|
package/dist/types/index.d.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
|
/** 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
|
+
"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.
|
|
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
|
+
}
|
package/src/OINORequest.ts
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
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>
|
|
@@ -29,21 +30,12 @@ export class OINORequest {
|
|
|
29
30
|
constructor (init?: OINORequestInit) {
|
|
30
31
|
this.params = init?.params ?? {}
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Copy values from different result.
|
|
35
|
-
*
|
|
36
|
-
* @param request source value
|
|
37
|
-
*/
|
|
38
|
-
copy(request: OINORequest) {
|
|
39
|
-
this.params = {...request.params}
|
|
40
|
-
}
|
|
41
33
|
}
|
|
42
34
|
|
|
43
35
|
export interface OINOHttpRequestInit extends OINORequestInit {
|
|
44
36
|
url?: URL
|
|
45
37
|
method?: string
|
|
46
|
-
headers?:
|
|
38
|
+
headers?: OINOHeadersInit
|
|
47
39
|
data?: string|Buffer|Uint8Array|object|null
|
|
48
40
|
requestType?:OINOContentType
|
|
49
41
|
responseType?:OINOContentType
|
|
@@ -57,7 +49,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
|
|
|
57
49
|
export class OINOHttpRequest extends OINORequest {
|
|
58
50
|
readonly url?: URL
|
|
59
51
|
readonly method: string
|
|
60
|
-
readonly headers:
|
|
52
|
+
readonly headers: OINOHeaders
|
|
61
53
|
readonly data: string|Buffer|Uint8Array|object|null
|
|
62
54
|
readonly requestType:OINOContentType
|
|
63
55
|
readonly responseType:OINOContentType
|
|
@@ -75,7 +67,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
75
67
|
super(init)
|
|
76
68
|
this.url = init.url
|
|
77
69
|
this.method = init.method ?? "GET"
|
|
78
|
-
this.headers = init.headers
|
|
70
|
+
this.headers = new OINOHeaders(init.headers)
|
|
79
71
|
this.data = init.data ?? ""
|
|
80
72
|
this.multipartBoundary = ""
|
|
81
73
|
this.lastModified = init.lastModified
|
|
@@ -86,7 +78,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
86
78
|
if (init.requestType) {
|
|
87
79
|
this.requestType = init.requestType
|
|
88
80
|
} else {
|
|
89
|
-
const request_type_param = this.url?.searchParams.get(OINO_REQUEST_TYPE_PARAM) || this.headers
|
|
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
|
|
90
82
|
if (request_type_param == OINOContentType.csv) {
|
|
91
83
|
this.requestType = OINOContentType.csv
|
|
92
84
|
|
|
@@ -105,7 +97,7 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
105
97
|
if (init.responseType) {
|
|
106
98
|
this.responseType = init.responseType
|
|
107
99
|
} else {
|
|
108
|
-
const response_type_param = this.url?.searchParams.get(OINO_RESPONSE_TYPE_PARAM) || this.headers
|
|
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
|
|
109
101
|
const accept_types = response_type_param?.split(', ') || []
|
|
110
102
|
let response_type:OINOContentType|undefined = undefined
|
|
111
103
|
for (let i=0; i<accept_types.length; i++) {
|
|
@@ -116,17 +108,17 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
116
108
|
}
|
|
117
109
|
this.responseType = response_type ?? OINOContentType.json
|
|
118
110
|
}
|
|
119
|
-
const last_modified = this.headers
|
|
111
|
+
const last_modified = this.headers.get("if-modified-since")
|
|
120
112
|
if (last_modified) {
|
|
121
113
|
this.lastModified = new Date(last_modified).getTime()
|
|
122
114
|
}
|
|
123
|
-
const etags = this.headers
|
|
115
|
+
const etags = this.headers.get("if-none-match")?.split(',').map(e => e.trim())
|
|
124
116
|
if (etags) {
|
|
125
117
|
this.etags = etags
|
|
126
118
|
}
|
|
127
119
|
}
|
|
128
120
|
|
|
129
|
-
static async
|
|
121
|
+
static async fromFetchRequest(request: Request): Promise<OINOHttpRequest> {
|
|
130
122
|
const body = await request.arrayBuffer()
|
|
131
123
|
return new OINOHttpRequest({
|
|
132
124
|
url: new URL(request.url),
|
|
@@ -136,4 +128,42 @@ export class OINOHttpRequest extends OINORequest {
|
|
|
136
128
|
})
|
|
137
129
|
}
|
|
138
130
|
|
|
131
|
+
dataAsText(): string {
|
|
132
|
+
if (this.data instanceof Uint8Array) {
|
|
133
|
+
return new TextDecoder().decode(this.data)
|
|
134
|
+
|
|
135
|
+
} else if (this.data instanceof Object) {
|
|
136
|
+
return JSON.stringify(this.data)
|
|
137
|
+
|
|
138
|
+
} else {
|
|
139
|
+
return this.data?.toString() || ""
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
dataAsParsedJson(): any {
|
|
144
|
+
return this.data ? JSON.parse(this.dataAsText()) : {}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
dataAsFormData(): URLSearchParams {
|
|
148
|
+
return new URLSearchParams(this.dataAsText() || "")
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
dataAsBuffer(): Buffer {
|
|
152
|
+
if (this.data === null) {
|
|
153
|
+
return Buffer.alloc(0)
|
|
154
|
+
|
|
155
|
+
} else if (this.data instanceof Buffer) {
|
|
156
|
+
return this.data
|
|
157
|
+
|
|
158
|
+
} else if (this.data instanceof Uint8Array) {
|
|
159
|
+
return Buffer.from(this.data)
|
|
160
|
+
|
|
161
|
+
} else if (this.data instanceof Object) {
|
|
162
|
+
return Buffer.from(JSON.stringify(this.data), "utf-8")
|
|
163
|
+
|
|
164
|
+
} else {
|
|
165
|
+
return Buffer.from(this.data, "utf-8")
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
139
169
|
}
|
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:
|
|
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.
|
|
152
|
+
headers.set('X-OINO-MESSAGE-'+j, message)
|
|
153
153
|
j++
|
|
154
154
|
}
|
|
155
155
|
if (copyWarnings && message.startsWith(OINO_WARNING_PREFIX)) {
|
|
156
|
-
headers.
|
|
156
|
+
headers.set('X-OINO-MESSAGE-'+j, message)
|
|
157
157
|
j++
|
|
158
158
|
}
|
|
159
159
|
if (copyInfos && message.startsWith(OINO_INFO_PREFIX)) {
|
|
160
|
-
headers.
|
|
160
|
+
headers.set('X-OINO-MESSAGE-'+j, message)
|
|
161
161
|
j++
|
|
162
162
|
}
|
|
163
163
|
if (copyDebug && message.startsWith(OINO_DEBUG_PREFIX)) {
|
|
164
|
-
headers.
|
|
164
|
+
headers.set('X-OINO-MESSAGE-'+j, message)
|
|
165
165
|
j++
|
|
166
166
|
}
|
|
167
167
|
}
|
|
@@ -178,6 +178,7 @@ export class OINOResult {
|
|
|
178
178
|
|
|
179
179
|
export interface OINOHttpResultInit extends OINOResultInit {
|
|
180
180
|
body?: string
|
|
181
|
+
headers?: OINOHeadersInit
|
|
181
182
|
expires?: number
|
|
182
183
|
lastModified?: number
|
|
183
184
|
}
|
|
@@ -190,6 +191,9 @@ export class OINOHttpResult extends OINOResult {
|
|
|
190
191
|
|
|
191
192
|
/** HTTP body data */
|
|
192
193
|
readonly body: string
|
|
194
|
+
|
|
195
|
+
/** HTTP headers */
|
|
196
|
+
readonly headers: OINOHeaders
|
|
193
197
|
|
|
194
198
|
/** HTTP cache expiration value
|
|
195
199
|
* Note: default 0 means no expiration and 'Pragma: no-cache' is set.
|
|
@@ -208,6 +212,7 @@ export class OINOHttpResult extends OINOResult {
|
|
|
208
212
|
constructor(init?: OINOHttpResultInit) {
|
|
209
213
|
super(init)
|
|
210
214
|
this.body = init?.body ?? ""
|
|
215
|
+
this.headers = new OINOHeaders(init?.headers)
|
|
211
216
|
this.expires = init?.expires ?? 0
|
|
212
217
|
this.lastModified = init?.lastModified ?? 0
|
|
213
218
|
this._etag = ""
|
|
@@ -230,14 +235,18 @@ export class OINOHttpResult extends OINOResult {
|
|
|
230
235
|
*
|
|
231
236
|
* @param headers HTTP headers (overrides existing values)
|
|
232
237
|
*/
|
|
233
|
-
|
|
234
|
-
const
|
|
238
|
+
getFetchResponse(headers?:OINOHeadersInit):Response {
|
|
239
|
+
const merged_headers = new OINOHeaders(this.headers)
|
|
240
|
+
if (headers) {
|
|
241
|
+
merged_headers.setHeaders(headers)
|
|
242
|
+
}
|
|
243
|
+
const result: Response = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers })
|
|
235
244
|
result.headers.set('Content-Length', this.body.length.toString())
|
|
236
|
-
if (this.lastModified > 0) {
|
|
245
|
+
if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
|
|
237
246
|
result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString())
|
|
238
247
|
}
|
|
239
|
-
if (this.expires >= 0) {
|
|
240
|
-
result.headers.set('Expires', Math.round(this.expires).
|
|
248
|
+
if (merged_headers['Expires'] === undefined && this.expires >= 0) {
|
|
249
|
+
result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString())
|
|
241
250
|
if (this.expires == 0) {
|
|
242
251
|
result.headers.set('Pragma', 'no-cache')
|
|
243
252
|
}
|
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"
|