@oino-ts/common 0.17.2 → 0.17.3

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.
@@ -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,18 @@ 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
+ 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
+ }
62
65
  this.data = init.data ?? "";
63
66
  this.multipartBoundary = "";
64
67
  this.lastModified = init.lastModified;
@@ -110,7 +113,7 @@ class OINOHttpRequest extends OINORequest {
110
113
  this.etags = etags;
111
114
  }
112
115
  }
113
- static async fromRequest(request) {
116
+ static async fromFetchRequest(request) {
114
117
  const body = await request.arrayBuffer();
115
118
  return new OINOHttpRequest({
116
119
  url: new URL(request.url),
@@ -119,5 +122,39 @@ class OINOHttpRequest extends OINORequest {
119
122
  data: Buffer.from(body),
120
123
  });
121
124
  }
125
+ dataAsText() {
126
+ if (this.data instanceof Uint8Array) {
127
+ return new TextDecoder().decode(this.data);
128
+ }
129
+ else if (this.data instanceof Object) {
130
+ return JSON.stringify(this.data);
131
+ }
132
+ else {
133
+ return this.data?.toString() || "";
134
+ }
135
+ }
136
+ dataAsParsedJson() {
137
+ return this.data ? JSON.parse(this.dataAsText()) : {};
138
+ }
139
+ dataAsFormData() {
140
+ return new URLSearchParams(this.dataAsText() || "");
141
+ }
142
+ dataAsBuffer() {
143
+ if (this.data === null) {
144
+ return Buffer.alloc(0);
145
+ }
146
+ else if (this.data instanceof Buffer) {
147
+ return this.data;
148
+ }
149
+ else if (this.data instanceof Uint8Array) {
150
+ return Buffer.from(this.data);
151
+ }
152
+ else if (this.data instanceof Object) {
153
+ return Buffer.from(JSON.stringify(this.data), "utf-8");
154
+ }
155
+ else {
156
+ return Buffer.from(this.data, "utf-8");
157
+ }
158
+ }
122
159
  }
123
160
  exports.OINOHttpRequest = OINOHttpRequest;
@@ -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 = init?.headers ?? {};
184
187
  this.expires = init?.expires ?? 0;
185
188
  this.lastModified = init?.lastModified ?? 0;
186
189
  this._etag = "";
@@ -201,14 +204,15 @@ class OINOHttpResult extends OINOResult {
201
204
  *
202
205
  * @param headers HTTP headers (overrides existing values)
203
206
  */
204
- getHttpResponse(headers) {
205
- const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: headers });
207
+ getFetchResponse(headers) {
208
+ const merged_headers = { ...this.headers, ...headers };
209
+ const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
206
210
  result.headers.set('Content-Length', this.body.length.toString());
207
- if (this.lastModified > 0) {
211
+ if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
208
212
  result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString());
209
213
  }
210
- if (this.expires >= 0) {
211
- result.headers.set('Expires', Math.round(this.expires).toString());
214
+ if (merged_headers['Expires'] === undefined && this.expires >= 0) {
215
+ result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString());
212
216
  if (this.expires == 0) {
213
217
  result.headers.set('Pragma', 'no-cache');
214
218
  }
@@ -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,18 @@ 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
+ 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
+ }
58
61
  this.data = init.data ?? "";
59
62
  this.multipartBoundary = "";
60
63
  this.lastModified = init.lastModified;
@@ -106,7 +109,7 @@ export class OINOHttpRequest extends OINORequest {
106
109
  this.etags = etags;
107
110
  }
108
111
  }
109
- static async fromRequest(request) {
112
+ static async fromFetchRequest(request) {
110
113
  const body = await request.arrayBuffer();
111
114
  return new OINOHttpRequest({
112
115
  url: new URL(request.url),
@@ -115,4 +118,38 @@ export class OINOHttpRequest extends OINORequest {
115
118
  data: Buffer.from(body),
116
119
  });
117
120
  }
121
+ dataAsText() {
122
+ if (this.data instanceof Uint8Array) {
123
+ return new TextDecoder().decode(this.data);
124
+ }
125
+ else if (this.data instanceof Object) {
126
+ return JSON.stringify(this.data);
127
+ }
128
+ else {
129
+ return this.data?.toString() || "";
130
+ }
131
+ }
132
+ dataAsParsedJson() {
133
+ return this.data ? JSON.parse(this.dataAsText()) : {};
134
+ }
135
+ dataAsFormData() {
136
+ return new URLSearchParams(this.dataAsText() || "");
137
+ }
138
+ dataAsBuffer() {
139
+ if (this.data === null) {
140
+ return Buffer.alloc(0);
141
+ }
142
+ else if (this.data instanceof Buffer) {
143
+ return this.data;
144
+ }
145
+ else if (this.data instanceof Uint8Array) {
146
+ return Buffer.from(this.data);
147
+ }
148
+ else if (this.data instanceof Object) {
149
+ return Buffer.from(JSON.stringify(this.data), "utf-8");
150
+ }
151
+ else {
152
+ return Buffer.from(this.data, "utf-8");
153
+ }
154
+ }
118
155
  }
@@ -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 = init?.headers ?? {};
180
183
  this.expires = init?.expires ?? 0;
181
184
  this.lastModified = init?.lastModified ?? 0;
182
185
  this._etag = "";
@@ -197,14 +200,15 @@ export class OINOHttpResult extends OINOResult {
197
200
  *
198
201
  * @param headers HTTP headers (overrides existing values)
199
202
  */
200
- getHttpResponse(headers) {
201
- const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: headers });
203
+ getFetchResponse(headers) {
204
+ const merged_headers = { ...this.headers, ...headers };
205
+ const result = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers });
202
206
  result.headers.set('Content-Length', this.body.length.toString());
203
- if (this.lastModified > 0) {
207
+ if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
204
208
  result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString());
205
209
  }
206
- if (this.expires >= 0) {
207
- result.headers.set('Expires', Math.round(this.expires).toString());
210
+ if (merged_headers['Expires'] === undefined && this.expires >= 0) {
211
+ result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString());
208
212
  if (this.expires == 0) {
209
213
  result.headers.set('Pragma', 'no-cache');
210
214
  }
@@ -17,17 +17,16 @@ export declare class OINORequest {
17
17
  *
18
18
  */
19
19
  constructor(init?: OINORequestInit);
20
- /**
21
- * Copy values from different result.
22
- *
23
- * @param request source value
24
- */
25
- copy(request: OINORequest): void;
26
20
  }
21
+ /**
22
+ * Type for HTTP headers that just guarantees keys are normalized to lowercase.
23
+ *
24
+ */
25
+ export type OINOHttpHeaders = Record<string, string>;
27
26
  export interface OINOHttpRequestInit extends OINORequestInit {
28
27
  url?: URL;
29
28
  method?: string;
30
- headers?: Record<string, string>;
29
+ headers?: OINOHttpHeaders | Record<string, string>;
31
30
  data?: string | Buffer | Uint8Array | object | null;
32
31
  requestType?: OINOContentType;
33
32
  responseType?: OINOContentType;
@@ -40,7 +39,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
40
39
  export declare class OINOHttpRequest extends OINORequest {
41
40
  readonly url?: URL;
42
41
  readonly method: string;
43
- readonly headers: Record<string, string>;
42
+ readonly headers: OINOHttpHeaders;
44
43
  readonly data: string | Buffer | Uint8Array | object | null;
45
44
  readonly requestType: OINOContentType;
46
45
  readonly responseType: OINOContentType;
@@ -54,5 +53,9 @@ export declare class OINOHttpRequest extends OINORequest {
54
53
  *
55
54
  */
56
55
  constructor(init: OINOHttpRequestInit);
57
- static fromRequest(request: Request): Promise<OINOHttpRequest>;
56
+ static fromFetchRequest(request: Request): Promise<OINOHttpRequest>;
57
+ dataAsText(): string;
58
+ dataAsParsedJson(): any;
59
+ dataAsFormData(): URLSearchParams;
60
+ dataAsBuffer(): Buffer;
58
61
  }
@@ -88,6 +88,7 @@ export declare class OINOResult {
88
88
  }
89
89
  export interface OINOHttpResultInit extends OINOResultInit {
90
90
  body?: string;
91
+ headers?: Record<string, string>;
91
92
  expires?: number;
92
93
  lastModified?: number;
93
94
  }
@@ -98,6 +99,8 @@ export declare class OINOHttpResult extends OINOResult {
98
99
  private _etag;
99
100
  /** HTTP body data */
100
101
  readonly body: string;
102
+ /** HTTP headers */
103
+ readonly headers?: Record<string, string>;
101
104
  /** HTTP cache expiration value
102
105
  * Note: default 0 means no expiration and 'Pragma: no-cache' is set.
103
106
  */
@@ -121,5 +124,5 @@ export declare class OINOHttpResult extends OINOResult {
121
124
  *
122
125
  * @param headers HTTP headers (overrides existing values)
123
126
  */
124
- getHttpResponse(headers?: Record<string, string>): Response;
127
+ getFetchResponse(headers?: Record<string, string>): Response;
125
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oino-ts/common",
3
- "version": "0.17.2",
3
+ "version": "0.17.3",
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.2",
22
+ "@oino-ts/types": "0.17.3",
23
23
  "@types/node": "^22.0.0",
24
24
  "typescript": "~5.9.0"
25
25
  },
@@ -29,21 +29,18 @@ export class OINORequest {
29
29
  constructor (init?: OINORequestInit) {
30
30
  this.params = init?.params ?? {}
31
31
  }
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
32
  }
42
33
 
34
+ /**
35
+ * Type for HTTP headers that just guarantees keys are normalized to lowercase.
36
+ *
37
+ */
38
+ export type OINOHttpHeaders = Record<string, string>
39
+
43
40
  export interface OINOHttpRequestInit extends OINORequestInit {
44
41
  url?: URL
45
42
  method?: string
46
- headers?: Record<string, string>
43
+ headers?: OINOHttpHeaders|Record<string, string>
47
44
  data?: string|Buffer|Uint8Array|object|null
48
45
  requestType?:OINOContentType
49
46
  responseType?:OINOContentType
@@ -57,7 +54,7 @@ export interface OINOHttpRequestInit extends OINORequestInit {
57
54
  export class OINOHttpRequest extends OINORequest {
58
55
  readonly url?: URL
59
56
  readonly method: string
60
- readonly headers: Record<string, string>
57
+ readonly headers: OINOHttpHeaders
61
58
  readonly data: string|Buffer|Uint8Array|object|null
62
59
  readonly requestType:OINOContentType
63
60
  readonly responseType:OINOContentType
@@ -75,7 +72,18 @@ export class OINOHttpRequest extends OINORequest {
75
72
  super(init)
76
73
  this.url = init.url
77
74
  this.method = init.method ?? "GET"
78
- this.headers = init.headers ?? {}
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
+
79
87
  this.data = init.data ?? ""
80
88
  this.multipartBoundary = ""
81
89
  this.lastModified = init.lastModified
@@ -126,7 +134,7 @@ export class OINOHttpRequest extends OINORequest {
126
134
  }
127
135
  }
128
136
 
129
- static async fromRequest(request: Request): Promise<OINOHttpRequest> {
137
+ static async fromFetchRequest(request: Request): Promise<OINOHttpRequest> {
130
138
  const body = await request.arrayBuffer()
131
139
  return new OINOHttpRequest({
132
140
  url: new URL(request.url),
@@ -136,4 +144,42 @@ export class OINOHttpRequest extends OINORequest {
136
144
  })
137
145
  }
138
146
 
147
+ dataAsText(): string {
148
+ if (this.data instanceof Uint8Array) {
149
+ return new TextDecoder().decode(this.data)
150
+
151
+ } else if (this.data instanceof Object) {
152
+ return JSON.stringify(this.data)
153
+
154
+ } else {
155
+ return this.data?.toString() || ""
156
+ }
157
+ }
158
+
159
+ dataAsParsedJson(): any {
160
+ return this.data ? JSON.parse(this.dataAsText()) : {}
161
+ }
162
+
163
+ dataAsFormData(): URLSearchParams {
164
+ return new URLSearchParams(this.dataAsText() || "")
165
+ }
166
+
167
+ dataAsBuffer(): Buffer {
168
+ if (this.data === null) {
169
+ return Buffer.alloc(0)
170
+
171
+ } else if (this.data instanceof Buffer) {
172
+ return this.data
173
+
174
+ } else if (this.data instanceof Uint8Array) {
175
+ return Buffer.from(this.data)
176
+
177
+ } else if (this.data instanceof Object) {
178
+ return Buffer.from(JSON.stringify(this.data), "utf-8")
179
+
180
+ } else {
181
+ return Buffer.from(this.data, "utf-8")
182
+ }
183
+ }
184
+
139
185
  }
package/src/OINOResult.ts CHANGED
@@ -178,6 +178,7 @@ export class OINOResult {
178
178
 
179
179
  export interface OINOHttpResultInit extends OINOResultInit {
180
180
  body?: string
181
+ headers?: Record<string, string>
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?: Record<string, string>
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 = init?.headers ?? {}
211
216
  this.expires = init?.expires ?? 0
212
217
  this.lastModified = init?.lastModified ?? 0
213
218
  this._etag = ""
@@ -230,14 +235,15 @@ export class OINOHttpResult extends OINOResult {
230
235
  *
231
236
  * @param headers HTTP headers (overrides existing values)
232
237
  */
233
- getHttpResponse(headers?:Record<string, string>):Response {
234
- const result:Response = new Response(this.body, {status:this.status, statusText: this.statusText, headers: headers})
238
+ getFetchResponse(headers?:Record<string, string>):Response {
239
+ const merged_headers = { ...this.headers, ...headers }
240
+ const result: Response = new Response(this.body, { status: this.status, statusText: this.statusText, headers: merged_headers })
235
241
  result.headers.set('Content-Length', this.body.length.toString())
236
- if (this.lastModified > 0) {
242
+ if (merged_headers['Last-Modified'] === undefined && this.lastModified > 0) {
237
243
  result.headers.set('Last-Modified', new Date(this.lastModified).toUTCString())
238
244
  }
239
- if (this.expires >= 0) {
240
- result.headers.set('Expires', Math.round(this.expires).toString())
245
+ if (merged_headers['Expires'] === undefined && this.expires >= 0) {
246
+ result.headers.set('Expires', new Date(Date.now() + Math.round(this.expires)).toUTCString())
241
247
  if (this.expires == 0) {
242
248
  result.headers.set('Pragma', 'no-cache')
243
249
  }