1
1
import path from 'path' ;
2
-
2
+ import json5 from 'json5' ;
3
+ import fs from 'node:fs' ;
3
4
import findUp from 'find-up' ;
4
5
5
6
export interface PackageInfo {
@@ -8,7 +9,7 @@ export interface PackageInfo {
8
9
dirname : string ;
9
10
}
10
11
11
- function getClosestPackageInfo ( directory : string ) {
12
+ function getClosestPackageInfo ( directory : string ) : PackageInfo | undefined {
12
13
const packageJsonPath = findUp . sync ( 'package.json' , {
13
14
cwd : directory ,
14
15
} ) ;
@@ -24,6 +25,37 @@ function getClosestPackageInfo(directory: string) {
24
25
}
25
26
}
26
27
28
+ function getClosestDenoJson ( directory : string ) : PackageInfo | undefined {
29
+ const denoJsonPath = findUp . sync ( 'deno.json' , {
30
+ cwd : directory ,
31
+ } ) ;
32
+
33
+ if ( denoJsonPath ) {
34
+ const { name } = require ( denoJsonPath ) ;
35
+
36
+ return {
37
+ name,
38
+ path : denoJsonPath ,
39
+ dirname : path . dirname ( denoJsonPath ) ,
40
+ } ;
41
+ }
42
+
43
+ // Deno also supports `deno.jsonc`
44
+ const denoJsoncPath = findUp . sync ( 'deno.jsonc' , {
45
+ cwd : directory ,
46
+ } ) ;
47
+
48
+ if ( denoJsoncPath ) {
49
+ const { name } = json5 . parse ( fs . readFileSync ( denoJsoncPath , 'utf-8' ) ) ;
50
+
51
+ return {
52
+ name,
53
+ path : denoJsoncPath ,
54
+ dirname : path . dirname ( denoJsoncPath ) ,
55
+ } ;
56
+ }
57
+ }
58
+
27
59
const packageInfoCache = new Map < string , PackageInfo > ( ) ;
28
60
29
61
export function getPackageInfo ( cwd ?: string | null ) : PackageInfo {
@@ -34,18 +66,37 @@ export function getPackageInfo(cwd?: string | null): PackageInfo {
34
66
return cachedValue ;
35
67
}
36
68
37
- let packageInfo = getClosestPackageInfo ( resolvedCwd ) ;
69
+ let packageInfo : PackageInfo | undefined ;
70
+
71
+ // Deno projects don't necessarily have a package.json
72
+ if ( typeof process . versions . deno === 'string' ) {
73
+ packageInfo = getClosestDenoJson ( resolvedCwd ) ;
38
74
39
- while ( packageInfo && ! packageInfo . name ) {
40
- packageInfo = getClosestPackageInfo (
41
- path . resolve ( packageInfo . dirname , '..' ) ,
42
- ) ;
75
+ // No need to look further as nested deno.json files is not supported
76
+ // in Deno without being a workspace member. If they are a workspace
77
+ // member, they are expected to have the `name` field anyway.
43
78
}
44
79
45
- if ( ! packageInfo || ! packageInfo . name ) {
46
- throw new Error (
47
- `Couldn't find parent package.json with a name field from '${ resolvedCwd } '` ,
48
- ) ;
80
+ if ( ! packageInfo ) {
81
+ packageInfo = getClosestPackageInfo ( resolvedCwd ) ;
82
+
83
+ while ( packageInfo && ! packageInfo . name ) {
84
+ packageInfo = getClosestPackageInfo (
85
+ path . resolve ( packageInfo . dirname , '..' ) ,
86
+ ) ;
87
+ }
88
+
89
+ if ( ! packageInfo || ! packageInfo . name ) {
90
+ if ( typeof process . versions . deno === 'string' ) {
91
+ throw new Error (
92
+ `Couldn't find parent deno.json, deno.jsonc or package.json with a name field from '${ resolvedCwd } '` ,
93
+ ) ;
94
+ } else {
95
+ throw new Error (
96
+ `Couldn't find parent package.json with a name field from '${ resolvedCwd } '` ,
97
+ ) ;
98
+ }
99
+ }
49
100
}
50
101
51
102
packageInfoCache . set ( resolvedCwd , packageInfo ) ;
0 commit comments