Skip to content

Commit 4bf812e

Browse files
authored
Refactor: find up (#1019)
1 parent 65473bb commit 4bf812e

File tree

3 files changed

+43
-18
lines changed

3 files changed

+43
-18
lines changed

packages/schema/src/cli/cli-util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME } from '../language-server/cons
1313
import { ZModelFormatter } from '../language-server/zmodel-formatter';
1414
import { createZModelServices, ZModelServices } from '../language-server/zmodel-module';
1515
import { mergeBaseModel, resolveImport, resolveTransitiveImports } from '../utils/ast-utils';
16-
import { findPackageJson } from '../utils/pkg-utils';
16+
import { findUp } from '../utils/pkg-utils';
1717
import { getVersion } from '../utils/version-utils';
1818
import { CliError } from './cli-error';
1919

@@ -280,7 +280,7 @@ export async function formatDocument(fileName: string) {
280280

281281
export function getDefaultSchemaLocation() {
282282
// handle override from package.json
283-
const pkgJsonPath = findPackageJson();
283+
const pkgJsonPath = findUp(['package.json']);
284284
if (pkgJsonPath) {
285285
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
286286
if (typeof pkgJson?.zenstack?.schema === 'string') {

packages/schema/src/plugins/prisma/schema-generator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import { name } from '.';
4848
import { getStringLiteral } from '../../language-server/validator/utils';
4949
import telemetry from '../../telemetry';
5050
import { execPackage } from '../../utils/exec-utils';
51-
import { findPackageJson } from '../../utils/pkg-utils';
51+
import { findUp } from '../../utils/pkg-utils';
5252
import {
5353
ModelFieldType,
5454
AttributeArg as PrismaAttributeArg,
@@ -450,7 +450,7 @@ export default class PrismaSchemaGenerator {
450450

451451
export function getDefaultPrismaOutputFile(schemaPath: string) {
452452
// handle override from package.json
453-
const pkgJsonPath = findPackageJson(path.dirname(schemaPath));
453+
const pkgJsonPath = findUp(['package.json'], path.dirname(schemaPath));
454454
if (pkgJsonPath) {
455455
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
456456
if (typeof pkgJson?.zenstack?.prisma === 'string') {

packages/schema/src/utils/pkg-utils.ts

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
1-
import fs from 'fs';
2-
import path from 'path';
1+
import fs from 'node:fs';
2+
import path from 'node:path';
33
import { execSync } from './exec-utils';
44

55
export type PackageManagers = 'npm' | 'yarn' | 'pnpm';
66

7-
function findUp(names: string[], cwd: string): string | undefined {
8-
let dir = cwd;
9-
// eslint-disable-next-line no-constant-condition
10-
while (true) {
11-
const target = names.find((name) => fs.existsSync(path.join(dir, name)));
12-
if (target) return target;
13-
14-
const up = path.resolve(dir, '..');
15-
if (up === dir) return undefined; // it'll fail anyway
16-
dir = up;
17-
}
7+
/**
8+
* A type named FindUp that takes a type parameter e which extends boolean.
9+
* If e extends true, it returns a union type of string[] or undefined.
10+
* If e does not extend true, it returns a union type of string or undefined.
11+
*
12+
* @export
13+
* @template e A type parameter that extends boolean
14+
*/
15+
export type FindUp<e extends boolean> = e extends true ? string[] | undefined : string | undefined
16+
/**
17+
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
18+
* Optionally return a single path or multiple paths.
19+
* If multiple allowed, return all paths found.
20+
* If no paths are found, return undefined.
21+
*
22+
* @export
23+
* @template [e=false]
24+
* @param names An array of strings representing names to search for within the directory
25+
* @param cwd A string representing the current working directory
26+
* @param [multiple=false as e] A boolean flag indicating whether to search for multiple levels. Useful for finding node_modules directories...
27+
* @param [result=[]] An array of strings representing the accumulated results used in multiple results
28+
* @returns Path(s) to a specific file or folder within the directory or parent directories
29+
*/
30+
export function findUp<e extends boolean = false>(names: string[], cwd: string = process.cwd(), multiple: e = false as e, result: string[] = []): FindUp<e> {
31+
if (!names.some((name) => !!name)) return undefined;
32+
const target = names.find((name) => fs.existsSync(path.join(cwd, name)));
33+
if (multiple == false && target) return path.join(cwd, target) as FindUp<e>;
34+
if (target) result.push(path.join(cwd, target));
35+
const up = path.resolve(cwd, '..');
36+
if (up === cwd) return (multiple && result.length > 0 ? result : undefined) as FindUp<e>; // it'll fail anyway
37+
return findUp(names, up, multiple, result);
1838
}
1939

2040
function getPackageManager(projectPath = '.'): PackageManagers {
@@ -85,6 +105,11 @@ export function ensurePackage(
85105
}
86106
}
87107

108+
/**
109+
* A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
110+
* It iterates through the directory structure going one level up at a time until it finds a package.json file. If no package.json file is found, it returns undefined.
111+
* @deprecated Use findUp instead @see findUp
112+
*/
88113
export function findPackageJson(searchPath?: string) {
89114
let currDir = searchPath ?? process.cwd();
90115
while (currDir) {
@@ -102,7 +127,7 @@ export function findPackageJson(searchPath?: string) {
102127
}
103128

104129
export function getPackageJson(searchPath?: string) {
105-
const pkgJsonPath = findPackageJson(searchPath);
130+
const pkgJsonPath = findUp(['package.json'], searchPath ?? process.cwd());
106131
if (pkgJsonPath) {
107132
return JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
108133
} else {

0 commit comments

Comments
 (0)