<commit_before>import { join } from 'path';
import fs from 'fs';
import { ensureDir } from 'fs-extra';
import { promisify } from 'util';
import getProjectByIdOrName from '../projects/get-project-by-id-or-name';
import Client from '../client';
import { ProjectNotFound } from '../errors';
import getUser from '../get-user';
import getTeamById from '../get-team-by-id';
import { Output } from '../output';
import { Project } from '../../types';
import { Org, ProjectLink } from '../../types';
import chalk from 'chalk';
import { prependEmoji, emoji } from '../emoji';

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

export const NOW_FOLDER = '.now';
export const NOW_FOLDER_README = 'README.txt';
export const NOW_PROJECT_LINK_FILE = 'project.json';

async function getLink(path?: string): Promise<ProjectLink | null> {
  try {
    const json = await readFile(
      join(path || process.cwd(), NOW_FOLDER, NOW_PROJECT_LINK_FILE),
      { encoding: 'utf8' }
    );

    const link: ProjectLink = JSON.parse(json);

    return link;
  } catch (error) {
    // link file does not exists, project is not linked
    if (['ENOENT', 'ENOTDIR'].includes(error.code)) {
      return null;
    }

    // link file can't be read<commit_msg>[now-cli] Fix ID check for orgs (#3934)<commit_after>import { join } from 'path';
import fs from 'fs';
import { ensureDir } from 'fs-extra';
import { promisify } from 'util';
import getProjectByIdOrName from '../projects/get-project-by-id-or-name';
import Client from '../client';
import { ProjectNotFound } from '../errors';
import getUser from '../get-user';
import getTeamById from '../get-team-by-id';
import { Output } from '../output';
import { Project } from '../../types';
import { Org, ProjectLink } from '../../types';
import chalk from 'chalk';
import { prependEmoji, emoji } from '../emoji';
import AJV from 'ajv';

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

export const NOW_FOLDER = '.now';
export const NOW_FOLDER_README = 'README.txt';
export const NOW_PROJECT_LINK_FILE = 'project.json';

const linkSchema = {
  type: 'object',
  required: ['projectId', 'orgId'],
  properties: {
    projectId: {
      type: 'string',
      minLength: 1,
    },
    orgId: {
      type: 'string',
      minLength: 1,
    },
  },
};

async function getLink(path?: string): Promise<ProjectLink | null> {
  try {
    const json = await readFile(
      join(path || process.cwd(), NOW_FOLDER, NOW_PROJECT_LINK_FILE),
      { encoding: 'utf8' }
    );

    const ajv = new AJV();
    const link: ProjectLink = JSON.parse(json);

    if (!ajv.validate(linkSchema, link)) {
      throw new Error(
        'Now project settings are invalid. To link your project again, remove the `.now` directory.'
      );
    }

    return link;
  } catch (error) {
    // link file does not exists, project is not linked
    if (['ENOENT', 'ENOTDIR'].includes(error.code)) {
      return null;
    }

    // link file can't be read
{'fraction_non_alphanumeric': 0.15303080490228552, 'fraction_numerical': 0.002649884067572044, 'mean_word_length': 3.332855093256815, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1448038', 'n_tokens_mistral': 976, 'n_tokens_neox': 953, 'n_words': 291}