Skip to content

Commit 17d4e68

Browse files
committed
Parse pnp data from .pnp.cjs
1 parent e6f86e8 commit 17d4e68

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

internal/pnp/manifestparser.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,47 @@ type PnpManifestData struct {
7474
packageRegistryTrie *PackageRegistryTrie
7575
}
7676

77-
func parseManifestFromPath(manifestPath string) (*PnpManifestData, error) {
78-
data, err := os.ReadFile(manifestPath)
79-
if err != nil {
80-
return nil, fmt.Errorf("failed to read .pnp.data.json file: %w", err)
77+
func parseManifestFromPath(manifestDir string) (*PnpManifestData, error) {
78+
pnpDataString := ""
79+
80+
data, err := os.ReadFile(path.Join(manifestDir, ".pnp.data.json"))
81+
if err == nil {
82+
pnpDataString = string(data)
83+
} else {
84+
data, err := os.ReadFile(path.Join(manifestDir, ".pnp.cjs"))
85+
if err != nil {
86+
return nil, fmt.Errorf("failed to read .pnp.cjs file: %w", err)
87+
}
88+
89+
pnpString := string(data)
90+
91+
manifestRegex := regexp2.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`, regexp2.None)
92+
matches, err := manifestRegex.FindStringMatch(pnpString)
93+
if err != nil || matches == nil {
94+
return nil, fmt.Errorf("We failed to locate the PnP data payload inside its manifest file. Did you manually edit the file?")
95+
}
96+
97+
start := matches.Index + matches.Length
98+
var b strings.Builder
99+
b.Grow(len(pnpString))
100+
for i := start; i < len(pnpString); i++ {
101+
if pnpString[i] == '\'' {
102+
break
103+
}
104+
105+
if pnpString[i] != '\\' {
106+
b.WriteByte(pnpString[i])
107+
}
108+
}
109+
pnpDataString = b.String()
81110
}
82111

83112
var rawData map[string]interface{}
84-
if err := json.Unmarshal(data, &rawData); err != nil {
85-
return nil, fmt.Errorf("failed to parse JSON: %w", err)
113+
if err := json.Unmarshal([]byte(pnpDataString), &rawData); err != nil {
114+
return nil, fmt.Errorf("failed to parse JSON PnP data: %w", err)
86115
}
87116

88-
pnpData, err := parsePnpManifest(rawData, manifestPath)
117+
pnpData, err := parsePnpManifest(rawData, manifestDir)
89118
if err != nil {
90119
return nil, fmt.Errorf("failed to parse PnP data: %w", err)
91120
}
@@ -94,8 +123,8 @@ func parseManifestFromPath(manifestPath string) (*PnpManifestData, error) {
94123
}
95124

96125
// TODO add error handling for corrupted data
97-
func parsePnpManifest(rawData map[string]interface{}, manifestPath string) (*PnpManifestData, error) {
98-
data := &PnpManifestData{dirPath: path.Dir(manifestPath)}
126+
func parsePnpManifest(rawData map[string]interface{}, manifestDir string) (*PnpManifestData, error) {
127+
data := &PnpManifestData{dirPath: manifestDir}
99128

100129
if roots, ok := rawData["dependencyTreeRoots"].([]interface{}); ok {
101130
for _, root := range roots {

internal/pnp/pnp.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package pnp
22

33
import (
4+
"fmt"
45
"sync"
56
"sync/atomic"
67
)
@@ -41,6 +42,7 @@ func GetPnpApi(filePath string) *PnpApi {
4142
cachedPnpApi = pnpApi
4243
} else {
4344
// Couldn't load PnP API
45+
fmt.Println("Error loading PnP API", err)
4446
cachedPnpApi = nil
4547
}
4648

internal/pnp/pnpapi.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ func (p *PnpApi) findClosestPnpManifest() (*PnpManifestData, error) {
113113
for {
114114
pnpPath := path.Join(directoryPath, ".pnp.cjs")
115115
if _, err := os.Stat(pnpPath); err == nil {
116-
manifestPath := path.Join(directoryPath, ".pnp.data.json")
117-
return parseManifestFromPath(manifestPath)
116+
return parseManifestFromPath(directoryPath)
118117
}
119118

120119
directoryPath = path.Dir(directoryPath)

0 commit comments

Comments
 (0)