prepare-package 1.0.5 → 1.1.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.
Files changed (3) hide show
  1. package/dist/index.js +186 -34
  2. package/package.json +4 -3
  3. package/src/index.js +186 -34
package/dist/index.js CHANGED
@@ -1,15 +1,20 @@
1
- module.exports = function (options) {
2
- const jetpack = require('fs-jetpack');
3
- const fetch = require('wonderful-fetch');
4
- const path = require('path');
5
- const chalk = require('chalk');
6
- const thisPackageJSON = require('../package.json');
7
- const theirPackageJSON = require(path.join(process.cwd(), 'package.json'));
8
- const isLivePreparation = theirPackageJSON.name !== 'prepare-package';
9
- // const argv = require('yargs').argv;
1
+ const jetpack = require('fs-jetpack');
2
+ const fetch = require('wonderful-fetch');
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+
6
+ // const argv = require('yargs').argv;
10
7
 
8
+ module.exports = async function (options) {
9
+ // Set the options
11
10
  options = options || {};
12
11
  options.purge = typeof options.purge === 'undefined' ? true : options.purge;
12
+ options.cwd = options.cwd || process.cwd();
13
+ options.isPostInstall = typeof options.isPostInstall === 'undefined' ? false : options.isPostInstall;
14
+
15
+ const thisPackageJSON = require('../package.json');
16
+ const theirPackageJSON = require(path.join(options.cwd, 'package.json'));
17
+ const isLivePreparation = theirPackageJSON.name !== 'prepare-package';
13
18
 
14
19
  // const options = {
15
20
  // purge: argv['--purge'] || argv['-p'],
@@ -18,16 +23,16 @@ module.exports = function (options) {
18
23
  // Fix their package.json
19
24
  theirPackageJSON.main = theirPackageJSON.main || './dist/index.js';
20
25
  theirPackageJSON.preparePackage = theirPackageJSON.preparePackage || {};
21
- theirPackageJSON.preparePackage.input = path.resolve(theirPackageJSON.preparePackage.input || './src');
22
- theirPackageJSON.preparePackage.output = path.resolve(theirPackageJSON.preparePackage.output || './dist');
26
+ theirPackageJSON.preparePackage.input = theirPackageJSON.preparePackage.input || './src';
27
+ theirPackageJSON.preparePackage.output = theirPackageJSON.preparePackage.output || './dist';
23
28
  theirPackageJSON.preparePackage.replace = theirPackageJSON.preparePackage.replace || {};
24
29
 
25
30
  // Add script
26
31
  theirPackageJSON.scripts = theirPackageJSON.scripts || {};
27
32
  theirPackageJSON.scripts.prepare = theirPackageJSON.scripts.prepare
28
- || 'node -e "require(`prepare-package`)()"';
33
+ || 'node -e \'require(`prepare-package`)()\'';
29
34
  theirPackageJSON.scripts['prepare:watch'] = theirPackageJSON.scripts['prepare:watch']
30
- || `nodemon -w ${theirPackageJSON.preparePackage.input} -e '*' --exec 'npm run prepare'`
35
+ || `nodemon -w ./src -e '*' --exec 'npm run prepare'`
31
36
 
32
37
  // Log the options
33
38
  console.log(chalk.blue(`[prepare-package]: Options... purge=${options.purge}`));
@@ -37,44 +42,191 @@ module.exports = function (options) {
37
42
 
38
43
  // Remove the output folder
39
44
  jetpack.remove(
40
- theirPackageJSON.preparePackage.output,
45
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.output),
41
46
  )
42
47
 
43
48
  // Copy the input folder to the output folder
44
49
  jetpack.copy(
45
- theirPackageJSON.preparePackage.input,
46
- theirPackageJSON.preparePackage.output,
50
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.input),
51
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.output),
47
52
  )
48
53
 
49
54
  // Only do this part on the actual package that is using THIS package because we dont't want to replace THIS {version}
50
55
  if (isLivePreparation) {
51
- function _replaceMain() {
52
- let content = jetpack.read(theirPackageJSON.main)
53
- // .replace(/{version}/igm, package.version)
54
- .replace(/{version}/igm, theirPackageJSON.version)
55
- return content;
56
- }
56
+ const mainPath = path.resolve(options.cwd, theirPackageJSON.main);
57
+
58
+ // Replace the main file
59
+ jetpack.write(
60
+ mainPath,
61
+ jetpack.read(mainPath)
62
+ .replace(/{version}/igm, theirPackageJSON.version),
63
+ );
64
+
65
+ // Replace the package.json
57
66
  jetpack.write(
58
- theirPackageJSON.main,
59
- _replaceMain()
60
- )
67
+ path.resolve(options.cwd, 'package.json'),
68
+ JSON.stringify(theirPackageJSON, null, 2)
69
+ );
61
70
  }
62
71
 
72
+ // Handle post install
73
+ if (options.isPostInstall) {
74
+ // Send analytics
75
+ await sendAnalytics(thisPackageJSON, theirPackageJSON)
76
+ .then(() => {
77
+ console.log(chalk.green(`[prepare-package]: Sent analytics...`));
78
+ })
79
+ .catch(e => {
80
+ console.log(chalk.red(`[prepare-package]: Failed to send analytics...`, e));
81
+ });
82
+ }
83
+
84
+ // If purge is disabled, then return
63
85
  if (options.purge === false) {
64
86
  return;
65
- } else {
66
- return fetch(`https://purge.jsdelivr.net/npm/${theirPackageJSON.name}@latest`, {
87
+ }
88
+
89
+ // Purge the CDN
90
+ return fetch(`https://purge.jsdelivr.net/npm/${theirPackageJSON.name}@latest`, {
91
+ response: 'json',
92
+ tries: 3,
93
+ })
94
+ .then(result => {
95
+ console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
96
+ })
97
+ .catch(e => {
98
+ console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
99
+ })
100
+ }
101
+
102
+ // Send analytics
103
+ function sendAnalytics(thisPackageJSON, theirPackageJSON) {
104
+ return new Promise(async function(resolve, reject) {
105
+ const uuidv5 = require('uuid').v5;
106
+ const os = require('os');
107
+ const userInfo = os.userInfo();
108
+
109
+ // Build url and body
110
+ const analyticsId = 'G-9YP4NNBLY3';
111
+ const analyticsSecret = 'w3Z2tfucR9KFPB8it5WkyQ';
112
+ const url = `https://www.google-analytics.com/mp/collect?measurement_id=${analyticsId}&api_secret=${analyticsSecret}`;
113
+ const mac = getDeviceUniqueId();
114
+ const uuid = uuidv5(mac, '4caf995a-3d43-451b-b34d-e535d2663bc1');
115
+ const simpleOS = getSimpleOS(os.platform());
116
+ const body = {
117
+ client_id: uuid,
118
+ user_id: uuid,
119
+ // timestamp_micros: new Date().getTime() * 1000,
120
+ user_properties: {
121
+ operating_system: simpleOS,
122
+ },
123
+ user_data: {
124
+ },
125
+ // consent: {},
126
+ // non_personalized_ads: false,
127
+ events: [{
128
+ name: theirPackageJSON.name,
129
+ params: {
130
+ packageName: theirPackageJSON.name,
131
+ packageVersion: theirPackageJSON.version,
132
+ preparePackageVersion: thisPackageJSON.version,
133
+ os: simpleOS,
134
+ platform: os.platform(),
135
+ arch: os.arch(),
136
+ release: os.release(),
137
+ hostname: os.hostname(),
138
+ cpus: os.cpus().length,
139
+ memory: os.totalmem(),
140
+ uptime: os.uptime(),
141
+ username: userInfo.username,
142
+ homedir: userInfo.homedir,
143
+ shell: userInfo.shell,
144
+ uid: userInfo.uid,
145
+ gid: userInfo.gid,
146
+ },
147
+ }],
148
+ }
149
+
150
+ // Get the user's location
151
+ const geolocation = await fetch('https://ipapi.co/json/', {
67
152
  response: 'json',
68
- tries: 3,
69
- })
70
- .then(result => {
71
- // console.log(chalk.green(`[prepare-package]: Purged... name=${theirPackageJSON.name}`), result);
72
- console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
153
+ tries: 2,
154
+ timeout: 30000,
73
155
  })
74
156
  .catch(e => {
75
- console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
157
+ console.log(chalk.red(`[prepare-package]: Failed to get geolocation...`, e));
158
+ });
159
+
160
+ // Add the geolocation to the body
161
+ if (geolocation) {
162
+ body.user_data.city = geolocation.city || 'Unknown';
163
+ body.user_data.region = geolocation.region || 'Unknown';
164
+ body.user_data.country = geolocation.country || 'Unknown';
165
+
166
+ body.user_properties.language = (geolocation.languages || 'Unknown').split(',')[0];
167
+ }
168
+
169
+ // Log the options
170
+ // console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid), body, body.events[0].params);
171
+ console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid));
172
+
173
+ // Send event
174
+ fetch(url, {
175
+ method: 'post',
176
+ response: 'text',
177
+ tries: 2,
178
+ timeout: 30000,
179
+ body: body,
76
180
  })
181
+ .then((r) => {
182
+ resolve(r);
183
+ })
184
+ .catch((e) => {
185
+ reject(e);
186
+ });
187
+ });
188
+ }
189
+
190
+ const getDeviceUniqueId = () => {
191
+ const os = require('os');
192
+ const interfaces = os.networkInterfaces();
193
+
194
+ // Find the first valid MAC address
195
+ for (const name in interfaces) {
196
+ for (const net of interfaces[name]) {
197
+ if (!net.internal && net.mac && net.mac !== '00:00:00:00:00:00') {
198
+ return net.mac;
199
+ }
200
+ }
77
201
  }
78
202
 
203
+ // Log
204
+ console.warn('No valid MAC address found. Generating a random MAC address.');
205
+
206
+ // Generate a random MAC address
207
+ const hexDigits = '0123456789ABCDEF';
208
+ let mac = '';
209
+ for (let i = 0; i < 6; i++) {
210
+ let byte = '';
211
+ for (let j = 0; j < 2; j++) {
212
+ byte += hexDigits.charAt(Math.floor(Math.random() * 16));
213
+ }
214
+ mac += byte;
215
+ if (i !== 5) mac += ':';
216
+ }
217
+ return mac;
218
+ };
219
+
220
+ const getSimpleOS = (platform) => {
221
+ switch (platform) {
222
+ case 'darwin':
223
+ return 'mac';
224
+ case 'win32':
225
+ return 'windows';
226
+ case 'linux':
227
+ return 'linux';
228
+ default:
229
+ return platform;
230
+ }
231
+ };
79
232
 
80
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prepare-package",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "description": "Prepare a Node.js package before being published",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  "start": "node -e 'require(`./src/index.js`)()'",
9
9
  "prepare": "node -e 'require(`./src/index.js`)()'",
10
10
  "prepare:watch": "nodemon -w ./src -e '*' --exec 'npm run prepare'",
11
- "postinstall": "node -e 'console.log(`🚀 prepare-package has been installed successfully!`)'"
11
+ "postinstall": "node -e 'require(`./dist/index.js`)({cwd: process.env.INIT_CWD, isPostInstall: true})'"
12
12
  },
13
13
  "preparePackage": {
14
14
  "input": "src",
@@ -37,7 +37,8 @@
37
37
  "dependencies": {
38
38
  "chalk": "^4.1.2",
39
39
  "fs-jetpack": "^4.3.1",
40
- "wonderful-fetch": "^1.0.0"
40
+ "uuid": "^9.0.1",
41
+ "wonderful-fetch": "^1.1.9"
41
42
  },
42
43
  "devDependencies": {
43
44
  "mocha": "^8.4.0"
package/src/index.js CHANGED
@@ -1,15 +1,20 @@
1
- module.exports = function (options) {
2
- const jetpack = require('fs-jetpack');
3
- const fetch = require('wonderful-fetch');
4
- const path = require('path');
5
- const chalk = require('chalk');
6
- const thisPackageJSON = require('../package.json');
7
- const theirPackageJSON = require(path.join(process.cwd(), 'package.json'));
8
- const isLivePreparation = theirPackageJSON.name !== 'prepare-package';
9
- // const argv = require('yargs').argv;
1
+ const jetpack = require('fs-jetpack');
2
+ const fetch = require('wonderful-fetch');
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+
6
+ // const argv = require('yargs').argv;
10
7
 
8
+ module.exports = async function (options) {
9
+ // Set the options
11
10
  options = options || {};
12
11
  options.purge = typeof options.purge === 'undefined' ? true : options.purge;
12
+ options.cwd = options.cwd || process.cwd();
13
+ options.isPostInstall = typeof options.isPostInstall === 'undefined' ? false : options.isPostInstall;
14
+
15
+ const thisPackageJSON = require('../package.json');
16
+ const theirPackageJSON = require(path.join(options.cwd, 'package.json'));
17
+ const isLivePreparation = theirPackageJSON.name !== 'prepare-package';
13
18
 
14
19
  // const options = {
15
20
  // purge: argv['--purge'] || argv['-p'],
@@ -18,16 +23,16 @@ module.exports = function (options) {
18
23
  // Fix their package.json
19
24
  theirPackageJSON.main = theirPackageJSON.main || './dist/index.js';
20
25
  theirPackageJSON.preparePackage = theirPackageJSON.preparePackage || {};
21
- theirPackageJSON.preparePackage.input = path.resolve(theirPackageJSON.preparePackage.input || './src');
22
- theirPackageJSON.preparePackage.output = path.resolve(theirPackageJSON.preparePackage.output || './dist');
26
+ theirPackageJSON.preparePackage.input = theirPackageJSON.preparePackage.input || './src';
27
+ theirPackageJSON.preparePackage.output = theirPackageJSON.preparePackage.output || './dist';
23
28
  theirPackageJSON.preparePackage.replace = theirPackageJSON.preparePackage.replace || {};
24
29
 
25
30
  // Add script
26
31
  theirPackageJSON.scripts = theirPackageJSON.scripts || {};
27
32
  theirPackageJSON.scripts.prepare = theirPackageJSON.scripts.prepare
28
- || 'node -e "require(`prepare-package`)()"';
33
+ || 'node -e \'require(`prepare-package`)()\'';
29
34
  theirPackageJSON.scripts['prepare:watch'] = theirPackageJSON.scripts['prepare:watch']
30
- || `nodemon -w ${theirPackageJSON.preparePackage.input} -e '*' --exec 'npm run prepare'`
35
+ || `nodemon -w ./src -e '*' --exec 'npm run prepare'`
31
36
 
32
37
  // Log the options
33
38
  console.log(chalk.blue(`[prepare-package]: Options... purge=${options.purge}`));
@@ -37,44 +42,191 @@ module.exports = function (options) {
37
42
 
38
43
  // Remove the output folder
39
44
  jetpack.remove(
40
- theirPackageJSON.preparePackage.output,
45
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.output),
41
46
  )
42
47
 
43
48
  // Copy the input folder to the output folder
44
49
  jetpack.copy(
45
- theirPackageJSON.preparePackage.input,
46
- theirPackageJSON.preparePackage.output,
50
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.input),
51
+ path.resolve(options.cwd, theirPackageJSON.preparePackage.output),
47
52
  )
48
53
 
49
54
  // Only do this part on the actual package that is using THIS package because we dont't want to replace THIS {version}
50
55
  if (isLivePreparation) {
51
- function _replaceMain() {
52
- let content = jetpack.read(theirPackageJSON.main)
53
- // .replace(/{version}/igm, package.version)
54
- .replace(/{version}/igm, theirPackageJSON.version)
55
- return content;
56
- }
56
+ const mainPath = path.resolve(options.cwd, theirPackageJSON.main);
57
+
58
+ // Replace the main file
59
+ jetpack.write(
60
+ mainPath,
61
+ jetpack.read(mainPath)
62
+ .replace(/{version}/igm, theirPackageJSON.version),
63
+ );
64
+
65
+ // Replace the package.json
57
66
  jetpack.write(
58
- theirPackageJSON.main,
59
- _replaceMain()
60
- )
67
+ path.resolve(options.cwd, 'package.json'),
68
+ JSON.stringify(theirPackageJSON, null, 2)
69
+ );
61
70
  }
62
71
 
72
+ // Handle post install
73
+ if (options.isPostInstall) {
74
+ // Send analytics
75
+ await sendAnalytics(thisPackageJSON, theirPackageJSON)
76
+ .then(() => {
77
+ console.log(chalk.green(`[prepare-package]: Sent analytics...`));
78
+ })
79
+ .catch(e => {
80
+ console.log(chalk.red(`[prepare-package]: Failed to send analytics...`, e));
81
+ });
82
+ }
83
+
84
+ // If purge is disabled, then return
63
85
  if (options.purge === false) {
64
86
  return;
65
- } else {
66
- return fetch(`https://purge.jsdelivr.net/npm/${theirPackageJSON.name}@latest`, {
87
+ }
88
+
89
+ // Purge the CDN
90
+ return fetch(`https://purge.jsdelivr.net/npm/${theirPackageJSON.name}@latest`, {
91
+ response: 'json',
92
+ tries: 3,
93
+ })
94
+ .then(result => {
95
+ console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
96
+ })
97
+ .catch(e => {
98
+ console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
99
+ })
100
+ }
101
+
102
+ // Send analytics
103
+ function sendAnalytics(thisPackageJSON, theirPackageJSON) {
104
+ return new Promise(async function(resolve, reject) {
105
+ const uuidv5 = require('uuid').v5;
106
+ const os = require('os');
107
+ const userInfo = os.userInfo();
108
+
109
+ // Build url and body
110
+ const analyticsId = 'G-9YP4NNBLY3';
111
+ const analyticsSecret = 'w3Z2tfucR9KFPB8it5WkyQ';
112
+ const url = `https://www.google-analytics.com/mp/collect?measurement_id=${analyticsId}&api_secret=${analyticsSecret}`;
113
+ const mac = getDeviceUniqueId();
114
+ const uuid = uuidv5(mac, '4caf995a-3d43-451b-b34d-e535d2663bc1');
115
+ const simpleOS = getSimpleOS(os.platform());
116
+ const body = {
117
+ client_id: uuid,
118
+ user_id: uuid,
119
+ // timestamp_micros: new Date().getTime() * 1000,
120
+ user_properties: {
121
+ operating_system: simpleOS,
122
+ },
123
+ user_data: {
124
+ },
125
+ // consent: {},
126
+ // non_personalized_ads: false,
127
+ events: [{
128
+ name: theirPackageJSON.name,
129
+ params: {
130
+ packageName: theirPackageJSON.name,
131
+ packageVersion: theirPackageJSON.version,
132
+ preparePackageVersion: thisPackageJSON.version,
133
+ os: simpleOS,
134
+ platform: os.platform(),
135
+ arch: os.arch(),
136
+ release: os.release(),
137
+ hostname: os.hostname(),
138
+ cpus: os.cpus().length,
139
+ memory: os.totalmem(),
140
+ uptime: os.uptime(),
141
+ username: userInfo.username,
142
+ homedir: userInfo.homedir,
143
+ shell: userInfo.shell,
144
+ uid: userInfo.uid,
145
+ gid: userInfo.gid,
146
+ },
147
+ }],
148
+ }
149
+
150
+ // Get the user's location
151
+ const geolocation = await fetch('https://ipapi.co/json/', {
67
152
  response: 'json',
68
- tries: 3,
69
- })
70
- .then(result => {
71
- // console.log(chalk.green(`[prepare-package]: Purged... name=${theirPackageJSON.name}`), result);
72
- console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
153
+ tries: 2,
154
+ timeout: 30000,
73
155
  })
74
156
  .catch(e => {
75
- console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
157
+ console.log(chalk.red(`[prepare-package]: Failed to get geolocation...`, e));
158
+ });
159
+
160
+ // Add the geolocation to the body
161
+ if (geolocation) {
162
+ body.user_data.city = geolocation.city || 'Unknown';
163
+ body.user_data.region = geolocation.region || 'Unknown';
164
+ body.user_data.country = geolocation.country || 'Unknown';
165
+
166
+ body.user_properties.language = (geolocation.languages || 'Unknown').split(',')[0];
167
+ }
168
+
169
+ // Log the options
170
+ // console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid), body, body.events[0].params);
171
+ console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid));
172
+
173
+ // Send event
174
+ fetch(url, {
175
+ method: 'post',
176
+ response: 'text',
177
+ tries: 2,
178
+ timeout: 30000,
179
+ body: body,
76
180
  })
181
+ .then((r) => {
182
+ resolve(r);
183
+ })
184
+ .catch((e) => {
185
+ reject(e);
186
+ });
187
+ });
188
+ }
189
+
190
+ const getDeviceUniqueId = () => {
191
+ const os = require('os');
192
+ const interfaces = os.networkInterfaces();
193
+
194
+ // Find the first valid MAC address
195
+ for (const name in interfaces) {
196
+ for (const net of interfaces[name]) {
197
+ if (!net.internal && net.mac && net.mac !== '00:00:00:00:00:00') {
198
+ return net.mac;
199
+ }
200
+ }
77
201
  }
78
202
 
203
+ // Log
204
+ console.warn('No valid MAC address found. Generating a random MAC address.');
205
+
206
+ // Generate a random MAC address
207
+ const hexDigits = '0123456789ABCDEF';
208
+ let mac = '';
209
+ for (let i = 0; i < 6; i++) {
210
+ let byte = '';
211
+ for (let j = 0; j < 2; j++) {
212
+ byte += hexDigits.charAt(Math.floor(Math.random() * 16));
213
+ }
214
+ mac += byte;
215
+ if (i !== 5) mac += ':';
216
+ }
217
+ return mac;
218
+ };
219
+
220
+ const getSimpleOS = (platform) => {
221
+ switch (platform) {
222
+ case 'darwin':
223
+ return 'mac';
224
+ case 'win32':
225
+ return 'windows';
226
+ case 'linux':
227
+ return 'linux';
228
+ default:
229
+ return platform;
230
+ }
231
+ };
79
232
 
80
- }