@netlify/build-info 6.2.2 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/bin.js +1 -1
  2. package/lib/browser/file-system.d.ts +25 -0
  3. package/lib/browser/file-system.js +70 -0
  4. package/lib/build-systems/bazel.d.ts +8 -0
  5. package/lib/build-systems/bazel.js +12 -0
  6. package/lib/build-systems/buck.d.ts +8 -0
  7. package/lib/build-systems/buck.js +12 -0
  8. package/lib/build-systems/build-system.d.ts +20 -0
  9. package/lib/build-systems/build-system.js +18 -0
  10. package/lib/build-systems/gradle.d.ts +8 -0
  11. package/lib/build-systems/gradle.js +12 -0
  12. package/lib/build-systems/index.d.ts +2 -0
  13. package/lib/build-systems/index.js +11 -0
  14. package/lib/build-systems/lage.d.ts +6 -0
  15. package/lib/build-systems/lage.js +6 -0
  16. package/lib/build-systems/moon.d.ts +8 -0
  17. package/lib/build-systems/moon.js +18 -0
  18. package/lib/build-systems/nix.d.ts +8 -0
  19. package/lib/build-systems/nix.js +12 -0
  20. package/lib/build-systems/nrwl.d.ts +11 -0
  21. package/lib/build-systems/nrwl.js +11 -0
  22. package/lib/build-systems/pants.d.ts +8 -0
  23. package/lib/build-systems/pants.js +12 -0
  24. package/lib/build-systems/rush.d.ts +6 -0
  25. package/lib/build-systems/rush.js +6 -0
  26. package/lib/build-systems/turbo.d.ts +6 -0
  27. package/lib/build-systems/turbo.js +6 -0
  28. package/lib/file-system.d.ts +69 -0
  29. package/lib/file-system.js +195 -0
  30. package/lib/index.d.ts +2 -1
  31. package/lib/index.js +2 -1
  32. package/lib/{bin.d.ts → node/bin.d.ts} +0 -0
  33. package/lib/{bin.js → node/bin.js} +2 -3
  34. package/lib/node/file-system.d.ts +19 -0
  35. package/lib/node/file-system.js +65 -0
  36. package/lib/node/get-build-info.d.ts +20 -0
  37. package/lib/node/get-build-info.js +46 -0
  38. package/lib/{detect-package-manager.d.ts → package-managers/detect-package-manager.d.ts} +2 -4
  39. package/lib/package-managers/detect-package-manager.js +75 -0
  40. package/lib/project.d.ts +33 -0
  41. package/lib/project.js +82 -0
  42. package/lib/workspaces/detect-workspace.d.ts +22 -0
  43. package/lib/workspaces/detect-workspace.js +56 -0
  44. package/lib/workspaces/get-workspace-packages.d.ts +3 -0
  45. package/lib/workspaces/get-workspace-packages.js +66 -0
  46. package/package.json +9 -4
  47. package/lib/context.d.ts +0 -11
  48. package/lib/context.js +0 -45
  49. package/lib/detect-build-system.d.ts +0 -5
  50. package/lib/detect-build-system.js +0 -145
  51. package/lib/detect-package-manager.js +0 -71
  52. package/lib/get-build-info.d.ts +0 -11
  53. package/lib/get-build-info.js +0 -34
  54. package/lib/workspaces.d.ts +0 -22
  55. package/lib/workspaces.js +0 -56
package/bin.js CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  // This is a workaround for npm issue: https://github.com/npm/cli/issues/2632
4
4
 
5
- import './lib/bin.js'
5
+ import './lib/node/bin.js'
@@ -0,0 +1,25 @@
1
+ import { DirType, FileSystem } from '../file-system.js';
2
+ /** A sample implementation of a github provider */
3
+ export declare class GithubProvider {
4
+ repo: string;
5
+ branch?: string | undefined;
6
+ constructor(repo: string, branch?: string | undefined);
7
+ dir(filePath?: string): Promise<{
8
+ path: string;
9
+ type: 'file' | 'dir';
10
+ }[]>;
11
+ read(filePath: string): Promise<string>;
12
+ private request;
13
+ }
14
+ /** A sample implementation of a web based file system that fetches from Github */
15
+ export declare class WebFS extends FileSystem {
16
+ git: GithubProvider;
17
+ constructor(git: GithubProvider);
18
+ isAbsolute(path: string): boolean;
19
+ resolve(...paths: string[]): string;
20
+ fileExists(path: string): Promise<boolean>;
21
+ /** Get a list of directory entries */
22
+ readDir(path: string): Promise<string[]>;
23
+ readDir(path: string, withFileTypes: true): Promise<Record<string, DirType>>;
24
+ readFile(path: string): Promise<string>;
25
+ }
@@ -0,0 +1,70 @@
1
+ import { FileSystem } from '../file-system.js';
2
+ /** A sample implementation of a github provider */
3
+ export class GithubProvider {
4
+ repo;
5
+ branch;
6
+ constructor(repo, branch) {
7
+ this.repo = repo;
8
+ this.branch = branch;
9
+ }
10
+ async dir(filePath = '') {
11
+ let path = `/repos/${this.repo}/contents${filePath}`;
12
+ if (this.branch) {
13
+ path += `?ref=${this.branch}`;
14
+ }
15
+ return this.request(path);
16
+ }
17
+ async read(filePath) {
18
+ const headers = { Accept: 'application/vnd.github.VERSION.raw' };
19
+ let path = `/repos/${this.repo}/contents${filePath}`;
20
+ if (this.branch) {
21
+ path += `?ref=${this.branch}`;
22
+ }
23
+ return this.request(path, headers);
24
+ }
25
+ async request(path, headers = {}) {
26
+ const response = await fetch(new URL(path, `https://api.github.com`).href, { headers });
27
+ if (response.headers?.get('Content-Type')?.match(/json/)) {
28
+ const json = await response.json();
29
+ if (!response.ok) {
30
+ Promise.reject(json);
31
+ }
32
+ return json;
33
+ }
34
+ return response.text();
35
+ }
36
+ }
37
+ /** A sample implementation of a web based file system that fetches from Github */
38
+ export class WebFS extends FileSystem {
39
+ git;
40
+ constructor(git) {
41
+ super();
42
+ this.git = git;
43
+ }
44
+ isAbsolute(path) {
45
+ return path.startsWith('/');
46
+ }
47
+ resolve(...paths) {
48
+ const path = this.join(...paths);
49
+ return this.isAbsolute(path) ? path : this.join(this.cwd, path);
50
+ }
51
+ async fileExists(path) {
52
+ try {
53
+ this.readFile(path);
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ async readDir(path, withFileTypes) {
61
+ const result = await this.git.dir(this.resolve(path));
62
+ if (!withFileTypes) {
63
+ return result.map(({ path }) => path);
64
+ }
65
+ return result.reduce((prev, cur) => ({ ...prev, [cur.path]: cur.type === 'dir' ? 'directory' : 'file' }), {});
66
+ }
67
+ async readFile(path) {
68
+ return this.git.read(this.resolve(path));
69
+ }
70
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Bazel extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Bazel extends BaseBuildTool {
3
+ id = 'bazel';
4
+ name = 'Bazel';
5
+ configFiles = ['.bazelrc', 'WORKSPACE', 'WORKSPACE.bazel', 'BUILD.bazel'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ return this;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Buck extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Buck extends BaseBuildTool {
3
+ id = 'buck';
4
+ name = 'Buck';
5
+ configFiles = ['.buckconfig', 'BUCK'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ return this;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,20 @@
1
+ import { Project } from '../project.js';
2
+ export interface BuildSystem {
3
+ id: string;
4
+ name: string;
5
+ version?: string;
6
+ detect(project: Project): Promise<BuildSystem | undefined>;
7
+ }
8
+ export declare abstract class BaseBuildTool implements BuildSystem {
9
+ id: string;
10
+ name: string;
11
+ version?: string;
12
+ configFiles: string[];
13
+ detect(project: Project): Promise<this | undefined>;
14
+ /** Get's a JSON from the class information */
15
+ toJSON(): {
16
+ id: string;
17
+ name: string;
18
+ version: string | undefined;
19
+ };
20
+ }
@@ -0,0 +1,18 @@
1
+ export class BaseBuildTool {
2
+ id;
3
+ name;
4
+ version;
5
+ configFiles = [];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ const pkgJson = await project.getPackageJSON(project.fs.dirname(config));
10
+ this.version = pkgJson.devDependencies?.[this.id];
11
+ return this;
12
+ }
13
+ }
14
+ /** Get's a JSON from the class information */
15
+ toJSON() {
16
+ return { id: this.id, name: this.name, version: this.version };
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Gradle extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Gradle extends BaseBuildTool {
3
+ id = 'gradle';
4
+ name = 'Gradle';
5
+ configFiles = ['build.gradle'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ return this;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,2 @@
1
+ import { Bazel } from './bazel.js';
2
+ export declare const buildSystems: (typeof Bazel)[];
@@ -0,0 +1,11 @@
1
+ import { Bazel } from './bazel.js';
2
+ import { Buck } from './buck.js';
3
+ import { Gradle } from './gradle.js';
4
+ import { Lage } from './lage.js';
5
+ import { Moon } from './moon.js';
6
+ import { Nix } from './nix.js';
7
+ import { Lerna, Nx } from './nrwl.js';
8
+ import { Pants } from './pants.js';
9
+ import { Rush } from './rush.js';
10
+ import { Turbo } from './turbo.js';
11
+ export const buildSystems = [Bazel, Buck, Gradle, Lage, Lerna, Moon, Nix, Nx, Pants, Rush, Turbo];
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export declare class Lage extends BaseBuildTool {
3
+ id: string;
4
+ name: string;
5
+ configFiles: string[];
6
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Lage extends BaseBuildTool {
3
+ id = 'lage';
4
+ name = 'Lage';
5
+ configFiles = ['lage.config.js'];
6
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Moon extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,18 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Moon extends BaseBuildTool {
3
+ id = 'moon';
4
+ name = 'MoonRepo';
5
+ configFiles = ['.moon'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, {
8
+ cwd: project.baseDirectory,
9
+ type: 'directory',
10
+ stopAt: project.root,
11
+ });
12
+ if (config) {
13
+ const pkgJson = await project.getPackageJSON(config);
14
+ this.version = pkgJson.devDependencies?.[this.id];
15
+ return this;
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Nix extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Nix extends BaseBuildTool {
3
+ id = 'nix';
4
+ name = 'Nix';
5
+ configFiles = ['default.nix', 'shell.nix', 'release.nix'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ return this;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export declare class Nx extends BaseBuildTool {
3
+ id: string;
4
+ name: string;
5
+ configFiles: string[];
6
+ }
7
+ export declare class Lerna extends BaseBuildTool {
8
+ id: string;
9
+ name: string;
10
+ configFiles: string[];
11
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Nx extends BaseBuildTool {
3
+ id = 'nx';
4
+ name = 'Nx';
5
+ configFiles = ['nx.json'];
6
+ }
7
+ export class Lerna extends BaseBuildTool {
8
+ id = 'lerna';
9
+ name = 'Lerna';
10
+ configFiles = ['lerna.json'];
11
+ }
@@ -0,0 +1,8 @@
1
+ import { Project } from '../project.js';
2
+ import { BaseBuildTool } from './build-system.js';
3
+ export declare class Pants extends BaseBuildTool {
4
+ id: string;
5
+ name: string;
6
+ configFiles: string[];
7
+ detect(project: Project): Promise<this | undefined>;
8
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Pants extends BaseBuildTool {
3
+ id = 'pants';
4
+ name = 'Pants';
5
+ configFiles = ['pants.toml'];
6
+ async detect(project) {
7
+ const config = await project.fs.findUp(this.configFiles, { cwd: project.baseDirectory, stopAt: project.root });
8
+ if (config) {
9
+ return this;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export declare class Rush extends BaseBuildTool {
3
+ id: string;
4
+ name: string;
5
+ configFiles: string[];
6
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Rush extends BaseBuildTool {
3
+ id = 'rush';
4
+ name = 'Rush';
5
+ configFiles = ['rush.json'];
6
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export declare class Turbo extends BaseBuildTool {
3
+ id: string;
4
+ name: string;
5
+ configFiles: string[];
6
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseBuildTool } from './build-system.js';
2
+ export class Turbo extends BaseBuildTool {
3
+ id = 'turbo';
4
+ name = 'TurboRepo';
5
+ configFiles = ['turbo.json'];
6
+ }
@@ -0,0 +1,69 @@
1
+ export interface Logger {
2
+ debug(...any: any[]): void;
3
+ log(...any: any[]): void;
4
+ error(...any: any[]): void;
5
+ }
6
+ export type DirType = 'directory' | 'file';
7
+ export type TextFile = {
8
+ content: string;
9
+ type: 'text';
10
+ };
11
+ export type JSONFile<T = Record<string, any>> = {
12
+ content: T;
13
+ type: 'json';
14
+ };
15
+ export type TOMLFile = {
16
+ content: string;
17
+ type: 'toml';
18
+ };
19
+ export type File = TextFile | JSONFile | TOMLFile;
20
+ export type findUpOptions = {
21
+ cwd?: string;
22
+ type?: DirType;
23
+ stopAt?: string;
24
+ };
25
+ export declare abstract class FileSystem {
26
+ logger: Logger;
27
+ /**
28
+ * This is a in memory representation of the parsed files
29
+ * The keys are always stored in posix style
30
+ * If the value is null then the file did not get read up in memory yet.
31
+ * If the value is a string it already got read up in mem.
32
+ */
33
+ files: Map<string, File | null>;
34
+ /** The current working directory will be set by the project */
35
+ cwd: string;
36
+ abstract fileExists(path: string): Promise<boolean>;
37
+ abstract readDir(path: string): Promise<string[]>;
38
+ abstract readDir(path: string, withFileTypes: true): Promise<Record<string, DirType>>;
39
+ abstract readDir(path: string, withFileTypes?: true): Promise<Record<string, DirType> | string[]>;
40
+ abstract readFile(path: string): Promise<string>;
41
+ /** resolves a path to an absolute path */
42
+ abstract resolve(...paths: string[]): string;
43
+ /** check if a path is an absolute path */
44
+ abstract isAbsolute(path: string): boolean;
45
+ /** returns the last portion of a path */
46
+ basename(path: string): string;
47
+ /** returns the relative path from to based on the current working directory */
48
+ relative(from: string, to: string): string;
49
+ /** returns the directory name of a path */
50
+ dirname(path: string): string;
51
+ /** A platform independent version of path.join() */
52
+ join(...segments: string[]): string;
53
+ /** adds a file to the file map */
54
+ setFile(path: string, content: File): void;
55
+ /** get a file from the file map */
56
+ getFile(path: string): File | null;
57
+ /** get a json file from the file map */
58
+ getJSONFile<T = Record<string, any>>(path: string): JSONFile<T> | null;
59
+ /** get a toml file from the file map */
60
+ getTOMLFile(path: string): TOMLFile | null;
61
+ /** Checks if a file is already in our in memory representation */
62
+ hasFile(path: any): boolean;
63
+ /** Gracefully reads a file as JSON and parses it */
64
+ readJSON<V = Record<string, unknown>>(path: string): Promise<Partial<V>>;
65
+ /** Find a file or directory by walking up parent directories. */
66
+ findUp(name: string | readonly string[], options?: findUpOptions): Promise<string | undefined>;
67
+ /** Find files or directories by walking up parent directories. */
68
+ findUpMultiple(name: string | readonly string[], options?: findUpOptions): Promise<string[]>;
69
+ }
@@ -0,0 +1,195 @@
1
+ class DefaultLogger {
2
+ debug(...data) {
3
+ // TODO: add reporting
4
+ console.debug(...data);
5
+ }
6
+ log(...data) {
7
+ console.log(...data);
8
+ }
9
+ error(...data) {
10
+ // TODO: on error add reporting
11
+ console.error(...data);
12
+ }
13
+ }
14
+ export class FileSystem {
15
+ logger = new DefaultLogger();
16
+ /**
17
+ * This is a in memory representation of the parsed files
18
+ * The keys are always stored in posix style
19
+ * If the value is null then the file did not get read up in memory yet.
20
+ * If the value is a string it already got read up in mem.
21
+ */
22
+ files = new Map();
23
+ /** The current working directory will be set by the project */
24
+ cwd = '/';
25
+ /** returns the last portion of a path */
26
+ basename(path) {
27
+ return this.join(path).split('/').pop() || '';
28
+ }
29
+ /** returns the relative path from to based on the current working directory */
30
+ relative(from, to) {
31
+ const absoluteFrom = this.isAbsolute(from) ? from : this.join(this.cwd, from);
32
+ const absoluteTo = this.isAbsolute(to) ? to : this.join(this.cwd, to);
33
+ // if the paths are equal return an empty string
34
+ if (absoluteFrom === absoluteTo) {
35
+ return '';
36
+ }
37
+ const matching = [];
38
+ // split by / excluding the starting slash
39
+ const fromParts = this.join(absoluteFrom).split(/(?<!^)\//gm);
40
+ const toParts = this.join(absoluteTo).split(/(?<!^)\//gm);
41
+ for (let i = 0, max = toParts.length; i < max; i++) {
42
+ if (toParts[i] === fromParts?.[i]) {
43
+ matching.push(toParts[i]);
44
+ }
45
+ else {
46
+ break;
47
+ }
48
+ }
49
+ // calculate how many dirs we need to go up from the to path
50
+ const toUp = toParts.length - matching.length;
51
+ const fromUp = fromParts.length - matching.length;
52
+ // the max we have to go up
53
+ const up = Math.max(toUp, fromUp);
54
+ // if we have something from the 'from' to go up go up the max difference
55
+ const result = fromUp > 0 ? [...new Array(up).fill('..')] : [];
56
+ // if we have some parts left add them to the going up
57
+ if (toUp > 0) {
58
+ result.push(...toParts.slice(-toUp));
59
+ }
60
+ return result.join('/');
61
+ }
62
+ /** returns the directory name of a path */
63
+ dirname(path) {
64
+ const parts = this.join(path).split('/');
65
+ parts.pop();
66
+ // Preserve the initial slash if there was one.
67
+ if (parts.length === 1 && parts[0] === '') {
68
+ return '/';
69
+ }
70
+ return parts.join('/');
71
+ }
72
+ /** A platform independent version of path.join() */
73
+ join(...segments) {
74
+ let parts = [];
75
+ for (let i = 0, max = segments.length; i < max; i++) {
76
+ // split the segments to parts by all kind of separator (forward and backward)
77
+ parts = parts.concat(segments[i].split(/[\\/]/g));
78
+ }
79
+ // resolve .. inside path segments
80
+ const resolvedParts = [];
81
+ for (let i = 0, max = parts.length; i < max; i++) {
82
+ const part = parts[i];
83
+ // Remove leading and trailing slashes
84
+ // Also remove "." segments
85
+ if (!part || part === '.')
86
+ continue;
87
+ // Interpret ".." to pop the last segment
88
+ if (part === '..') {
89
+ resolvedParts.pop();
90
+ }
91
+ else {
92
+ resolvedParts.push(part);
93
+ }
94
+ }
95
+ // Preserve the initial slash if there was one.
96
+ if (parts[0] === '') {
97
+ resolvedParts.unshift('');
98
+ }
99
+ return resolvedParts.join('/') || (resolvedParts.length ? '/' : '.');
100
+ }
101
+ /** adds a file to the file map */
102
+ setFile(path, content) {
103
+ this.files.set(path, content);
104
+ }
105
+ /** get a file from the file map */
106
+ getFile(path) {
107
+ return this.files.get(path) || null;
108
+ }
109
+ /** get a json file from the file map */
110
+ getJSONFile(path) {
111
+ const file = this.files.get(path) || null;
112
+ if (file?.type === 'json') {
113
+ return file;
114
+ }
115
+ return null;
116
+ }
117
+ /** get a toml file from the file map */
118
+ getTOMLFile(path) {
119
+ const file = this.files.get(path) || null;
120
+ if (file?.type === 'toml') {
121
+ return file;
122
+ }
123
+ return null;
124
+ }
125
+ /** Checks if a file is already in our in memory representation */
126
+ hasFile(path) {
127
+ const resolvedPath = path;
128
+ const file = this.files.get(resolvedPath);
129
+ return Boolean(file?.content);
130
+ }
131
+ /** Gracefully reads a file as JSON and parses it */
132
+ async readJSON(path) {
133
+ try {
134
+ const content = JSON.parse(await this.readFile(path));
135
+ this.files.set(path, { content, type: 'json' });
136
+ return content;
137
+ }
138
+ catch (error) {
139
+ this.logger.error(`Could not parse JSON file ${path}\n${error}`);
140
+ return {};
141
+ }
142
+ }
143
+ /** Find a file or directory by walking up parent directories. */
144
+ async findUp(name, options = {}) {
145
+ let startDir = this.resolve(options.cwd || this.cwd);
146
+ // function for a recursive call
147
+ const readUp = async () => {
148
+ const entries = await this.readDir(startDir, true);
149
+ const found = Object.entries(entries).find(([entry, dirType]) => {
150
+ if ((typeof name === 'string' && entry === name) || (Array.isArray(name) && name.includes(entry))) {
151
+ if (options.type) {
152
+ if (options.type === dirType) {
153
+ return entry;
154
+ }
155
+ }
156
+ return entry;
157
+ }
158
+ });
159
+ // either found something or reached the root and nothing found
160
+ if (found?.[0]) {
161
+ return this.join(startDir, found[0]);
162
+ }
163
+ if (startDir === '/' || (options.stopAt && this.resolve(options.stopAt) === startDir)) {
164
+ return;
165
+ }
166
+ startDir = this.join(startDir, '..');
167
+ // recursive call to walk up
168
+ return readUp();
169
+ };
170
+ return readUp();
171
+ }
172
+ /** Find files or directories by walking up parent directories. */
173
+ async findUpMultiple(name, options = {}) {
174
+ let startDir = this.resolve(options.cwd || this.cwd);
175
+ const found = [];
176
+ // function for a recursive call
177
+ const readUp = async () => {
178
+ const entries = await this.readDir(startDir, true);
179
+ for (const [entry, dirType] of Object.entries(entries)) {
180
+ if ((typeof name === 'string' && entry === name) || (Array.isArray(name) && name.includes(entry))) {
181
+ if ((options.type && options.type === dirType) || !options.type) {
182
+ found.push(this.resolve(startDir, entry));
183
+ }
184
+ }
185
+ }
186
+ if (startDir === '/' || (options.stopAt && this.resolve(options.stopAt) === startDir)) {
187
+ return found;
188
+ }
189
+ startDir = this.join(startDir, '..');
190
+ // recursive call to walk up
191
+ return readUp();
192
+ };
193
+ return readUp();
194
+ }
195
+ }
package/lib/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { getBuildInfo } from './get-build-info.js';
1
+ export * from './file-system.js';
2
+ export * from './project.js';
package/lib/index.js CHANGED
@@ -1 +1,2 @@
1
- export { getBuildInfo } from './get-build-info.js';
1
+ export * from './file-system.js';
2
+ export * from './project.js';
File without changes