isomorphic-git 1.10.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,230 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
+
7
+ var get = _interopDefault(require('simple-get'));
8
+
9
+ /**
10
+ * @typedef {Object} GitProgressEvent
11
+ * @property {string} phase
12
+ * @property {number} loaded
13
+ * @property {number} total
14
+ */
15
+
16
+ /**
17
+ * @callback ProgressCallback
18
+ * @param {GitProgressEvent} progress
19
+ * @returns {void | Promise<void>}
20
+ */
21
+
22
+ /**
23
+ * @typedef {Object} GitHttpRequest
24
+ * @property {string} url - The URL to request
25
+ * @property {string} [method='GET'] - The HTTP method to use
26
+ * @property {Object<string, string>} [headers={}] - Headers to include in the HTTP request
27
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
28
+ * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
29
+ * @property {object} [signal] - Reserved for future use (canceling a request)
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} GitHttpResponse
34
+ * @property {string} url - The final URL that was fetched after any redirects
35
+ * @property {string} [method] - The HTTP method that was used
36
+ * @property {Object<string, string>} [headers] - HTTP response headers
37
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of the response
38
+ * @property {number} statusCode - The HTTP status code
39
+ * @property {string} statusMessage - The HTTP status message
40
+ */
41
+
42
+ /**
43
+ * @callback HttpFetch
44
+ * @param {GitHttpRequest} request
45
+ * @returns {Promise<GitHttpResponse>}
46
+ */
47
+
48
+ /**
49
+ * @typedef {Object} HttpClient
50
+ * @property {HttpFetch} request
51
+ */
52
+
53
+ // Convert a value to an Async Iterator
54
+ // This will be easier with async generator functions.
55
+ function fromValue(value) {
56
+ let queue = [value];
57
+ return {
58
+ next() {
59
+ return Promise.resolve({ done: queue.length === 0, value: queue.pop() })
60
+ },
61
+ return() {
62
+ queue = [];
63
+ return {}
64
+ },
65
+ [Symbol.asyncIterator]() {
66
+ return this
67
+ },
68
+ }
69
+ }
70
+
71
+ function getIterator(iterable) {
72
+ if (iterable[Symbol.asyncIterator]) {
73
+ return iterable[Symbol.asyncIterator]()
74
+ }
75
+ if (iterable[Symbol.iterator]) {
76
+ return iterable[Symbol.iterator]()
77
+ }
78
+ if (iterable.next) {
79
+ return iterable
80
+ }
81
+ return fromValue(iterable)
82
+ }
83
+
84
+ // Currently 'for await' upsets my linters.
85
+ async function forAwait(iterable, cb) {
86
+ const iter = getIterator(iterable);
87
+ while (true) {
88
+ const { value, done } = await iter.next();
89
+ if (value) await cb(value);
90
+ if (done) break
91
+ }
92
+ if (iter.return) iter.return();
93
+ }
94
+
95
+ function asyncIteratorToStream(iter) {
96
+ const { PassThrough } = require('readable-stream');
97
+ const stream = new PassThrough();
98
+ setTimeout(async () => {
99
+ await forAwait(iter, chunk => stream.write(chunk));
100
+ stream.end();
101
+ }, 1);
102
+ return stream
103
+ }
104
+
105
+ async function collect(iterable) {
106
+ let size = 0;
107
+ const buffers = [];
108
+ // This will be easier once `for await ... of` loops are available.
109
+ await forAwait(iterable, value => {
110
+ buffers.push(value);
111
+ size += value.byteLength;
112
+ });
113
+ const result = new Uint8Array(size);
114
+ let nextIndex = 0;
115
+ for (const buffer of buffers) {
116
+ result.set(buffer, nextIndex);
117
+ nextIndex += buffer.byteLength;
118
+ }
119
+ return result
120
+ }
121
+
122
+ // Convert a Node stream to an Async Iterator
123
+ function fromNodeStream(stream) {
124
+ // Use native async iteration if it's available.
125
+ const asyncIterator = Object.getOwnPropertyDescriptor(
126
+ stream,
127
+ Symbol.asyncIterator
128
+ );
129
+ if (asyncIterator && asyncIterator.enumerable) {
130
+ return stream
131
+ }
132
+ // Author's Note
133
+ // I tried many MANY ways to do this.
134
+ // I tried two npm modules (stream-to-async-iterator and streams-to-async-iterator) with no luck.
135
+ // I tried using 'readable' and .read(), and .pause() and .resume()
136
+ // It took me two loooong evenings to get to this point.
137
+ // So if you are horrified that this solution just builds up a queue with no backpressure,
138
+ // and turns Promises inside out, too bad. This is the first code that worked reliably.
139
+ let ended = false;
140
+ const queue = [];
141
+ let defer = {};
142
+ stream.on('data', chunk => {
143
+ queue.push(chunk);
144
+ if (defer.resolve) {
145
+ defer.resolve({ value: queue.shift(), done: false });
146
+ defer = {};
147
+ }
148
+ });
149
+ stream.on('error', err => {
150
+ if (defer.reject) {
151
+ defer.reject(err);
152
+ defer = {};
153
+ }
154
+ });
155
+ stream.on('end', () => {
156
+ ended = true;
157
+ if (defer.resolve) {
158
+ defer.resolve({ done: true });
159
+ defer = {};
160
+ }
161
+ });
162
+ return {
163
+ next() {
164
+ return new Promise((resolve, reject) => {
165
+ if (queue.length === 0 && ended) {
166
+ return resolve({ done: true })
167
+ } else if (queue.length > 0) {
168
+ return resolve({ value: queue.shift(), done: false })
169
+ } else if (queue.length === 0 && !ended) {
170
+ defer = { resolve, reject };
171
+ }
172
+ })
173
+ },
174
+ return() {
175
+ stream.removeAllListeners();
176
+ if (stream.destroy) stream.destroy();
177
+ },
178
+ [Symbol.asyncIterator]() {
179
+ return this
180
+ },
181
+ }
182
+ }
183
+
184
+ /**
185
+ * HttpClient
186
+ *
187
+ * @param {GitHttpRequest} request
188
+ * @returns {Promise<GitHttpResponse>}
189
+ */
190
+ async function request({
191
+ onProgress,
192
+ url,
193
+ method = 'GET',
194
+ headers = {},
195
+ body,
196
+ }) {
197
+ // If we can, we should send it as a single buffer so it sets a Content-Length header.
198
+ if (body && Array.isArray(body)) {
199
+ body = Buffer.from(await collect(body));
200
+ } else if (body) {
201
+ body = asyncIteratorToStream(body);
202
+ }
203
+ return new Promise((resolve, reject) => {
204
+ get(
205
+ {
206
+ url,
207
+ method,
208
+ headers,
209
+ body,
210
+ },
211
+ (err, res) => {
212
+ if (err) return reject(err)
213
+ const iter = fromNodeStream(res);
214
+ resolve({
215
+ url: res.url,
216
+ method: res.method,
217
+ statusCode: res.statusCode,
218
+ statusMessage: res.statusMessage,
219
+ body: iter,
220
+ headers: res.headers,
221
+ });
222
+ }
223
+ );
224
+ })
225
+ }
226
+
227
+ var index = { request };
228
+
229
+ exports.default = index;
230
+ exports.request = request;
@@ -0,0 +1,77 @@
1
+ export default index;
2
+ export type GitProgressEvent = {
3
+ phase: string;
4
+ loaded: number;
5
+ total: number;
6
+ };
7
+ export type ProgressCallback = (progress: GitProgressEvent) => void | Promise<void>;
8
+ export type GitHttpRequest = {
9
+ /**
10
+ * - The URL to request
11
+ */
12
+ url: string;
13
+ /**
14
+ * - The HTTP method to use
15
+ */
16
+ method?: string;
17
+ /**
18
+ * - Headers to include in the HTTP request
19
+ */
20
+ headers?: {
21
+ [x: string]: string;
22
+ };
23
+ /**
24
+ * - An async iterator of Uint8Arrays that make up the body of POST requests
25
+ */
26
+ body?: any;
27
+ /**
28
+ * - Reserved for future use (emitting `GitProgressEvent`s)
29
+ */
30
+ onProgress?: ProgressCallback;
31
+ /**
32
+ * - Reserved for future use (canceling a request)
33
+ */
34
+ signal?: any;
35
+ };
36
+ export type GitHttpResponse = {
37
+ /**
38
+ * - The final URL that was fetched after any redirects
39
+ */
40
+ url: string;
41
+ /**
42
+ * - The HTTP method that was used
43
+ */
44
+ method?: string;
45
+ /**
46
+ * - HTTP response headers
47
+ */
48
+ headers?: {
49
+ [x: string]: string;
50
+ };
51
+ /**
52
+ * - An async iterator of Uint8Arrays that make up the body of the response
53
+ */
54
+ body?: any;
55
+ /**
56
+ * - The HTTP status code
57
+ */
58
+ statusCode: number;
59
+ /**
60
+ * - The HTTP status message
61
+ */
62
+ statusMessage: string;
63
+ };
64
+ export type HttpFetch = (request: GitHttpRequest) => Promise<GitHttpResponse>;
65
+ export type HttpClient = {
66
+ request: HttpFetch;
67
+ };
68
+ declare namespace index {
69
+ export { request };
70
+ }
71
+ /**
72
+ * HttpClient
73
+ *
74
+ * @param {GitHttpRequest} request
75
+ * @returns {Promise<GitHttpResponse>}
76
+ */
77
+ export function request({ onProgress, url, method, headers, body, }: GitHttpRequest): Promise<GitHttpResponse>;
@@ -0,0 +1,224 @@
1
+ import get from 'simple-get';
2
+
3
+ /**
4
+ * @typedef {Object} GitProgressEvent
5
+ * @property {string} phase
6
+ * @property {number} loaded
7
+ * @property {number} total
8
+ */
9
+
10
+ /**
11
+ * @callback ProgressCallback
12
+ * @param {GitProgressEvent} progress
13
+ * @returns {void | Promise<void>}
14
+ */
15
+
16
+ /**
17
+ * @typedef {Object} GitHttpRequest
18
+ * @property {string} url - The URL to request
19
+ * @property {string} [method='GET'] - The HTTP method to use
20
+ * @property {Object<string, string>} [headers={}] - Headers to include in the HTTP request
21
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
22
+ * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
23
+ * @property {object} [signal] - Reserved for future use (canceling a request)
24
+ */
25
+
26
+ /**
27
+ * @typedef {Object} GitHttpResponse
28
+ * @property {string} url - The final URL that was fetched after any redirects
29
+ * @property {string} [method] - The HTTP method that was used
30
+ * @property {Object<string, string>} [headers] - HTTP response headers
31
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of the response
32
+ * @property {number} statusCode - The HTTP status code
33
+ * @property {string} statusMessage - The HTTP status message
34
+ */
35
+
36
+ /**
37
+ * @callback HttpFetch
38
+ * @param {GitHttpRequest} request
39
+ * @returns {Promise<GitHttpResponse>}
40
+ */
41
+
42
+ /**
43
+ * @typedef {Object} HttpClient
44
+ * @property {HttpFetch} request
45
+ */
46
+
47
+ // Convert a value to an Async Iterator
48
+ // This will be easier with async generator functions.
49
+ function fromValue(value) {
50
+ let queue = [value];
51
+ return {
52
+ next() {
53
+ return Promise.resolve({ done: queue.length === 0, value: queue.pop() })
54
+ },
55
+ return() {
56
+ queue = [];
57
+ return {}
58
+ },
59
+ [Symbol.asyncIterator]() {
60
+ return this
61
+ },
62
+ }
63
+ }
64
+
65
+ function getIterator(iterable) {
66
+ if (iterable[Symbol.asyncIterator]) {
67
+ return iterable[Symbol.asyncIterator]()
68
+ }
69
+ if (iterable[Symbol.iterator]) {
70
+ return iterable[Symbol.iterator]()
71
+ }
72
+ if (iterable.next) {
73
+ return iterable
74
+ }
75
+ return fromValue(iterable)
76
+ }
77
+
78
+ // Currently 'for await' upsets my linters.
79
+ async function forAwait(iterable, cb) {
80
+ const iter = getIterator(iterable);
81
+ while (true) {
82
+ const { value, done } = await iter.next();
83
+ if (value) await cb(value);
84
+ if (done) break
85
+ }
86
+ if (iter.return) iter.return();
87
+ }
88
+
89
+ function asyncIteratorToStream(iter) {
90
+ const { PassThrough } = require('readable-stream');
91
+ const stream = new PassThrough();
92
+ setTimeout(async () => {
93
+ await forAwait(iter, chunk => stream.write(chunk));
94
+ stream.end();
95
+ }, 1);
96
+ return stream
97
+ }
98
+
99
+ async function collect(iterable) {
100
+ let size = 0;
101
+ const buffers = [];
102
+ // This will be easier once `for await ... of` loops are available.
103
+ await forAwait(iterable, value => {
104
+ buffers.push(value);
105
+ size += value.byteLength;
106
+ });
107
+ const result = new Uint8Array(size);
108
+ let nextIndex = 0;
109
+ for (const buffer of buffers) {
110
+ result.set(buffer, nextIndex);
111
+ nextIndex += buffer.byteLength;
112
+ }
113
+ return result
114
+ }
115
+
116
+ // Convert a Node stream to an Async Iterator
117
+ function fromNodeStream(stream) {
118
+ // Use native async iteration if it's available.
119
+ const asyncIterator = Object.getOwnPropertyDescriptor(
120
+ stream,
121
+ Symbol.asyncIterator
122
+ );
123
+ if (asyncIterator && asyncIterator.enumerable) {
124
+ return stream
125
+ }
126
+ // Author's Note
127
+ // I tried many MANY ways to do this.
128
+ // I tried two npm modules (stream-to-async-iterator and streams-to-async-iterator) with no luck.
129
+ // I tried using 'readable' and .read(), and .pause() and .resume()
130
+ // It took me two loooong evenings to get to this point.
131
+ // So if you are horrified that this solution just builds up a queue with no backpressure,
132
+ // and turns Promises inside out, too bad. This is the first code that worked reliably.
133
+ let ended = false;
134
+ const queue = [];
135
+ let defer = {};
136
+ stream.on('data', chunk => {
137
+ queue.push(chunk);
138
+ if (defer.resolve) {
139
+ defer.resolve({ value: queue.shift(), done: false });
140
+ defer = {};
141
+ }
142
+ });
143
+ stream.on('error', err => {
144
+ if (defer.reject) {
145
+ defer.reject(err);
146
+ defer = {};
147
+ }
148
+ });
149
+ stream.on('end', () => {
150
+ ended = true;
151
+ if (defer.resolve) {
152
+ defer.resolve({ done: true });
153
+ defer = {};
154
+ }
155
+ });
156
+ return {
157
+ next() {
158
+ return new Promise((resolve, reject) => {
159
+ if (queue.length === 0 && ended) {
160
+ return resolve({ done: true })
161
+ } else if (queue.length > 0) {
162
+ return resolve({ value: queue.shift(), done: false })
163
+ } else if (queue.length === 0 && !ended) {
164
+ defer = { resolve, reject };
165
+ }
166
+ })
167
+ },
168
+ return() {
169
+ stream.removeAllListeners();
170
+ if (stream.destroy) stream.destroy();
171
+ },
172
+ [Symbol.asyncIterator]() {
173
+ return this
174
+ },
175
+ }
176
+ }
177
+
178
+ /**
179
+ * HttpClient
180
+ *
181
+ * @param {GitHttpRequest} request
182
+ * @returns {Promise<GitHttpResponse>}
183
+ */
184
+ async function request({
185
+ onProgress,
186
+ url,
187
+ method = 'GET',
188
+ headers = {},
189
+ body,
190
+ }) {
191
+ // If we can, we should send it as a single buffer so it sets a Content-Length header.
192
+ if (body && Array.isArray(body)) {
193
+ body = Buffer.from(await collect(body));
194
+ } else if (body) {
195
+ body = asyncIteratorToStream(body);
196
+ }
197
+ return new Promise((resolve, reject) => {
198
+ get(
199
+ {
200
+ url,
201
+ method,
202
+ headers,
203
+ body,
204
+ },
205
+ (err, res) => {
206
+ if (err) return reject(err)
207
+ const iter = fromNodeStream(res);
208
+ resolve({
209
+ url: res.url,
210
+ method: res.method,
211
+ statusCode: res.statusCode,
212
+ statusMessage: res.statusMessage,
213
+ body: iter,
214
+ headers: res.headers,
215
+ });
216
+ }
217
+ );
218
+ })
219
+ }
220
+
221
+ var index = { request };
222
+
223
+ export default index;
224
+ export { request };
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "main": "index.cjs",
4
+ "module": "index.js",
5
+ "typings": "index.d.ts"
6
+ }
@@ -0,0 +1,170 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ /**
6
+ * @typedef {Object} GitProgressEvent
7
+ * @property {string} phase
8
+ * @property {number} loaded
9
+ * @property {number} total
10
+ */
11
+
12
+ /**
13
+ * @callback ProgressCallback
14
+ * @param {GitProgressEvent} progress
15
+ * @returns {void | Promise<void>}
16
+ */
17
+
18
+ /**
19
+ * @typedef {Object} GitHttpRequest
20
+ * @property {string} url - The URL to request
21
+ * @property {string} [method='GET'] - The HTTP method to use
22
+ * @property {Object<string, string>} [headers={}] - Headers to include in the HTTP request
23
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
24
+ * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
25
+ * @property {object} [signal] - Reserved for future use (canceling a request)
26
+ */
27
+
28
+ /**
29
+ * @typedef {Object} GitHttpResponse
30
+ * @property {string} url - The final URL that was fetched after any redirects
31
+ * @property {string} [method] - The HTTP method that was used
32
+ * @property {Object<string, string>} [headers] - HTTP response headers
33
+ * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of the response
34
+ * @property {number} statusCode - The HTTP status code
35
+ * @property {string} statusMessage - The HTTP status message
36
+ */
37
+
38
+ /**
39
+ * @callback HttpFetch
40
+ * @param {GitHttpRequest} request
41
+ * @returns {Promise<GitHttpResponse>}
42
+ */
43
+
44
+ /**
45
+ * @typedef {Object} HttpClient
46
+ * @property {HttpFetch} request
47
+ */
48
+
49
+ // Convert a value to an Async Iterator
50
+ // This will be easier with async generator functions.
51
+ function fromValue(value) {
52
+ let queue = [value];
53
+ return {
54
+ next() {
55
+ return Promise.resolve({ done: queue.length === 0, value: queue.pop() })
56
+ },
57
+ return() {
58
+ queue = [];
59
+ return {}
60
+ },
61
+ [Symbol.asyncIterator]() {
62
+ return this
63
+ },
64
+ }
65
+ }
66
+
67
+ function getIterator(iterable) {
68
+ if (iterable[Symbol.asyncIterator]) {
69
+ return iterable[Symbol.asyncIterator]()
70
+ }
71
+ if (iterable[Symbol.iterator]) {
72
+ return iterable[Symbol.iterator]()
73
+ }
74
+ if (iterable.next) {
75
+ return iterable
76
+ }
77
+ return fromValue(iterable)
78
+ }
79
+
80
+ // Currently 'for await' upsets my linters.
81
+ async function forAwait(iterable, cb) {
82
+ const iter = getIterator(iterable);
83
+ while (true) {
84
+ const { value, done } = await iter.next();
85
+ if (value) await cb(value);
86
+ if (done) break
87
+ }
88
+ if (iter.return) iter.return();
89
+ }
90
+
91
+ async function collect(iterable) {
92
+ let size = 0;
93
+ const buffers = [];
94
+ // This will be easier once `for await ... of` loops are available.
95
+ await forAwait(iterable, value => {
96
+ buffers.push(value);
97
+ size += value.byteLength;
98
+ });
99
+ const result = new Uint8Array(size);
100
+ let nextIndex = 0;
101
+ for (const buffer of buffers) {
102
+ result.set(buffer, nextIndex);
103
+ nextIndex += buffer.byteLength;
104
+ }
105
+ return result
106
+ }
107
+
108
+ // Convert a web ReadableStream (not Node stream!) to an Async Iterator
109
+ // adapted from https://jakearchibald.com/2017/async-iterators-and-generators/
110
+ function fromStream(stream) {
111
+ // Use native async iteration if it's available.
112
+ if (stream[Symbol.asyncIterator]) return stream
113
+ const reader = stream.getReader();
114
+ return {
115
+ next() {
116
+ return reader.read()
117
+ },
118
+ return() {
119
+ reader.releaseLock();
120
+ return {}
121
+ },
122
+ [Symbol.asyncIterator]() {
123
+ return this
124
+ },
125
+ }
126
+ }
127
+
128
+ /* eslint-env browser */
129
+
130
+ /**
131
+ * HttpClient
132
+ *
133
+ * @param {GitHttpRequest} request
134
+ * @returns {Promise<GitHttpResponse>}
135
+ */
136
+ async function request({
137
+ onProgress,
138
+ url,
139
+ method = 'GET',
140
+ headers = {},
141
+ body,
142
+ }) {
143
+ // streaming uploads aren't possible yet in the browser
144
+ if (body) {
145
+ body = await collect(body);
146
+ }
147
+ const res = await fetch(url, { method, headers, body });
148
+ const iter =
149
+ res.body && res.body.getReader
150
+ ? fromStream(res.body)
151
+ : [new Uint8Array(await res.arrayBuffer())];
152
+ // convert Header object to ordinary JSON
153
+ headers = {};
154
+ for (const [key, value] of res.headers.entries()) {
155
+ headers[key] = value;
156
+ }
157
+ return {
158
+ url: res.url,
159
+ method: res.method,
160
+ statusCode: res.status,
161
+ statusMessage: res.statusText,
162
+ body: iter,
163
+ headers: headers,
164
+ }
165
+ }
166
+
167
+ var index = { request };
168
+
169
+ exports.default = index;
170
+ exports.request = request;