aboutsummaryrefslogtreecommitdiff
path: root/node_modules/node-pre-gyp/lib/util/napi.js
blob: 327fe5bf06a2406a4acee872f3948a6274b5ee1b (plain)
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
150
151
152
153
154
155
156
"use strict";

var fs = require('fs');
var rm = require('rimraf');

module.exports = exports;

var versionArray = process.version
	.substr(1)
	.replace(/-.*$/, '')
	.split('.')
	.map(function(item) {
		return +item;
	});

var napi_multiple_commands = [
	'build',
	'clean',
	'configure',
	'package',
	'publish',
	'reveal',
	'testbinary',
	'testpackage',
	'unpublish'
];

var napi_build_version_tag = 'napi_build_version=';

module.exports.get_napi_version = function() {
	// returns the non-zero numeric napi version or undefined if napi is not supported.
	var version = process.versions.napi; // can be undefined
	if (!version) { // this code should never need to be updated
		if (versionArray[0] === 9 && versionArray[1] >= 3) version = 2; // 9.3.0+
		else if (versionArray[0] === 8) version = 1; // 8.0.0+
	}
	return version;
};

module.exports.get_napi_version_as_string = function() {
	// returns the napi version as a string or an empty string if napi is not supported.
	var version = module.exports.get_napi_version();
	return version ? ''+version : '';
};

module.exports.validate_package_json = function(package_json) { // return err
	var binary = package_json.binary;
	var module_path_ok = binary.module_path && binary.module_path.indexOf('{napi_build_version}') !== -1;
	var remote_path_ok = binary.remote_path && binary.remote_path.indexOf('{napi_build_version}') !== -1;
	var package_name_ok = binary.package_name && binary.package_name.indexOf('{napi_build_version}') !== -1;
	var napi_build_versions = module.exports.get_napi_build_versions(package_json);

	if (napi_build_versions) {
		napi_build_versions.forEach(function(napi_build_version){
			if (!(parseInt(napi_build_version,10) === napi_build_version && napi_build_version > 0)) {
				throw new Error("All values specified in napi_versions must be positive integers.");
			}
		});
	}

	if (napi_build_versions && (!module_path_ok || (!remote_path_ok && !package_name_ok))) {
		throw new Error("When napi_versions is specified; module_path and either remote_path or " +
			"package_name must contain the substitution string '{napi_build_version}`.");
	}

	if ((module_path_ok || remote_path_ok || package_name_ok) && !napi_build_versions) {
		throw new Error("When the substitution string '{napi_build_version}` is specified in " +
			"module_path, remote_path, or package_name; napi_versions must also be specified.");
	}

	if (napi_build_versions && !module.exports.get_best_napi_build_version(package_json)) {
		throw new Error(
			'The N-API version of this Node instance is ' + module.exports.get_napi_version() + '. ' +
			'This module supports N-API version(s) ' + module.exports.get_napi_build_versions(package_json) + '. ' +
			'This Node instance cannot run this module.');
	}

};

module.exports.expand_commands = function(package_json, commands) {
	var expanded_commands = [];
	var napi_build_versions = module.exports.get_napi_build_versions(package_json);
	commands.forEach(function(command){
		if (napi_build_versions && command.name === 'install') {
			var napi_build_version = module.exports.get_best_napi_build_version(package_json);
			var args = napi_build_version ? [ napi_build_version_tag+napi_build_version ] : [ ];
			expanded_commands.push ({ name: command.name, args: args });
		} else if (napi_build_versions && napi_multiple_commands.includes(command.name)) {
			napi_build_versions.forEach(function(napi_build_version){
				var args = command.args.slice();
				args.push (napi_build_version_tag+napi_build_version);
				expanded_commands.push ({ name: command.name, args: args });
			});
		} else {
			expanded_commands.push (command);
		}
	});
	return expanded_commands;
};

module.exports.get_napi_build_versions = function(package_json) {
	var napi_build_versions = [];
	if (package_json.binary && package_json.binary.napi_versions) { // remove duplicates
		package_json.binary.napi_versions.forEach(function(napi_version) {
			if (!napi_build_versions.includes(napi_version)) napi_build_versions.push(napi_version);
		});
	}
	return napi_build_versions.length ? napi_build_versions : undefined;
};

module.exports.get_command_arg = function(napi_build_version) {
	return napi_build_version_tag + napi_build_version;
};

module.exports.get_napi_build_version_from_command_args = function(command_args) {
	for (var i = 0; i < command_args.length; i++) {
		var arg = command_args[i];
		if (arg.indexOf(napi_build_version_tag) === 0) {
			return parseInt(arg.substr(napi_build_version_tag.length),10);
		}
	}
	return undefined;
};

module.exports.swap_build_dir_out = function(napi_build_version) {
	if (napi_build_version) {
		rm.sync(module.exports.get_build_dir(napi_build_version));
		fs.renameSync('build', module.exports.get_build_dir(napi_build_version));
	}
};

module.exports.swap_build_dir_in = function(napi_build_version) {
	if (napi_build_version) {
		rm.sync('build');
		fs.renameSync(module.exports.get_build_dir(napi_build_version), 'build');
	}
};

module.exports.get_build_dir = function(napi_build_version) {
	return 'build-tmp-napi-v'+napi_build_version;
};

module.exports.get_best_napi_build_version = function(package_json) {
	var best_napi_build_version = 0;
	var napi_build_versions = module.exports.get_napi_build_versions (package_json);
	if (napi_build_versions) {
		var our_napi_version = module.exports.get_napi_version();
		napi_build_versions.forEach(function(napi_build_version){
			if (napi_build_version > best_napi_build_version &&
				napi_build_version <= our_napi_version) {
				best_napi_build_version = napi_build_version;
			}
		});
	}
	return best_napi_build_version === 0 ? undefined : best_napi_build_version;
};