1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports._installNpmLibDef = installNpmLibDef;
|
7 | exports._installNpmLibDefs = installNpmLibDefs;
|
8 | exports.name = exports.description = void 0;
|
9 | exports.run = run;
|
10 | exports.setup = setup;
|
11 |
|
12 | var _safe = _interopRequireDefault(require("colors/safe"));
|
13 |
|
14 | var _semver = _interopRequireDefault(require("semver"));
|
15 |
|
16 | var _cacheRepoUtils = require("../lib/cacheRepoUtils");
|
17 |
|
18 | var _codeSign = require("../lib/codeSign");
|
19 |
|
20 | var _envDefs = require("../lib/envDefs");
|
21 |
|
22 | var _fileUtils = require("../lib/fileUtils");
|
23 |
|
24 | var _flowProjectUtils = require("../lib/flowProjectUtils");
|
25 |
|
26 | var _flowVersion = require("../lib/flowVersion");
|
27 |
|
28 | var _ftConfig = require("../lib/ftConfig");
|
29 |
|
30 | var _node = require("../lib/node");
|
31 |
|
32 | var _npmLibDefs = require("../lib/npm/npmLibDefs");
|
33 |
|
34 | var _npmProjectUtils = require("../lib/npm/npmProjectUtils");
|
35 |
|
36 | var _semver2 = require("../lib/semver");
|
37 |
|
38 | var _stubUtils = require("../lib/stubUtils");
|
39 |
|
40 | var _logger = require("../lib/logger");
|
41 |
|
42 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
43 |
|
44 | const name = 'install [explicitLibDefs...]';
|
45 | exports.name = name;
|
46 | const description = 'Installs libdefs into the ./flow-typed directory';
|
47 | exports.description = description;
|
48 |
|
49 | function setup(yargs) {
|
50 | return yargs.usage(`$0 ${name} - ${description}`).positional('explicitLibDefs', {
|
51 | describe: 'Explicitly specify packages to install',
|
52 | default: []
|
53 | }).options({
|
54 | flowVersion: {
|
55 | alias: 'f',
|
56 | describe: 'The Flow version that fetched libdefs must be compatible with',
|
57 | type: 'string'
|
58 | },
|
59 | verbose: {
|
60 | describe: 'Print additional, verbose info while installing libdefs',
|
61 | type: 'boolean',
|
62 | demandOption: false
|
63 | },
|
64 | skip: {
|
65 | alias: 's',
|
66 | describe: 'Do not generate stubs for missing libdefs',
|
67 | type: 'boolean',
|
68 | demandOption: false
|
69 | },
|
70 | skipCache: {
|
71 | describe: 'Do not update cache prior to installing libdefs',
|
72 | type: 'boolean',
|
73 | demandOption: false
|
74 | },
|
75 | skipFlowRestart: {
|
76 | describe: 'Do not restart flow after installing libdefs',
|
77 | type: 'boolean',
|
78 | demandOption: false
|
79 | },
|
80 | libdefDir: {
|
81 | alias: 'l',
|
82 | describe: 'Use a custom directory to install libdefs',
|
83 | type: 'string',
|
84 | demandOption: false
|
85 | },
|
86 | cacheDir: {
|
87 | alias: 'c',
|
88 | describe: 'Directory (absolute or relative path, ~ is not supported) to store cache of libdefs',
|
89 | type: 'string',
|
90 | demandOption: false
|
91 | },
|
92 | packageDir: {
|
93 | alias: 'p',
|
94 | describe: 'The relative path of package.json where flow-bin is installed',
|
95 | type: 'string'
|
96 | },
|
97 | overwrite: {
|
98 | alias: 'o',
|
99 | describe: 'Overwrite an existing libdef',
|
100 | type: 'boolean',
|
101 | demandOption: false
|
102 | },
|
103 | ignoreDeps: {
|
104 | alias: 'i',
|
105 | describe: 'Dependency categories to ignore when installing definitions',
|
106 | choices: ['dev', 'bundled', 'peer'],
|
107 | type: 'array'
|
108 | },
|
109 | rootDir: {
|
110 | alias: 'r',
|
111 | describe: 'Directory of .flowconfig relative to node_modules',
|
112 | type: 'string'
|
113 | },
|
114 | useCacheUntil: {
|
115 | alias: 'u',
|
116 | describe: 'Use cache until specified time in milliseconds',
|
117 | type: 'number'
|
118 | }
|
119 | });
|
120 | }
|
121 |
|
122 | async function run(args) {
|
123 | const cwd = typeof args.rootDir === 'string' ? _node.path.resolve(args.rootDir) : process.cwd();
|
124 | const packageDir = typeof args.packageDir === 'string' ? _node.path.resolve(args.packageDir) : cwd;
|
125 | const flowVersion = await (0, _flowVersion.determineFlowSpecificVersion)(packageDir, args.flowVersion);
|
126 | const libdefDir = typeof args.libdefDir === 'string' ? args.libdefDir : 'flow-typed';
|
127 |
|
128 | if (args.ignoreDeps !== undefined && !Array.isArray(args.ignoreDeps)) {
|
129 | throw new Error('ignoreDeps is not array');
|
130 | }
|
131 |
|
132 | const ignoreDeps = (args.ignoreDeps || []).map(dep => {
|
133 | if (typeof dep !== 'string') {
|
134 | throw new Error('ignoreDeps should be array of strings');
|
135 | }
|
136 |
|
137 | return dep;
|
138 | });
|
139 |
|
140 | if (args.explicitLibDefs !== undefined && !Array.isArray(args.explicitLibDefs)) {
|
141 | throw new Error('explicitLibDefs is not array');
|
142 | }
|
143 |
|
144 | const explicitLibDefs = (args.explicitLibDefs || []).map(dep => {
|
145 | if (typeof dep !== 'string') {
|
146 | throw new Error('explicitLibDefs should be array of strings');
|
147 | }
|
148 |
|
149 | return dep;
|
150 | });
|
151 | const ftConfig = (0, _ftConfig.getFtConfig)(cwd);
|
152 |
|
153 | if (args.cacheDir) {
|
154 | const cacheDir = _node.path.resolve(String(args.cacheDir));
|
155 |
|
156 | console.log('• Setting cache dir', cacheDir);
|
157 | (0, _cacheRepoUtils._setCustomCacheDir)(cacheDir);
|
158 | }
|
159 |
|
160 | const useCacheUntil = Number(args.useCacheUntil) || _cacheRepoUtils.CACHE_REPO_EXPIRY;
|
161 |
|
162 | const {
|
163 | status: npmLibDefResult,
|
164 | dependencyEnvs
|
165 | } = await installNpmLibDefs({
|
166 | cwd,
|
167 | flowVersion,
|
168 | explicitLibDefs,
|
169 | libdefDir: libdefDir,
|
170 | verbose: Boolean(args.verbose),
|
171 | overwrite: Boolean(args.overwrite),
|
172 | skip: Boolean(args.skip),
|
173 | skipCache: Boolean(args.skipCache),
|
174 | ignoreDeps: ignoreDeps,
|
175 | useCacheUntil: Number(args.useCacheUntil) || _cacheRepoUtils.CACHE_REPO_EXPIRY,
|
176 | ftConfig
|
177 | });
|
178 |
|
179 | if (npmLibDefResult !== 0) {
|
180 | return npmLibDefResult;
|
181 | }
|
182 |
|
183 |
|
184 | if (ftConfig !== null && ftConfig !== void 0 && ftConfig.env || dependencyEnvs.length > 0) {
|
185 | var _ftConfig$env;
|
186 |
|
187 | const envLibDefResult = await installEnvLibDefs([...new Set([...((_ftConfig$env = ftConfig === null || ftConfig === void 0 ? void 0 : ftConfig.env) !== null && _ftConfig$env !== void 0 ? _ftConfig$env : []), ...dependencyEnvs])], flowVersion, cwd, libdefDir, useCacheUntil, Boolean(args.overwrite));
|
188 |
|
189 | if (envLibDefResult !== 0) {
|
190 | return envLibDefResult;
|
191 | }
|
192 | }
|
193 |
|
194 |
|
195 | if (!args.skipFlowRestart) {
|
196 | try {
|
197 | await _node.child_process.execP('npx flow stop');
|
198 | await _node.child_process.execP('npx flow');
|
199 | } catch (e) {
|
200 | console.log(_safe.default.red('!! Flow restarted with some errors'));
|
201 | }
|
202 | }
|
203 |
|
204 | return 0;
|
205 | }
|
206 |
|
207 | async function installEnvLibDefs(env, flowVersion, flowProjectRoot, libdefDir, useCacheUntil, overwrite) {
|
208 | if (env) {
|
209 | console.log(_safe.default.green('• `env` key found in `flow-typed.config.json`, attempting to install env definitions...\n'));
|
210 |
|
211 | if (!Array.isArray(env)) {
|
212 | console.log(_safe.default.yellow('Warning: `env` in `flow-typed.config.json` must be of type Array<string> - skipping'));
|
213 | return 0;
|
214 | }
|
215 |
|
216 |
|
217 | const envDefs = await (0, _envDefs.getEnvDefs)();
|
218 |
|
219 | const flowTypedDirPath = _node.path.join(flowProjectRoot, libdefDir, 'environments');
|
220 |
|
221 | await (0, _fileUtils.mkdirp)(flowTypedDirPath);
|
222 |
|
223 |
|
224 |
|
225 | await Promise.all(env.map(async en => {
|
226 | if (typeof en === 'string') {
|
227 | const def = await (0, _envDefs.findEnvDef)(en, flowVersion, useCacheUntil, envDefs);
|
228 |
|
229 | if (def) {
|
230 | const fileName = `${en}.js`;
|
231 |
|
232 | const defLocalPath = _node.path.join(flowTypedDirPath, fileName);
|
233 |
|
234 | const envAlreadyInstalled = await _node.fs.exists(defLocalPath);
|
235 |
|
236 | if (envAlreadyInstalled) {
|
237 | const localFile = _node.fs.readFileSync(defLocalPath, 'utf-8');
|
238 |
|
239 | if (!(0, _codeSign.verifySignedCode)(localFile) && !overwrite) {
|
240 | (0, _logger.listItem)(en, _safe.default.red(`${en} already exists and appears to have been manually written or changed!`), _safe.default.yellow(`Consider contributing your changes back to flow-typed repository :)`), _safe.default.yellow(`${en} already exists and appears to have been manually written or changed!`), _safe.default.yellow(`Read more at https://github.com/flow-typed/flow-typed/blob/main/CONTRIBUTING.md`), _safe.default.yellow(`Use --overwrite to overwrite the existing env defs.`));
|
241 | return;
|
242 | }
|
243 |
|
244 | _node.fs.unlink(defLocalPath);
|
245 | }
|
246 |
|
247 | const repoVersion = await (0, _envDefs.getEnvDefVersionHash)((0, _cacheRepoUtils.getCacheRepoDir)(), def);
|
248 | const codeSignPreprocessor = (0, _codeSign.signCodeStream)(repoVersion);
|
249 | await (0, _fileUtils.copyFile)(def.path, defLocalPath, codeSignPreprocessor);
|
250 | (0, _logger.listItem)(en, _safe.default.green(`.${_node.path.sep}${_node.path.relative(flowProjectRoot, defLocalPath)}`));
|
251 | } else {
|
252 | (0, _logger.listItem)(en, _safe.default.yellow(`Was unable to install ${en}. The env might not exist or there is not a version compatible with your version of flow`));
|
253 | }
|
254 | }
|
255 | }));
|
256 | }
|
257 |
|
258 | return 0;
|
259 | }
|
260 |
|
261 | const FLOW_BUILT_IN_NPM_LIBS = ['react'];
|
262 |
|
263 | async function installNpmLibDefs({
|
264 | cwd,
|
265 | flowVersion,
|
266 | explicitLibDefs,
|
267 | libdefDir,
|
268 | verbose,
|
269 | overwrite,
|
270 | skip,
|
271 | skipCache,
|
272 | ignoreDeps,
|
273 | useCacheUntil,
|
274 | ftConfig = {}
|
275 | }) {
|
276 | const flowProjectRoot = await (0, _flowProjectUtils.findFlowRoot)(cwd);
|
277 |
|
278 | if (flowProjectRoot === null) {
|
279 | console.error('Error: Unable to find a flow project in the current dir or any of ' + "it's parent dirs!\n" + 'Please run this command from within a Flow project.');
|
280 | return {
|
281 | status: 1,
|
282 | dependencyEnvs: []
|
283 | };
|
284 | }
|
285 |
|
286 | const libdefsToSearchFor = new Map();
|
287 | let ignoreDefs;
|
288 |
|
289 | if (Array.isArray(ftConfig.ignore)) {
|
290 | ignoreDefs = ftConfig.ignore;
|
291 | } else {
|
292 | try {
|
293 | ignoreDefs = _node.fs.readFileSync(_node.path.join(cwd, libdefDir, '.ignore'), 'utf-8').replace(/"/g, '').split('\n');
|
294 | } catch (err) {
|
295 |
|
296 | if (err.code !== 'ENOENT') {
|
297 | throw err;
|
298 | }
|
299 |
|
300 | ignoreDefs = [];
|
301 | }
|
302 | }
|
303 |
|
304 | let workspacesPkgJsonData;
|
305 |
|
306 |
|
307 | if (explicitLibDefs.length > 0) {
|
308 | for (var i = 0; i < explicitLibDefs.length; i++) {
|
309 | const term = explicitLibDefs[i];
|
310 | const termMatches = term.match(/(@[^@\/]+\/)?([^@]+)@(.+)/);
|
311 |
|
312 | if (termMatches == null) {
|
313 | const pkgJsonData = await (0, _npmProjectUtils.getPackageJsonData)(cwd);
|
314 | workspacesPkgJsonData = await (0, _npmProjectUtils.findWorkspacesPackages)(cwd, pkgJsonData, ftConfig);
|
315 | const pkgJsonDeps = workspacesPkgJsonData.reduce((acc, pckData) => {
|
316 | return (0, _npmProjectUtils.mergePackageJsonDependencies)(acc, (0, _npmProjectUtils.getPackageJsonDependencies)(pckData, [], []));
|
317 | }, (0, _npmProjectUtils.getPackageJsonDependencies)(pkgJsonData, [], []));
|
318 | const packageVersion = pkgJsonDeps[term];
|
319 |
|
320 | if (packageVersion) {
|
321 | libdefsToSearchFor.set(term, packageVersion);
|
322 | } else {
|
323 | console.error('ERROR: Package not found from package.json.\n' + 'Please specify version for the package in the format of `foo@1.2.3`');
|
324 | return {
|
325 | status: 1,
|
326 | dependencyEnvs: []
|
327 | };
|
328 | }
|
329 | } else {
|
330 | const [_, npmScope, pkgName, pkgVerStr] = termMatches;
|
331 | const scopedPkgName = npmScope != null ? npmScope + pkgName : pkgName;
|
332 | libdefsToSearchFor.set(scopedPkgName, pkgVerStr);
|
333 | }
|
334 | }
|
335 |
|
336 | console.log(`• Searching for ${libdefsToSearchFor.size} libdefs...`);
|
337 | } else {
|
338 | const pkgJsonData = await (0, _npmProjectUtils.getPackageJsonData)(cwd);
|
339 | workspacesPkgJsonData = await (0, _npmProjectUtils.findWorkspacesPackages)(cwd, pkgJsonData, ftConfig);
|
340 | const pkgJsonDeps = workspacesPkgJsonData.reduce((acc, pckData) => {
|
341 | return (0, _npmProjectUtils.mergePackageJsonDependencies)(acc, (0, _npmProjectUtils.getPackageJsonDependencies)(pckData, ignoreDeps, ignoreDefs));
|
342 | }, (0, _npmProjectUtils.getPackageJsonDependencies)(pkgJsonData, ignoreDeps, ignoreDefs));
|
343 |
|
344 | for (const pkgName in pkgJsonDeps) {
|
345 | libdefsToSearchFor.set(pkgName, pkgJsonDeps[pkgName]);
|
346 | }
|
347 |
|
348 | if (libdefsToSearchFor.size === 0) {
|
349 | console.error("No dependencies were found in this project's package.json!");
|
350 | return {
|
351 | status: 0,
|
352 | dependencyEnvs: []
|
353 | };
|
354 | }
|
355 |
|
356 | if (verbose) {
|
357 | libdefsToSearchFor.forEach((ver, name) => {
|
358 | console.log(`• Found package.json dependency: ${name}@${ver}`);
|
359 | });
|
360 | } else {
|
361 | console.log(`• Found ${libdefsToSearchFor.size} dependencies in package.json to install libdefs for. Searching...`);
|
362 | }
|
363 | }
|
364 |
|
365 | const libDefsToSearchForEntries = [...libdefsToSearchFor.entries()];
|
366 |
|
367 | const libDefsToInstall = new Map();
|
368 | const outdatedLibDefsToInstall = [];
|
369 | const unavailableLibDefs = [];
|
370 | const defDepsToInstall = {};
|
371 |
|
372 | const libDefs = await (0, _npmLibDefs.getCacheNpmLibDefs)(useCacheUntil, skipCache);
|
373 |
|
374 | const getLibDefsToInstall = async entries => {
|
375 | await Promise.all(entries.map(async ([name, ver]) => {
|
376 | delete defDepsToInstall[name];
|
377 |
|
378 |
|
379 |
|
380 | if (name === '//') {
|
381 | return;
|
382 | }
|
383 |
|
384 | if (FLOW_BUILT_IN_NPM_LIBS.indexOf(name) !== -1) {
|
385 | return;
|
386 | }
|
387 |
|
388 | const libDef = await (0, _npmLibDefs.findNpmLibDef)(name, ver, flowVersion, useCacheUntil, true, libDefs);
|
389 |
|
390 | if (libDef === null) {
|
391 | unavailableLibDefs.push({
|
392 | name,
|
393 | ver
|
394 | });
|
395 | } else {
|
396 | libDefsToInstall.set(name, libDef);
|
397 | const libDefLower = (0, _semver2.getRangeLowerBound)(libDef.version);
|
398 | const depLower = (0, _semver2.getRangeLowerBound)(ver);
|
399 |
|
400 | if (_semver.default.lt(libDefLower, depLower)) {
|
401 | outdatedLibDefsToInstall.push([libDef, {
|
402 | name,
|
403 | ver
|
404 | }]);
|
405 | }
|
406 |
|
407 |
|
408 | if (libDef.depVersions) {
|
409 | Object.keys(libDef.depVersions).forEach(dep => {
|
410 | if (libDef.depVersions) {
|
411 |
|
412 |
|
413 |
|
414 | defDepsToInstall[dep] = libDef.depVersions[dep];
|
415 | }
|
416 | });
|
417 | }
|
418 | }
|
419 | }));
|
420 | };
|
421 |
|
422 | await getLibDefsToInstall(libDefsToSearchForEntries);
|
423 | const pnpResolver = await (0, _npmProjectUtils.loadPnpResolver)(await (0, _npmProjectUtils.getPackageJsonData)(cwd));
|
424 | const dependencyEnvs = [];
|
425 |
|
426 |
|
427 | const untypedMissingLibDefs = [];
|
428 | const typedMissingLibDefs = [];
|
429 | await Promise.all(unavailableLibDefs.map(async ({
|
430 | name: pkgName,
|
431 | ver: pkgVer
|
432 | }) => {
|
433 | const {
|
434 | isFlowTyped,
|
435 | pkgPath
|
436 | } = await (0, _stubUtils.pkgHasFlowFiles)(cwd, pkgName, pnpResolver, workspacesPkgJsonData);
|
437 |
|
438 | if (isFlowTyped && pkgPath) {
|
439 | typedMissingLibDefs.push([pkgName, pkgVer, pkgPath]);
|
440 |
|
441 | try {
|
442 |
|
443 |
|
444 |
|
445 |
|
446 | const pkgFlowTypedConfig = await _node.fs.readJson(_node.path.join(pkgPath, 'flow-typed.config.json'));
|
447 |
|
448 | if (pkgFlowTypedConfig.env) {
|
449 | dependencyEnvs.push(...pkgFlowTypedConfig.env);
|
450 | }
|
451 | } catch (e) {
|
452 | }
|
453 | } else {
|
454 | untypedMissingLibDefs.push([pkgName, pkgVer]);
|
455 | }
|
456 | }));
|
457 |
|
458 |
|
459 |
|
460 |
|
461 | if (typedMissingLibDefs.length > 0) {
|
462 | const typedDepsLibDefsToSearchFor = [];
|
463 | await Promise.all(typedMissingLibDefs.map(async typedLibDef => {
|
464 | const pkgJsonData = await (0, _npmProjectUtils.getPackageJsonData)(`${typedLibDef[2]}/package.json`);
|
465 | const pkgJsonDeps = (0, _npmProjectUtils.getPackageJsonDependencies)(pkgJsonData,
|
466 |
|
467 | ['dev', 'peer', ...ignoreDeps], ignoreDefs);
|
468 |
|
469 | for (const pkgName in pkgJsonDeps) {
|
470 | if (!libDefsToInstall.has(pkgName)) {
|
471 | typedDepsLibDefsToSearchFor.push([pkgName, pkgJsonDeps[pkgName]]);
|
472 | }
|
473 | }
|
474 | }));
|
475 | await getLibDefsToInstall(typedDepsLibDefsToSearchFor);
|
476 | }
|
477 |
|
478 |
|
479 |
|
480 |
|
481 | if (Object.keys(defDepsToInstall).length > 0) {
|
482 | (0, _logger.sectionHeader)('Running definition dependency check');
|
483 |
|
484 | while (Object.keys(defDepsToInstall).length > 0) {
|
485 | await getLibDefsToInstall(Object.keys(defDepsToInstall).map(dep => {
|
486 | const libDef = libDefsToInstall.get(dep);
|
487 | const defVersions = defDepsToInstall[dep];
|
488 |
|
489 | if (libDef) {
|
490 | if (!defVersions.includes(libDef.version)) {
|
491 |
|
492 | (0, _logger.listItem)(_safe.default.yellow(`One of your definitions has a dependency to ${dep} @ version(s) ${defVersions.join(', ')}`), `You have version ${_safe.default.yellow(libDef.version)} installed`, `We're overriding to a supported version to fix flow-typed ${_safe.default.red('but you may experience other type errors')}`);
|
493 | } else {
|
494 |
|
495 |
|
496 | delete defDepsToInstall[dep];
|
497 | return ['', ''];
|
498 | }
|
499 | }
|
500 |
|
501 |
|
502 |
|
503 | return [dep, defVersions[defVersions.length - 1]];
|
504 | }).filter(o => !!o[0]));
|
505 | }
|
506 |
|
507 | (0, _logger.sectionHeader)('Check complete');
|
508 | }
|
509 |
|
510 |
|
511 | const libDefsToUninstall = new Map();
|
512 | const alreadyInstalledLibDefs = await (0, _npmLibDefs.getInstalledNpmLibDefs)(_node.path.join(flowProjectRoot), libdefDir);
|
513 | [...alreadyInstalledLibDefs.entries()].forEach(([filePath, npmLibDef]) => {
|
514 | const fullFilePath = _node.path.join(flowProjectRoot, filePath);
|
515 |
|
516 | switch (npmLibDef.kind) {
|
517 | case 'LibDef':
|
518 |
|
519 |
|
520 | const libDef = npmLibDef.libDef;
|
521 | const scopedPkgName = (0, _npmLibDefs.getScopedPackageName)(libDef);
|
522 |
|
523 | if (libDefsToInstall.has(scopedPkgName)) {
|
524 | libDefsToUninstall.set(scopedPkgName, fullFilePath);
|
525 | }
|
526 |
|
527 | break;
|
528 |
|
529 | case 'Stub':
|
530 | break;
|
531 |
|
532 | default:
|
533 | npmLibDef;
|
534 | }
|
535 | });
|
536 |
|
537 | if (libDefsToInstall.size > 0) {
|
538 | (0, _logger.sectionHeader)(`Installing ${libDefsToInstall.size} libDefs...`);
|
539 |
|
540 | const flowTypedDirPath = _node.path.join(flowProjectRoot, libdefDir, 'npm');
|
541 |
|
542 | await (0, _fileUtils.mkdirp)(flowTypedDirPath);
|
543 | const results = await Promise.all([...libDefsToInstall.values()].map(async libDef => {
|
544 | const toUninstall = libDefsToUninstall.get((0, _npmLibDefs.getScopedPackageName)(libDef));
|
545 |
|
546 | if (toUninstall != null) {
|
547 | await _node.fs.unlink(toUninstall);
|
548 | }
|
549 |
|
550 | return installNpmLibDef(libDef, flowTypedDirPath, overwrite);
|
551 | }));
|
552 |
|
553 | if (results.some(res => !res)) {
|
554 | return {
|
555 | status: 1,
|
556 | dependencyEnvs: []
|
557 | };
|
558 | }
|
559 | }
|
560 |
|
561 | if ((verbose || unavailableLibDefs.length === 0) && outdatedLibDefsToInstall.length > 0) {
|
562 | console.log('• The following installed libdefs are compatible with your ' + 'dependencies, but may not include all minor and patch changes for ' + 'your specific dependency version:\n');
|
563 | outdatedLibDefsToInstall.forEach(([libDef, {
|
564 | name: pkgName,
|
565 | ver: pkgVersion
|
566 | }]) => {
|
567 | console.log(' • libdef: %s (satisfies %s)', _safe.default.yellow(`${libDef.name}_${libDef.version}`), _safe.default.bold(`${pkgName}@${pkgVersion}`));
|
568 | const libDefPlural = outdatedLibDefsToInstall.length > 1 ? ['versioned updates', 'these packages'] : ['a versioned update', 'this package'];
|
569 | console.log(`\n` + ` Consider submitting ${libDefPlural[0]} for ${libDefPlural[1]} to \n` + ` https://github.com/flowtype/flow-typed/\n`);
|
570 | });
|
571 | }
|
572 |
|
573 | if (unavailableLibDefs.length > 0 && unavailableLibDefs.length === explicitLibDefs.length) {
|
574 |
|
575 |
|
576 | console.log(_safe.default.red(`!! No flow@${(0, _flowVersion.toSemverString)(flowVersion)}-compatible libdefs ` + `found in flow-typed for the explicitly requested libdefs. !!`) + '\n' + '\n' + 'Consider using `%s` to generate an empty libdef that you can fill in.', _safe.default.bold(`flow-typed create-stub ${explicitLibDefs.join(' ')}`));
|
577 | return {
|
578 | status: 1,
|
579 | dependencyEnvs: []
|
580 | };
|
581 | } else {
|
582 | if (untypedMissingLibDefs.length > 0 && !skip) {
|
583 | console.log('• Generating stubs for untyped dependencies...');
|
584 | await Promise.all(untypedMissingLibDefs.map(async ([pkgName, pkgVerStr]) => {
|
585 | await (0, _stubUtils.createStub)(flowProjectRoot, pkgName, pkgVerStr, overwrite, pnpResolver,
|
586 |
|
587 | false, libdefDir);
|
588 | }));
|
589 | console.log(_safe.default.red(`\n!! No flow@${(0, _flowVersion.toSemverString)(flowVersion)}-compatible libdefs ` + `found in flow-typed for the above untyped dependencies !!`));
|
590 | const plural = unavailableLibDefs.length > 1 ? ['libdefs', 'these packages', 'them'] : ['a libdef', 'this package', 'it'];
|
591 | console.log(`\n` + `We've generated ${'`'}any${'`'}-typed stubs for ${plural[1]}, but ` + `consider submitting \n` + `${plural[0]} for ${plural[2]} to ` + `${_safe.default.bold('https://github.com/flowtype/flow-typed/')}\n`);
|
592 | }
|
593 | }
|
594 |
|
595 | return {
|
596 | status: 0,
|
597 | dependencyEnvs
|
598 | };
|
599 | }
|
600 |
|
601 | async function installNpmLibDef(npmLibDef, npmDir, overwrite) {
|
602 | const scopedDir = npmLibDef.scope === null ? npmDir : _node.path.join(npmDir, npmLibDef.scope);
|
603 | (0, _fileUtils.mkdirp)(scopedDir);
|
604 | const fileName = `${npmLibDef.name}_${npmLibDef.version}.js`;
|
605 |
|
606 | const filePath = _node.path.join(scopedDir, fileName);
|
607 |
|
608 |
|
609 | try {
|
610 | const terseFilePath = _node.path.relative(_node.path.resolve(npmDir, '..', '..'), filePath);
|
611 |
|
612 | if (!overwrite && (await _node.fs.exists(filePath))) {
|
613 | (0, _logger.listItem)(_safe.default.bold(_safe.default.red(`${terseFilePath} already exists and appears to have been manually ` + `written or changed!`)), _safe.default.green(`Consider contributing your changes back to flow-typed repository :)`), `Read more at https://github.com/flow-typed/flow-typed/blob/main/CONTRIBUTING.md`, 'Use --overwrite to overwrite the existing libdef.');
|
614 | return true;
|
615 | }
|
616 |
|
617 | const repoVersion = await (0, _npmLibDefs.getNpmLibDefVersionHash)((0, _cacheRepoUtils.getCacheRepoDir)(), npmLibDef);
|
618 | const codeSignPreprocessor = (0, _codeSign.signCodeStream)(repoVersion);
|
619 | await (0, _fileUtils.copyFile)(npmLibDef.path, filePath, codeSignPreprocessor);
|
620 | (0, _logger.listItem)(fileName, _safe.default.green(`.${_node.path.sep}${terseFilePath}`));
|
621 |
|
622 | console.log(npmLibDef.name);
|
623 | console.log(scopedDir);
|
624 | const stubName = `${npmLibDef.name}_vx.x.x.js`;
|
625 |
|
626 | const stubPath = _node.path.join(scopedDir, stubName);
|
627 |
|
628 | if (overwrite && (await _node.fs.exists(stubPath))) {
|
629 | await _node.fs.unlink(stubPath);
|
630 | }
|
631 |
|
632 | return true;
|
633 | } catch (e) {
|
634 | console.error(` !! Failed to install ${npmLibDef.name} at ${filePath}`);
|
635 | console.error(` ERROR: ${e.message}`);
|
636 | return false;
|
637 | }
|
638 | } |
\ | No newline at end of file |