@basenjs/base-http 0.0.1

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,426 @@
1
+ import https from 'node:https';
2
+ import { BaseObject } from '@basenjs/base';
3
+ import http from 'node:http';
4
+ import qs from 'qs';
5
+ import multiparty from 'multiparty';
6
+
7
+ class BaseHttp extends BaseObject {
8
+ constructor() {
9
+ super();
10
+ this.logLevel = 'none';
11
+ }
12
+ static processResponse(response) {
13
+ return new Promise((resolve, reject) => {
14
+ // if(res.statusCode == '302') { // redirect
15
+ // if('location' in res.headers) {
16
+ // _.statusCode = 302;
17
+ // _.setHeader('Location', res.headers['location']);
18
+ // }
19
+ // }
20
+ });
21
+ }
22
+ static buildOptions(options) {
23
+ let headers = options.headers || {}, r = {
24
+ hostname: options.hostname || 'localhost',
25
+ path: options.path || '/',
26
+ port: options.port || (options.protocol === 'https' ? 443 : 80),
27
+ method: options.method || 'GET',
28
+ headers: {
29
+ 'Content-Type': headers['Content-Type'] || 'application/json',
30
+ 'Connection': headers['Connection'] || 'keep-alive',
31
+ 'Accept': headers['Accept'] || '*/*',
32
+ 'Accept-Encoding': headers['Accept-Encoding'] || 'deflate, br, zstd',
33
+ ...headers
34
+ }
35
+ };
36
+ return r;
37
+ }
38
+ static head(options) {
39
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'HEAD' });
40
+ }
41
+ static options(options) {
42
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'OPTIONS' });
43
+ }
44
+ static get(options) {
45
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'GET' });
46
+ }
47
+ static post(options, body) {
48
+ options.headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
49
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'POST' }, body);
50
+ }
51
+ static put(options, body) {
52
+ options.headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
53
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'PUT' }, body);
54
+ }
55
+ static patch(options, body) {
56
+ options.headers['Content-Length'] = body ? Buffer.byteLength(body) : 0;
57
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'PATCH' }, body);
58
+ }
59
+ static delete(options) {
60
+ return BaseHttp.request({ ...BaseHttp.buildOptions(options), method: 'DELETE' });
61
+ }
62
+ static async request(options, body = null, callbacks = { request: () => { }, data: () => { }, end: () => { } }) {
63
+ var buffer = Buffer.alloc(0);
64
+ const req = https.request(options, (res) => {
65
+ console.log('<p>https://' + options.hostname + options.path + '</p>');
66
+ console.log(`<p>STATUS: ${res.statusCode}</p>`);
67
+ console.log(`<p>HEADERS: ${JSON.stringify(res.headers)}</p>`);
68
+ res.setEncoding('utf8');
69
+ callbacks.request(res);
70
+ res.on('data', (chunk) => {
71
+ // this.log.debug(`<p>BODY: ${chunk}</p>`);
72
+ buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
73
+ callbacks.data(buffer);
74
+ });
75
+ res.on('end', () => {
76
+ // this.log.debug('No more data in response.');
77
+ callbacks.end(buffer);
78
+ return buffer;
79
+ });
80
+ });
81
+ req.on('error', (e) => {
82
+ console.log(`problem with request: ${e.message}`);
83
+ console.log(e.stack);
84
+ throw (e);
85
+ });
86
+ if (body && (options.method?.toLowerCase() in ['post', 'put', 'patch'])) {
87
+ req.write(body);
88
+ }
89
+ req.end();
90
+ return req;
91
+ }
92
+ }
93
+
94
+ class BaseHttpBody extends BaseObject {
95
+ _readable;
96
+ _chunks = [];
97
+ _dataWasRead = false;
98
+ _ended = false;
99
+ constructor(readable) {
100
+ super();
101
+ this._readable = readable;
102
+ }
103
+ get readable() {
104
+ return this._readable;
105
+ }
106
+ get dataWasRead() {
107
+ return this._dataWasRead;
108
+ }
109
+ async readAsBuffer() {
110
+ var _ = this;
111
+ return new Promise((resolve, reject) => {
112
+ var applyResolve = function () {
113
+ let readBody = '';
114
+ if (!_.dataWasRead && ('body' in _.readable) && _.readable.body) {
115
+ // body can be an object
116
+ readBody = typeof _.readable.body == 'object' ? JSON.stringify(_.readable.body) : _.readable.body + '';
117
+ _.log.info('BodyReader::readBodyAsBuffer _readable.body: ' + readBody);
118
+ _._chunks.push(Buffer.from(readBody));
119
+ }
120
+ resolve(Buffer.concat(_._chunks));
121
+ };
122
+ this._readable.on("data", (chunk) => {
123
+ _._dataWasRead = true;
124
+ _.log.debug('BodyReader event (data)');
125
+ _._chunks.push(chunk);
126
+ });
127
+ this._readable.on('close', () => {
128
+ _.log.debug('BodyReader event (close):');
129
+ if (!_._ended) {
130
+ applyResolve();
131
+ }
132
+ });
133
+ this._readable.on("end", () => {
134
+ _.log.debug('BodyReader event (end):');
135
+ _._ended = true;
136
+ applyResolve();
137
+ });
138
+ this._readable.on("error", (error) => {
139
+ _.log.error('BodyReader event (error): ' + error.message);
140
+ throw new Error(error.message);
141
+ });
142
+ });
143
+ }
144
+ ;
145
+ }
146
+
147
+ class BaseMultipartData extends BaseObject {
148
+ _form = new multiparty.Form();
149
+ _bodyRaw = Buffer.alloc(0);
150
+ fields = [];
151
+ files = [];
152
+ get form() {
153
+ return this._form;
154
+ }
155
+ get bodyRaw() {
156
+ return this._bodyRaw;
157
+ }
158
+ constructor() {
159
+ super();
160
+ }
161
+ parse(request) {
162
+ return this._parse(request);
163
+ }
164
+ parseRawText(text = '') {
165
+ if (text.length < 1) {
166
+ return;
167
+ }
168
+ }
169
+ _parse(request) {
170
+ var _ = this;
171
+ return new Promise((resolve, reject) => {
172
+ let contentType = request.headers['content-type'] || '', chunks = new Array();
173
+ // Errors may be emitted
174
+ // Note that if you are listening to 'part' events, the same error may be
175
+ // emitted from the `form` and the `part`.
176
+ _.form.on('error', function (err) {
177
+ _.log.debug('initMultipart: Error parsing form: ' + err.stack);
178
+ });
179
+ _.form.on('pipe', function (readable) {
180
+ _.log.debug('initMultipart: pipe ');
181
+ if (readable) {
182
+ readable.on('data', (chunk) => {
183
+ _.log.debug('initMultipart: piped readable: data ');
184
+ _.log.debug('initMultipart: piped readable:' + chunk);
185
+ chunks.push(chunk);
186
+ });
187
+ }
188
+ });
189
+ _.form.on('data', function (chunk) {
190
+ _.log.debug('initMultipart: data ');
191
+ });
192
+ // Parts are emitted when parsing the form
193
+ _.form.on('part', function (part) {
194
+ // You *must* act on the part by reading it
195
+ // NOTE: if you want to ignore it, just call "part.resume()"
196
+ if (part.filename === undefined) {
197
+ // filename is not defined when this is a field and not a file
198
+ _.log.debug('initMultipart: got field named ' + part.name);
199
+ // ignore field's content
200
+ part.resume();
201
+ }
202
+ if (part.filename !== undefined) {
203
+ // filename is defined when this is a file
204
+ // count++;
205
+ _.log.debug('initMultipart: got file named ' + part.name);
206
+ // ignore file's content here
207
+ part.resume();
208
+ }
209
+ part.on('error', function (err) {
210
+ // decide what to do
211
+ });
212
+ });
213
+ // Close emitted after form parsed
214
+ _.form.on('close', function () {
215
+ _.log.debug('initMultipart (requestIn): Upload completed!');
216
+ // res.setHeader('text/plain');
217
+ // res.end('Received ' + count + ' files');
218
+ _._bodyRaw = Buffer.concat(chunks);
219
+ resolve(_.bodyRaw);
220
+ });
221
+ if (contentType.match(/multipart/i) != null) {
222
+ // Parse req
223
+ _.form.parse(request);
224
+ }
225
+ else {
226
+ resolve('');
227
+ }
228
+ });
229
+ }
230
+ }
231
+
232
+ class BaseHttpProxy extends BaseObject {
233
+ requestIn;
234
+ responseOut;
235
+ forwardComplete = false;
236
+ _multipartData = new BaseMultipartData();
237
+ _requestInBodyReader;
238
+ ;
239
+ _responseInBodyReader;
240
+ forwardWaitCount = 0;
241
+ httpRequest = http.request({});
242
+ httpRequestInRawChunks = [];
243
+ httpRequestInRaw = Buffer.alloc(0);
244
+ httpResponseRawChunks = [];
245
+ httpResponseRaw = Buffer.alloc(0);
246
+ httpResponseRawChunksSize = 0;
247
+ WRITEABLE = {
248
+ 'post': 'POST',
249
+ 'patch': 'PATCH',
250
+ 'put': 'PUT'
251
+ };
252
+ HOST = 'ws.anything-2493814af352';
253
+ PATH_BASE = '/_p';
254
+ MAX_WAIT_COUNT = 30; // in seconds
255
+ constructor(requestIn, responseOut) {
256
+ super();
257
+ this.requestIn = requestIn;
258
+ this.responseOut = responseOut;
259
+ this._requestInBodyReader = new BaseHttpBody(this.requestIn);
260
+ this._responseInBodyReader = new BaseHttpBody(this.responseOut);
261
+ }
262
+ async forwardRequest() {
263
+ this.log.info('forwardRequest()');
264
+ this._initForwardRequest();
265
+ // this.httpRequest.end(); // move this to areas after writing
266
+ while (!this.forwardComplete && this.forwardWaitCount < this.MAX_WAIT_COUNT) {
267
+ await this.sleep(1000);
268
+ this.forwardWaitCount++;
269
+ }
270
+ }
271
+ sleep(millis) {
272
+ return new Promise(resolve => setTimeout(resolve, millis));
273
+ }
274
+ initEvents() {
275
+ var _ = this;
276
+ this.httpRequest.on('socket', function (socket) {
277
+ _.log.debug('socket (httpRequest out)');
278
+ socket.on('data', (chunk) => {
279
+ _.httpResponseRawChunksSize += chunk.length;
280
+ _.httpResponseRawChunks.push(Buffer.from(chunk));
281
+ _.log.debug('socket data chunk size (httpRequest out): ' + _.httpResponseRawChunksSize);
282
+ _.log.debug('socket data chunk (httpRequest out): ' + chunk);
283
+ });
284
+ socket.on('end', () => {
285
+ _.log.debug('socket end (httpRequest out)');
286
+ });
287
+ socket.on('close', () => {
288
+ _.log.debug('socket close (httpRequest out)');
289
+ _.log.debug('socket close chunk size (httpRequest out): ' + _.httpResponseRawChunksSize);
290
+ });
291
+ socket.resume();
292
+ });
293
+ }
294
+ _initHeaders() {
295
+ let contentType = this.requestIn.headers['content-type'];
296
+ this.requestIn.headers['host'] = this.HOST;
297
+ if (this.requestIn?.method?.toLowerCase() == 'post' && contentType?.match(/multipart/i) == null) {
298
+ this.log.info('setting content type for post');
299
+ this.requestIn.headers['content-type'] = 'application/x-www-form-urlencoded';
300
+ delete this.requestIn.headers['connection'];
301
+ // delete this.requestIn.headers['keep-alive'];
302
+ }
303
+ }
304
+ _initForwardRequest() {
305
+ var _ = this;
306
+ this.log.info('_initForwardRequest()');
307
+ this._initHeaders();
308
+ // DEBUG
309
+ this.log.debug('_initForwardRequest method (requestIn):' + this.requestIn.method);
310
+ // this.log.debug('_initForwardRequest body (requestIn):' + JSON.stringify(this.requestIn.body));
311
+ this.log.debug('_initForwardRequest headers (requestIn):' + JSON.stringify(this.requestIn.headers));
312
+ // this.log.debug('_initForwardRequest path (requestIn):' + JSON.stringify(this.requestIn.path));
313
+ this._requestInBodyReader = new BaseHttpBody(this.requestIn);
314
+ this._requestInBodyReader.readAsBuffer().then((data) => {
315
+ this.log.debug('_requestInBodyReader finished reading');
316
+ _.httpRequestInRaw.write(data.toString());
317
+ _._forwardRequest();
318
+ });
319
+ }
320
+ _forwardRequest() {
321
+ let url = new URL(this.requestIn.url || ''), query = qs.stringify(url.searchParams), path = url.pathname?.replace(this.PATH_BASE, '') + (query != '' ? '?' + query : '');
322
+ this.log.debug('_forwardRequest path (requestIn): ' + qs.stringify(url.pathname));
323
+ this.log.debug('_forwardRequest query (requestIn): ' + qs.stringify(url.searchParams));
324
+ const options = {
325
+ protocol: 'http:',
326
+ host: this.HOST,
327
+ port: 14599,
328
+ path: path,
329
+ method: this.requestIn.method,
330
+ headers: this.requestIn.headers,
331
+ };
332
+ this.log.debug(JSON.stringify(options));
333
+ var _ = this;
334
+ this.httpRequest = http.request(options);
335
+ this.httpRequest.on('response', (responseIn) => {
336
+ _.log.info('httpRequest response:');
337
+ _._responseInBodyReader = new BaseHttpBody(responseIn);
338
+ _._responseInBodyReader.readAsBuffer().then((data) => {
339
+ _.log.debug('_responseInBodyReader finished reading');
340
+ let headers = {}, dataBuffer = Buffer.alloc(0), contentType = responseIn.headers['Content-Type'] || '';
341
+ contentType = typeof contentType == 'string' ? contentType : contentType.join('; ');
342
+ _.log.debug('-- end event (callback)');
343
+ _.log.debug('-- chunks collected length: ' + Buffer.byteLength(data));
344
+ _.log.debug('-- chunks: ' + data.toString());
345
+ let fIsolateData = function (httpResponseRaw) {
346
+ let EOH = '\r\n\r\n';
347
+ return (httpResponseRaw.slice(httpResponseRaw.indexOf(EOH) + EOH.length));
348
+ };
349
+ dataBuffer = fIsolateData(Buffer.concat(_.httpResponseRawChunks));
350
+ if (contentType.length > 0) {
351
+ headers['Content-Type'] = responseIn.headers['content-type'];
352
+ if (contentType.match(/multipart|image/i) != null) {
353
+ headers['Content-Length'] = Buffer.byteLength(dataBuffer);
354
+ }
355
+ // if(responseIn.headers['content-type'] == 'image/png') {
356
+ // headers['Content-Length'] = Buffer.byteLength(dataBuffer);
357
+ // }
358
+ }
359
+ else {
360
+ headers['Content-Type'] = 'application/json';
361
+ }
362
+ _.log.debug('sending response with headers: ' + JSON.stringify(headers));
363
+ if (contentType.match(/json|text|html|xml/gim) != null) {
364
+ _.log.debug('sending text');
365
+ _.log.debug('sending text headers (responseOut):' + JSON.stringify(headers));
366
+ _.responseOut.write(data);
367
+ }
368
+ else {
369
+ _.log.debug('sending binary');
370
+ _.log.debug('sending binary headers (responseOut):' + JSON.stringify(headers));
371
+ // Logger.debug(data);
372
+ _.responseOut.writeHead(responseIn.statusCode, headers);
373
+ _.responseOut.write(dataBuffer);
374
+ }
375
+ // _.log.debug('buffer:');
376
+ // _.log.debug(data);
377
+ // _.log.debug('-- end buffer');
378
+ // this writes everything out and is not contexualized by content type above
379
+ // responseOut.send(data);
380
+ _.forwardComplete = true;
381
+ });
382
+ });
383
+ this.initEvents();
384
+ let method = this.requestIn?.method?.toLowerCase() || '';
385
+ if (method in this.WRITEABLE) {
386
+ this.log.info('writing writeable: ' + Buffer.byteLength(this.httpRequestInRaw));
387
+ this._writeWritable(this.httpRequestInRaw).then((bodyWritten) => {
388
+ this.httpRequest.end();
389
+ });
390
+ }
391
+ else {
392
+ this.httpRequest.end(this.httpRequestInRaw);
393
+ }
394
+ // this._multipartData.parse(this.requestIn).then(bodyRaw => {
395
+ // this.writePost();
396
+ // });
397
+ }
398
+ _writeWritable(bodyBuffer) {
399
+ var _ = this;
400
+ return new Promise((resolve, reject) => {
401
+ let contentType = _.requestIn.headers['Content-Type'] || '', bodyObject = null, dataPostParts = [], method = this.requestIn?.method?.toLowerCase() || '';
402
+ contentType = typeof contentType == 'string' ? contentType : contentType.join('; ');
403
+ if (!bodyBuffer || (!(method in _.WRITEABLE))) {
404
+ resolve([]);
405
+ }
406
+ if (method == 'post' && contentType.match(/multipart/i) == null) {
407
+ bodyObject = JSON.parse(bodyBuffer.toString());
408
+ _.log.debug('writing post:' + JSON.stringify(bodyObject));
409
+ _.log.debug('post data: ' + JSON.stringify(bodyObject));
410
+ for (let key in bodyObject) {
411
+ dataPostParts.push(key + '=' + encodeURIComponent(bodyObject[key]));
412
+ }
413
+ _.log.debug('writing post data: ' + dataPostParts.join('&'));
414
+ _.httpRequest.write(dataPostParts.join('&'));
415
+ resolve(dataPostParts);
416
+ }
417
+ else {
418
+ _.log.debug('writing data: ' + JSON.stringify(bodyBuffer));
419
+ _.httpRequest.write(bodyBuffer);
420
+ resolve(bodyBuffer);
421
+ }
422
+ });
423
+ }
424
+ }
425
+
426
+ export { BaseHttp, BaseHttpBody, BaseHttpProxy, BaseMultipartData };
@@ -0,0 +1 @@
1
+ export { BaseHttp, BaseHttpBody, BaseHttpProxy, BaseMultipartData } from './lib/index';
@@ -0,0 +1,20 @@
1
+ import http from 'node:http';
2
+ import { Url } from 'node:url';
3
+ import { BaseObject } from '@basenjs/base';
4
+ export declare class BaseHttp extends BaseObject {
5
+ constructor();
6
+ static processResponse(response: http.IncomingMessage): Promise<Buffer>;
7
+ static buildOptions(options: http.RequestOptions | any | Url): http.RequestOptions;
8
+ static head(options: http.RequestOptions | any | Url): Promise<http.ClientRequest | undefined>;
9
+ static options(options: http.RequestOptions | any | Url): Promise<http.ClientRequest | undefined>;
10
+ static get(options: http.RequestOptions | any | Url): Promise<http.ClientRequest | undefined>;
11
+ static post(options: http.RequestOptions | any | Url, body: any): Promise<http.ClientRequest | undefined>;
12
+ static put(options: http.RequestOptions | any | Url, body: any): Promise<http.ClientRequest | undefined>;
13
+ static patch(options: http.RequestOptions | any | Url, body: any): Promise<http.ClientRequest | undefined>;
14
+ static delete(options: http.RequestOptions | any | Url): Promise<http.ClientRequest | undefined>;
15
+ static request(options: http.RequestOptions | any | Url, body?: any, callbacks?: {
16
+ request: (response: http.IncomingMessage) => void;
17
+ data: (buffer: Buffer) => void;
18
+ end: (buffer: Buffer) => void;
19
+ }): Promise<http.ClientRequest | undefined>;
20
+ }
@@ -0,0 +1,12 @@
1
+ import http from 'node:http';
2
+ import { BaseObject } from '@basenjs/base';
3
+ export declare class BaseHttpBody extends BaseObject {
4
+ _readable: http.ClientRequest | http.IncomingMessage;
5
+ _chunks: Buffer[];
6
+ _dataWasRead: boolean;
7
+ _ended: boolean;
8
+ constructor(readable: http.ClientRequest | http.IncomingMessage | any);
9
+ get readable(): http.ClientRequest | http.IncomingMessage;
10
+ get dataWasRead(): boolean;
11
+ readAsBuffer(): Promise<Buffer>;
12
+ }
@@ -0,0 +1,35 @@
1
+ import http from 'node:http';
2
+ import { BaseObject } from '@basenjs/base';
3
+ import { BaseHttpBody } from './BaseHttpBody';
4
+ import { BaseMultipartData } from './BaseMultipartData';
5
+ export declare class BaseHttpProxy extends BaseObject {
6
+ requestIn: http.IncomingMessage;
7
+ responseOut: http.ServerResponse;
8
+ forwardComplete: boolean;
9
+ _multipartData: BaseMultipartData;
10
+ _requestInBodyReader: BaseHttpBody;
11
+ _responseInBodyReader: BaseHttpBody;
12
+ forwardWaitCount: number;
13
+ httpRequest: http.ClientRequest;
14
+ httpRequestInRawChunks: Buffer[];
15
+ httpRequestInRaw: Buffer<ArrayBuffer>;
16
+ httpResponseRawChunks: Buffer[];
17
+ httpResponseRaw: Buffer<ArrayBuffer>;
18
+ httpResponseRawChunksSize: number;
19
+ WRITEABLE: {
20
+ post: string;
21
+ patch: string;
22
+ put: string;
23
+ };
24
+ HOST: string;
25
+ PATH_BASE: string;
26
+ MAX_WAIT_COUNT: number;
27
+ constructor(requestIn: any, responseOut: any);
28
+ forwardRequest(): Promise<void>;
29
+ sleep(millis: number): Promise<unknown>;
30
+ initEvents(): void;
31
+ _initHeaders(): void;
32
+ _initForwardRequest(): void;
33
+ _forwardRequest(): void;
34
+ _writeWritable(bodyBuffer: Buffer): Promise<unknown>;
35
+ }
@@ -0,0 +1,14 @@
1
+ import multiparty from 'multiparty';
2
+ import { BaseObject } from '@basenjs/base';
3
+ export declare class BaseMultipartData extends BaseObject {
4
+ _form: multiparty.Form;
5
+ _bodyRaw: Buffer<ArrayBuffer>;
6
+ fields: any[];
7
+ files: any[];
8
+ get form(): multiparty.Form;
9
+ get bodyRaw(): Buffer;
10
+ constructor();
11
+ parse(request: any): Promise<unknown>;
12
+ parseRawText(text?: string): void;
13
+ private _parse;
14
+ }
@@ -0,0 +1,4 @@
1
+ export { BaseHttp } from './BaseHttp';
2
+ export { BaseHttpBody } from './BaseHttpBody';
3
+ export { BaseHttpProxy } from './BaseHttpProxy';
4
+ export { BaseMultipartData } from './BaseMultipartData';
package/npm-build.bat ADDED
@@ -0,0 +1,4 @@
1
+ @echo off
2
+ cls
3
+ call npm run build
4
+ pause
package/npm-login.bat ADDED
@@ -0,0 +1,4 @@
1
+ @echo off
2
+ cls
3
+ call npm login
4
+ pause
@@ -0,0 +1,4 @@
1
+ @echo off
2
+ cls
3
+ call npm publish --access public
4
+ pause
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@basenjs/base-http",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "description": "A base HTTP library for Node.js projects.",
6
+ "type": "module",
7
+ "main": "dist/cjs/index.cjs",
8
+ "module": "dist/esm/index.mjs",
9
+ "types": "dist/types/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "require": {
13
+ "types": "./dist/cjs/index.cjs",
14
+ "default": "./dist/cjs/index.cjs"
15
+ },
16
+ "import": "./dist/esm/index.mjs",
17
+ "types": "./dist/types/index.d.ts"
18
+ }
19
+ },
20
+ "keywords": [],
21
+ "author": {
22
+ "name": "g-greene"
23
+ },
24
+ "scripts": {
25
+ "build": "rollup -c && npm run build:types",
26
+ "build:types": "tsc -p tsconfig.declarations.json",
27
+ "release": "npm run build && npm version patch && npm publish && git push --follow-tags",
28
+ "release:minor": "npm run build && npm version minor && npm publish && git push --follow-tags",
29
+ "release:major": "npm run build && npm version major && npm publish && git push --follow-tags"
30
+ },
31
+ "license": "ISC",
32
+ "devDependencies": {
33
+ "@rollup/plugin-typescript": "^12.1.2",
34
+ "@types/node": "^22.19.2",
35
+ "prettier": "^3.5.3",
36
+ "rollup": "^4.40.0",
37
+ "tslib": "^2.8.1",
38
+ "typescript": "^5.8.3"
39
+ },
40
+ "dependencies": {
41
+ "@basenjs/base": "^0.0.2",
42
+ "multiparty": "^4.2.3",
43
+ "qs": "^6.14.0"
44
+ }
45
+ }
@@ -0,0 +1,22 @@
1
+ import typescript from '@rollup/plugin-typescript';
2
+
3
+ export default {
4
+ input: 'src/index.ts',
5
+ output: [
6
+ {
7
+ dir: 'dist/esm',
8
+ format: 'esm',
9
+ entryFileNames: '[name].mjs',
10
+ },
11
+ {
12
+ dir: 'dist/cjs',
13
+ format: 'cjs',
14
+ entryFileNames: '[name].cjs',
15
+ },
16
+ ],
17
+ plugins: [
18
+ typescript({
19
+ tsconfig: './tsconfig.json',
20
+ }),
21
+ ],
22
+ };
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { BaseHttp, BaseHttpBody, BaseHttpProxy, BaseMultipartData } from './lib/index';