@zcatalyst/transport 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist-cjs/fetch-handler.js +266 -0
  2. package/dist-cjs/http-handler.js +402 -0
  3. package/dist-cjs/index.browser.js +18 -0
  4. package/dist-cjs/index.js +32 -0
  5. package/dist-cjs/utils/clonable-stream.js +107 -0
  6. package/dist-cjs/utils/constants.js +55 -0
  7. package/dist-cjs/utils/enums.js +22 -0
  8. package/dist-cjs/utils/errors.js +10 -0
  9. package/dist-cjs/utils/form-data.js +217 -0
  10. package/dist-cjs/utils/helpers.js +10 -0
  11. package/dist-cjs/utils/interfaces.js +2 -0
  12. package/dist-cjs/utils/request-agent.js +22 -0
  13. package/dist-cjs/utils/request-timeout.js +14 -0
  14. package/dist-es/fetch-handler.js +261 -0
  15. package/dist-es/http-handler.js +361 -0
  16. package/dist-es/index.browser.js +12 -0
  17. package/dist-es/index.js +23 -0
  18. package/dist-es/utils/clonable-stream.js +105 -0
  19. package/dist-es/utils/constants.js +52 -0
  20. package/dist-es/utils/enums.js +19 -0
  21. package/dist-es/utils/errors.js +6 -0
  22. package/dist-es/utils/form-data.js +213 -0
  23. package/dist-es/utils/helpers.js +7 -0
  24. package/dist-es/utils/interfaces.js +1 -0
  25. package/dist-es/utils/request-agent.js +20 -0
  26. package/dist-es/utils/request-timeout.js +11 -0
  27. package/dist-types/fetch-handler.d.ts +40 -0
  28. package/dist-types/http-handler.d.ts +39 -0
  29. package/dist-types/index.browser.d.ts +13 -0
  30. package/dist-types/index.d.ts +16 -0
  31. package/dist-types/ts3.4/fetch-handler.d.ts +40 -0
  32. package/dist-types/ts3.4/http-handler.d.ts +39 -0
  33. package/dist-types/ts3.4/index.browser.d.ts +13 -0
  34. package/dist-types/ts3.4/index.d.ts +16 -0
  35. package/dist-types/ts3.4/utils/clonable-stream.d.ts +21 -0
  36. package/dist-types/ts3.4/utils/constants.d.ts +11 -0
  37. package/dist-types/ts3.4/utils/enums.d.ts +16 -0
  38. package/dist-types/ts3.4/utils/errors.d.ts +4 -0
  39. package/dist-types/ts3.4/utils/form-data.d.ts +44 -0
  40. package/dist-types/ts3.4/utils/helpers.d.ts +1 -0
  41. package/dist-types/ts3.4/utils/interfaces.d.ts +64 -0
  42. package/dist-types/ts3.4/utils/request-agent.d.ts +6 -0
  43. package/dist-types/ts3.4/utils/request-timeout.d.ts +1 -0
  44. package/dist-types/utils/clonable-stream.d.ts +21 -0
  45. package/dist-types/utils/constants.d.ts +11 -0
  46. package/dist-types/utils/enums.d.ts +16 -0
  47. package/dist-types/utils/errors.d.ts +4 -0
  48. package/dist-types/utils/form-data.d.ts +44 -0
  49. package/dist-types/utils/helpers.d.ts +1 -0
  50. package/dist-types/utils/interfaces.d.ts +64 -0
  51. package/dist-types/utils/request-agent.d.ts +6 -0
  52. package/dist-types/utils/request-timeout.d.ts +1 -0
  53. package/package.json +10 -5
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FormData = exports.CatalystAPIError = exports.ResponseType = exports.RequestType = exports.Handler = void 0;
7
+ const auth_1 = require("@zcatalyst/auth");
8
+ const http_handler_1 = require("./http-handler");
9
+ const form_data_1 = __importDefault(require("./utils/form-data"));
10
+ exports.FormData = form_data_1.default;
11
+ class Handler {
12
+ constructor(app, component) {
13
+ if (!app) {
14
+ app = new auth_1.ZCAuth().getDefaultCredentials();
15
+ }
16
+ if (!(app instanceof auth_1.CatalystApp)) {
17
+ throw new auth_1.CatalystAppError('INVALID_PROJECT_CREDENTIALS', 'Unable to process the project credentials. Please verify that the initialization is configured correctly.');
18
+ }
19
+ this.app = app;
20
+ this.component = component;
21
+ }
22
+ async send(options) {
23
+ const _httpRequester = new http_handler_1.AuthorizedHttpClient(this.app, this.component);
24
+ return (await _httpRequester.send(options));
25
+ }
26
+ }
27
+ exports.Handler = Handler;
28
+ var enums_1 = require("./utils/enums");
29
+ Object.defineProperty(exports, "RequestType", { enumerable: true, get: function () { return enums_1.RequestType; } });
30
+ Object.defineProperty(exports, "ResponseType", { enumerable: true, get: function () { return enums_1.ResponseType; } });
31
+ var errors_1 = require("./utils/errors");
32
+ Object.defineProperty(exports, "CatalystAPIError", { enumerable: true, get: function () { return errors_1.CatalystAPIError; } });
@@ -0,0 +1,107 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const process_1 = require("process");
4
+ const stream_1 = require("stream");
5
+ function clonePiped(that) {
6
+ if (--that._clonesCount === 0 && !that.destroyed) {
7
+ that._original?.pipe(that);
8
+ that._original = undefined;
9
+ }
10
+ }
11
+ function _destroy(error, callback) {
12
+ if (!error) {
13
+ this.push(null);
14
+ this.end();
15
+ }
16
+ (0, process_1.nextTick)(callback, error);
17
+ }
18
+ function forwardDestroy(src, dest) {
19
+ function destroy(err) {
20
+ src.removeListener('close', onClose);
21
+ dest.destroy(err);
22
+ }
23
+ function onClose() {
24
+ dest.end();
25
+ }
26
+ src.on('error', destroy);
27
+ src.on('close', onClose);
28
+ }
29
+ class StreamClone extends stream_1.PassThrough {
30
+ constructor(parent) {
31
+ super({ objectMode: parent.readableObjectMode });
32
+ this.parent = parent;
33
+ forwardDestroy(parent, this);
34
+ parent._internalPipe = true;
35
+ parent.pipe(this);
36
+ parent._internalPipe = false;
37
+ this.on('newListener', this.onDataClone);
38
+ this.once('resume', this.onResumeClone);
39
+ }
40
+ onDataClone(event, _listener) {
41
+ if (event === 'data' || event === 'readable' || event === 'close') {
42
+ (0, process_1.nextTick)(clonePiped, this.parent);
43
+ this.removeListener('newListener', this.onDataClone);
44
+ this.removeListener('resume', this.onResumeClone);
45
+ }
46
+ }
47
+ onResumeClone() {
48
+ this.removeListener('newListener', this.onDataClone);
49
+ this.removeListener('resume', this.onResumeClone);
50
+ (0, process_1.nextTick)(clonePiped, this.parent);
51
+ }
52
+ clone() {
53
+ return this.parent.clone();
54
+ }
55
+ isCloneable(stream) {
56
+ return stream instanceof CloneableStream || stream instanceof StreamClone;
57
+ }
58
+ }
59
+ class CloneableStream extends stream_1.PassThrough {
60
+ constructor(stream) {
61
+ super({ objectMode: stream.readableObjectMode });
62
+ this._original = stream;
63
+ this._clonesCount = 1;
64
+ this._internalPipe = false;
65
+ forwardDestroy(stream, this);
66
+ this.on('newListener', this.onData);
67
+ this.on('resume', this.onResume);
68
+ this._hasListener = true;
69
+ this._destroy = _destroy;
70
+ }
71
+ onData(event, _listener) {
72
+ if (event === 'data' || event === 'readable') {
73
+ this._hasListener = false;
74
+ this.removeListener('newListener', this.onData);
75
+ this.removeListener('resume', this.onResume);
76
+ (0, process_1.nextTick)(clonePiped, this);
77
+ }
78
+ }
79
+ onResume() {
80
+ this._hasListener = false;
81
+ this.removeListener('newListener', this.onData);
82
+ this.removeListener('resume', this.onResume);
83
+ (0, process_1.nextTick)(clonePiped, this);
84
+ }
85
+ resume() {
86
+ if (this._internalPipe) {
87
+ return this;
88
+ }
89
+ stream_1.PassThrough.prototype.resume.call(this);
90
+ return this;
91
+ }
92
+ clone() {
93
+ if (!this._original) {
94
+ throw new Error('already started');
95
+ }
96
+ this._clonesCount++;
97
+ this.removeListener('newListener', this.onData);
98
+ this.removeListener('resume', this.onResume);
99
+ const clone = new StreamClone(this);
100
+ if (this._hasListener) {
101
+ this.on('newListener', this.onData);
102
+ this.on('resume', this.onResume);
103
+ }
104
+ return clone;
105
+ }
106
+ }
107
+ exports.default = CloneableStream;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HTTP_CODE_REV_MAP = exports.ZD_CSRPARAM = exports.X_ZCSRF_TOKEN = exports.REQUEST_PROPERTY = exports.HTTP_HEADER_MAP = exports.HTTP_CODE_MAP = void 0;
4
+ exports.HTTP_CODE_MAP = {
5
+ OK: {
6
+ CODE: 200,
7
+ TEXT: 'OK'
8
+ },
9
+ NO_CONTENT: {
10
+ CODE: 204,
11
+ TEXT: 'NO CONTENT'
12
+ },
13
+ INTERNAL_SERVER_ERROR: {
14
+ CODE: 500,
15
+ TEXT: 'INTERNAL SERVER ERROR'
16
+ },
17
+ RESOURCE_NOT_FOUND: {
18
+ CODE: 404,
19
+ TEXT: 'RESOURCE NOT FOUND'
20
+ },
21
+ BAD_REQUEST: {
22
+ CODE: 400,
23
+ TEXT: 'BAD REQUEST'
24
+ },
25
+ UNAUTHORIZED: {
26
+ CODE: 401,
27
+ TEXT: 'UNAUTHORIZED'
28
+ },
29
+ CONFLICT: {
30
+ CODE: 409,
31
+ TEXT: 'CONFLICT, MAY BE YOU ARE TRYING TO CREATE A RESOURCE THAT ALREADY EXIST!'
32
+ },
33
+ FORBIDDEN: {
34
+ CODE: 403,
35
+ TEXT: 'FORBIDDEN, MAY BE YOUR USAGE REACHED MAX ALLOWED LIMIT!'
36
+ },
37
+ UNEXPECTED: {
38
+ CODE: 101,
39
+ TEXT: 'UNEXPECTED RESPONSE FOUND'
40
+ }
41
+ };
42
+ exports.HTTP_HEADER_MAP = {
43
+ CONTENT_JSON: 'application/json; charset=utf-8',
44
+ AUTHORIZATION_KEY: 'Authorization'
45
+ };
46
+ exports.REQUEST_PROPERTY = {
47
+ BLOB: 'blob'
48
+ };
49
+ exports.X_ZCSRF_TOKEN = 'X-ZCSRF-TOKEN';
50
+ exports.ZD_CSRPARAM = 'zd_csrparam';
51
+ const HTTP_CODE_REV_MAP = {};
52
+ exports.HTTP_CODE_REV_MAP = HTTP_CODE_REV_MAP;
53
+ const HTTP_CODE_MAP_KEYS = Object.keys(exports.HTTP_CODE_MAP);
54
+ for (const KEY of HTTP_CODE_MAP_KEYS)
55
+ HTTP_CODE_REV_MAP[exports.HTTP_CODE_MAP[KEY].CODE] = exports.HTTP_CODE_MAP[KEY];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FormDataKeys = exports.RequestType = exports.ResponseType = void 0;
4
+ var ResponseType;
5
+ (function (ResponseType) {
6
+ ResponseType["RAW"] = "raw";
7
+ ResponseType["JSON"] = "json";
8
+ ResponseType["STRING"] = "string";
9
+ ResponseType["BUFFER"] = "buffer";
10
+ })(ResponseType || (exports.ResponseType = ResponseType = {}));
11
+ var RequestType;
12
+ (function (RequestType) {
13
+ RequestType["FILE"] = "file";
14
+ RequestType["JSON"] = "json";
15
+ RequestType["URL_ENCODED"] = "url_encoded";
16
+ RequestType["RAW"] = "raw";
17
+ })(RequestType || (exports.RequestType = RequestType = {}));
18
+ var FormDataKeys;
19
+ (function (FormDataKeys) {
20
+ FormDataKeys["CODE"] = "code";
21
+ FormDataKeys["FILE_NAME"] = "file_name";
22
+ })(FormDataKeys || (exports.FormDataKeys = FormDataKeys = {}));
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CatalystAPIError = void 0;
4
+ const utils_1 = require("@zcatalyst/utils");
5
+ class CatalystAPIError extends utils_1.PrefixedCatalystError {
6
+ constructor(code, message, value, statusCode) {
7
+ super('app', code, message, value, statusCode);
8
+ }
9
+ }
10
+ exports.CatalystAPIError = CatalystAPIError;
@@ -0,0 +1,217 @@
1
+ 'use strict';
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = require("path");
7
+ const stream_1 = require("stream");
8
+ const util_1 = require("util");
9
+ const clonable_stream_1 = __importDefault(require("./clonable-stream"));
10
+ class FormData extends stream_1.Stream {
11
+ constructor(streams) {
12
+ super();
13
+ this.writable = false;
14
+ this.readable = true;
15
+ this.released = false;
16
+ this.streams = streams || [];
17
+ this.insideLoop = false;
18
+ this.pendingNext = false;
19
+ }
20
+ isStream(value) {
21
+ return (value !== undefined &&
22
+ value !== null &&
23
+ ((typeof value.on === 'function' &&
24
+ typeof value.pipe === 'function') ||
25
+ value instanceof stream_1.Readable));
26
+ }
27
+ _multiPartHeader(field, value) {
28
+ const contentDisposition = this._getContentDisposition(value);
29
+ const contentType = this._getContentType(value);
30
+ let contents = '';
31
+ const headers = {
32
+ 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
33
+ 'Content-Type': [contentType]
34
+ };
35
+ for (const prop in headers) {
36
+ if (headers[prop]) {
37
+ const header = headers[prop];
38
+ if (header.length > 0) {
39
+ contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;
40
+ }
41
+ }
42
+ }
43
+ return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
44
+ }
45
+ _getContentDisposition(value) {
46
+ let filename = '';
47
+ let contentDisposition = '';
48
+ if (value['name'] || value['path']) {
49
+ filename = (0, path_1.basename)(value['name'] || value['path']);
50
+ }
51
+ else if (value['readable'] && value.hasOwnProperty('httpVersion')) {
52
+ filename = (0, path_1.basename)(value['client']._httpMessage.path || '');
53
+ }
54
+ if (filename) {
55
+ contentDisposition = 'filename="' + filename + '"';
56
+ }
57
+ return contentDisposition;
58
+ }
59
+ _getContentType(value) {
60
+ let contentType = '';
61
+ if (value.readable && value.hasOwnProperty('httpVersion')) {
62
+ contentType = value.headers['content-type'];
63
+ }
64
+ if (!contentType) {
65
+ contentType = FormData.CONTENT_TYPE;
66
+ }
67
+ return contentType;
68
+ }
69
+ _lastBoundary() {
70
+ return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;
71
+ }
72
+ _generateBoundary() {
73
+ let boundary = '--------------------------';
74
+ for (let i = 0; i < 24; i++) {
75
+ boundary += Math.floor(Math.random() * 10).toString(16);
76
+ }
77
+ this.boundary = boundary;
78
+ return boundary;
79
+ }
80
+ _error(err) {
81
+ this._reset();
82
+ this.emit('error', err);
83
+ }
84
+ _handleStreamErrors(stream) {
85
+ stream.on('error', (err) => {
86
+ this._error(err);
87
+ });
88
+ }
89
+ _pipeNext(stream) {
90
+ this.currentStream = stream;
91
+ if (this.isStream(stream)) {
92
+ stream.on('end', this._getNext.bind(this));
93
+ stream.pipe(this, {
94
+ end: false
95
+ });
96
+ return;
97
+ }
98
+ const value = stream;
99
+ this.write(value);
100
+ this._getNext();
101
+ }
102
+ _getNext() {
103
+ this.currentStream = undefined;
104
+ if (this.insideLoop) {
105
+ this.pendingNext = true;
106
+ return;
107
+ }
108
+ this.insideLoop = true;
109
+ try {
110
+ do {
111
+ this.pendingNext = false;
112
+ const stream = this.streams.shift();
113
+ if (typeof stream === 'undefined') {
114
+ this.end();
115
+ }
116
+ else {
117
+ this._pipeNext(stream);
118
+ }
119
+ } while (this.pendingNext);
120
+ }
121
+ finally {
122
+ this.insideLoop = false;
123
+ }
124
+ }
125
+ _reset() {
126
+ this.writable = false;
127
+ this.streams = [];
128
+ this.currentStream = undefined;
129
+ }
130
+ createClone() {
131
+ const newStreams = [];
132
+ this.streams.forEach((stream) => {
133
+ const clone = this.isStream(stream)
134
+ ? new clonable_stream_1.default(stream).clone()
135
+ : stream;
136
+ newStreams.push(clone);
137
+ });
138
+ return new FormData(newStreams);
139
+ }
140
+ append(field, value) {
141
+ if (Array.isArray(value)) {
142
+ this._error(new Error('Arrays are not supported.'));
143
+ return this;
144
+ }
145
+ if (typeof value !== 'string' && !Buffer.isBuffer(value) && !this.isStream(value)) {
146
+ value = (0, util_1.inspect)(value);
147
+ }
148
+ if (this.isStream(value)) {
149
+ this._handleStreamErrors(value);
150
+ }
151
+ this.streams.push(this._multiPartHeader(field, value));
152
+ this.streams.push(value);
153
+ this.streams.push(FormData.LINE_BREAK);
154
+ return this;
155
+ }
156
+ getHeaders(userHeaders) {
157
+ const formHeaders = {};
158
+ for (const header in userHeaders) {
159
+ if (userHeaders[header]) {
160
+ formHeaders[header.toLowerCase()] = userHeaders[header];
161
+ }
162
+ }
163
+ formHeaders['content-type'] = 'multipart/form-data; boundary=' + this.getBoundary();
164
+ return formHeaders;
165
+ }
166
+ getBoundary() {
167
+ if (this.boundary === undefined) {
168
+ return this._generateBoundary();
169
+ }
170
+ return this.boundary;
171
+ }
172
+ pipe(dest, options) {
173
+ stream_1.Stream.prototype.pipe.call(this, dest, options);
174
+ this.resume();
175
+ return dest;
176
+ }
177
+ write(data) {
178
+ const lastPart = this.streams.length === 0;
179
+ this.emit('data', data);
180
+ if (lastPart) {
181
+ this.emit('data', this._lastBoundary());
182
+ }
183
+ return true;
184
+ }
185
+ pause() {
186
+ if (this.currentStream !== undefined &&
187
+ typeof this.currentStream.pause === 'function') {
188
+ this.currentStream.pause();
189
+ }
190
+ this.emit('pause');
191
+ }
192
+ resume() {
193
+ if (!this.released) {
194
+ this.released = true;
195
+ this.writable = true;
196
+ this._getNext();
197
+ }
198
+ if (this.currentStream && typeof this.currentStream.resume === 'function') {
199
+ this.currentStream.resume();
200
+ }
201
+ this.emit('resume');
202
+ }
203
+ end() {
204
+ this._reset();
205
+ this.emit('end');
206
+ }
207
+ destroy() {
208
+ this._reset();
209
+ this.emit('close');
210
+ }
211
+ toString() {
212
+ return '[object FormData]';
213
+ }
214
+ }
215
+ FormData.LINE_BREAK = '\r\n';
216
+ FormData.CONTENT_TYPE = 'application/octet-stream';
217
+ exports.default = FormData;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isHttps = isHttps;
4
+ function isHttps(url) {
5
+ if (url === undefined) {
6
+ return false;
7
+ }
8
+ const parsedUrl = url instanceof URL ? url : new URL(url);
9
+ return parsedUrl.protocol === 'https:';
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@zcatalyst/utils");
4
+ const http_1 = require("http");
5
+ const https_1 = require("https");
6
+ const agentMap = {};
7
+ class RequestAgent {
8
+ constructor(isHttps, host, replaceAgent) {
9
+ const protocol = isHttps ? utils_1.CONSTANTS.PROTOCOL.HTTPS : utils_1.CONSTANTS.PROTOCOL.HTTP;
10
+ if (agentMap[protocol] === undefined) {
11
+ agentMap[protocol] = {};
12
+ }
13
+ const protocolMap = agentMap[protocol];
14
+ if (protocolMap[host] === undefined || replaceAgent) {
15
+ protocolMap[host] = isHttps
16
+ ? new https_1.Agent({ keepAlive: true })
17
+ : new http_1.Agent({ keepAlive: true });
18
+ }
19
+ this.agent = protocolMap[host];
20
+ }
21
+ }
22
+ exports.default = RequestAgent;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestTimeout = requestTimeout;
4
+ function requestTimeout(timeoutInMs = 0) {
5
+ return new Promise((resolve, reject) => {
6
+ if (timeoutInMs) {
7
+ setTimeout(() => {
8
+ const timeoutError = new Error(`Request did not complete within ${timeoutInMs} ms`);
9
+ timeoutError.name = 'TimeoutError';
10
+ reject(timeoutError);
11
+ }, timeoutInMs);
12
+ }
13
+ });
14
+ }