@bratel/dgit 0.0.13 → 0.0.14

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/src/dgit.ts CHANGED
@@ -1,256 +1,266 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import async from 'async';
4
- import repo from './repo';
5
- import { createLogger } from './log';
6
- import { requestGetPromise, requestOnStream } from './request';
7
- import {
8
- DgitGlobalOption,
9
- RepoOptionType,
10
- RepoTreeNode,
11
- DgitLifeCycle,
12
- DgitLoadGitTree,
1
+ import type {
2
+ DgitGlobalOption,
3
+ DgitLifeCycle,
4
+ DgitLoadGitTree,
5
+ RepoOptionType,
6
+ RepoTreeNode,
13
7
  } from './type';
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import process from 'node:process';
11
+ import async from 'async';
14
12
  import {
15
- ParseGithubHttpsLink, isHttpsLink, MakeDirs,
13
+ isHttpsLink,
14
+ MakeDirs,
15
+ ParseGithubHttpsLink,
16
16
  } from './cmd/utils';
17
+ import { createLogger } from './log';
18
+ import repo from './repo';
19
+ import { requestGetPromise, requestOnStream } from './request';
17
20
 
18
21
  const UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36';
19
22
  const DEFAULT_PARALLEL_LIMIT = 10;
20
23
  const MAX_PARALLEL_LIMIT = 100;
21
24
  const JSON_STRINGIFY_PADDING = 2;
22
25
 
23
- const dgit = async (
24
- repoOption: RepoOptionType,
25
- dPath: string,
26
- dgitOptions?: DgitGlobalOption,
27
- hooks?: DgitLifeCycle & DgitLoadGitTree,
28
- ): Promise<void> => {
29
- const {
30
- username, password, token, githubLink, proxy = '',
31
- } = repoOption;
32
-
33
- let {
34
- owner, repoName, ref = 'master', relativePath = '.',
35
- } = repoOption;
36
-
37
- if (githubLink && isHttpsLink(githubLink)) {
38
- const parseResult = ParseGithubHttpsLink(githubLink);
39
- owner = parseResult.owner;
40
- repoName = parseResult.repoName;
41
- ref = parseResult.ref;
42
- relativePath = parseResult.relativePath;
43
- }
26
+ async function dgit(repoOption: RepoOptionType, dPath: string, dgitOptions?: DgitGlobalOption, hooks?: DgitLifeCycle & DgitLoadGitTree): Promise<void> {
27
+ const {
28
+ username,
29
+ password,
30
+ token,
31
+ githubLink,
32
+ proxy = '',
33
+ } = repoOption;
34
+
35
+ let {
36
+ owner,
37
+ repoName,
38
+ ref = 'master',
39
+ relativePath = '.',
40
+ } = repoOption;
41
+
42
+ if (githubLink && isHttpsLink(githubLink)) {
43
+ const parseResult = ParseGithubHttpsLink(githubLink);
44
+ owner = parseResult.owner;
45
+ repoName = parseResult.repoName;
46
+ ref = parseResult.ref;
47
+ relativePath = parseResult.relativePath;
48
+ }
49
+
50
+ if (!owner || !repoName) {
51
+ throw new Error('invalid repo option.');
52
+ }
53
+
54
+ const logger = createLogger(dgitOptions);
55
+
56
+ const { exclude = [], include = [] } = dgitOptions || {};
57
+
58
+ let { parallelLimit = DEFAULT_PARALLEL_LIMIT } = dgitOptions || {};
59
+ if (!parallelLimit || parallelLimit <= 0) {
60
+ logger('parallelLimit value is invalid.');
61
+ parallelLimit = DEFAULT_PARALLEL_LIMIT;
62
+ }
63
+
64
+ parallelLimit > MAX_PARALLEL_LIMIT && (parallelLimit = MAX_PARALLEL_LIMIT);
65
+
66
+ const {
67
+ onSuccess,
68
+ onError,
69
+ onProgress,
70
+ onFinish,
71
+ onRetry,
72
+ onResolved,
73
+ beforeLoadTree,
74
+ afterLoadTree,
75
+ } = hooks || {};
76
+
77
+ let onSuccessResolve: (data?: any) => void = () => {};
78
+ let onErrorReject: (err?: any) => void = () => {};
79
+
80
+ const prom: Promise<void> = new Promise((resolve, reject) => {
81
+ onSuccessResolve = resolve;
82
+ onErrorReject = reject;
83
+ });
84
+
85
+ const { getRepoTreeUrl, getDownloadUrl } = repo(owner, repoName, ref, proxy);
86
+ const url = getRepoTreeUrl();
87
+
88
+ const headers = {
89
+ 'User-Agent': UserAgent,
90
+ 'Authorization': token ? `token ${token}` : undefined,
91
+ };
92
+
93
+ const auth = username && password
94
+ ? {
95
+ user: username,
96
+ pass: password,
97
+ sendImmediately: true,
98
+ }
99
+ : undefined;
100
+
101
+ const options = {
102
+ url,
103
+ headers,
104
+ auth,
105
+ };
106
+
107
+ const destPath = path.isAbsolute(dPath) ? dPath : path.resolve(process.cwd(), dPath);
108
+
109
+ logger(' request repo tree options.');
110
+ logger(JSON.stringify(options, null, JSON_STRINGIFY_PADDING));
111
+
112
+ try {
113
+ logger(' loading remote repo tree...');
114
+ beforeLoadTree && beforeLoadTree();
115
+ const body = await requestGetPromise(options, dgitOptions || {}, {
116
+ onRetry() {
117
+ logger(` request ${url} failed. Retrying...`);
118
+ onRetry && onRetry();
119
+ },
120
+ });
44
121
 
45
- if (!owner || !repoName) {
46
- throw new Error('invalid repo option.');
47
- }
122
+ logger(' loading remote repo tree succeed.');
123
+ afterLoadTree && afterLoadTree();
124
+ const result = JSON.parse(body);
48
125
 
49
- const logger = createLogger(dgitOptions);
126
+ if (!result.tree || result.tree.length <= 0) {
127
+ throw new Error('404 repo not found!');
128
+ }
50
129
 
51
- const { exclude = [], include = []} = dgitOptions || {};
130
+ const treeNodeList: RepoTreeNode[] = result.tree;
131
+ const includeTreeNodeList = treeNodeList.filter((node) => {
132
+ const nPath = path.resolve(__dirname, node.path);
133
+ const rPath = path.resolve(__dirname, relativePath);
134
+ if (!nPath.startsWith(rPath) || node.type !== 'blob') {
135
+ return false;
136
+ }
137
+ if (
138
+ exclude.some(v => nPath.startsWith(path.resolve(rPath, v)))
139
+ && include.every(v => !nPath.startsWith(path.resolve(rPath, v)))
140
+ ) {
141
+ return false;
142
+ }
143
+ return true;
144
+ });
52
145
 
53
- let { parallelLimit = DEFAULT_PARALLEL_LIMIT } = dgitOptions || {};
54
- if (!parallelLimit || parallelLimit <= 0) {
55
- logger('parallelLimit value is invalid.');
56
- parallelLimit = DEFAULT_PARALLEL_LIMIT;
146
+ if (includeTreeNodeList.length <= 0) {
147
+ throw new Error(`404 repo ${relativePath} not found!`);
57
148
  }
58
149
 
59
- parallelLimit > MAX_PARALLEL_LIMIT && (parallelLimit = MAX_PARALLEL_LIMIT);
60
-
61
- const {
62
- onSuccess,
63
- onError,
64
- onProgress,
65
- onFinish,
66
- onRetry,
67
- onResolved,
68
- beforeLoadTree,
69
- afterLoadTree,
70
- } = hooks || {};
71
-
72
- let onSuccessResolve: (data?: any)=> void = () => {};
73
- let onErrorReject: (err?: any)=> void = () => {};
74
-
75
- const prom: Promise<void> = new Promise((resolve, reject) => {
76
- onSuccessResolve = resolve;
77
- onErrorReject = reject;
150
+ const totalStatus = includeTreeNodeList.reduce(
151
+ (prev, cur) => {
152
+ if (cur.type === 'blob') {
153
+ prev.size += cur.size;
154
+ prev.count++;
155
+ }
156
+ return prev;
157
+ },
158
+ { size: 0, count: 0 },
159
+ );
160
+
161
+ let currentSize = 0;
162
+ let currentCount = 0;
163
+
164
+ onResolved
165
+ && onResolved({
166
+ currentSize,
167
+ currentCount,
168
+ totalSize: totalStatus.size,
169
+ totalCount: totalStatus.count,
78
170
  });
79
171
 
80
- const { getRepoTreeUrl, getDownloadUrl } = repo(owner, repoName, ref, proxy);
81
- const url = getRepoTreeUrl();
82
-
83
- const headers = {
84
- 'User-Agent' : UserAgent,
85
- Authorization: token ? `token ${ token }` : undefined,
86
- };
87
-
88
- const auth = username && password ?
89
- {
90
- user : username,
91
- pass : password,
92
- sendImmediately: true,
93
- } :
94
- undefined;
95
-
96
- const options = {
97
- url, headers, auth,
98
- };
99
-
100
- const destPath = path.isAbsolute(dPath) ? dPath : path.resolve(process.cwd(), dPath);
101
-
102
- logger(' request repo tree options.');
103
- logger(JSON.stringify(options, null, JSON_STRINGIFY_PADDING));
104
-
105
- try {
106
- logger(' loading remote repo tree...');
107
- beforeLoadTree && beforeLoadTree();
108
- const body = await requestGetPromise(options, dgitOptions || {}, {
109
- onRetry () {
110
- logger(` request ${ url } failed. Retrying...`);
111
- onRetry && onRetry();
112
- },
113
- });
172
+ logger(' include files resolved.');
173
+ logger(
174
+ '',
175
+ JSON.stringify({
176
+ currentSize,
177
+ currentCount,
178
+ totalSize: totalStatus.size,
179
+ totalCount: totalStatus.count,
180
+ }),
181
+ );
182
+
183
+ async.eachLimit(
184
+ includeTreeNodeList,
185
+ parallelLimit,
186
+ (node, callback) => {
187
+ const downloadUrl = getDownloadUrl(node.path);
188
+
189
+ const rPath = path.resolve(destPath, relativePath);
190
+ const tPath = path.resolve(destPath, node.path);
191
+ const root = path.resolve(destPath, '.');
192
+
193
+ let targetPath: string;
194
+ if (rPath === tPath) {
195
+ targetPath = path.resolve(destPath, path.basename(tPath));
196
+ }
197
+ else {
198
+ targetPath = tPath.replace(rPath, root);
199
+ }
114
200
 
115
- logger(' loading remote repo tree succeed.');
116
- afterLoadTree && afterLoadTree();
117
- const result = JSON.parse(body);
201
+ logger('', node.path, relativePath, targetPath);
118
202
 
119
- if (!result.tree || result.tree.length <= 0) {
120
- throw new Error('404 repo not found!');
203
+ if (!fs.existsSync(path.dirname(targetPath))) {
204
+ MakeDirs(path.dirname(targetPath));
121
205
  }
122
206
 
123
- const treeNodeList: RepoTreeNode[] = result.tree;
124
- const includeTreeNodeList = treeNodeList.filter(node => {
125
- const nPath = path.resolve(__dirname, node.path);
126
- const rPath = path.resolve(__dirname, relativePath);
127
- if (!nPath.startsWith(rPath) || node.type !== 'blob') {
128
- return false;
129
- }
130
- if (
131
- exclude.some(v => nPath.startsWith(path.resolve(rPath, v))) &&
132
- include.every(v => !nPath.startsWith(path.resolve(rPath, v)))
133
- ) {
134
- return false;
135
- }
136
- return true;
137
- });
207
+ const ws = fs.createWriteStream(targetPath);
138
208
 
139
- if (includeTreeNodeList.length <= 0) {
140
- throw new Error(`404 repo ${ relativePath } not found!`);
141
- }
209
+ logger(` downloading from ${downloadUrl}...`);
142
210
 
143
- const totalStatus = includeTreeNodeList.reduce(
144
- (prev, cur) => {
145
- if (cur.type === 'blob') {
146
- prev.size += cur.size;
147
- prev.count++;
148
- }
149
- return prev;
150
- },
151
- { size: 0, count: 0 },
152
- );
153
-
154
- let currentSize = 0;
155
- let currentCount = 0;
156
-
157
- onResolved &&
158
- onResolved({
159
- currentSize,
160
- currentCount,
161
- totalSize : totalStatus.size,
162
- totalCount: totalStatus.count,
163
- });
211
+ requestOnStream(downloadUrl, ws, dgitOptions || {}, {
212
+ onSuccess() {
213
+ currentCount++;
214
+ currentSize += node.size;
215
+
216
+ logger(` write file ${node.path} succeed.
217
+ size: [${currentSize}/${totalStatus.size}],
218
+ count: [${currentCount}/${totalStatus.count}]`);
164
219
 
165
- logger(' include files resolved.');
166
- logger(
167
- '',
168
- JSON.stringify({
220
+ onProgress
221
+ && onProgress(
222
+ {
223
+ totalCount: totalStatus.count,
224
+ totalSize: totalStatus.size,
169
225
  currentSize,
170
226
  currentCount,
171
- totalSize : totalStatus.size,
172
- totalCount: totalStatus.count,
173
- }),
174
- );
175
-
176
- async.eachLimit(
177
- includeTreeNodeList,
178
- parallelLimit,
179
- (node, callback) => {
180
- const downloadUrl = getDownloadUrl(node.path);
181
-
182
- const rPath = path.resolve(destPath, relativePath);
183
- const tPath = path.resolve(destPath, node.path);
184
- const root = path.resolve(destPath, '.');
185
-
186
- let targetPath: string;
187
- if (rPath === tPath) {
188
- targetPath = path.resolve(destPath, path.basename(tPath));
189
- } else {
190
- targetPath = tPath.replace(rPath, root);
191
- }
192
-
193
- logger('', node.path, relativePath, targetPath);
194
-
195
- if (!fs.existsSync(path.dirname(targetPath))) {
196
- MakeDirs(path.dirname(targetPath));
197
- }
198
-
199
- const ws = fs.createWriteStream(targetPath);
200
-
201
- logger(` downloading from ${ downloadUrl }...`);
202
-
203
- requestOnStream(downloadUrl, ws, dgitOptions || {}, {
204
- onSuccess () {
205
- currentCount++;
206
- currentSize += node.size;
207
-
208
- logger(` write file ${ node.path } succeed.
209
- size: [${ currentSize }/${ totalStatus.size }],
210
- count: [${ currentCount }/${ totalStatus.count }]`);
211
-
212
- onProgress &&
213
- onProgress(
214
- {
215
- totalCount: totalStatus.count,
216
- totalSize : totalStatus.size,
217
- currentSize,
218
- currentCount,
219
- },
220
- node,
221
- );
222
-
223
- callback();
224
- },
225
- onError (err) {
226
- logger('', err);
227
- callback(new Error(` request ${ downloadUrl } failed.`));
228
- },
229
- onRetry () {
230
- logger(` request ${ downloadUrl } failed. Retrying...`);
231
- onRetry && onRetry();
232
- },
233
- });
234
- },
235
- err => {
236
- if (err) {
237
- onError && onError(err);
238
- onFinish && onFinish();
239
- onErrorReject(err);
240
- } else {
241
- onSuccess && onSuccess();
242
- onFinish && onFinish();
243
- onSuccessResolve();
244
- }
245
- },
246
- );
247
- } catch (error) {
248
- onError && onError(error);
249
- onFinish && onFinish();
250
- onErrorReject(error);
251
- }
252
-
253
- return prom;
254
- };
227
+ },
228
+ node,
229
+ );
230
+
231
+ callback();
232
+ },
233
+ onError(err) {
234
+ logger('', err);
235
+ callback(new Error(` request ${downloadUrl} failed.`));
236
+ },
237
+ onRetry() {
238
+ logger(` request ${downloadUrl} failed. Retrying...`);
239
+ onRetry && onRetry();
240
+ },
241
+ });
242
+ },
243
+ (err) => {
244
+ if (err) {
245
+ onError && onError(err);
246
+ onFinish && onFinish();
247
+ onErrorReject(err);
248
+ }
249
+ else {
250
+ onSuccess && onSuccess();
251
+ onFinish && onFinish();
252
+ onSuccessResolve();
253
+ }
254
+ },
255
+ );
256
+ }
257
+ catch (error) {
258
+ onError && onError(error);
259
+ onFinish && onFinish();
260
+ onErrorReject(error);
261
+ }
262
+
263
+ return prom;
264
+ }
255
265
 
256
266
  export default dgit;
package/src/log.ts CHANGED
@@ -1,12 +1,14 @@
1
- import { DgitGlobalOption } from './type';
1
+ import type { DgitGlobalOption } from './type';
2
2
 
3
3
  const DEFAULT_PREFIX = '[dgit-logger]';
4
4
 
5
- export const createLogger = (option?: DgitGlobalOption) => (...message: any[]) => {
5
+ export function createLogger(option?: DgitGlobalOption) {
6
+ return (...message: any[]) => {
6
7
  if (option && option.log) {
7
- const prefix = option ?
8
- option.logPrefix || DEFAULT_PREFIX :
9
- DEFAULT_PREFIX;
10
- console.log(prefix, ...message, '\n');
8
+ const prefix = option
9
+ ? option.logPrefix || DEFAULT_PREFIX
10
+ : DEFAULT_PREFIX;
11
+ console.log(prefix, ...message, '\n');
11
12
  }
12
- };
13
+ };
14
+ }
package/src/repo.ts CHANGED
@@ -1,6 +1,8 @@
1
- const repoUtils = (owner: string, repoName: string, ref: string, proxy: string) => ({
2
- getRepoTreeUrl: () => `https://api.github.com/repos/${ owner }/${ repoName }/git/trees/${ ref }?recursive=1`,
3
- getDownloadUrl: (path: string) => `${ proxy ? `${ proxy }/` : '' }https://raw.githubusercontent.com/${ owner }/${ repoName }/${ ref }/${ path }`,
4
- });
1
+ function repoUtils(owner: string, repoName: string, ref: string, proxy: string) {
2
+ return {
3
+ getRepoTreeUrl: () => `https://api.github.com/repos/${owner}/${repoName}/git/trees/${ref}?recursive=1`,
4
+ getDownloadUrl: (path: string) => `${proxy ? `${proxy}/` : ''}https://raw.githubusercontent.com/${owner}/${repoName}/${ref}/${path}`,
5
+ };
6
+ }
5
7
 
6
8
  export default repoUtils;