保誠-保戶業務員媒合平台
HelenHuang
2022-06-09 9bdb95c9e34cef640534e5e5a1e2225a80442000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// - scan dirs
//   - stat items
//   - hash files
//   - stat dir items under
//     - hash files
// - hash files
 
const crypto = require('crypto');
const fs = require('graceful-fs');
const path = require('path');
 
const pkgDir = require('pkg-dir');
 
const promisify = require('./util/promisify');
 
const readFile = promisify(fs.readFile);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
 
function hashFile(file) {
  return readFile(file)
    .then(src => [
      file,
      crypto
        .createHash('md5')
        .update(src)
        .digest('hex'),
    ])
    .catch(() => {});
}
 
function hashObject(obj) {
  const hash = crypto.createHash('md5');
  obj.forEach(item => {
    hash.update(item[0]);
    hash.update(item[1]);
  });
  return hash.digest('hex');
}
 
function hashFiles(root, files) {
  return Promise.all(files.map(file => hashFile(path.join(root, file)))).then(
    hashes => hashes.filter(Boolean),
  );
}
 
function flatten(items) {
  return (items || []).reduce(
    (carry, item) => (item ? carry.concat(item) : carry),
    [],
  );
}
 
const inputs = async ({ files, directories, root = process.cwd() } = {}) => {
  let defaults;
  if (!files && !directories) {
    const lockFiles = (await Promise.all(
      ['package-lock.json', 'yarn.lock'].map(f =>
        stat(path.join(root, f)).then(() => f, () => null),
      ),
    )).filter(Boolean);
    if (lockFiles.length) {
      return lockFiles;
    }
  }
  if (!files) {
    files = ['package.json'];
  }
  if (!directories) {
    directories = ['node_modules'];
  }
  directories = directories.map(d => `${d}/*`);
  return flatten([files, directories]);
};
 
module.exports = options => {
  options = options || {};
  const root = options.root || pkgDir.sync(process.cwd());
  let files = options.files;
  let directories = options.directories;
 
  let hashDefaults = Promise.resolve();
  if (!files && !directories) {
    hashDefaults = hashFiles(root, ['package-lock.json', 'yarn.lock']);
  }
 
  return hashDefaults
    .then(_defaults => {
      if (_defaults && _defaults.length > 0) {
        return [_defaults];
      } else {
        if (!files) {
          files = ['package.json'];
        }
        if (!directories) {
          directories = ['node_modules'];
        }
      }
 
      return Promise.all([
        hashFiles(root, files),
        Promise.all(
          directories.map(dir =>
            readdir(path.join(root, dir))
              .then(items =>
                Promise.all(
                  items.map(item =>
                    stat(path.join(root, dir, item))
                      .then(stat => {
                        if (stat.isDirectory()) {
                          return hashFiles(path.join(root, dir, item), files);
                        }
                        if (stat.isFile()) {
                          return hashFile(path.join(root, dir, item)).then(
                            hash => (hash ? [hash] : hash),
                          );
                        }
                      })
                      .catch(function(...args) {
                        console.error(args);
                      }),
                  ),
                ).then(hashes => hashes.filter(Boolean)),
              )
              .catch(() => {})
              .then(flatten),
          ),
        ).then(flatten),
      ]);
    })
    .then(flatten)
    .then(items => {
      items.forEach(item => {
        item[0] = path.relative(root, item[0]);
      });
      // console.log(items);
      items.sort((a, b) => {
        if (a[0] < b[0]) {
          return -1;
        } else if (a[0] > b[0]) {
          return 1;
        }
        return 0;
      });
      return hashObject(items);
    });
};
 
module.exports.inputs = inputs;