xref: /expo/tools/src/Npm.ts (revision 75e080d0)
1import { spawnAsync, spawnJSONCommandAsync } from './Utils';
2
3export const EXPO_DEVELOPERS_TEAM_NAME = 'expo:developers';
4
5export type PackageViewType = null | {
6  name: string;
7  version: string;
8  'dist-tags': {
9    latest: string;
10    [tag: string]: string;
11  };
12  versions: string[];
13  time: {
14    created: string;
15    modified: string;
16    [time: string]: string;
17  };
18  maintainers: string[];
19  description: string;
20  author: string;
21  gitHead: string;
22  // and more but these are the basic ones, we shouldn't need more.
23  [key: string]: unknown;
24};
25
26/**
27 * Runs `npm view` for package with given name. Returns null if package is not published yet.
28 */
29export async function getPackageViewAsync(
30  packageName: string,
31  version?: string
32): Promise<PackageViewType> {
33  try {
34    return await spawnJSONCommandAsync('npm', [
35      'view',
36      version ? `${packageName}@${version}` : packageName,
37      '--json',
38    ]);
39  } catch {
40    return null;
41  }
42}
43
44/**
45 * Publishes a package at given directory to the global npm registry.
46 */
47export async function publishPackageAsync(
48  packageDir: string,
49  tagName: string = 'latest',
50  dryRun: boolean = false
51): Promise<void> {
52  const args = ['publish', '--tag', tagName, '--access', 'public'];
53
54  if (dryRun) {
55    args.push('--dry-run');
56  }
57  await spawnAsync('npm', args, {
58    cwd: packageDir,
59  });
60}
61
62/**
63 * Adds dist-tag to a specific version of the package.
64 */
65export async function addTagAsync(
66  packageName: string,
67  version: string,
68  tagName: string
69): Promise<void> {
70  await spawnAsync('npm', ['dist-tag', 'add', `${packageName}@${version}`, tagName]);
71}
72
73/**
74 * Removes package's tag with given name.
75 */
76export async function removeTagAsync(packageName: string, tagName: string): Promise<void> {
77  await spawnAsync('npm', ['dist-tag', 'rm', packageName, tagName]);
78}
79
80/**
81 * Gets a list of user names in the team with given team name.
82 */
83export async function getTeamMembersAsync(teamName: string): Promise<string[]> {
84  return await spawnJSONCommandAsync('npm', ['team', 'ls', teamName, '--json']);
85}
86
87/**
88 * Adds a package to organization team granting access to everyone in the team.
89 */
90export async function grantReadWriteAccessAsync(
91  packageName: string,
92  teamName: string
93): Promise<void> {
94  await spawnAsync('npm', ['access', 'grant', 'read-write', teamName, packageName]);
95}
96
97/**
98 * Returns a name of the currently logged in user or `null` if logged out.
99 */
100export async function whoamiAsync(): Promise<string | null> {
101  try {
102    const { stdout } = await spawnAsync('npm', ['whoami']);
103    return stdout.trim();
104  } catch {
105    return null;
106  }
107}
108