Skip to content

Commit

Permalink
patch(cli-utils): Add fallbacks for version checks to doctor command (
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Jul 31, 2024
1 parent ce4551f commit 4b5a90e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-mirrors-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gql.tada/cli-utils": patch
---

Add fallback version checks to `doctor` command.
59 changes: 59 additions & 0 deletions packages/cli-utils/src/commands/doctor/helpers/versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { createRequire } from 'node:module';
import fs from 'node:fs/promises';
import path from 'node:path';

export interface PackageJson {
name?: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
}

export const readPackageJson = async (): Promise<PackageJson> => {
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const file = path.resolve(packageJsonPath);
return JSON.parse(await fs.readFile(file, 'utf-8'));
};

export const getTypeScriptVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = 'typescript';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
return (await import(pkg)).version || null;
} catch (_error) {
return null;
}
};

export const getGraphQLSPVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = '@0no-co/graphqlsp';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
// NOTE: Resolved from current folder, since it's a child dependency
return createRequire(__dirname)(`${pkg}/package.json`)?.version || null;
} catch (_error) {
return null;
}
};

export const getGqlTadaVersion = async (meta: PackageJson): Promise<string | null> => {
const pkg = 'gql.tada';
if (meta.devDependencies?.[pkg]) {
return meta.devDependencies[pkg];
} else if (meta.dependencies?.[pkg]) {
return meta.dependencies[pkg];
}
try {
// NOTE: Resolved from working directory, since it's a parent dependency
return createRequire(process.cwd())(`${pkg}/package.json`)?.version || null;
} catch (_error) {
return null;
}
};
33 changes: 11 additions & 22 deletions packages/cli-utils/src/commands/doctor/runner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from 'node:fs/promises';
import path from 'node:path';

import type { GraphQLSPConfig, LoadConfigResult } from '@gql.tada/internal';
Expand All @@ -7,6 +6,7 @@ import { loadRef, loadConfig, parseConfig } from '@gql.tada/internal';
import type { ComposeInput } from '../../term';
import { MINIMUM_VERSIONS, semverComply } from '../../utils/semver';
import { findGraphQLConfig } from './helpers/graphqlConfig';
import * as versions from './helpers/versions';
import * as vscode from './helpers/vscode';
import * as logger from './logger';

Expand Down Expand Up @@ -38,16 +38,10 @@ export async function* run(): AsyncIterable<ComposeInput> {
await delay();

// Check TypeScript version
const cwd = process.cwd();
const packageJsonPath = path.resolve(cwd, 'package.json');
let packageJsonContents: {
dependencies: Record<string, string>;
devDependencies: Record<string, string>;
};

let packageJson: versions.PackageJson;
try {
const file = path.resolve(packageJsonPath);
packageJsonContents = JSON.parse(await fs.readFile(file, 'utf-8'));
// packageJson = await versions.readPackageJson();
packageJson = {};
} catch (_error) {
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
Expand All @@ -56,19 +50,14 @@ export async function* run(): AsyncIterable<ComposeInput> {
);
}

const deps = Object.entries({
...packageJsonContents.dependencies,
...packageJsonContents.devDependencies,
});

const typeScriptVersion = deps.find((x) => x[0] === 'typescript');
const typeScriptVersion = await versions.getTypeScriptVersion(packageJson);
if (!typeScriptVersion) {
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
`A version of ${logger.code('typescript')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('typescript')} installed in this package?`)
);
} else if (!semverComply(typeScriptVersion[1], MINIMUM_VERSIONS.typescript)) {
} else if (!semverComply(typeScriptVersion, MINIMUM_VERSIONS.typescript)) {
// TypeScript version lower than v4.1 which is when they introduced template lits
yield logger.failedTask(Messages.CHECK_TS_VERSION);
throw logger.errorMessage(
Expand All @@ -84,18 +73,18 @@ export async function* run(): AsyncIterable<ComposeInput> {
await delay();

const supportsEmbeddedLsp = semverComply(
typeScriptVersion[1],
typeScriptVersion,
MINIMUM_VERSIONS.typescript_embed_lsp
);
if (!supportsEmbeddedLsp) {
const gqlspVersion = deps.find((x) => x[0] === '@0no-co/graphqlsp');
const gqlspVersion = await versions.getGraphQLSPVersion(packageJson);
if (!gqlspVersion) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`A version of ${logger.code('@0no-co/graphqlsp')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('@0no-co/graphqlsp')} installed?`)
);
} else if (!semverComply(gqlspVersion[1], MINIMUM_VERSIONS.lsp)) {
} else if (!semverComply(gqlspVersion, MINIMUM_VERSIONS.lsp)) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`The version of ${logger.code(
Expand All @@ -108,14 +97,14 @@ export async function* run(): AsyncIterable<ComposeInput> {
}
}

const gqlTadaVersion = deps.find((x) => x[0] === 'gql.tada');
const gqlTadaVersion = await versions.getGqlTadaVersion(packageJson);
if (!gqlTadaVersion) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`A version of ${logger.code('gql.tada')} was not found in your dependencies.\n` +
logger.hint(`Is ${logger.code('gql.tada')} installed?`)
);
} else if (!semverComply(gqlTadaVersion[1], '1.0.0')) {
} else if (!semverComply(gqlTadaVersion, '1.0.0')) {
yield logger.failedTask(Messages.CHECK_DEPENDENCIES);
throw logger.errorMessage(
`The version of ${logger.code('gql.tada')} in your dependencies is out of date.\n` +
Expand Down

0 comments on commit 4b5a90e

Please sign in to comment.