prepare-package 1.1.0 → 1.1.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 (3) hide show
  1. package/dist/index.js +164 -9
  2. package/package.json +4 -3
  3. package/src/index.js +164 -9
package/dist/index.js CHANGED
@@ -2,13 +2,15 @@ const jetpack = require('fs-jetpack');
2
2
  const fetch = require('wonderful-fetch');
3
3
  const path = require('path');
4
4
  const chalk = require('chalk');
5
+
5
6
  // const argv = require('yargs').argv;
6
7
 
7
- module.exports = function (options) {
8
+ module.exports = async function (options) {
8
9
  // Set the options
9
10
  options = options || {};
10
11
  options.purge = typeof options.purge === 'undefined' ? true : options.purge;
11
12
  options.cwd = options.cwd || process.cwd();
13
+ options.isPostInstall = typeof options.isPostInstall === 'undefined' ? false : options.isPostInstall;
12
14
 
13
15
  const thisPackageJSON = require('../package.json');
14
16
  const theirPackageJSON = require(path.join(options.cwd, 'package.json'));
@@ -67,20 +69,173 @@ module.exports = function (options) {
67
69
  );
68
70
  }
69
71
 
72
+ // Handle post install
73
+ if (options.isPostInstall) {
74
+ // Send analytics
75
+ await sendAnalytics(thisPackageJSON, theirPackageJSON)
76
+ .then((r) => {
77
+ console.log(chalk.green(`[prepare-package]: Sent analytics code=${r.status}...`));
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
70
85
  if (options.purge === false) {
71
86
  return;
72
- } else {
73
- 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 name = (theirPackageJSON.name || 'unknown')
117
+ // Replace anything not a letter, number, or underscore with an underscore
118
+ .replace(/[^a-zA-Z0-9_]/g, '_')
119
+ // Remove leading and trailing underscores
120
+ .replace(/^_+|_+$/g, '')
121
+ // Remove multiple underscores
122
+ .replace(/_+/g, '_');
123
+
124
+ // Build body
125
+ const body = {
126
+ client_id: uuid,
127
+ user_id: uuid,
128
+ // timestamp_micros: new Date().getTime() * 1000,
129
+ user_properties: {
130
+ // operating_system: simpleOS, // CAUSES EVENT TO NOT BE SENT
131
+ },
132
+ user_data: {
133
+ },
134
+ // consent: {},
135
+ // non_personalized_ads: false,
136
+ events: [{
137
+ name: name,
138
+ params: {
139
+ packageName: theirPackageJSON.name,
140
+ packageVersion: theirPackageJSON.version,
141
+ preparePackageVersion: thisPackageJSON.version,
142
+ os: simpleOS,
143
+ platform: os.platform(),
144
+ arch: os.arch(),
145
+ release: os.release(),
146
+ hostname: os.hostname(),
147
+ cpus: os.cpus().length,
148
+ memory: os.totalmem(),
149
+ uptime: os.uptime(),
150
+ username: userInfo.username,
151
+ homedir: userInfo.homedir,
152
+ shell: userInfo.shell,
153
+ uid: userInfo.uid,
154
+ gid: userInfo.gid,
155
+ },
156
+ }],
157
+ }
158
+
159
+ // Get the user's location
160
+ const geolocation = await fetch('https://ipapi.co/json/', {
74
161
  response: 'json',
75
- tries: 3,
76
- })
77
- .then(result => {
78
- console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
162
+ tries: 2,
163
+ timeout: 30000,
79
164
  })
80
165
  .catch(e => {
81
- console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
166
+ console.log(chalk.red(`[prepare-package]: Failed to get geolocation...`, e));
167
+ });
168
+
169
+ // Add the geolocation to the body
170
+ if (geolocation) {
171
+ body.user_data.city = geolocation.city || 'Unknown';
172
+ body.user_data.region = geolocation.region || 'Unknown';
173
+ body.user_data.country = geolocation.country || 'Unknown';
174
+
175
+ body.user_properties.language = (geolocation.languages || 'Unknown').split(',')[0];
176
+ }
177
+
178
+ // Log the options
179
+ console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid), body, body.events[0].params);
180
+ // console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid));
181
+
182
+ // Send event
183
+ fetch(url, {
184
+ method: 'post',
185
+ response: 'raw',
186
+ tries: 2,
187
+ timeout: 30000,
188
+ body: body,
82
189
  })
83
- }
190
+ .then((r) => {
191
+ resolve(r);
192
+ })
193
+ .catch((e) => {
194
+ reject(e);
195
+ });
196
+ });
84
197
  }
85
198
 
199
+ const getDeviceUniqueId = () => {
200
+ const os = require('os');
201
+ const interfaces = os.networkInterfaces();
202
+
203
+ // Find the first valid MAC address
204
+ for (const name in interfaces) {
205
+ for (const net of interfaces[name]) {
206
+ if (!net.internal && net.mac && net.mac !== '00:00:00:00:00:00') {
207
+ return net.mac;
208
+ }
209
+ }
210
+ }
211
+
212
+ // Log
213
+ console.warn('No valid MAC address found. Generating a random MAC address.');
214
+
215
+ // Generate a random MAC address
216
+ const hexDigits = '0123456789ABCDEF';
217
+ let mac = '';
218
+ for (let i = 0; i < 6; i++) {
219
+ let byte = '';
220
+ for (let j = 0; j < 2; j++) {
221
+ byte += hexDigits.charAt(Math.floor(Math.random() * 16));
222
+ }
223
+ mac += byte;
224
+ if (i !== 5) mac += ':';
225
+ }
226
+ return mac;
227
+ };
228
+
229
+ const getSimpleOS = (platform) => {
230
+ switch (platform) {
231
+ case 'darwin':
232
+ return 'mac';
233
+ case 'win32':
234
+ return 'windows';
235
+ case 'linux':
236
+ return 'linux';
237
+ default:
238
+ return platform;
239
+ }
240
+ };
86
241
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prepare-package",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
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 'require(`./dist/index.js`)({cwd: process.env.INIT_CWD})'"
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
@@ -2,13 +2,15 @@ const jetpack = require('fs-jetpack');
2
2
  const fetch = require('wonderful-fetch');
3
3
  const path = require('path');
4
4
  const chalk = require('chalk');
5
+
5
6
  // const argv = require('yargs').argv;
6
7
 
7
- module.exports = function (options) {
8
+ module.exports = async function (options) {
8
9
  // Set the options
9
10
  options = options || {};
10
11
  options.purge = typeof options.purge === 'undefined' ? true : options.purge;
11
12
  options.cwd = options.cwd || process.cwd();
13
+ options.isPostInstall = typeof options.isPostInstall === 'undefined' ? false : options.isPostInstall;
12
14
 
13
15
  const thisPackageJSON = require('../package.json');
14
16
  const theirPackageJSON = require(path.join(options.cwd, 'package.json'));
@@ -67,20 +69,173 @@ module.exports = function (options) {
67
69
  );
68
70
  }
69
71
 
72
+ // Handle post install
73
+ if (options.isPostInstall) {
74
+ // Send analytics
75
+ await sendAnalytics(thisPackageJSON, theirPackageJSON)
76
+ .then((r) => {
77
+ console.log(chalk.green(`[prepare-package]: Sent analytics code=${r.status}...`));
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
70
85
  if (options.purge === false) {
71
86
  return;
72
- } else {
73
- 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 name = (theirPackageJSON.name || 'unknown')
117
+ // Replace anything not a letter, number, or underscore with an underscore
118
+ .replace(/[^a-zA-Z0-9_]/g, '_')
119
+ // Remove leading and trailing underscores
120
+ .replace(/^_+|_+$/g, '')
121
+ // Remove multiple underscores
122
+ .replace(/_+/g, '_');
123
+
124
+ // Build body
125
+ const body = {
126
+ client_id: uuid,
127
+ user_id: uuid,
128
+ // timestamp_micros: new Date().getTime() * 1000,
129
+ user_properties: {
130
+ // operating_system: simpleOS, // CAUSES EVENT TO NOT BE SENT
131
+ },
132
+ user_data: {
133
+ },
134
+ // consent: {},
135
+ // non_personalized_ads: false,
136
+ events: [{
137
+ name: name,
138
+ params: {
139
+ packageName: theirPackageJSON.name,
140
+ packageVersion: theirPackageJSON.version,
141
+ preparePackageVersion: thisPackageJSON.version,
142
+ os: simpleOS,
143
+ platform: os.platform(),
144
+ arch: os.arch(),
145
+ release: os.release(),
146
+ hostname: os.hostname(),
147
+ cpus: os.cpus().length,
148
+ memory: os.totalmem(),
149
+ uptime: os.uptime(),
150
+ username: userInfo.username,
151
+ homedir: userInfo.homedir,
152
+ shell: userInfo.shell,
153
+ uid: userInfo.uid,
154
+ gid: userInfo.gid,
155
+ },
156
+ }],
157
+ }
158
+
159
+ // Get the user's location
160
+ const geolocation = await fetch('https://ipapi.co/json/', {
74
161
  response: 'json',
75
- tries: 3,
76
- })
77
- .then(result => {
78
- console.log(chalk.green(`[prepare-package]: Purged... ${theirPackageJSON.name}`));
162
+ tries: 2,
163
+ timeout: 30000,
79
164
  })
80
165
  .catch(e => {
81
- console.log(chalk.red(`[prepare-package]: Failed to purge... ${theirPackageJSON.name}`, e));
166
+ console.log(chalk.red(`[prepare-package]: Failed to get geolocation...`, e));
167
+ });
168
+
169
+ // Add the geolocation to the body
170
+ if (geolocation) {
171
+ body.user_data.city = geolocation.city || 'Unknown';
172
+ body.user_data.region = geolocation.region || 'Unknown';
173
+ body.user_data.country = geolocation.country || 'Unknown';
174
+
175
+ body.user_properties.language = (geolocation.languages || 'Unknown').split(',')[0];
176
+ }
177
+
178
+ // Log the options
179
+ console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid), body, body.events[0].params);
180
+ // console.log(chalk.blue(`[prepare-package]: Sending analytics...`, mac, uuid));
181
+
182
+ // Send event
183
+ fetch(url, {
184
+ method: 'post',
185
+ response: 'raw',
186
+ tries: 2,
187
+ timeout: 30000,
188
+ body: body,
82
189
  })
83
- }
190
+ .then((r) => {
191
+ resolve(r);
192
+ })
193
+ .catch((e) => {
194
+ reject(e);
195
+ });
196
+ });
84
197
  }
85
198
 
199
+ const getDeviceUniqueId = () => {
200
+ const os = require('os');
201
+ const interfaces = os.networkInterfaces();
202
+
203
+ // Find the first valid MAC address
204
+ for (const name in interfaces) {
205
+ for (const net of interfaces[name]) {
206
+ if (!net.internal && net.mac && net.mac !== '00:00:00:00:00:00') {
207
+ return net.mac;
208
+ }
209
+ }
210
+ }
211
+
212
+ // Log
213
+ console.warn('No valid MAC address found. Generating a random MAC address.');
214
+
215
+ // Generate a random MAC address
216
+ const hexDigits = '0123456789ABCDEF';
217
+ let mac = '';
218
+ for (let i = 0; i < 6; i++) {
219
+ let byte = '';
220
+ for (let j = 0; j < 2; j++) {
221
+ byte += hexDigits.charAt(Math.floor(Math.random() * 16));
222
+ }
223
+ mac += byte;
224
+ if (i !== 5) mac += ':';
225
+ }
226
+ return mac;
227
+ };
228
+
229
+ const getSimpleOS = (platform) => {
230
+ switch (platform) {
231
+ case 'darwin':
232
+ return 'mac';
233
+ case 'win32':
234
+ return 'windows';
235
+ case 'linux':
236
+ return 'linux';
237
+ default:
238
+ return platform;
239
+ }
240
+ };
86
241