From 2ae52e90457c844164fea55a3dec960223b92dd6 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 29 Oct 2025 14:48:14 +0100 Subject: [PATCH 01/32] Implement yarn pnp api --- internal/pnp/pnp.go | 13 ++ internal/pnp/pnpapi.go | 341 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 internal/pnp/pnp.go create mode 100644 internal/pnp/pnpapi.go diff --git a/internal/pnp/pnp.go b/internal/pnp/pnp.go new file mode 100644 index 00000000000..476c0ea107d --- /dev/null +++ b/internal/pnp/pnp.go @@ -0,0 +1,13 @@ +package pnp + +func InitPnpApi(fs PnpApiFS, filePath string) *PnpApi { + pnpApi := &PnpApi{fs: fs, url: filePath} + + manifestData, err := pnpApi.findClosestPnpManifest() + if err == nil { + pnpApi.manifest = manifestData + return pnpApi + } + + return nil +} diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go new file mode 100644 index 00000000000..eb33849b5a6 --- /dev/null +++ b/internal/pnp/pnpapi.go @@ -0,0 +1,341 @@ +package pnp + +/* + * Yarn Plug'n'Play (generally referred to as Yarn PnP) is the default installation strategy in modern releases of Yarn. + * Yarn PnP generates a single Node.js loader file in place of the typical node_modules folder. + * This loader file, named .pnp.cjs, contains all information about your project's dependency tree, informing your tools as to + * the location of the packages on the disk and letting them know how to resolve require and import calls. + * + * The full specification is available at https://yarnpkg.com/advanced/pnp-spec + */ + +import ( + "errors" + "fmt" + "strings" + + "github.com/microsoft/typescript-go/internal/tspath" +) + +type PnpApi struct { + fs PnpApiFS + url string + manifest *PnpManifestData +} + +// FS abstraction used by the PnpApi to access the file system +// We can't use the vfs.FS interface because it creates an import cycle: core -> pnp -> vfs -> core +type PnpApiFS interface { + FileExists(path string) bool + ReadFile(path string) (contents string, ok bool) +} + +func (p *PnpApi) RefreshManifest() error { + var newData *PnpManifestData + var err error + + if p.manifest == nil { + newData, err = p.findClosestPnpManifest() + } else { + newData, err = parseManifestFromPath(p.fs, p.manifest.dirPath) + } + + if err != nil { + return err + } + + p.manifest = newData + return nil +} + +func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (string, error) { + if p.manifest == nil { + panic("ResolveToUnqualified called with no PnP manifest available") + } + + ident, modulePath, err := p.ParseBareIdentifier(specifier) + if err != nil { + // Skipping resolution + return "", nil + } + + parentLocator, err := p.FindLocator(parentPath) + if err != nil || parentLocator == nil { + // Skipping resolution + return "", nil + } + + parentPkg := p.GetPackage(parentLocator) + + var referenceOrAlias *PackageDependency + for _, dep := range parentPkg.PackageDependencies { + if dep.Ident == ident { + referenceOrAlias = &dep + break + } + } + + // If not found, try fallback if enabled + if referenceOrAlias == nil { + if p.manifest.enableTopLevelFallback { + excluded := false + if exclusion, ok := p.manifest.fallbackExclusionMap[parentLocator.Name]; ok { + for _, entry := range exclusion.Entries { + if entry == parentLocator.Reference { + excluded = true + break + } + } + } + if !excluded { + fallback := p.ResolveViaFallback(ident) + if fallback != nil { + referenceOrAlias = fallback + } + } + } + } + + // undeclared dependency + if referenceOrAlias == nil { + if parentLocator.Name == "" { + return "", fmt.Errorf("Your application tried to access %s, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", ident, ident, parentPath) + } + return "", fmt.Errorf("%s tried to access %s, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", parentLocator.Name, ident, ident, parentPath) + } + + // unfulfilled peer dependency + if !referenceOrAlias.IsAlias() && referenceOrAlias.Reference == "" { + if parentLocator.Name == "" { + return "", fmt.Errorf("Your application tried to access %s (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed.\n\nRequired package: %s\nRequired by: %s", ident, ident, parentPath) + } + return "", fmt.Errorf("%s tried to access %s (a peer dependency) but it isn't provided by its ancestors/your application; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", parentLocator.Name, ident, ident, parentPath) + } + + var dependencyPkg *PackageInfo + if referenceOrAlias.IsAlias() { + dependencyPkg = p.GetPackage(&Locator{Name: referenceOrAlias.AliasName, Reference: referenceOrAlias.Reference}) + } else { + dependencyPkg = p.GetPackage(&Locator{Name: referenceOrAlias.Ident, Reference: referenceOrAlias.Reference}) + } + + return tspath.ResolvePath(p.manifest.dirPath, dependencyPkg.PackageLocation, modulePath), nil +} + +func (p *PnpApi) findClosestPnpManifest() (*PnpManifestData, error) { + directoryPath := tspath.GetNormalizedAbsolutePath(p.url, "/") + + for { + pnpPath := tspath.CombinePaths(directoryPath, ".pnp.cjs") + if p.fs.FileExists(pnpPath) { + return parseManifestFromPath(p.fs, directoryPath) + } + + if tspath.IsDiskPathRoot(directoryPath) { + return nil, errors.New("no PnP manifest found") + } + + directoryPath = tspath.GetDirectoryPath(directoryPath) + } +} + +func (p *PnpApi) GetPackage(locator *Locator) *PackageInfo { + packageRegistryMap := p.manifest.packageRegistryMap + packageInfo, ok := packageRegistryMap[locator.Name][locator.Reference] + if !ok { + panic(locator.Name + " should have an entry in the package registry") + } + + return packageInfo +} + +func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { + relativePath := tspath.GetRelativePathFromDirectory(p.manifest.dirPath, parentPath, + tspath.ComparePathsOptions{UseCaseSensitiveFileNames: true}) + + if p.manifest.ignorePatternData != nil { + match, err := p.manifest.ignorePatternData.MatchString(relativePath) + if err != nil { + return nil, err + } + + if match { + return nil, nil + } + } + + var relativePathWithDot string + if strings.HasPrefix(relativePath, "../") { + relativePathWithDot = relativePath + } else { + relativePathWithDot = "./" + relativePath + } + + var bestLength int + var bestLocator *Locator + pathSegments := strings.Split(relativePathWithDot, "/") + currentTrie := p.manifest.packageRegistryTrie + + // Go down the trie, looking for the latest defined packageInfo that matches the path + for index, segment := range pathSegments { + currentTrie = currentTrie.childrenPathSegments[segment] + + if currentTrie == nil || currentTrie.childrenPathSegments == nil { + break + } + + if currentTrie.packageData != nil && index >= bestLength { + bestLength = index + bestLocator = &Locator{Name: currentTrie.packageData.ident, Reference: currentTrie.packageData.reference} + } + } + + if bestLocator == nil { + return nil, fmt.Errorf("no package found for path %s", relativePath) + } + + return bestLocator, nil +} + +func (p *PnpApi) ResolveViaFallback(name string) *PackageDependency { + topLevelPkg := p.GetPackage(&Locator{Name: "", Reference: ""}) + + if topLevelPkg != nil { + for _, dep := range topLevelPkg.PackageDependencies { + if dep.Ident == name { + return &dep + } + } + } + + for _, dep := range p.manifest.fallbackPool { + if dep[0] == name { + return &PackageDependency{ + Ident: dep[0], + Reference: dep[1], + AliasName: "", + } + } + } + + return nil +} + +func (p *PnpApi) ParseBareIdentifier(specifier string) (ident string, modulePath string, err error) { + if len(specifier) == 0 { + return "", "", fmt.Errorf("Empty specifier: %s", specifier) + } + + firstSlash := strings.Index(specifier, "/") + + if specifier[0] == '@' { + if firstSlash == -1 { + return "", "", fmt.Errorf("Invalid specifier: %s", specifier) + } + + secondSlash := strings.Index(specifier[firstSlash+1:], "/") + + if secondSlash == -1 { + ident = specifier + } else { + ident = specifier[:firstSlash+1+secondSlash] + } + } else { + firstSlash := strings.Index(specifier, "/") + + if firstSlash == -1 { + ident = specifier + } else { + ident = specifier[:firstSlash] + } + } + + modulePath = specifier[len(ident):] + + return ident, modulePath, nil +} + +func (p *PnpApi) GetPnpTypeRoots(currentDirectory string) []string { + if p.manifest == nil { + return []string{} + } + + currentDirectory = tspath.NormalizePath(currentDirectory) + + currentPackage, err := p.FindLocator(currentDirectory) + if err != nil { + return []string{} + } + + if currentPackage == nil { + return []string{} + } + + packageDependencies := p.GetPackage(currentPackage).PackageDependencies + + typeRoots := []string{} + for _, dep := range packageDependencies { + if strings.HasPrefix(dep.Ident, "@types/") && dep.Reference != "" { + packageInfo := p.GetPackage(&Locator{Name: dep.Ident, Reference: dep.Reference}) + typeRoots = append(typeRoots, tspath.GetDirectoryPath( + tspath.ResolvePath(p.manifest.dirPath, packageInfo.PackageLocation), + )) + } + } + + return typeRoots +} + +func (p *PnpApi) IsImportable(fromFileName string, toFileName string) bool { + fromLocator, errFromLocator := p.FindLocator(fromFileName) + toLocator, errToLocator := p.FindLocator(toFileName) + + if fromLocator == nil || toLocator == nil || errFromLocator != nil || errToLocator != nil { + return false + } + + fromInfo := p.GetPackage(fromLocator) + for _, dep := range fromInfo.PackageDependencies { + if dep.Reference == toLocator.Reference { + if dep.IsAlias() && dep.AliasName == toLocator.Name { + return true + } + + if dep.Ident == toLocator.Name { + return true + } + } + } + + return false +} + +func (p *PnpApi) GetPackageLocationAbsolutePath(packageInfo *PackageInfo) string { + if packageInfo == nil { + return "" + } + + packageLocation := packageInfo.PackageLocation + return tspath.ResolvePath(p.manifest.dirPath, packageLocation) +} + +func (p *PnpApi) IsInPnpModule(fromFileName string, toFileName string) bool { + fromLocator, _ := p.FindLocator(fromFileName) + toLocator, _ := p.FindLocator(toFileName) + // The targeted filename is in a pnp module different from the requesting filename + return fromLocator != nil && toLocator != nil && fromLocator.Name != toLocator.Name +} + +func (p *PnpApi) AppendPnpTypeRoots(nmTypes []string, baseDir string, nmFromConfig bool) ([]string, bool) { + pnpTypes := p.GetPnpTypeRoots(baseDir) + + if len(nmTypes) > 0 { + return append(nmTypes, pnpTypes...), nmFromConfig + } + + if len(pnpTypes) > 0 { + return pnpTypes, false + } + + return nil, false +} From 134f3dcbcb68f8235037c7f34562646ceaa15ec7 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 29 Oct 2025 14:54:02 +0100 Subject: [PATCH 02/32] Add pnpVFS + tests --- internal/vfs/pnpvfs/pnpvfs.go | 235 +++++++++++++++++++++++ internal/vfs/pnpvfs/pnpvfs_test.go | 296 +++++++++++++++++++++++++++++ 2 files changed, 531 insertions(+) create mode 100644 internal/vfs/pnpvfs/pnpvfs.go create mode 100644 internal/vfs/pnpvfs/pnpvfs_test.go diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go new file mode 100644 index 00000000000..d88894a21f2 --- /dev/null +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -0,0 +1,235 @@ +package pnpvfs + +import ( + "archive/zip" + "path" + "strconv" + "strings" + "sync" + "time" + + "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/iovfs" +) + +type pnpFS struct { + fs vfs.FS + cachedZipReadersMap map[string]*zip.ReadCloser + cacheReaderMutex sync.Mutex +} + +var _ vfs.FS = (*pnpFS)(nil) + +func From(fs vfs.FS) *pnpFS { + pnpFS := &pnpFS{ + fs: fs, + cachedZipReadersMap: make(map[string]*zip.ReadCloser), + } + + return pnpFS +} + +func (pnpFS *pnpFS) DirectoryExists(path string) bool { + path, _, _ = resolveVirtual(path) + + if strings.HasSuffix(path, ".zip") { + return pnpFS.fs.FileExists(path) + } + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + + return fs.DirectoryExists(formattedPath) +} + +func (pnpFS *pnpFS) FileExists(path string) bool { + path, _, _ = resolveVirtual(path) + + if strings.HasSuffix(path, ".zip") { + return pnpFS.fs.FileExists(path) + } + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.FileExists(formattedPath) +} + +func (pnpFS *pnpFS) GetAccessibleEntries(path string) vfs.Entries { + path, hash, basePath := resolveVirtual(path) + + fs, formattedPath, zipPath := getMatchingFS(pnpFS, path) + entries := fs.GetAccessibleEntries(formattedPath) + + for i, dir := range entries.Directories { + fullPath := tspath.CombinePaths(zipPath+formattedPath, dir) + entries.Directories[i] = makeVirtualPath(basePath, hash, fullPath) + } + + for i, file := range entries.Files { + fullPath := tspath.CombinePaths(zipPath+formattedPath, file) + entries.Files[i] = makeVirtualPath(basePath, hash, fullPath) + } + + return entries +} + +func (pnpFS *pnpFS) ReadFile(path string) (contents string, ok bool) { + path, _, _ = resolveVirtual(path) + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.ReadFile(formattedPath) +} + +func (pnpFS *pnpFS) Chtimes(path string, mtime time.Time, atime time.Time) error { + path, _, _ = resolveVirtual(path) + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.Chtimes(formattedPath, mtime, atime) +} + +func (pnpFS *pnpFS) Realpath(path string) string { + path, hash, basePath := resolveVirtual(path) + + fs, formattedPath, zipPath := getMatchingFS(pnpFS, path) + fullPath := zipPath + fs.Realpath(formattedPath) + return makeVirtualPath(basePath, hash, fullPath) +} + +func (pnpFS *pnpFS) Remove(path string) error { + path, _, _ = resolveVirtual(path) + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.Remove(formattedPath) +} + +func (pnpFS *pnpFS) Stat(path string) vfs.FileInfo { + path, _, _ = resolveVirtual(path) + + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.Stat(formattedPath) +} + +func (pnpFS *pnpFS) UseCaseSensitiveFileNames() bool { + // pnp fs is always case sensitive + return true +} + +func (pnpFS *pnpFS) WalkDir(root string, walkFn vfs.WalkDirFunc) error { + root, hash, basePath := resolveVirtual(root) + + fs, formattedPath, zipPath := getMatchingFS(pnpFS, root) + return fs.WalkDir(formattedPath, (func(path string, d vfs.DirEntry, err error) error { + fullPath := zipPath + path + return walkFn(makeVirtualPath(basePath, hash, fullPath), d, err) + })) +} + +func (pnpFS *pnpFS) WriteFile(path string, data string, writeByteOrderMark bool) error { + path, _, _ = resolveVirtual(path) + + fs, formattedPath, zipPath := getMatchingFS(pnpFS, path) + if zipPath != "" { + panic("cannot write to zip file") + } + + return fs.WriteFile(formattedPath, data, writeByteOrderMark) +} + +func splitZipPath(path string) (string, string) { + parts := strings.Split(path, ".zip/") + if len(parts) < 2 { + return path, "/" + } + return parts[0] + ".zip", "/" + parts[1] +} + +func getMatchingFS(pnpFS *pnpFS, path string) (vfs.FS, string, string) { + if !tspath.IsZipPath(path) { + return pnpFS.fs, path, "" + } + + zipPath, internalPath := splitZipPath(path) + + zipStat := pnpFS.fs.Stat(zipPath) + if zipStat == nil { + return pnpFS.fs, path, "" + } + + var usedReader *zip.ReadCloser + + pnpFS.cacheReaderMutex.Lock() + defer pnpFS.cacheReaderMutex.Unlock() + + cachedReader, ok := pnpFS.cachedZipReadersMap[zipPath] + if ok { + usedReader = cachedReader + } else { + zipReader, err := zip.OpenReader(zipPath) + if err != nil { + return pnpFS.fs, path, "" + } + + usedReader = zipReader + pnpFS.cachedZipReadersMap[zipPath] = usedReader + } + + return iovfs.From(usedReader, pnpFS.fs.UseCaseSensitiveFileNames()), internalPath, zipPath +} + +// Virtual paths are used to make different paths resolve to the same real file or folder, which is necessary in some cases when PnP is enabled +// See https://yarnpkg.com/advanced/lexicon#virtual-package and https://yarnpkg.com/advanced/pnpapi#resolvevirtual for more details +func resolveVirtual(path string) (realPath string, hash string, basePath string) { + idx := strings.Index(path, "/__virtual__/") + if idx == -1 { + return path, "", "" + } + + base := path[:idx] + rest := path[idx+len("/__virtual__/"):] + parts := strings.SplitN(rest, "/", 3) + if len(parts) < 3 { + // Not enough parts to match the pattern, return as is + return path, "", "" + } + hash = parts[0] + subpath := parts[2] + depth, err := strconv.Atoi(parts[1]) + if err != nil || depth < 0 { + // Invalid n, return as is + return path, "", "" + } + + basePath = path[:idx] + "/__virtual__" + + // Apply dirname n times to base + for range depth { + base = tspath.GetDirectoryPath(base) + } + // Join base and subpath + if base == "/" { + return "/" + subpath, hash, basePath + } + + return tspath.CombinePaths(base, subpath), hash, basePath +} + +func makeVirtualPath(basePath string, hash string, targetPath string) string { + if basePath == "" || hash == "" { + return targetPath + } + + relativePath := tspath.GetRelativePathFromDirectory( + tspath.GetDirectoryPath(basePath), + targetPath, + tspath.ComparePathsOptions{UseCaseSensitiveFileNames: true}) + + segments := strings.Split(relativePath, "/") + + depth := 0 + for depth < len(segments) && segments[depth] == ".." { + depth++ + } + + subPath := strings.Join(segments[depth:], "/") + + return path.Join(basePath, hash, strconv.Itoa(depth), subPath) +} diff --git a/internal/vfs/pnpvfs/pnpvfs_test.go b/internal/vfs/pnpvfs/pnpvfs_test.go new file mode 100644 index 00000000000..f5d12fa775f --- /dev/null +++ b/internal/vfs/pnpvfs/pnpvfs_test.go @@ -0,0 +1,296 @@ +package pnpvfs_test + +import ( + "archive/zip" + "fmt" + "os" + "strings" + "testing" + + "github.com/microsoft/typescript-go/internal/testutil" + "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/osvfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" + "github.com/microsoft/typescript-go/internal/vfs/vfstest" + "gotest.tools/v3/assert" +) + +func createTestZip(t *testing.T, files map[string]string) string { + t.Helper() + + tmpDir := t.TempDir() + zipPath := tspath.CombinePaths(tmpDir, "test.zip") + + file, err := os.Create(zipPath) + assert.NilError(t, err) + defer file.Close() + + w := zip.NewWriter(file) + defer w.Close() + + for name, content := range files { + f, err := w.Create(name) + assert.NilError(t, err) + _, err = f.Write([]byte(content)) + assert.NilError(t, err) + } + + return zipPath +} + +func TestPnpVfs_BasicFileOperations(t *testing.T) { + t.Parallel() + + underlyingFS := vfstest.FromMap(map[string]string{ + "/project/src/index.ts": "export const hello = 'world';", + "/project/package.json": `{"name": "test"}`, + }, true) + + fs := pnpvfs.From(underlyingFS) + assert.Assert(t, fs.FileExists("/project/src/index.ts")) + assert.Assert(t, !fs.FileExists("/project/nonexistent.ts")) + + content, ok := fs.ReadFile("/project/src/index.ts") + assert.Assert(t, ok) + assert.Equal(t, "export const hello = 'world';", content) + + assert.Assert(t, fs.DirectoryExists("/project/src")) + assert.Assert(t, !fs.DirectoryExists("/project/nonexistent")) + + var files []string + err := fs.WalkDir("/", func(path string, d vfs.DirEntry, err error) error { + if !d.IsDir() { + files = append(files, path) + } + return nil + }) + + assert.NilError(t, err) + assert.DeepEqual(t, files, []string{"/project/package.json", "/project/src/index.ts"}) + + err = fs.WriteFile("/project/src/index.ts", "export const hello = 'world2';", false) + assert.NilError(t, err) + + content, ok = fs.ReadFile("/project/src/index.ts") + assert.Assert(t, ok) + assert.Equal(t, "export const hello = 'world2';", content) +} + +func TestPnpVfs_ZipFileDetection(t *testing.T) { + t.Parallel() + + zipFiles := map[string]string{ + "src/index.ts": "export const hello = 'world';", + "package.json": `{"name": "test-project"}`, + } + + zipPath := createTestZip(t, zipFiles) + + underlyingFS := vfstest.FromMap(map[string]string{ + zipPath: "zip content placeholder", + }, true) + + fs := pnpvfs.From(underlyingFS) + + fmt.Println(zipPath) + assert.Assert(t, fs.FileExists(zipPath)) + + zipInternalPath := zipPath + "/src/index.ts" + assert.Assert(t, fs.FileExists(zipInternalPath)) + + content, ok := fs.ReadFile(zipInternalPath) + assert.Assert(t, ok) + assert.Equal(t, content, zipFiles["src/index.ts"]) +} + +func TestPnpVfs_ErrorHandling(t *testing.T) { + t.Parallel() + + fs := pnpvfs.From(osvfs.FS()) + + t.Run("NonexistentZipFile", func(t *testing.T) { + t.Parallel() + + result := fs.FileExists("/nonexistent/path/archive.zip/file.txt") + assert.Assert(t, !result) + + _, ok := fs.ReadFile("/nonexistent/archive.zip/file.txt") + assert.Assert(t, !ok) + }) + + t.Run("InvalidZipFile", func(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + fakePath := tspath.CombinePaths(tmpDir, "fake.zip") + err := os.WriteFile(fakePath, []byte("not a zip file"), 0o644) + assert.NilError(t, err) + + result := fs.FileExists(fakePath + "/file.txt") + assert.Assert(t, !result) + }) + + t.Run("WriteToZipFile", func(t *testing.T) { + t.Parallel() + + zipFiles := map[string]string{ + "src/index.ts": "export const hello = 'world';", + } + zipPath := createTestZip(t, zipFiles) + + testutil.AssertPanics(t, func() { + _ = fs.WriteFile(zipPath+"/src/index.ts", "hello, world", false) + }, "cannot write to zip file") + }) +} + +func TestPnpVfs_CaseSensitivity(t *testing.T) { + t.Parallel() + + sensitiveFS := pnpvfs.From(vfstest.FromMap(map[string]string{}, true)) + assert.Assert(t, sensitiveFS.UseCaseSensitiveFileNames()) + insensitiveFS := pnpvfs.From(vfstest.FromMap(map[string]string{}, false)) + // pnpvfs is always case sensitive + assert.Assert(t, insensitiveFS.UseCaseSensitiveFileNames()) +} + +func TestPnpVfs_FallbackToRegularFiles(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + regularFile := tspath.CombinePaths(tmpDir, "regular.ts") + err := os.WriteFile(regularFile, []byte("regular content"), 0o644) + assert.NilError(t, err) + + fs := pnpvfs.From(osvfs.FS()) + + assert.Assert(t, fs.FileExists(regularFile)) + + content, ok := fs.ReadFile(regularFile) + assert.Assert(t, ok) + assert.Equal(t, "regular content", content) + assert.Assert(t, fs.DirectoryExists(tmpDir)) +} + +func TestZipPath_Detection(t *testing.T) { + t.Parallel() + + testCases := []struct { + path string + shouldBeZip bool + }{ + {"/normal/path/file.txt", false}, + {"/path/to/archive.zip", true}, + {"/path/to/archive.zip/internal/file.txt", true}, + {"/path/archive.zip/nested/dir/file.ts", true}, + {"/path/file.zip.txt", false}, + {"/absolute/archive.zip", true}, + {"/absolute/archive.zip/file.txt", true}, + } + + for _, tc := range testCases { + t.Run(tc.path, func(t *testing.T) { + t.Parallel() + assert.Assert(t, tspath.IsZipPath(tc.path) == tc.shouldBeZip) + }) + } +} + +func TestPnpVfs_VirtualPathHandling(t *testing.T) { + t.Parallel() + + underlyingFS := vfstest.FromMap(map[string]string{ + "/project/packages/packageA/indexA.ts": "export const helloA = 'world';", + "/project/packages/packageA/package.json": `{"name": "packageA"}`, + "/project/packages/packageB/indexB.ts": "export const helloB = 'world';", + "/project/packages/packageB/package.json": `{"name": "packageB"}`, + }, true) + + fs := pnpvfs.From(underlyingFS) + assert.Assert(t, fs.FileExists("/project/packages/__virtual__/packageA-virtual-123456/0/packageA/package.json")) + assert.Assert(t, fs.FileExists("/project/packages/subfolder/__virtual__/packageA-virtual-123456/1/packageA/package.json")) + + content, ok := fs.ReadFile("/project/packages/__virtual__/packageB-virtual-123456/0/packageB/package.json") + assert.Assert(t, ok) + assert.Equal(t, `{"name": "packageB"}`, content) + + assert.Assert(t, fs.DirectoryExists("/project/packages/__virtual__/packageB-virtual-123456/0/packageB")) + assert.Assert(t, !fs.DirectoryExists("/project/packages/__virtual__/packageB-virtual-123456/0/nonexistent")) + + entries := fs.GetAccessibleEntries("/project/packages/__virtual__/packageB-virtual-123456/0/packageB") + assert.DeepEqual(t, entries.Files, []string{ + "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/indexB.ts", + "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/package.json", + }) + assert.DeepEqual(t, entries.Directories, []string(nil)) + + files := []string{} + err := fs.WalkDir("/project/packages/__virtual__/packageB-virtual-123456/0/packageB", func(path string, d vfs.DirEntry, err error) error { + if !d.IsDir() { + files = append(files, path) + } + return nil + }) + assert.NilError(t, err) + assert.DeepEqual(t, files, []string{ + "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/indexB.ts", + "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/package.json", + }) +} + +func TestPnpVfs_RealZipIntegration(t *testing.T) { + t.Parallel() + + zipFiles := map[string]string{ + "src/index.ts": "export const hello = 'world';", + "src/utils/helpers.ts": "export function add(a: number, b: number) { return a + b; }", + "package.json": `{"name": "test-project", "version": "1.0.0"}`, + "tsconfig.json": `{"compilerOptions": {"target": "es2020"}}`, + } + + zipPath := createTestZip(t, zipFiles) + fs := pnpvfs.From(osvfs.FS()) + + assert.Assert(t, fs.FileExists(zipPath)) + + indexPath := zipPath + "/src/index.ts" + packagePath := zipPath + "/package.json" + assert.Assert(t, fs.FileExists(indexPath)) + assert.Assert(t, fs.FileExists(packagePath)) + assert.Assert(t, fs.DirectoryExists(zipPath+"/src")) + + content, ok := fs.ReadFile(indexPath) + assert.Assert(t, ok) + assert.Equal(t, content, zipFiles["src/index.ts"]) + + content, ok = fs.ReadFile(packagePath) + assert.Assert(t, ok) + assert.Equal(t, content, zipFiles["package.json"]) + + entries := fs.GetAccessibleEntries(zipPath) + assert.DeepEqual(t, entries.Files, []string{zipPath + "/package.json", zipPath + "/tsconfig.json"}) + assert.DeepEqual(t, entries.Directories, []string{zipPath + "/src"}) + + entries = fs.GetAccessibleEntries(zipPath + "/src") + assert.DeepEqual(t, entries.Files, []string{zipPath + "/src/index.ts"}) + assert.DeepEqual(t, entries.Directories, []string{zipPath + "/src/utils"}) + + assert.Equal(t, fs.Realpath(indexPath), indexPath) + + files := []string{} + err := fs.WalkDir(zipPath, func(path string, d vfs.DirEntry, err error) error { + if !d.IsDir() { + files = append(files, path) + } + return nil + }) + assert.NilError(t, err) + assert.DeepEqual(t, files, []string{zipPath + "/package.json", zipPath + "/src/index.ts", zipPath + "/src/utils/helpers.ts", zipPath + "/tsconfig.json"}) + + assert.Assert(t, fs.FileExists(zipPath+"/src/__virtual__/src-virtual-123456/0/index.ts")) + + splitZipPath := strings.Split(zipPath, "/") + beforeZipVirtualPath := strings.Join(splitZipPath[0:len(splitZipPath)-2], "/") + "/__virtual__/zip-virtual-123456/0/" + strings.Join(splitZipPath[len(splitZipPath)-2:], "/") + "/src/index.ts" + assert.Assert(t, fs.FileExists(beforeZipVirtualPath)) +} From fad87fa2f44d2afd93b091280f45c7961fe1fab9 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 29 Oct 2025 15:06:15 +0100 Subject: [PATCH 03/32] Insert pnpApi in Host for LSP and CLI usages --- cmd/tsgo/sys.go | 17 +- internal/api/server.go | 11 +- internal/checker/checker_test.go | 6 +- internal/compiler/emitHost.go | 3 + internal/compiler/host.go | 13 +- internal/compiler/program.go | 6 + internal/compiler/program_test.go | 6 +- .../compiler/projectreferencedtsfakinghost.go | 6 + internal/core/compileroptions.go | 14 +- internal/execute/build/compilerHost.go | 5 + internal/execute/build/host.go | 5 + internal/execute/build/orchestrator.go | 1 + internal/execute/tsc.go | 4 +- internal/execute/tsc/compile.go | 3 + internal/execute/tsctests/sys.go | 21 +- internal/execute/watcher.go | 4 +- internal/ls/autoimports.go | 5 + internal/ls/host.go | 2 + internal/ls/string_completions.go | 1 + internal/lsp/lsproto/lsp.go | 2 +- internal/lsp/server.go | 10 +- internal/module/resolver.go | 69 +++- internal/module/resolver_test.go | 18 +- internal/module/types.go | 2 + internal/modulespecifiers/specifiers.go | 151 +++++++- internal/modulespecifiers/types.go | 3 + internal/pnp/manifestparser.go | 324 ++++++++++++++++++ internal/project/compilerhost.go | 16 + internal/project/configfileregistrybuilder.go | 10 + internal/project/projectcollectionbuilder.go | 4 +- internal/project/session.go | 6 + internal/project/snapshot.go | 16 + internal/testutil/harnessutil/harnessutil.go | 14 +- .../tstransforms/importelision_test.go | 5 + internal/tsoptions/tsconfigparsing.go | 2 + .../tsoptionstest/vfsparseconfighost.go | 16 +- internal/tspath/path.go | 15 + 37 files changed, 779 insertions(+), 37 deletions(-) create mode 100644 internal/pnp/manifestparser.go diff --git a/cmd/tsgo/sys.go b/cmd/tsgo/sys.go index e5b2b8d569a..e423fff24ab 100644 --- a/cmd/tsgo/sys.go +++ b/cmd/tsgo/sys.go @@ -8,9 +8,11 @@ import ( "github.com/microsoft/typescript-go/internal/bundled" "github.com/microsoft/typescript-go/internal/execute/tsc" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/osvfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "golang.org/x/term" ) @@ -20,6 +22,7 @@ type osSys struct { defaultLibraryPath string cwd string start time.Time + pnpApi *pnp.PnpApi } func (s *osSys) SinceStart() time.Duration { @@ -59,6 +62,10 @@ func (s *osSys) GetEnvironmentVariable(name string) string { return os.Getenv(name) } +func (s *osSys) PnpApi() *pnp.PnpApi { + return s.pnpApi +} + func newSystem() *osSys { cwd, err := os.Getwd() if err != nil { @@ -66,11 +73,19 @@ func newSystem() *osSys { os.Exit(int(tsc.ExitStatusInvalidProject_OutputsSkipped)) } + var fs vfs.FS = osvfs.FS() + + pnpApi := pnp.InitPnpApi(fs, tspath.NormalizePath(cwd)) + if pnpApi != nil { + fs = pnpvfs.From(fs) + } + return &osSys{ cwd: tspath.NormalizePath(cwd), - fs: bundled.WrapFS(osvfs.FS()), + fs: bundled.WrapFS(fs), defaultLibraryPath: bundled.LibPath(), writer: os.Stdout, start: time.Now(), + pnpApi: pnpApi, } } diff --git a/internal/api/server.go b/internal/api/server.go index 5a3ce4213b8..68e4a9141c7 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -15,10 +15,12 @@ import ( "github.com/microsoft/typescript-go/internal/bundled" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/osvfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) //go:generate go tool golang.org/x/tools/cmd/stringer -type=MessageType -output=stringer_generated.go @@ -93,12 +95,19 @@ func NewServer(options *ServerOptions) *Server { panic("Cwd is required") } + var fs vfs.FS = osvfs.FS() + + pnpApi := pnp.InitPnpApi(fs, options.Cwd) + if pnpApi != nil { + fs = pnpvfs.From(fs) + } + server := &Server{ r: bufio.NewReader(options.In), w: bufio.NewWriter(options.Out), stderr: options.Err, cwd: options.Cwd, - fs: bundled.WrapFS(osvfs.FS()), + fs: bundled.WrapFS(fs), defaultLibraryPath: options.DefaultLibraryPath, } logger := logging.NewLogger(options.Err) diff --git a/internal/checker/checker_test.go b/internal/checker/checker_test.go index c5029ecbc9b..c9041c6606b 100644 --- a/internal/checker/checker_test.go +++ b/internal/checker/checker_test.go @@ -36,7 +36,7 @@ foo.bar;` fs = bundled.WrapFS(fs) cd := "/" - host := compiler.NewCompilerHost(cd, fs, bundled.LibPath(), nil, nil) + host := compiler.NewCompilerHost(cd, fs, bundled.LibPath(), nil, nil, nil) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, host, nil) assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line") @@ -70,7 +70,7 @@ func TestCheckSrcCompiler(t *testing.T) { rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler") - host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil) + host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil, nil) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil) assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line") p := compiler.NewProgram(compiler.ProgramOptions{ @@ -87,7 +87,7 @@ func BenchmarkNewChecker(b *testing.B) { rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler") - host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil) + host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil, nil) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil) assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line") p := compiler.NewProgram(compiler.ProgramOptions{ diff --git a/internal/compiler/emitHost.go b/internal/compiler/emitHost.go index fcc04063429..b408ee7f5c4 100644 --- a/internal/compiler/emitHost.go +++ b/internal/compiler/emitHost.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/modulespecifiers" "github.com/microsoft/typescript-go/internal/outputpaths" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/printer" "github.com/microsoft/typescript-go/internal/transformers/declarations" "github.com/microsoft/typescript-go/internal/tsoptions" @@ -24,6 +25,7 @@ type EmitHost interface { GetCurrentDirectory() string CommonSourceDirectory() string IsEmitBlocked(file string) bool + PnpApi() *pnp.PnpApi } var _ EmitHost = (*emitHost)(nil) @@ -107,6 +109,7 @@ func (host *emitHost) Options() *core.CompilerOptions { return host.program.Opti func (host *emitHost) SourceFiles() []*ast.SourceFile { return host.program.SourceFiles() } func (host *emitHost) GetCurrentDirectory() string { return host.program.GetCurrentDirectory() } func (host *emitHost) CommonSourceDirectory() string { return host.program.CommonSourceDirectory() } +func (host *emitHost) PnpApi() *pnp.PnpApi { return host.program.PnpApi() } func (host *emitHost) UseCaseSensitiveFileNames() bool { return host.program.UseCaseSensitiveFileNames() } diff --git a/internal/compiler/host.go b/internal/compiler/host.go index 68f3cf620a5..e6eea429559 100644 --- a/internal/compiler/host.go +++ b/internal/compiler/host.go @@ -4,6 +4,7 @@ import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" @@ -17,6 +18,7 @@ type CompilerHost interface { Trace(msg string) GetSourceFile(opts ast.SourceFileParseOptions) *ast.SourceFile GetResolvedProjectReference(fileName string, path tspath.Path) *tsoptions.ParsedCommandLine + PnpApi() *pnp.PnpApi } var _ CompilerHost = (*compilerHost)(nil) @@ -27,6 +29,7 @@ type compilerHost struct { defaultLibraryPath string extendedConfigCache tsoptions.ExtendedConfigCache trace func(msg string) + pnpApi *pnp.PnpApi } func NewCachedFSCompilerHost( @@ -34,9 +37,10 @@ func NewCachedFSCompilerHost( fs vfs.FS, defaultLibraryPath string, extendedConfigCache tsoptions.ExtendedConfigCache, + pnpApi *pnp.PnpApi, trace func(msg string), ) CompilerHost { - return NewCompilerHost(currentDirectory, cachedvfs.From(fs), defaultLibraryPath, extendedConfigCache, trace) + return NewCompilerHost(currentDirectory, cachedvfs.From(fs), defaultLibraryPath, extendedConfigCache, pnpApi, trace) } func NewCompilerHost( @@ -44,17 +48,20 @@ func NewCompilerHost( fs vfs.FS, defaultLibraryPath string, extendedConfigCache tsoptions.ExtendedConfigCache, + pnpApi *pnp.PnpApi, trace func(msg string), ) CompilerHost { if trace == nil { trace = func(msg string) {} } + return &compilerHost{ currentDirectory: currentDirectory, fs: fs, defaultLibraryPath: defaultLibraryPath, extendedConfigCache: extendedConfigCache, trace: trace, + pnpApi: pnpApi, } } @@ -70,6 +77,10 @@ func (h *compilerHost) GetCurrentDirectory() string { return h.currentDirectory } +func (h *compilerHost) PnpApi() *pnp.PnpApi { + return h.pnpApi +} + func (h *compilerHost) Trace(msg string) { h.trace(msg) } diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 794d2fa96de..236974c5cea 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -20,6 +20,7 @@ import ( "github.com/microsoft/typescript-go/internal/modulespecifiers" "github.com/microsoft/typescript-go/internal/outputpaths" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/printer" "github.com/microsoft/typescript-go/internal/scanner" "github.com/microsoft/typescript-go/internal/sourcemap" @@ -78,6 +79,11 @@ func (p *Program) GetCurrentDirectory() string { return p.Host().GetCurrentDirectory() } +// PnpApi implements checker.Program. +func (p *Program) PnpApi() *pnp.PnpApi { + return p.Host().PnpApi() +} + // GetGlobalTypingsCacheLocation implements checker.Program. func (p *Program) GetGlobalTypingsCacheLocation() string { return "" // !!! see src/tsserver/nodeServer.ts for strada's node-specific implementation diff --git a/internal/compiler/program_test.go b/internal/compiler/program_test.go index ae3a967b30d..7d9a6f604b1 100644 --- a/internal/compiler/program_test.go +++ b/internal/compiler/program_test.go @@ -243,7 +243,7 @@ func TestProgram(t *testing.T) { CompilerOptions: &opts, }, }, - Host: compiler.NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, nil), + Host: compiler.NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, nil, nil), }) actualFiles := []string{} @@ -280,7 +280,7 @@ func BenchmarkNewProgram(b *testing.B) { CompilerOptions: &opts, }, }, - Host: compiler.NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, nil), + Host: compiler.NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, nil, nil), } for b.Loop() { @@ -297,7 +297,7 @@ func BenchmarkNewProgram(b *testing.B) { fs := osvfs.FS() fs = bundled.WrapFS(fs) - host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil) + host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, nil, nil) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), nil, host, nil) assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line") diff --git a/internal/compiler/projectreferencedtsfakinghost.go b/internal/compiler/projectreferencedtsfakinghost.go index 916dce2225d..b88482c838c 100644 --- a/internal/compiler/projectreferencedtsfakinghost.go +++ b/internal/compiler/projectreferencedtsfakinghost.go @@ -7,6 +7,7 @@ import ( "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/module" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/cachedvfs" @@ -42,6 +43,11 @@ func (h *projectReferenceDtsFakingHost) GetCurrentDirectory() string { return h.host.GetCurrentDirectory() } +// PnpApi implements module.ResolutionHost. +func (h *projectReferenceDtsFakingHost) PnpApi() *pnp.PnpApi { + return h.host.PnpApi() +} + type projectReferenceDtsFakingVfs struct { projectReferenceFileMapper *projectReferenceFileMapper dtsDirectories collections.Set[tspath.Path] diff --git a/internal/core/compileroptions.go b/internal/core/compileroptions.go index ab1936ca767..17b51ba5c3f 100644 --- a/internal/core/compileroptions.go +++ b/internal/core/compileroptions.go @@ -6,6 +6,7 @@ import ( "sync" "github.com/microsoft/typescript-go/internal/collections" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" ) @@ -300,7 +301,7 @@ func (options *CompilerOptions) GetStrictOptionValue(value Tristate) bool { return options.Strict == TSTrue } -func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string) (result []string, fromConfig bool) { +func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string, pnpApi *pnp.PnpApi) (result []string, fromConfig bool) { if options.TypeRoots != nil { return options.TypeRoots, true } @@ -316,6 +317,17 @@ func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string) ( } } + nmTypes, nmFromConfig := options.GetNodeModulesTypeRoots(baseDir) + + if pnpApi != nil { + typeRoots, fromConfig := pnpApi.AppendPnpTypeRoots(nmTypes, baseDir, nmFromConfig) + return typeRoots, fromConfig + } + + return nmTypes, nmFromConfig +} + +func (options *CompilerOptions) GetNodeModulesTypeRoots(baseDir string) (result []string, fromConfig bool) { typeRoots := make([]string, 0, strings.Count(baseDir, "/")) tspath.ForEachAncestorDirectory(baseDir, func(dir string) (any, bool) { typeRoots = append(typeRoots, tspath.CombinePaths(dir, "node_modules", "@types")) diff --git a/internal/execute/build/compilerHost.go b/internal/execute/build/compilerHost.go index f11f06b9fca..4c6189d2450 100644 --- a/internal/execute/build/compilerHost.go +++ b/internal/execute/build/compilerHost.go @@ -3,6 +3,7 @@ package build import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/compiler" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" @@ -27,6 +28,10 @@ func (h *compilerHost) GetCurrentDirectory() string { return h.host.GetCurrentDirectory() } +func (h *compilerHost) PnpApi() *pnp.PnpApi { + return h.host.PnpApi() +} + func (h *compilerHost) Trace(msg string) { h.trace(msg) } diff --git a/internal/execute/build/host.go b/internal/execute/build/host.go index 91f50aa59c6..451e7afce4c 100644 --- a/internal/execute/build/host.go +++ b/internal/execute/build/host.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/compiler" "github.com/microsoft/typescript-go/internal/execute/incremental" "github.com/microsoft/typescript-go/internal/execute/tsc" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" @@ -45,6 +46,10 @@ func (h *host) GetCurrentDirectory() string { return h.host.GetCurrentDirectory() } +func (h *host) PnpApi() *pnp.PnpApi { + return h.host.PnpApi() +} + func (h *host) Trace(msg string) { panic("build.Orchestrator.host does not support tracing, use a different host for tracing") } diff --git a/internal/execute/build/orchestrator.go b/internal/execute/build/orchestrator.go index d521031780b..27d138c1510 100644 --- a/internal/execute/build/orchestrator.go +++ b/internal/execute/build/orchestrator.go @@ -387,6 +387,7 @@ func NewOrchestrator(opts Options) *Orchestrator { orchestrator.opts.Sys.FS(), orchestrator.opts.Sys.DefaultLibraryPath(), nil, + orchestrator.opts.Sys.PnpApi(), nil, ), mTimes: &collections.SyncMap[tspath.Path, time.Time]{}, diff --git a/internal/execute/tsc.go b/internal/execute/tsc.go index 65bf8d43bb8..e85adb835d5 100644 --- a/internal/execute/tsc.go +++ b/internal/execute/tsc.go @@ -245,7 +245,7 @@ func performIncrementalCompilation( compileTimes *tsc.CompileTimes, testing tsc.CommandLineTesting, ) tsc.CommandLineResult { - host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys, testing)) + host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, sys.PnpApi(), getTraceFromSys(sys, testing)) buildInfoReadStart := sys.Now() oldProgram := incremental.ReadBuildInfoProgram(config, incremental.NewBuildInfoReader(host), host) compileTimes.BuildInfoReadTime = sys.Now().Sub(buildInfoReadStart) @@ -288,7 +288,7 @@ func performCompilation( compileTimes *tsc.CompileTimes, testing tsc.CommandLineTesting, ) tsc.CommandLineResult { - host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys, testing)) + host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, sys.PnpApi(), getTraceFromSys(sys, testing)) // todo: cache, statistics, tracing parseStart := sys.Now() program := compiler.NewProgram(compiler.ProgramOptions{ diff --git a/internal/execute/tsc/compile.go b/internal/execute/tsc/compile.go index 4adc1df9e98..d17566b2c16 100644 --- a/internal/execute/tsc/compile.go +++ b/internal/execute/tsc/compile.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/compiler" "github.com/microsoft/typescript-go/internal/execute/incremental" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" ) @@ -21,6 +22,8 @@ type System interface { GetWidthOfTerminal() int GetEnvironmentVariable(name string) string + PnpApi() *pnp.PnpApi + Now() time.Time SinceStart() time.Duration } diff --git a/internal/execute/tsctests/sys.go b/internal/execute/tsctests/sys.go index 199fce8e76f..dc2322765f4 100644 --- a/internal/execute/tsctests/sys.go +++ b/internal/execute/tsctests/sys.go @@ -16,12 +16,14 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/execute/incremental" "github.com/microsoft/typescript-go/internal/execute/tsc" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/testutil/harnessutil" "github.com/microsoft/typescript-go/internal/testutil/stringtestutil" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/iovfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" ) @@ -86,13 +88,14 @@ func (t *TestClock) SinceStart() time.Duration { func NewTscSystem(files FileMap, useCaseSensitiveFileNames bool, cwd string) *testSys { clock := &TestClock{start: time.Now()} - return &testSys{ - fs: &testFs{ - FS: vfstest.FromMapWithClock(files, useCaseSensitiveFileNames, clock), - }, - cwd: cwd, - clock: clock, + var fs vfs.FS = vfstest.FromMapWithClock(files, useCaseSensitiveFileNames, clock) + + pnpApi := pnp.InitPnpApi(fs, tspath.NormalizePath(cwd)) + if pnpApi != nil { + fs = pnpvfs.From(fs) } + + return &testSys{fs: &testFs{FS: fs}, cwd: cwd, clock: clock, pnpApi: pnpApi} } func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *testSys { @@ -151,6 +154,8 @@ type testSys struct { cwd string env map[string]string clock *TestClock + + pnpApi *pnp.PnpApi } var ( @@ -200,6 +205,10 @@ func (s *testSys) GetCurrentDirectory() string { return s.cwd } +func (s *testSys) PnpApi() *pnp.PnpApi { + return s.pnpApi +} + func (s *testSys) Writer() io.Writer { return s.currentWrite } diff --git a/internal/execute/watcher.go b/internal/execute/watcher.go index 1c1a97b2382..5c8f3321680 100644 --- a/internal/execute/watcher.go +++ b/internal/execute/watcher.go @@ -45,7 +45,7 @@ func createWatcher(sys tsc.System, configParseResult *tsoptions.ParsedCommandLin } func (w *Watcher) start() { - w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil, getTraceFromSys(w.sys, w.testing)) + w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil, w.sys.PnpApi(), getTraceFromSys(w.sys, w.testing)) w.program = incremental.ReadBuildInfoProgram(w.config, incremental.NewBuildInfoReader(w.host), w.host) if w.testing == nil { @@ -122,7 +122,7 @@ func (w *Watcher) hasErrorsInTsConfig() bool { } w.config = configParseResult } - w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(w.sys, w.testing)) + w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), extendedConfigCache, w.sys.PnpApi(), getTraceFromSys(w.sys, w.testing)) return false } diff --git a/internal/ls/autoimports.go b/internal/ls/autoimports.go index ec9ef60d6bd..9902a3d69ba 100644 --- a/internal/ls/autoimports.go +++ b/internal/ls/autoimports.go @@ -420,6 +420,11 @@ func (l *LanguageService) isImportable( // } fromPath := fromFile.FileName() + pnpApi := l.host.PnpApi() + if pnpApi != nil { + return pnpApi.IsImportable(fromPath, toFile.FileName()) + } + useCaseSensitiveFileNames := moduleSpecifierResolutionHost.UseCaseSensitiveFileNames() globalTypingsCache := l.GetProgram().GetGlobalTypingsCacheLocation() modulePaths := modulespecifiers.GetEachFileNameOfModule( diff --git a/internal/ls/host.go b/internal/ls/host.go index 8f517b787ce..daeffd7711c 100644 --- a/internal/ls/host.go +++ b/internal/ls/host.go @@ -4,10 +4,12 @@ import ( "github.com/microsoft/typescript-go/internal/format" "github.com/microsoft/typescript-go/internal/ls/lsconv" "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/sourcemap" ) type Host interface { + PnpApi() *pnp.PnpApi UseCaseSensitiveFileNames() bool ReadFile(path string) (contents string, ok bool) Converters() *lsconv.Converters diff --git a/internal/ls/string_completions.go b/internal/ls/string_completions.go index 749ad880c60..eaee300342c 100644 --- a/internal/ls/string_completions.go +++ b/internal/ls/string_completions.go @@ -522,6 +522,7 @@ func getStringLiteralCompletionsFromModuleNames( program *compiler.Program, ) *stringLiteralCompletions { // !!! needs `getModeForUsageLocationWorker` + // TODO investigate if we will need to update this for pnp, once available return nil } diff --git a/internal/lsp/lsproto/lsp.go b/internal/lsp/lsproto/lsp.go index dd172077c2f..ea59298bcb7 100644 --- a/internal/lsp/lsproto/lsp.go +++ b/internal/lsp/lsproto/lsp.go @@ -14,7 +14,7 @@ import ( type DocumentUri string // !!! func (uri DocumentUri) FileName() string { - if strings.HasPrefix(string(uri), "file://") { + if strings.HasPrefix(string(uri), "file://") || strings.HasPrefix(string(uri), "zip:") { parsed := core.Must(url.Parse(string(uri))) if parsed.Host != "" { return "//" + parsed.Host + parsed.Path diff --git a/internal/lsp/server.go b/internal/lsp/server.go index d5a2aca5a3b..02f5ab7fe12 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -18,11 +18,13 @@ import ( "github.com/microsoft/typescript-go/internal/ls/lsconv" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project" "github.com/microsoft/typescript-go/internal/project/ata" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "golang.org/x/sync/errgroup" "golang.org/x/text/language" ) @@ -701,6 +703,12 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali cwd = s.cwd } + fs := s.fs + pnpApi := pnp.InitPnpApi(fs, cwd) + if pnpApi != nil { + fs = pnpvfs.From(fs) + } + s.session = project.NewSession(&project.SessionInit{ Options: &project.SessionOptions{ CurrentDirectory: cwd, @@ -711,7 +719,7 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali LoggingEnabled: true, DebounceDelay: 500 * time.Millisecond, }, - FS: s.fs, + FS: fs, Logger: s.logger, Client: s, NpmExecutor: s, diff --git a/internal/module/resolver.go b/internal/module/resolver.go index 11306047595..0f31ac568c9 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -207,7 +207,7 @@ func (r *Resolver) ResolveTypeReferenceDirective( compilerOptions := GetCompilerOptionsWithRedirect(r.compilerOptions, redirectedReference) containingDirectory := tspath.GetDirectoryPath(containingFile) - typeRoots, fromConfig := compilerOptions.GetEffectiveTypeRoots(r.host.GetCurrentDirectory()) + typeRoots, fromConfig := compilerOptions.GetEffectiveTypeRoots(r.host.GetCurrentDirectory(), r.host.PnpApi()) if traceBuilder != nil { traceBuilder.write(diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2.Format(typeReferenceDirectiveName, containingFile, strings.Join(typeRoots, ","))) traceBuilder.traceResolutionUsingProjectReference(redirectedReference) @@ -474,7 +474,7 @@ func (r *resolutionState) resolveNodeLikeWorker() *ResolvedModule { resolved := r.nodeLoadModuleByRelativeName(r.extensions, candidate, false, true) return r.createResolvedModule( resolved, - resolved != nil && strings.Contains(resolved.path, "/node_modules/"), + resolved != nil && (tspath.IsExternalLibraryImport(resolved.path)), ) } return r.createResolvedModule(nil, false) @@ -913,6 +913,11 @@ func (r *resolutionState) loadModuleFromNearestNodeModulesDirectory(typesScopeOn } func (r *resolutionState) loadModuleFromNearestNodeModulesDirectoryWorker(ext extensions, mode core.ResolutionMode, typesScopeOnly bool) *resolved { + if r.resolver.host.PnpApi() != nil { + // !!! stop at global cache + return r.loadModuleFromImmediateNodeModulesDirectoryPnP(ext, r.containingDirectory, typesScopeOnly) + } + result, _ := tspath.ForEachAncestorDirectory( r.containingDirectory, func(directory string) (result *resolved, stop bool) { @@ -952,11 +957,52 @@ func (r *resolutionState) loadModuleFromImmediateNodeModulesDirectory(extensions return continueSearching() } +/* +With Plug and Play, we directly resolve the path of the moduleName using the PnP API, instead of searching for it in the node_modules directory + +See github.com/microsoft/typescript-go/internal/pnp package for more details +*/ +func (r *resolutionState) loadModuleFromImmediateNodeModulesDirectoryPnP(extensions extensions, directory string, typesScopeOnly bool) *resolved { + if !typesScopeOnly { + if packageResult := r.loadModuleFromPnpResolution(extensions, r.name, directory); !packageResult.shouldContinueSearching() { + return packageResult + } + } + + if extensions&extensionsDeclaration != 0 { + result := r.loadModuleFromPnpResolution(extensionsDeclaration, "@types/"+r.mangleScopedPackageName(r.name), directory) + + return result + } + + return nil +} + +func (r *resolutionState) loadModuleFromPnpResolution(ext extensions, moduleName string, issuer string) *resolved { + pnpApi := r.resolver.host.PnpApi() + + if pnpApi != nil { + packageName, rest := ParsePackageName(moduleName) + // TODO: bubble up yarn resolution errors, instead of _ + packageDirectory, _ := pnpApi.ResolveToUnqualified(packageName, issuer) + if packageDirectory != "" { + candidate := tspath.NormalizePath(tspath.CombinePaths(packageDirectory, rest)) + return r.loadModuleFromSpecificNodeModulesDirectoryImpl(ext, true /* nodeModulesDirectoryExists */, candidate, rest, packageDirectory) + } + } + + return nil +} + func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectory(ext extensions, moduleName string, nodeModulesDirectory string, nodeModulesDirectoryExists bool) *resolved { candidate := tspath.NormalizePath(tspath.CombinePaths(nodeModulesDirectory, moduleName)) packageName, rest := ParsePackageName(moduleName) packageDirectory := tspath.CombinePaths(nodeModulesDirectory, packageName) + return r.loadModuleFromSpecificNodeModulesDirectoryImpl(ext, nodeModulesDirectoryExists, candidate, rest, packageDirectory) +} + +func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectoryImpl(ext extensions, nodeModulesDirectoryExists bool, candidate string, rest string, packageDirectory string) *resolved { var rootPackageInfo *packagejson.InfoCacheEntry // First look for a nested package.json, as in `node_modules/foo/bar/package.json` packageInfo := r.getPackageJsonInfo(candidate, !nodeModulesDirectoryExists) @@ -1035,7 +1081,7 @@ func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectory(ext extensi } func (r *resolutionState) createResolvedModuleHandlingSymlink(resolved *resolved) *ResolvedModule { - isExternalLibraryImport := resolved != nil && strings.Contains(resolved.path, "/node_modules/") + isExternalLibraryImport := resolved != nil && (tspath.IsExternalLibraryImport(resolved.path)) if r.compilerOptions.PreserveSymlinks != core.TSTrue && isExternalLibraryImport && resolved.originalPath == "" && @@ -1083,7 +1129,7 @@ func (r *resolutionState) createResolvedTypeReferenceDirective(resolved *resolve resolvedTypeReferenceDirective.ResolvedFileName = resolved.path resolvedTypeReferenceDirective.Primary = primary resolvedTypeReferenceDirective.PackageId = resolved.packageId - resolvedTypeReferenceDirective.IsExternalLibraryImport = strings.Contains(resolved.path, "/node_modules/") + resolvedTypeReferenceDirective.IsExternalLibraryImport = tspath.IsExternalLibraryImport(resolved.path) if r.compilerOptions.PreserveSymlinks != core.TSTrue { originalPath, resolvedFileName := r.getOriginalAndResolvedFileName(resolved.path) @@ -1739,8 +1785,19 @@ func (r *resolutionState) readPackageJsonPeerDependencies(packageJsonInfo *packa } nodeModules := packageDirectory[:nodeModulesIndex+len("/node_modules")] + "/" builder := strings.Builder{} + pnpApi := r.resolver.host.PnpApi() for name := range peerDependencies.Value { - peerPackageJson := r.getPackageJsonInfo(nodeModules+name /*onlyRecordFailures*/, false) + var peerDependencyPath string + + if pnpApi != nil { + peerDependencyPath, _ = pnpApi.ResolveToUnqualified(name, packageDirectory) + } + + if peerDependencyPath == "" { + peerDependencyPath = nodeModules + name + } + + peerPackageJson := r.getPackageJsonInfo(peerDependencyPath, false /*onlyRecordFailures*/) if peerPackageJson != nil { version := peerPackageJson.Contents.Version.Value builder.WriteString("+") @@ -1983,7 +2040,7 @@ func GetAutomaticTypeDirectiveNames(options *core.CompilerOptions, host Resoluti } var result []string - typeRoots, _ := options.GetEffectiveTypeRoots(host.GetCurrentDirectory()) + typeRoots, _ := options.GetEffectiveTypeRoots(host.GetCurrentDirectory(), host.PnpApi()) for _, root := range typeRoots { if host.FS().DirectoryExists(root) { for _, typeDirectivePath := range host.FS().GetAccessibleEntries(root).Directories { diff --git a/internal/module/resolver_test.go b/internal/module/resolver_test.go index 37330dc8d58..a7917a0979d 100644 --- a/internal/module/resolver_test.go +++ b/internal/module/resolver_test.go @@ -14,10 +14,12 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/jsonutil" "github.com/microsoft/typescript-go/internal/module" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/repo" "github.com/microsoft/typescript-go/internal/testutil/baseline" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" @@ -144,6 +146,7 @@ type vfsModuleResolutionHost struct { fs vfs.FS currentDirectory string traces []string + pnpApi *pnp.PnpApi } func fixRoot(path string) string { @@ -164,9 +167,17 @@ func newVFSModuleResolutionHost(files map[string]string, currentDirectory string } else if currentDirectory[0] != '/' { currentDirectory = "/.src/" + currentDirectory } + + var mapFS vfs.FS = vfstest.FromMap(fs, true /*useCaseSensitiveFileNames*/) + pnpApi := pnp.InitPnpApi(mapFS, tspath.NormalizePath(currentDirectory)) + if pnpApi != nil { + mapFS = pnpvfs.From(mapFS) + } + return &vfsModuleResolutionHost{ - fs: vfstest.FromMap(fs, true /*useCaseSensitiveFileNames*/), + fs: mapFS, currentDirectory: currentDirectory, + pnpApi: pnpApi, } } @@ -179,6 +190,11 @@ func (v *vfsModuleResolutionHost) GetCurrentDirectory() string { return v.currentDirectory } +// PnpApi implements ModuleResolutionHost. +func (v *vfsModuleResolutionHost) PnpApi() *pnp.PnpApi { + return v.pnpApi +} + // Trace implements ModuleResolutionHost. func (v *vfsModuleResolutionHost) Trace(msg string) { v.mu.Lock() diff --git a/internal/module/types.go b/internal/module/types.go index 7999e022a34..c01ce19aac0 100644 --- a/internal/module/types.go +++ b/internal/module/types.go @@ -7,6 +7,7 @@ import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" ) @@ -14,6 +15,7 @@ import ( type ResolutionHost interface { FS() vfs.FS GetCurrentDirectory() string + PnpApi() *pnp.PnpApi } type ModeAwareCacheKey struct { diff --git a/internal/modulespecifiers/specifiers.go b/internal/modulespecifiers/specifiers.go index fd040fc14e4..96aba57739a 100644 --- a/internal/modulespecifiers/specifiers.go +++ b/internal/modulespecifiers/specifiers.go @@ -271,9 +271,14 @@ func GetEachFileNameOfModule( // so we only need to remove them from the realpath filenames. for _, p := range targets { if !(shouldFilterIgnoredPaths && containsIgnoredPath(p)) { + IsInNodeModules := ContainsNodeModules(p) + if pnpApi := host.PnpApi(); pnpApi != nil { + IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(importingFileName, p) + } + results = append(results, ModulePath{ FileName: p, - IsInNodeModules: ContainsNodeModules(p), + IsInNodeModules: IsInNodeModules, IsRedirect: referenceRedirect == p, }) } @@ -314,9 +319,14 @@ func GetEachFileNameOfModule( if preferSymlinks { for _, p := range targets { if !(shouldFilterIgnoredPaths && containsIgnoredPath(p)) { + IsInNodeModules := ContainsNodeModules(p) + if pnpApi := host.PnpApi(); pnpApi != nil { + IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(importingFileName, p) + } + results = append(results, ModulePath{ FileName: p, - IsInNodeModules: ContainsNodeModules(p), + IsInNodeModules: IsInNodeModules, IsRedirect: referenceRedirect == p, }) } @@ -681,6 +691,131 @@ func tryGetModuleNameFromRootDirs( return processEnding(shortest, allowedEndings, compilerOptions, host) } +// TODO: This code partially duplicates tryGetModuleNameAsNodeModule, is it better to keep it isolated from the node module version or should we merge them? +func tryGetModuleNameAsPnpPackage( + pathObj ModulePath, + info Info, + importingSourceFile SourceFileForSpecifierGeneration, + host ModuleSpecifierGenerationHost, + options *core.CompilerOptions, + userPreferences UserPreferences, + packageNameOnly bool, + overrideMode core.ResolutionMode, +) string { + pnpApi := host.PnpApi() + if pnpApi == nil { + return "" + } + + pnpPackageName := "" + fromLocator, _ := pnpApi.FindLocator(importingSourceFile.FileName()) + toLocator, _ := pnpApi.FindLocator(pathObj.FileName) + + // Don't use the package name when the imported file is inside + // the source directory (prefer a relative path instead) + if fromLocator == toLocator { + return "" + } + + if fromLocator != nil && toLocator != nil { + fromInfo := pnpApi.GetPackage(fromLocator) + + useToLocator := false + + for i := range fromInfo.PackageDependencies { + isAlias := fromInfo.PackageDependencies[i].IsAlias() + if isAlias && fromInfo.PackageDependencies[i].AliasName == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { + useToLocator = true + break + } else if fromInfo.PackageDependencies[i].Ident == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { + useToLocator = true + break + } + } + + if useToLocator { + pnpPackageName = toLocator.Name + } + } + + var parts *NodeModulePathParts + if toLocator != nil { + toInfo := pnpApi.GetPackage(toLocator) + packageRootAbsolutePath := pnpApi.GetPackageLocationAbsolutePath(toInfo) + parts = &NodeModulePathParts{ + TopLevelNodeModulesIndex: -1, + TopLevelPackageNameIndex: -1, + PackageRootIndex: len(packageRootAbsolutePath), + FileNameIndex: strings.LastIndex(pathObj.FileName, "/"), + } + } + + if parts == nil { + return "" + } + + // Simplify the full file path to something that can be resolved by Node. + preferences := getModuleSpecifierPreferences(userPreferences, host, options, importingSourceFile, "") + allowedEndings := preferences.getAllowedEndingsInPreferredOrder(core.ResolutionModeNone) + + moduleSpecifier := pathObj.FileName + isPackageRootPath := false + if !packageNameOnly { + packageRootIndex := parts.PackageRootIndex + var moduleFileName string + for true { + // If the module could be imported by a directory name, use that directory's name + pkgJsonResults := tryDirectoryWithPackageJson( + *parts, + pathObj, + importingSourceFile, + host, + overrideMode, + options, + allowedEndings, + pnpPackageName, + ) + moduleFileToTry := pkgJsonResults.moduleFileToTry + packageRootPath := pkgJsonResults.packageRootPath + blockedByExports := pkgJsonResults.blockedByExports + verbatimFromExports := pkgJsonResults.verbatimFromExports + if blockedByExports { + return "" // File is under this package.json, but is not publicly exported - there's no way to name it via `node_modules` resolution + } + if verbatimFromExports { + return moduleFileToTry + } + //} + if len(packageRootPath) > 0 { + moduleSpecifier = packageRootPath + isPackageRootPath = true + break + } + if len(moduleFileName) == 0 { + moduleFileName = moduleFileToTry + } + // try with next level of directory + packageRootIndex = core.IndexAfter(pathObj.FileName, "/", packageRootIndex+1) + if packageRootIndex == -1 { + moduleSpecifier = processEnding(moduleFileName, allowedEndings, options, host) + break + } + } + } + + if pathObj.IsRedirect && !isPackageRootPath { + return "" + } + + // If the module was found in @types, get the actual Node package name + nodeModulesDirectoryName := moduleSpecifier[parts.TopLevelPackageNameIndex+1:] + if pnpPackageName != "" { + nodeModulesDirectoryName = pnpPackageName + moduleSpecifier[parts.PackageRootIndex:] + } + + return GetPackageNameFromTypesPackageName(nodeModulesDirectoryName) +} + func tryGetModuleNameAsNodeModule( pathObj ModulePath, info Info, @@ -691,6 +826,11 @@ func tryGetModuleNameAsNodeModule( packageNameOnly bool, overrideMode core.ResolutionMode, ) string { + pnpModuleName := tryGetModuleNameAsPnpPackage(pathObj, info, importingSourceFile, host, options, userPreferences, packageNameOnly, overrideMode) + if pnpModuleName != "" { + return pnpModuleName + } + parts := GetNodeModulePathParts(pathObj.FileName) if parts == nil { return "" @@ -716,6 +856,7 @@ func tryGetModuleNameAsNodeModule( overrideMode, options, allowedEndings, + "", ) moduleFileToTry := pkgJsonResults.moduleFileToTry packageRootPath := pkgJsonResults.packageRootPath @@ -778,6 +919,7 @@ func tryDirectoryWithPackageJson( overrideMode core.ResolutionMode, options *core.CompilerOptions, allowedEndings []ModuleSpecifierEnding, + packageNameOverride string, ) pkgJsonDirAttemptResult { rootIdx := parts.PackageRootIndex if rootIdx == -1 { @@ -809,7 +951,10 @@ func tryDirectoryWithPackageJson( // name in the package.json content via url/filepath dependency specifiers. We need to // use the actual directory name, so don't look at `packageJsonContent.name` here. nodeModulesDirectoryName := packageRootPath[parts.TopLevelPackageNameIndex+1:] - packageName := GetPackageNameFromTypesPackageName(nodeModulesDirectoryName) + packageName := packageNameOverride + if packageName == "" { + packageName = GetPackageNameFromTypesPackageName(nodeModulesDirectoryName) + } conditions := module.GetConditions(options, importMode) var fromExports string diff --git a/internal/modulespecifiers/types.go b/internal/modulespecifiers/types.go index c83dde2d838..e9e95b770b5 100644 --- a/internal/modulespecifiers/types.go +++ b/internal/modulespecifiers/types.go @@ -5,6 +5,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" ) @@ -52,6 +53,8 @@ type ModuleSpecifierGenerationHost interface { UseCaseSensitiveFileNames() bool GetCurrentDirectory() string + PnpApi() *pnp.PnpApi + GetProjectReferenceFromSource(path tspath.Path) *tsoptions.SourceOutputAndProjectReference GetRedirectTargets(path tspath.Path) []string GetSourceOfProjectReferenceIfOutputIncluded(file ast.HasFileName) string diff --git a/internal/pnp/manifestparser.go b/internal/pnp/manifestparser.go new file mode 100644 index 00000000000..8e75f2edc68 --- /dev/null +++ b/internal/pnp/manifestparser.go @@ -0,0 +1,324 @@ +package pnp + +import ( + "errors" + "fmt" + "strings" + + "github.com/go-json-experiment/json" + + "github.com/dlclark/regexp2" + "github.com/microsoft/typescript-go/internal/tspath" +) + +type LinkType string + +const ( + LinkTypeSoft LinkType = "SOFT" + LinkTypeHard LinkType = "HARD" +) + +type PackageDependency struct { + Ident string + Reference string // Either the direct reference or alias reference + AliasName string // Empty if not an alias +} + +func (pd PackageDependency) IsAlias() bool { + return pd.AliasName != "" +} + +type PackageInfo struct { + PackageLocation string `json:"packageLocation"` + PackageDependencies []PackageDependency `json:"packageDependencies,omitempty"` + LinkType LinkType `json:"linkType,omitempty"` + DiscardFromLookup bool `json:"discardFromLookup,omitempty"` + PackagePeers []string `json:"packagePeers,omitempty"` +} + +type Locator struct { + Name string `json:"name"` + Reference string `json:"reference"` +} + +type FallbackExclusion struct { + Name string `json:"name"` + Entries []string `json:"entries"` +} + +type PackageTrieData struct { + ident string + reference string + info *PackageInfo +} + +type PackageRegistryTrie struct { + pathSegment string + childrenPathSegments map[string]*PackageRegistryTrie + packageData *PackageTrieData +} + +type PnpManifestData struct { + dirPath string + + ignorePatternData *regexp2.Regexp + enableTopLevelFallback bool + + fallbackPool [][2]string + fallbackExclusionMap map[string]*FallbackExclusion + + dependencyTreeRoots []Locator + + // Nested maps for package registry (ident -> reference -> PackageInfo) + packageRegistryMap map[string]map[string]*PackageInfo + packageRegistryTrie *PackageRegistryTrie +} + +func parseManifestFromPath(fs PnpApiFS, manifestDir string) (*PnpManifestData, error) { + pnpDataString := "" + + data, ok := fs.ReadFile(tspath.CombinePaths(manifestDir, ".pnp.data.json")) + if ok { + pnpDataString = data + } else { + pnpScriptString, ok := fs.ReadFile(tspath.CombinePaths(manifestDir, ".pnp.cjs")) + if !ok { + return nil, errors.New("failed to read .pnp.cjs file") + } + + manifestRegex := regexp2.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`, regexp2.None) + matches, err := manifestRegex.FindStringMatch(pnpScriptString) + if err != nil || matches == nil { + return nil, errors.New("We failed to locate the PnP data payload inside its manifest file. Did you manually edit the file?") + } + + start := matches.Index + matches.Length + var b strings.Builder + b.Grow(len(pnpScriptString)) + for i := start; i < len(pnpScriptString); i++ { + if pnpScriptString[i] == '\'' { + break + } + + if pnpScriptString[i] != '\\' { + b.WriteByte(pnpScriptString[i]) + } + } + pnpDataString = b.String() + } + + return parseManifestFromData(pnpDataString, manifestDir) +} + +func parseManifestFromData(pnpDataString string, manifestDir string) (*PnpManifestData, error) { + var rawData map[string]interface{} + if err := json.Unmarshal([]byte(pnpDataString), &rawData); err != nil { + return nil, fmt.Errorf("failed to parse JSON PnP data: %w", err) + } + + pnpData, err := parsePnpManifest(rawData, manifestDir) + if err != nil { + return nil, fmt.Errorf("failed to parse PnP data: %w", err) + } + + return pnpData, nil +} + +// TODO add error handling for corrupted data +func parsePnpManifest(rawData map[string]interface{}, manifestDir string) (*PnpManifestData, error) { + data := &PnpManifestData{dirPath: manifestDir} + + if roots, ok := rawData["dependencyTreeRoots"].([]interface{}); ok { + for _, root := range roots { + if rootMap, ok := root.(map[string]interface{}); ok { + data.dependencyTreeRoots = append(data.dependencyTreeRoots, Locator{ + Name: getField(rootMap, "name", parseString), + Reference: getField(rootMap, "reference", parseString), + }) + } + } + } + + ignorePatternData := getField(rawData, "ignorePatternData", parseString) + if ignorePatternData != "" { + ignorePatternDataRegexp, err := regexp2.Compile(ignorePatternData, regexp2.None) + if err != nil { + return nil, fmt.Errorf("failed to compile ignore pattern data: %w", err) + } + + data.ignorePatternData = ignorePatternDataRegexp + } + + data.enableTopLevelFallback = getField(rawData, "enableTopLevelFallback", parseBool) + + data.fallbackPool = getField(rawData, "fallbackPool", parseStringPairs) + + data.fallbackExclusionMap = make(map[string]*FallbackExclusion) + + if exclusions, ok := rawData["fallbackExclusionList"].([]interface{}); ok { + for _, exclusion := range exclusions { + if exclusionArr, ok := exclusion.([]interface{}); ok && len(exclusionArr) == 2 { + name := parseString(exclusionArr[0]) + entries := parseStringArray(exclusionArr[1]) + exclusionEntry := &FallbackExclusion{ + Name: name, + Entries: entries, + } + data.fallbackExclusionMap[exclusionEntry.Name] = exclusionEntry + } + } + } + + data.packageRegistryMap = make(map[string]map[string]*PackageInfo) + + if registryData, ok := rawData["packageRegistryData"].([]interface{}); ok { + for _, entry := range registryData { + if entryArr, ok := entry.([]interface{}); ok && len(entryArr) == 2 { + ident := parseString(entryArr[0]) + + if data.packageRegistryMap[ident] == nil { + data.packageRegistryMap[ident] = make(map[string]*PackageInfo) + } + + if versions, ok := entryArr[1].([]interface{}); ok { + for _, version := range versions { + if versionArr, ok := version.([]interface{}); ok && len(versionArr) == 2 { + reference := parseString(versionArr[0]) + + if infoMap, ok := versionArr[1].(map[string]interface{}); ok { + packageInfo := &PackageInfo{ + PackageLocation: getField(infoMap, "packageLocation", parseString), + PackageDependencies: getField(infoMap, "packageDependencies", parsePackageDependencies), + LinkType: LinkType(getField(infoMap, "linkType", parseString)), + DiscardFromLookup: getField(infoMap, "discardFromLookup", parseBool), + PackagePeers: getField(infoMap, "packagePeers", parseStringArray), + } + + data.packageRegistryMap[ident][reference] = packageInfo + data.addPackageToTrie(ident, reference, packageInfo) + } + } + } + } + } + } + } + + return data, nil +} + +func (data *PnpManifestData) addPackageToTrie(ident string, reference string, packageInfo *PackageInfo) { + if data.packageRegistryTrie == nil { + data.packageRegistryTrie = &PackageRegistryTrie{ + pathSegment: "", + childrenPathSegments: make(map[string]*PackageRegistryTrie), + packageData: nil, + } + } + + packageData := &PackageTrieData{ + ident: ident, + reference: reference, + info: packageInfo, + } + + packagePath := tspath.RemoveTrailingDirectorySeparator(packageInfo.PackageLocation) + packagePathSegments := strings.Split(packagePath, "/") + + currentTrie := data.packageRegistryTrie + + for _, segment := range packagePathSegments { + if currentTrie.childrenPathSegments[segment] == nil { + currentTrie.childrenPathSegments[segment] = &PackageRegistryTrie{ + pathSegment: segment, + childrenPathSegments: make(map[string]*PackageRegistryTrie), + packageData: nil, + } + } + + currentTrie = currentTrie.childrenPathSegments[segment] + } + + currentTrie.packageData = packageData +} + +// Helper functions for parsing JSON values - following patterns from tsoptions.parseString, etc. +func parseString(value interface{}) string { + if str, ok := value.(string); ok { + return str + } + return "" +} + +func parseBool(value interface{}) bool { + if val, ok := value.(bool); ok { + return val + } + return false +} + +func parseStringArray(value interface{}) []string { + if arr, ok := value.([]interface{}); ok { + if arr == nil { + return nil + } + result := make([]string, 0, len(arr)) + for _, v := range arr { + if str, ok := v.(string); ok { + result = append(result, str) + } + } + return result + } + return nil +} + +func parseStringPairs(value interface{}) [][2]string { + var result [][2]string + if arr, ok := value.([]interface{}); ok { + for _, item := range arr { + if pair, ok := item.([]interface{}); ok && len(pair) == 2 { + result = append(result, [2]string{ + parseString(pair[0]), + parseString(pair[1]), + }) + } + } + } + return result +} + +func parsePackageDependencies(value interface{}) []PackageDependency { + var result []PackageDependency + if arr, ok := value.([]interface{}); ok { + for _, item := range arr { + if pair, ok := item.([]interface{}); ok && len(pair) == 2 { + ident := parseString(pair[0]) + + // Check if second element is string (simple reference) or array (alias) + if str, ok := pair[1].(string); ok { + result = append(result, PackageDependency{ + Ident: ident, + Reference: str, + AliasName: "", + }) + } else if aliasPair, ok := pair[1].([]interface{}); ok && len(aliasPair) == 2 { + result = append(result, PackageDependency{ + Ident: ident, + Reference: parseString(aliasPair[1]), + AliasName: parseString(aliasPair[0]), + }) + } + } + } + } + return result +} + +func getField[T any](m map[string]interface{}, key string, parser func(interface{}) T) T { + if val, exists := m[key]; exists { + return parser(val) + } + var zero T + return zero +} diff --git a/internal/project/compilerhost.go b/internal/project/compilerhost.go index d58b3522b84..97d19f81d8e 100644 --- a/internal/project/compilerhost.go +++ b/internal/project/compilerhost.go @@ -6,10 +6,12 @@ import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/compiler" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) var _ compiler.CompilerHost = (*compilerHost)(nil) @@ -19,6 +21,8 @@ type compilerHost struct { currentDirectory string sessionOptions *SessionOptions + pnpApi *pnp.PnpApi + fs *snapshotFSBuilder compilerFS *compilerFS configFileRegistry *ConfigFileRegistry @@ -50,6 +54,11 @@ func newCompilerHost( builder *projectCollectionBuilder, logger *logging.LogTree, ) *compilerHost { + pnpApi := pnp.InitPnpApi(builder.fs.fs, currentDirectory) + if pnpApi != nil { + builder.fs.fs = pnpvfs.From(builder.fs.fs) + } + seenFiles := &collections.SyncSet[tspath.Path]{} compilerFS := &compilerFS{ source: &builderFileSource{ @@ -66,6 +75,8 @@ func newCompilerHost( compilerFS: compilerFS, seenFiles: seenFiles, + pnpApi: pnpApi, + fs: builder.fs, project: project, builder: builder, @@ -108,6 +119,11 @@ func (c *compilerHost) GetCurrentDirectory() string { return c.currentDirectory } +// PnpApi implements compiler.CompilerHost. +func (c *compilerHost) PnpApi() *pnp.PnpApi { + return c.pnpApi +} + // GetResolvedProjectReference implements compiler.CompilerHost. func (c *compilerHost) GetResolvedProjectReference(fileName string, path tspath.Path) *tsoptions.ParsedCommandLine { if c.builder == nil { diff --git a/internal/project/configfileregistrybuilder.go b/internal/project/configfileregistrybuilder.go index c8fc308500c..d609e44a02e 100644 --- a/internal/project/configfileregistrybuilder.go +++ b/internal/project/configfileregistrybuilder.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/dirty" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/tsoptions" @@ -28,6 +29,8 @@ type configFileRegistryBuilder struct { extendedConfigCache *extendedConfigCache sessionOptions *SessionOptions + pnpApi *pnp.PnpApi + base *ConfigFileRegistry configs *dirty.SyncMap[tspath.Path, *configFileEntry] configFileNames *dirty.Map[tspath.Path, *configFileNames] @@ -38,6 +41,7 @@ func newConfigFileRegistryBuilder( oldConfigFileRegistry *ConfigFileRegistry, extendedConfigCache *extendedConfigCache, sessionOptions *SessionOptions, + pnpApi *pnp.PnpApi, logger *logging.LogTree, ) *configFileRegistryBuilder { return &configFileRegistryBuilder{ @@ -45,6 +49,7 @@ func newConfigFileRegistryBuilder( base: oldConfigFileRegistry, sessionOptions: sessionOptions, extendedConfigCache: extendedConfigCache, + pnpApi: pnpApi, configs: dirty.NewSyncMap(oldConfigFileRegistry.configs, nil), configFileNames: dirty.NewMap(oldConfigFileRegistry.configFileNames), @@ -570,6 +575,11 @@ func (c *configFileRegistryBuilder) GetCurrentDirectory() string { return c.sessionOptions.CurrentDirectory } +// PnpApi implements tsoptions.ParseConfigHost. +func (c *configFileRegistryBuilder) PnpApi() *pnp.PnpApi { + return c.pnpApi +} + // GetExtendedConfig implements tsoptions.ExtendedConfigCache. func (c *configFileRegistryBuilder) GetExtendedConfig(fileName string, path tspath.Path, parse func() *tsoptions.ExtendedConfigCacheEntry) *tsoptions.ExtendedConfigCacheEntry { fh := c.fs.GetFileByPath(fileName, path) diff --git a/internal/project/projectcollectionbuilder.go b/internal/project/projectcollectionbuilder.go index c7ed8bd2f93..2c99c624344 100644 --- a/internal/project/projectcollectionbuilder.go +++ b/internal/project/projectcollectionbuilder.go @@ -10,6 +10,7 @@ import ( "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/dirty" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/tsoptions" @@ -54,6 +55,7 @@ func newProjectCollectionBuilder( oldAPIOpenedProjects map[tspath.Path]struct{}, compilerOptionsForInferredProjects *core.CompilerOptions, sessionOptions *SessionOptions, + pnpApi *pnp.PnpApi, parseCache *ParseCache, extendedConfigCache *extendedConfigCache, ) *projectCollectionBuilder { @@ -65,7 +67,7 @@ func newProjectCollectionBuilder( parseCache: parseCache, extendedConfigCache: extendedConfigCache, base: oldProjectCollection, - configFileRegistryBuilder: newConfigFileRegistryBuilder(fs, oldConfigFileRegistry, extendedConfigCache, sessionOptions, nil), + configFileRegistryBuilder: newConfigFileRegistryBuilder(fs, oldConfigFileRegistry, extendedConfigCache, sessionOptions, pnpApi, nil), newSnapshotID: newSnapshotID, configuredProjects: dirty.NewSyncMap(oldProjectCollection.configuredProjects, nil), inferredProject: dirty.NewBox(oldProjectCollection.inferredProject), diff --git a/internal/project/session.go b/internal/project/session.go index 9e5a17aac66..85f3e4dea71 100644 --- a/internal/project/session.go +++ b/internal/project/session.go @@ -16,6 +16,7 @@ import ( "github.com/microsoft/typescript-go/internal/ls" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/ata" "github.com/microsoft/typescript-go/internal/project/background" "github.com/microsoft/typescript-go/internal/project/logging" @@ -185,6 +186,11 @@ func (s *Session) GetCurrentDirectory() string { return s.options.CurrentDirectory } +// PnpApi implements module.ResolutionHost +func (s *Session) PnpApi() *pnp.PnpApi { + return s.snapshot.PnpApi() +} + // Gets current UserPreferences, always a copy func (s *Session) UserPreferences() *lsutil.UserPreferences { s.configRWMu.Lock() diff --git a/internal/project/snapshot.go b/internal/project/snapshot.go index 29f3c374f29..1c299bb758c 100644 --- a/internal/project/snapshot.go +++ b/internal/project/snapshot.go @@ -12,11 +12,13 @@ import ( "github.com/microsoft/typescript-go/internal/ls/lsconv" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/ata" "github.com/microsoft/typescript-go/internal/project/dirty" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/sourcemap" "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) type Snapshot struct { @@ -39,6 +41,8 @@ type Snapshot struct { builderLogs *logging.LogTree apiError error + + pnpApi *pnp.PnpApi } // NewSnapshot @@ -53,6 +57,11 @@ func NewSnapshot( config Config, toPath func(fileName string) tspath.Path, ) *Snapshot { + pnpApi := pnp.InitPnpApi(fs.fs, sessionOptions.CurrentDirectory) + if pnpApi != nil { + fs.fs = pnpvfs.From(fs.fs) + } + s := &Snapshot{ id: id, @@ -64,6 +73,8 @@ func NewSnapshot( ProjectCollection: &ProjectCollection{toPath: toPath}, compilerOptionsForInferredProjects: compilerOptionsForInferredProjects, config: config, + + pnpApi: pnpApi, } s.converters = lsconv.NewConverters(s.sessionOptions.PositionEncoding, s.LSPLineMap) s.refCount.Store(1) @@ -114,6 +125,10 @@ func (s *Snapshot) UseCaseSensitiveFileNames() bool { return s.fs.fs.UseCaseSensitiveFileNames() } +func (s *Snapshot) PnpApi() *pnp.PnpApi { + return s.pnpApi +} + func (s *Snapshot) ReadFile(fileName string) (string, bool) { handle := s.GetFile(fileName) if handle == nil { @@ -227,6 +242,7 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma s.ProjectCollection.apiOpenedProjects, compilerOptionsForInferredProjects, s.sessionOptions, + s.pnpApi, session.parseCache, session.extendedConfigCache, ) diff --git a/internal/testutil/harnessutil/harnessutil.go b/internal/testutil/harnessutil/harnessutil.go index 772eb169c0c..966566f6388 100644 --- a/internal/testutil/harnessutil/harnessutil.go +++ b/internal/testutil/harnessutil/harnessutil.go @@ -23,12 +23,14 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/outputpaths" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/repo" "github.com/microsoft/typescript-go/internal/sourcemap" "github.com/microsoft/typescript-go/internal/testutil" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" ) @@ -206,9 +208,15 @@ func CompileFilesEx( fs := vfstest.FromMap(testfs, harnessOptions.UseCaseSensitiveFileNames) fs = bundled.WrapFS(fs) + + pnpApi := pnp.InitPnpApi(fs, currentDirectory) + if pnpApi != nil { + fs = pnpvfs.From(fs) + } + fs = NewOutputRecorderFS(fs) - host := createCompilerHost(fs, bundled.LibPath(), currentDirectory) + host := createCompilerHost(fs, bundled.LibPath(), currentDirectory, pnpApi) var configFile *tsoptions.TsConfigSourceFile var errors []*ast.Diagnostic if tsconfig != nil { @@ -601,13 +609,13 @@ func (t *TracerForBaselining) Reset() { t.packageJsonCache = make(map[tspath.Path]bool) } -func createCompilerHost(fs vfs.FS, defaultLibraryPath string, currentDirectory string) *cachedCompilerHost { +func createCompilerHost(fs vfs.FS, defaultLibraryPath string, currentDirectory string, pnpApi *pnp.PnpApi) *cachedCompilerHost { tracer := NewTracerForBaselining(tspath.ComparePathsOptions{ UseCaseSensitiveFileNames: fs.UseCaseSensitiveFileNames(), CurrentDirectory: currentDirectory, }, &strings.Builder{}) return &cachedCompilerHost{ - CompilerHost: compiler.NewCompilerHost(currentDirectory, fs, defaultLibraryPath, nil, tracer.Trace), + CompilerHost: compiler.NewCompilerHost(currentDirectory, fs, defaultLibraryPath, nil, pnpApi, tracer.Trace), tracer: tracer, } } diff --git a/internal/transformers/tstransforms/importelision_test.go b/internal/transformers/tstransforms/importelision_test.go index 3dc5c227cd4..46d14db15aa 100644 --- a/internal/transformers/tstransforms/importelision_test.go +++ b/internal/transformers/tstransforms/importelision_test.go @@ -9,6 +9,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/modulespecifiers" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/printer" "github.com/microsoft/typescript-go/internal/testutil/emittestutil" "github.com/microsoft/typescript-go/internal/testutil/parsetestutil" @@ -61,6 +62,10 @@ func (p *fakeProgram) GetCurrentDirectory() string { return "" } +func (p *fakeProgram) PnpApi() *pnp.PnpApi { + return nil +} + func (p *fakeProgram) GetGlobalTypingsCacheLocation() string { return "" } diff --git a/internal/tsoptions/tsconfigparsing.go b/internal/tsoptions/tsconfigparsing.go index 9ccef5af8df..d2d70a1a92e 100644 --- a/internal/tsoptions/tsconfigparsing.go +++ b/internal/tsoptions/tsconfigparsing.go @@ -16,6 +16,7 @@ import ( "github.com/microsoft/typescript-go/internal/jsnum" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" ) @@ -672,6 +673,7 @@ func ParseConfigFileTextToJson(fileName string, path tspath.Path, jsonText strin type ParseConfigHost interface { FS() vfs.FS GetCurrentDirectory() string + PnpApi() *pnp.PnpApi } type resolverHost struct { diff --git a/internal/tsoptions/tsoptionstest/vfsparseconfighost.go b/internal/tsoptions/tsoptionstest/vfsparseconfighost.go index 249617083ef..2f8e746380d 100644 --- a/internal/tsoptions/tsoptionstest/vfsparseconfighost.go +++ b/internal/tsoptions/tsoptionstest/vfsparseconfighost.go @@ -1,9 +1,11 @@ package tsoptionstest import ( + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" ) @@ -21,6 +23,7 @@ func fixRoot(path string) string { type VfsParseConfigHost struct { Vfs vfs.FS CurrentDirectory string + pnpApi *pnp.PnpApi } var _ tsoptions.ParseConfigHost = (*VfsParseConfigHost)(nil) @@ -33,9 +36,20 @@ func (h *VfsParseConfigHost) GetCurrentDirectory() string { return h.CurrentDirectory } +func (h *VfsParseConfigHost) PnpApi() *pnp.PnpApi { + return h.pnpApi +} + func NewVFSParseConfigHost(files map[string]string, currentDirectory string, useCaseSensitiveFileNames bool) *VfsParseConfigHost { + var fs vfs.FS = vfstest.FromMap(files, useCaseSensitiveFileNames) + pnpApi := pnp.InitPnpApi(fs, tspath.NormalizePath(currentDirectory)) + if pnpApi != nil { + fs = pnpvfs.From(fs) + } + return &VfsParseConfigHost{ - Vfs: vfstest.FromMap(files, useCaseSensitiveFileNames), + Vfs: fs, CurrentDirectory: currentDirectory, + pnpApi: nil, } } diff --git a/internal/tspath/path.go b/internal/tspath/path.go index de092215071..c7dfb642b5b 100644 --- a/internal/tspath/path.go +++ b/internal/tspath/path.go @@ -869,6 +869,17 @@ func IsExternalModuleNameRelative(moduleName string) bool { return PathIsRelative(moduleName) || IsRootedDiskPath(moduleName) } +func IsExternalLibraryImport(path string) bool { + // When PnP is enabled, some internal libraries can be resolved as virtual packages, which should be treated as external libraries + // Since these virtual pnp packages don't have a `/node_modules/` folder, we need to check for the presence of `/__virtual__/` in the path + // See https://yarnpkg.com/advanced/lexicon#virtual-package for more details + return strings.Contains(path, "/node_modules/") || isPnpVirtualPath(path) +} + +func isPnpVirtualPath(path string) bool { + return strings.Contains(path, "/__virtual__/") +} + type ComparePathsOptions struct { UseCaseSensitiveFileNames bool CurrentDirectory string @@ -1018,6 +1029,10 @@ func HasExtension(fileName string) bool { return strings.Contains(GetBaseFileName(fileName), ".") } +func IsZipPath(path string) bool { + return strings.Contains(path, ".zip/") || strings.HasSuffix(path, ".zip") +} + func SplitVolumePath(path string) (volume string, rest string, ok bool) { if len(path) >= 2 && IsVolumeCharacter(path[0]) && path[1] == ':' { return strings.ToLower(path[0:2]), path[2:], true From f086507b6a076fca68875fe2619fad1975efb1bf Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 29 Oct 2025 15:06:45 +0100 Subject: [PATCH 04/32] Handle zip paths for LSP --- _extension/src/client.ts | 9 ++++++++- internal/ls/lsconv/converters.go | 9 ++++++++- internal/ls/lsconv/converters_test.go | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/_extension/src/client.ts b/_extension/src/client.ts index b759501e979..916bedec524 100644 --- a/_extension/src/client.ts +++ b/_extension/src/client.ts @@ -28,7 +28,14 @@ export class Client { this.clientOptions = { documentSelector: [ ...jsTsLanguageModes.map(language => ({ scheme: "file", language })), - ...jsTsLanguageModes.map(language => ({ scheme: "untitled", language })), + ...jsTsLanguageModes.map(language => ({ + scheme: "untitled", + language, + })), + ...jsTsLanguageModes.map(language => ({ + scheme: "zip", + language, + })), ], outputChannel: this.outputChannel, traceOutputChannel: this.traceOutputChannel, diff --git a/internal/ls/lsconv/converters.go b/internal/ls/lsconv/converters.go index 3b290b446c0..dc85df69d0b 100644 --- a/internal/ls/lsconv/converters.go +++ b/internal/ls/lsconv/converters.go @@ -128,7 +128,14 @@ func FileNameToDocumentURI(fileName string) lsproto.DocumentUri { parts[i] = extraEscapeReplacer.Replace(url.PathEscape(part)) } - return lsproto.DocumentUri("file://" + volume + strings.Join(parts, "/")) + var prefix string + if tspath.IsZipPath(fileName) { + prefix = "zip:" + } else { + prefix = "file:" + } + + return lsproto.DocumentUri(prefix + "//" + volume + strings.Join(parts, "/")) } func (c *Converters) LineAndCharacterToPosition(script Script, lineAndCharacter lsproto.Position) core.TextPos { diff --git a/internal/ls/lsconv/converters_test.go b/internal/ls/lsconv/converters_test.go index 30babd1df54..f3492a8dbb0 100644 --- a/internal/ls/lsconv/converters_test.go +++ b/internal/ls/lsconv/converters_test.go @@ -31,6 +31,9 @@ func TestDocumentURIToFileName(t *testing.T) { {"file://localhost/c%24/GitDevelopment/express", "//localhost/c$/GitDevelopment/express"}, {"file:///c%3A/test%20with%20%2525/c%23code", "c:/test with %25/c#code"}, + {"zip:///path/to/archive.zip/file.ts", "/path/to/archive.zip/file.ts"}, + {"zip:///d:/work/tsgo932/lib/archive.zip/utils.ts", "d:/work/tsgo932/lib/archive.zip/utils.ts"}, + {"untitled:Untitled-1", "^/untitled/ts-nul-authority/Untitled-1"}, {"untitled:Untitled-1#fragment", "^/untitled/ts-nul-authority/Untitled-1#fragment"}, {"untitled:c:/Users/jrieken/Code/abc.txt", "^/untitled/ts-nul-authority/c:/Users/jrieken/Code/abc.txt"}, @@ -69,6 +72,9 @@ func TestFileNameToDocumentURI(t *testing.T) { {"//localhost/c$/GitDevelopment/express", "file://localhost/c%24/GitDevelopment/express"}, {"c:/test with %25/c#code", "file:///c%3A/test%20with%20%2525/c%23code"}, + {"/path/to/archive.zip/file.ts", "zip:///path/to/archive.zip/file.ts"}, + {"d:/work/tsgo932/lib/archive.zip/utils.ts", "zip:///d%3A/work/tsgo932/lib/archive.zip/utils.ts"}, + {"^/untitled/ts-nul-authority/Untitled-1", "untitled:Untitled-1"}, {"^/untitled/ts-nul-authority/c:/Users/jrieken/Code/abc.txt", "untitled:c:/Users/jrieken/Code/abc.txt"}, {"^/untitled/ts-nul-authority///wsl%2Bubuntu/home/jabaile/work/TypeScript-go/newfile.ts", "untitled://wsl%2Bubuntu/home/jabaile/work/TypeScript-go/newfile.ts"}, From e4a3c4b16e82852451f7ed10b39fa066cab3cd86 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 29 Oct 2025 15:07:04 +0100 Subject: [PATCH 05/32] Add pnp tests --- internal/pnp/pnp.go | 6 + .../testutil/tsbaseline/js_emit_baseline.go | 3 +- .../compiler/pnpDeclarationEmitWorkspace.js | 121 ++++++++++++++ .../pnpDeclarationEmitWorkspace.symbols | 78 +++++++++ .../pnpDeclarationEmitWorkspace.types | 65 ++++++++ .../reference/compiler/pnpSimpleTest.js | 110 +++++++++++++ .../reference/compiler/pnpSimpleTest.symbols | 39 +++++ .../reference/compiler/pnpSimpleTest.types | 42 +++++ .../pnpTransitiveDependencies.errors.txt | 121 ++++++++++++++ .../compiler/pnpTransitiveDependencies.js | 153 ++++++++++++++++++ .../pnpTransitiveDependencies.symbols | 95 +++++++++++ .../compiler/pnpTransitiveDependencies.types | 98 +++++++++++ .../compiler/pnpTypeRootsResolution.js | 103 ++++++++++++ .../compiler/pnpTypeRootsResolution.symbols | 60 +++++++ .../compiler/pnpTypeRootsResolution.types | 53 ++++++ .../compiler/pnpDeclarationEmitWorkspace.ts | 110 +++++++++++++ .../tests/cases/compiler/pnpSimpleTest.ts | 97 +++++++++++ .../compiler/pnpTransitiveDependencies.ts | 117 ++++++++++++++ .../cases/compiler/pnpTypeRootsResolution.ts | 91 +++++++++++ 19 files changed, 1561 insertions(+), 1 deletion(-) create mode 100644 testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js create mode 100644 testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.symbols create mode 100644 testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.types create mode 100644 testdata/baselines/reference/compiler/pnpSimpleTest.js create mode 100644 testdata/baselines/reference/compiler/pnpSimpleTest.symbols create mode 100644 testdata/baselines/reference/compiler/pnpSimpleTest.types create mode 100644 testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt create mode 100644 testdata/baselines/reference/compiler/pnpTransitiveDependencies.js create mode 100644 testdata/baselines/reference/compiler/pnpTransitiveDependencies.symbols create mode 100644 testdata/baselines/reference/compiler/pnpTransitiveDependencies.types create mode 100644 testdata/baselines/reference/compiler/pnpTypeRootsResolution.js create mode 100644 testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols create mode 100644 testdata/baselines/reference/compiler/pnpTypeRootsResolution.types create mode 100644 testdata/tests/cases/compiler/pnpDeclarationEmitWorkspace.ts create mode 100644 testdata/tests/cases/compiler/pnpSimpleTest.ts create mode 100644 testdata/tests/cases/compiler/pnpTransitiveDependencies.ts create mode 100644 testdata/tests/cases/compiler/pnpTypeRootsResolution.ts diff --git a/internal/pnp/pnp.go b/internal/pnp/pnp.go index 476c0ea107d..dccf186c226 100644 --- a/internal/pnp/pnp.go +++ b/internal/pnp/pnp.go @@ -1,5 +1,7 @@ package pnp +import "strings" + func InitPnpApi(fs PnpApiFS, filePath string) *PnpApi { pnpApi := &PnpApi{fs: fs, url: filePath} @@ -11,3 +13,7 @@ func InitPnpApi(fs PnpApiFS, filePath string) *PnpApi { return nil } + +func IsPnpLoaderFile(path string) bool { + return strings.HasSuffix(path, ".pnp.cjs") +} diff --git a/internal/testutil/tsbaseline/js_emit_baseline.go b/internal/testutil/tsbaseline/js_emit_baseline.go index 8b51c193497..f5905e3658c 100644 --- a/internal/testutil/tsbaseline/js_emit_baseline.go +++ b/internal/testutil/tsbaseline/js_emit_baseline.go @@ -9,6 +9,7 @@ import ( "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/testutil/baseline" "github.com/microsoft/typescript-go/internal/testutil/harnessutil" "github.com/microsoft/typescript-go/internal/tspath" @@ -213,7 +214,7 @@ func prepareDeclarationCompilationContext( } addDtsFile := func(file *harnessutil.TestFile, dtsFiles []*harnessutil.TestFile) []*harnessutil.TestFile { - if tspath.IsDeclarationFileName(file.UnitName) || tspath.HasJSONFileExtension(file.UnitName) { + if tspath.IsDeclarationFileName(file.UnitName) || tspath.HasJSONFileExtension(file.UnitName) || pnp.IsPnpLoaderFile(file.UnitName) { dtsFiles = append(dtsFiles, file) } else if tspath.HasTSFileExtension(file.UnitName) || (tspath.HasJSFileExtension(file.UnitName) && options.GetAllowJS()) { declFile := findResultCodeFile(file.UnitName) diff --git a/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js new file mode 100644 index 00000000000..a949a85d468 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js @@ -0,0 +1,121 @@ +//// [tests/cases/compiler/pnpDeclarationEmitWorkspace.ts] //// + +//// [.pnp.cjs] +module.exports = {}; + +//// [.pnp.data.json] +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "workspace:packages/package-a"] + ] + }] + ]], + ["package-a", [ + ["workspace:packages/package-a", { + "packageLocation": "./packages/package-a/", + "packageDependencies": [] + }] + ]] + ] +} + +//// [package.json] +{ + "name": "project", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "package-a": "workspace:*" + } +} + +//// [package.json] +{ + "name": "package-a", + "exports": { + "./other-subpath": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "dependencies": { + "package-b": "workspace:*" + } +} + +//// [index.d.ts] +export interface BaseConfig { + timeout: number; + retries: number; +} + +export interface DataOptions { + format: "json" | "xml"; + encoding: string; +} + +export interface ServiceConfig extends BaseConfig { + endpoint: string; + options: DataOptions; +} + +export type ConfigFactory = (endpoint: string) => ServiceConfig; + +export declare function createServiceConfig(endpoint: string): ServiceConfig; + +//// [index.js] +exports.initializeService = function(url) {}; + + +//// [index.ts] +import type { ServiceConfig, ConfigFactory } from 'package-a/other-subpath'; +import { createServiceConfig } from 'package-a/other-subpath'; + +export function initializeService(url: string): ServiceConfig { + return createServiceConfig(url); +} + +export const factory = createServiceConfig; + +export interface AppConfig { + service: ServiceConfig; + debug: boolean; +} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.factory = void 0; +exports.initializeService = initializeService; +const other_subpath_1 = require("package-a/other-subpath"); +function initializeService(url) { + return (0, other_subpath_1.createServiceConfig)(url); +} +exports.factory = other_subpath_1.createServiceConfig; + + +//// [index.d.ts] +import type { ServiceConfig } from 'package-a/other-subpath'; +import { createServiceConfig } from 'package-a/other-subpath'; +export declare function initializeService(url: string): ServiceConfig; +export declare const factory: typeof createServiceConfig; +export interface AppConfig { + service: ServiceConfig; + debug: boolean; +} diff --git a/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.symbols b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.symbols new file mode 100644 index 00000000000..c99e148d54e --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.symbols @@ -0,0 +1,78 @@ +//// [tests/cases/compiler/pnpDeclarationEmitWorkspace.ts] //// + +=== /src/index.ts === +import type { ServiceConfig, ConfigFactory } from 'package-a/other-subpath'; +>ServiceConfig : Symbol(ServiceConfig, Decl(index.ts, 0, 13)) +>ConfigFactory : Symbol(ConfigFactory, Decl(index.ts, 0, 28)) + +import { createServiceConfig } from 'package-a/other-subpath'; +>createServiceConfig : Symbol(createServiceConfig, Decl(index.ts, 1, 8)) + +export function initializeService(url: string): ServiceConfig { +>initializeService : Symbol(initializeService, Decl(index.ts, 1, 62)) +>url : Symbol(url, Decl(index.ts, 3, 34)) +>ServiceConfig : Symbol(ServiceConfig, Decl(index.ts, 0, 13)) + + return createServiceConfig(url); +>createServiceConfig : Symbol(createServiceConfig, Decl(index.ts, 1, 8)) +>url : Symbol(url, Decl(index.ts, 3, 34)) +} + +export const factory = createServiceConfig; +>factory : Symbol(factory, Decl(index.ts, 7, 12)) +>createServiceConfig : Symbol(createServiceConfig, Decl(index.ts, 1, 8)) + +export interface AppConfig { +>AppConfig : Symbol(AppConfig, Decl(index.ts, 7, 43)) + + service: ServiceConfig; +>service : Symbol(AppConfig.service, Decl(index.ts, 9, 28)) +>ServiceConfig : Symbol(ServiceConfig, Decl(index.ts, 0, 13)) + + debug: boolean; +>debug : Symbol(AppConfig.debug, Decl(index.ts, 10, 25)) +} + +=== /packages/package-a/index.d.ts === +export interface BaseConfig { +>BaseConfig : Symbol(BaseConfig, Decl(index.d.ts, 0, 0)) + + timeout: number; +>timeout : Symbol(BaseConfig.timeout, Decl(index.d.ts, 0, 29)) + + retries: number; +>retries : Symbol(BaseConfig.retries, Decl(index.d.ts, 1, 18)) +} + +export interface DataOptions { +>DataOptions : Symbol(DataOptions, Decl(index.d.ts, 3, 1)) + + format: "json" | "xml"; +>format : Symbol(DataOptions.format, Decl(index.d.ts, 5, 30)) + + encoding: string; +>encoding : Symbol(DataOptions.encoding, Decl(index.d.ts, 6, 25)) +} + +export interface ServiceConfig extends BaseConfig { +>ServiceConfig : Symbol(ServiceConfig, Decl(index.d.ts, 8, 1)) +>BaseConfig : Symbol(BaseConfig, Decl(index.d.ts, 0, 0)) + + endpoint: string; +>endpoint : Symbol(ServiceConfig.endpoint, Decl(index.d.ts, 10, 51)) + + options: DataOptions; +>options : Symbol(ServiceConfig.options, Decl(index.d.ts, 11, 19)) +>DataOptions : Symbol(DataOptions, Decl(index.d.ts, 3, 1)) +} + +export type ConfigFactory = (endpoint: string) => ServiceConfig; +>ConfigFactory : Symbol(ConfigFactory, Decl(index.d.ts, 13, 1)) +>endpoint : Symbol(endpoint, Decl(index.d.ts, 15, 29)) +>ServiceConfig : Symbol(ServiceConfig, Decl(index.d.ts, 8, 1)) + +export declare function createServiceConfig(endpoint: string): ServiceConfig; +>createServiceConfig : Symbol(createServiceConfig, Decl(index.d.ts, 15, 64)) +>endpoint : Symbol(endpoint, Decl(index.d.ts, 17, 44)) +>ServiceConfig : Symbol(ServiceConfig, Decl(index.d.ts, 8, 1)) + diff --git a/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.types b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.types new file mode 100644 index 00000000000..9e51fc8ba32 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.types @@ -0,0 +1,65 @@ +//// [tests/cases/compiler/pnpDeclarationEmitWorkspace.ts] //// + +=== /src/index.ts === +import type { ServiceConfig, ConfigFactory } from 'package-a/other-subpath'; +>ServiceConfig : ServiceConfig +>ConfigFactory : ConfigFactory + +import { createServiceConfig } from 'package-a/other-subpath'; +>createServiceConfig : (endpoint: string) => ServiceConfig + +export function initializeService(url: string): ServiceConfig { +>initializeService : (url: string) => ServiceConfig +>url : string + + return createServiceConfig(url); +>createServiceConfig(url) : ServiceConfig +>createServiceConfig : (endpoint: string) => ServiceConfig +>url : string +} + +export const factory = createServiceConfig; +>factory : (endpoint: string) => ServiceConfig +>createServiceConfig : (endpoint: string) => ServiceConfig + +export interface AppConfig { + service: ServiceConfig; +>service : ServiceConfig + + debug: boolean; +>debug : boolean +} + +=== /packages/package-a/index.d.ts === +export interface BaseConfig { + timeout: number; +>timeout : number + + retries: number; +>retries : number +} + +export interface DataOptions { + format: "json" | "xml"; +>format : "json" | "xml" + + encoding: string; +>encoding : string +} + +export interface ServiceConfig extends BaseConfig { + endpoint: string; +>endpoint : string + + options: DataOptions; +>options : DataOptions +} + +export type ConfigFactory = (endpoint: string) => ServiceConfig; +>ConfigFactory : ConfigFactory +>endpoint : string + +export declare function createServiceConfig(endpoint: string): ServiceConfig; +>createServiceConfig : (endpoint: string) => ServiceConfig +>endpoint : string + diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.js b/testdata/baselines/reference/compiler/pnpSimpleTest.js new file mode 100644 index 00000000000..4f17149ae57 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.js @@ -0,0 +1,110 @@ +//// [tests/cases/compiler/pnpSimpleTest.ts] //// + +//// [.pnp.cjs] +module.exports = {}; + +//// [.pnp.data.json] +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "npm:1.0.0"], + ["package-b", "npm:2.0.0"] + ] + }] + ]], + ["package-a", [ + ["npm:1.0.0", { + "packageLocation": "./.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/", + "packageDependencies": [] + }] + ]], + ["package-b", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/", + "packageDependencies": [] + }] + ]] + ] +} + +//// [package.json] +{ + "name": "project", + "dependencies": { + "package-a": "npm:1.0.0", + "package-b": "npm:2.0.0" + } +} + +//// [package.json] +{ + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": "./index.js" + }, + "types": "index.d.ts" +} + +//// [index.js] +exports.helperA = function(value) { + return "Helper A: " + value; +}; + +//// [index.d.ts] +export declare function helperA(value: string): string; + +//// [package.json] +{ + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.js" + }, + "types": "index.d.ts" +} + +//// [index.js] +exports.helperB = function(value) { + return "Helper B: " + value; +}; + +//// [index.d.ts] +export declare function helperB(value: number): string; + +//// [index.ts] +// Workspace package that imports both third-party dependencies +import { helperA } from 'package-a'; +import { helperB } from 'package-b'; + +export function processData(text: string, num: number): string { + const resultA = helperA(text); + const resultB = helperB(num); + return `${resultA} | ${resultB}`; +} + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.processData = processData; +// Workspace package that imports both third-party dependencies +const package_a_1 = require("package-a"); +const package_b_1 = require("package-b"); +function processData(text, num) { + const resultA = (0, package_a_1.helperA)(text); + const resultB = (0, package_b_1.helperB)(num); + return `${resultA} | ${resultB}`; +} diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.symbols b/testdata/baselines/reference/compiler/pnpSimpleTest.symbols new file mode 100644 index 00000000000..c2e6e68b830 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.symbols @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/pnpSimpleTest.ts] //// + +=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === +export declare function helperA(value: string): string; +>helperA : Symbol(helperA, Decl(index.d.ts, 0, 0)) +>value : Symbol(value, Decl(index.d.ts, 0, 32)) + +=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === +export declare function helperB(value: number): string; +>helperB : Symbol(helperB, Decl(index.d.ts, 0, 0)) +>value : Symbol(value, Decl(index.d.ts, 0, 32)) + +=== /src/index.ts === +// Workspace package that imports both third-party dependencies +import { helperA } from 'package-a'; +>helperA : Symbol(helperA, Decl(index.ts, 1, 8)) + +import { helperB } from 'package-b'; +>helperB : Symbol(helperB, Decl(index.ts, 2, 8)) + +export function processData(text: string, num: number): string { +>processData : Symbol(processData, Decl(index.ts, 2, 36)) +>text : Symbol(text, Decl(index.ts, 4, 28)) +>num : Symbol(num, Decl(index.ts, 4, 41)) + + const resultA = helperA(text); +>resultA : Symbol(resultA, Decl(index.ts, 5, 7)) +>helperA : Symbol(helperA, Decl(index.ts, 1, 8)) +>text : Symbol(text, Decl(index.ts, 4, 28)) + + const resultB = helperB(num); +>resultB : Symbol(resultB, Decl(index.ts, 6, 7)) +>helperB : Symbol(helperB, Decl(index.ts, 2, 8)) +>num : Symbol(num, Decl(index.ts, 4, 41)) + + return `${resultA} | ${resultB}`; +>resultA : Symbol(resultA, Decl(index.ts, 5, 7)) +>resultB : Symbol(resultB, Decl(index.ts, 6, 7)) +} diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.types b/testdata/baselines/reference/compiler/pnpSimpleTest.types new file mode 100644 index 00000000000..90ce12017ba --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.types @@ -0,0 +1,42 @@ +//// [tests/cases/compiler/pnpSimpleTest.ts] //// + +=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === +export declare function helperA(value: string): string; +>helperA : (value: string) => string +>value : string + +=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === +export declare function helperB(value: number): string; +>helperB : (value: number) => string +>value : number + +=== /src/index.ts === +// Workspace package that imports both third-party dependencies +import { helperA } from 'package-a'; +>helperA : (value: string) => string + +import { helperB } from 'package-b'; +>helperB : (value: number) => string + +export function processData(text: string, num: number): string { +>processData : (text: string, num: number) => string +>text : string +>num : number + + const resultA = helperA(text); +>resultA : string +>helperA(text) : string +>helperA : (value: string) => string +>text : string + + const resultB = helperB(num); +>resultB : string +>helperB(num) : string +>helperB : (value: number) => string +>num : number + + return `${resultA} | ${resultB}`; +>`${resultA} | ${resultB}` : string +>resultA : string +>resultB : string +} diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt new file mode 100644 index 00000000000..a3063b90480 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt @@ -0,0 +1,121 @@ +/src/index.ts(5,36): error TS2307: Cannot find module 'package-b' or its corresponding type declarations. + + +==== /.pnp.cjs (0 errors) ==== + module.exports = {}; + +==== /.pnp.data.json (0 errors) ==== + { + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "workspace:packages/package-a"] + ] + }] + ]], + ["package-a", [ + ["workspace:packages/package-a", { + "packageLocation": "./packages/package-a/", + "packageDependencies": [ + ["package-b", "workspace:packages/package-b"] + ] + }] + ]], + ["package-b", [ + ["workspace:packages/package-b", { + "packageLocation": "./packages/package-b/", + "packageDependencies": [] + }] + ]] + ] + } + +==== /package.json (0 errors) ==== + { + "name": "project", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "package-a": "workspace:packages/package-a" + } + } + +==== /packages/package-a/package.json (0 errors) ==== + { + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": "./index.ts" + }, + "dependencies": { + "package-b": "workspace:packages/package-b" + } + } + +==== /packages/package-a/index.ts (0 errors) ==== + import type { ConfigOptions } from 'package-b'; + + export interface HelperResult { + message: string; + config: ConfigOptions; + } + + export function helperA(value: string, config: ConfigOptions): HelperResult { + return { + message: "Helper A: " + value, + config: config + }; + } + +==== /packages/package-b/package.json (0 errors) ==== + { + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.ts" + } + } + +==== /packages/package-b/index.ts (0 errors) ==== + export interface ConfigOptions { + enabled: boolean; + timeout: number; + } + + export function helperB(value: number): string { + return "Helper B: " + value; + } + +==== /src/index.ts (1 errors) ==== + // Test that the project can import package-a directly + // package-a's types depend on package-b's types (ConfigOptions) + import { helperA } from 'package-a'; + import type { HelperResult } from 'package-a'; + import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'package-b' or its corresponding type declarations. + + export function useDirectDependency(text: string): HelperResult { + const config: ConfigOptions = { enabled: true, timeout: 5000 }; + return helperA(text, config); + } + + // Test that the project CANNOT import package-b directly even though package-a uses it + // This should cause an error since package-b is not in project's dependencies + export function attemptDirectImport(): ConfigOptions { + return { enabled: false, timeout: 1000 }; + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js new file mode 100644 index 00000000000..b55c6702266 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js @@ -0,0 +1,153 @@ +//// [tests/cases/compiler/pnpTransitiveDependencies.ts] //// + +//// [.pnp.cjs] +module.exports = {}; + +//// [.pnp.data.json] +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "workspace:packages/package-a"] + ] + }] + ]], + ["package-a", [ + ["workspace:packages/package-a", { + "packageLocation": "./packages/package-a/", + "packageDependencies": [ + ["package-b", "workspace:packages/package-b"] + ] + }] + ]], + ["package-b", [ + ["workspace:packages/package-b", { + "packageLocation": "./packages/package-b/", + "packageDependencies": [] + }] + ]] + ] +} + +//// [package.json] +{ + "name": "project", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "package-a": "workspace:packages/package-a" + } +} + +//// [package.json] +{ + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": "./index.ts" + }, + "dependencies": { + "package-b": "workspace:packages/package-b" + } +} + +//// [index.ts] +import type { ConfigOptions } from 'package-b'; + +export interface HelperResult { + message: string; + config: ConfigOptions; +} + +export function helperA(value: string, config: ConfigOptions): HelperResult { + return { + message: "Helper A: " + value, + config: config + }; +} + +//// [package.json] +{ + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.ts" + } +} + +//// [index.ts] +export interface ConfigOptions { + enabled: boolean; + timeout: number; +} + +export function helperB(value: number): string { + return "Helper B: " + value; +} + +//// [index.ts] +// Test that the project can import package-a directly +// package-a's types depend on package-b's types (ConfigOptions) +import { helperA } from 'package-a'; +import type { HelperResult } from 'package-a'; +import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency + +export function useDirectDependency(text: string): HelperResult { + const config: ConfigOptions = { enabled: true, timeout: 5000 }; + return helperA(text, config); +} + +// Test that the project CANNOT import package-b directly even though package-a uses it +// This should cause an error since package-b is not in project's dependencies +export function attemptDirectImport(): ConfigOptions { + return { enabled: false, timeout: 1000 }; +} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.helperB = helperB; +function helperB(value) { + return "Helper B: " + value; +} +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.helperA = helperA; +function helperA(value, config) { + return { + message: "Helper A: " + value, + config: config + }; +} +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.useDirectDependency = useDirectDependency; +exports.attemptDirectImport = attemptDirectImport; +// Test that the project can import package-a directly +// package-a's types depend on package-b's types (ConfigOptions) +const package_a_1 = require("package-a"); +function useDirectDependency(text) { + const config = { enabled: true, timeout: 5000 }; + return (0, package_a_1.helperA)(text, config); +} +// Test that the project CANNOT import package-b directly even though package-a uses it +// This should cause an error since package-b is not in project's dependencies +function attemptDirectImport() { + return { enabled: false, timeout: 1000 }; +} diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.symbols b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.symbols new file mode 100644 index 00000000000..752518b2ebe --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.symbols @@ -0,0 +1,95 @@ +//// [tests/cases/compiler/pnpTransitiveDependencies.ts] //// + +=== /packages/package-a/index.ts === +import type { ConfigOptions } from 'package-b'; +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 0, 13)) + +export interface HelperResult { +>HelperResult : Symbol(HelperResult, Decl(index.ts, 0, 47)) + + message: string; +>message : Symbol(HelperResult.message, Decl(index.ts, 2, 31)) + + config: ConfigOptions; +>config : Symbol(HelperResult.config, Decl(index.ts, 3, 18)) +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 0, 13)) +} + +export function helperA(value: string, config: ConfigOptions): HelperResult { +>helperA : Symbol(helperA, Decl(index.ts, 5, 1)) +>value : Symbol(value, Decl(index.ts, 7, 24)) +>config : Symbol(config, Decl(index.ts, 7, 38)) +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 0, 13)) +>HelperResult : Symbol(HelperResult, Decl(index.ts, 0, 47)) + + return { + message: "Helper A: " + value, +>message : Symbol(message, Decl(index.ts, 8, 10)) +>value : Symbol(value, Decl(index.ts, 7, 24)) + + config: config +>config : Symbol(config, Decl(index.ts, 9, 34)) +>config : Symbol(config, Decl(index.ts, 7, 38)) + + }; +} + +=== /packages/package-b/index.ts === +export interface ConfigOptions { +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 0, 0)) + + enabled: boolean; +>enabled : Symbol(ConfigOptions.enabled, Decl(index.ts, 0, 32)) + + timeout: number; +>timeout : Symbol(ConfigOptions.timeout, Decl(index.ts, 1, 19)) +} + +export function helperB(value: number): string { +>helperB : Symbol(helperB, Decl(index.ts, 3, 1)) +>value : Symbol(value, Decl(index.ts, 5, 24)) + + return "Helper B: " + value; +>value : Symbol(value, Decl(index.ts, 5, 24)) +} + +=== /src/index.ts === +// Test that the project can import package-a directly +// package-a's types depend on package-b's types (ConfigOptions) +import { helperA } from 'package-a'; +>helperA : Symbol(helperA, Decl(index.ts, 2, 8)) + +import type { HelperResult } from 'package-a'; +>HelperResult : Symbol(HelperResult, Decl(index.ts, 3, 13)) + +import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 4, 13)) + +export function useDirectDependency(text: string): HelperResult { +>useDirectDependency : Symbol(useDirectDependency, Decl(index.ts, 4, 47)) +>text : Symbol(text, Decl(index.ts, 6, 36)) +>HelperResult : Symbol(HelperResult, Decl(index.ts, 3, 13)) + + const config: ConfigOptions = { enabled: true, timeout: 5000 }; +>config : Symbol(config, Decl(index.ts, 7, 7)) +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 4, 13)) +>enabled : Symbol(enabled, Decl(index.ts, 7, 33)) +>timeout : Symbol(timeout, Decl(index.ts, 7, 48)) + + return helperA(text, config); +>helperA : Symbol(helperA, Decl(index.ts, 2, 8)) +>text : Symbol(text, Decl(index.ts, 6, 36)) +>config : Symbol(config, Decl(index.ts, 7, 7)) +} + +// Test that the project CANNOT import package-b directly even though package-a uses it +// This should cause an error since package-b is not in project's dependencies +export function attemptDirectImport(): ConfigOptions { +>attemptDirectImport : Symbol(attemptDirectImport, Decl(index.ts, 9, 1)) +>ConfigOptions : Symbol(ConfigOptions, Decl(index.ts, 4, 13)) + + return { enabled: false, timeout: 1000 }; +>enabled : Symbol(enabled, Decl(index.ts, 14, 10)) +>timeout : Symbol(timeout, Decl(index.ts, 14, 26)) +} + diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types new file mode 100644 index 00000000000..67a56d6ef3d --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types @@ -0,0 +1,98 @@ +//// [tests/cases/compiler/pnpTransitiveDependencies.ts] //// + +=== /packages/package-a/index.ts === +import type { ConfigOptions } from 'package-b'; +>ConfigOptions : ConfigOptions + +export interface HelperResult { + message: string; +>message : string + + config: ConfigOptions; +>config : ConfigOptions +} + +export function helperA(value: string, config: ConfigOptions): HelperResult { +>helperA : (value: string, config: ConfigOptions) => HelperResult +>value : string +>config : ConfigOptions + + return { +>{ message: "Helper A: " + value, config: config } : { message: string; config: ConfigOptions; } + + message: "Helper A: " + value, +>message : string +>"Helper A: " + value : string +>"Helper A: " : "Helper A: " +>value : string + + config: config +>config : ConfigOptions +>config : ConfigOptions + + }; +} + +=== /packages/package-b/index.ts === +export interface ConfigOptions { + enabled: boolean; +>enabled : boolean + + timeout: number; +>timeout : number +} + +export function helperB(value: number): string { +>helperB : (value: number) => string +>value : number + + return "Helper B: " + value; +>"Helper B: " + value : string +>"Helper B: " : "Helper B: " +>value : number +} + +=== /src/index.ts === +// Test that the project can import package-a directly +// package-a's types depend on package-b's types (ConfigOptions) +import { helperA } from 'package-a'; +>helperA : (value: string, config: import("/packages/package-b/index").ConfigOptions) => HelperResult + +import type { HelperResult } from 'package-a'; +>HelperResult : HelperResult + +import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency +>ConfigOptions : any + +export function useDirectDependency(text: string): HelperResult { +>useDirectDependency : (text: string) => HelperResult +>text : string + + const config: ConfigOptions = { enabled: true, timeout: 5000 }; +>config : ConfigOptions +>{ enabled: true, timeout: 5000 } : { enabled: boolean; timeout: number; } +>enabled : boolean +>true : true +>timeout : number +>5000 : 5000 + + return helperA(text, config); +>helperA(text, config) : HelperResult +>helperA : (value: string, config: import("/packages/package-b/index").ConfigOptions) => HelperResult +>text : string +>config : ConfigOptions +} + +// Test that the project CANNOT import package-b directly even though package-a uses it +// This should cause an error since package-b is not in project's dependencies +export function attemptDirectImport(): ConfigOptions { +>attemptDirectImport : () => ConfigOptions + + return { enabled: false, timeout: 1000 }; +>{ enabled: false, timeout: 1000 } : { enabled: boolean; timeout: number; } +>enabled : boolean +>false : false +>timeout : number +>1000 : 1000 +} + diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js new file mode 100644 index 00000000000..c1e90142710 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js @@ -0,0 +1,103 @@ +//// [tests/cases/compiler/pnpTypeRootsResolution.ts] //// + +//// [.pnp.cjs] +module.exports = {}; + +//// [.pnp.data.json] +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["server-lib", "npm:2.0.0"], + ["@types/server-lib", "npm:2.0.0"] + ] + }] + ]], + ["server-lib", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/server-lib-npm-2.0.0-ijkl9012/node_modules/server-lib/", + "packageDependencies": [] + }] + ]], + ["@types/server-lib", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/", + "packageDependencies": [ + ["@types/runtime", "npm:3.0.0"] + ] + }] + ]] + ] +} + +//// [package.json] +{ + "name": "project", + "dependencies": { + "server-lib": "2.0.0" + }, + "devDependencies": { + "@types/server-lib": "2.0.0", + } +} + +//// [package.json] +{ + "name": "server-lib", + "version": "2.0.0" +} + +//// [package.json] +{ + "name": "@types/server-lib", + "version": "2.0.0", + "types": "index.d.ts" +} + +//// [index.d.ts] +export interface Request { + params: Record; + query: Record; +} + +export interface Response { + send(body: Record): void; + json(body: Record): void; +} + +export declare function createServer(): Record; + +//// [index.ts] +// Test that TypeScript can resolve @types packages through PnP +import type { Request, Response } from 'server-lib'; +import { createServer } from 'server-lib'; + +export function handleRequest(req: Request, res: Response): void { + res.json({ data: 'Hello, world!' }); +} + +export const server = createServer(); + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.server = void 0; +exports.handleRequest = handleRequest; +const server_lib_1 = require("server-lib"); +function handleRequest(req, res) { + res.json({ data: 'Hello, world!' }); +} +exports.server = (0, server_lib_1.createServer)(); diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols new file mode 100644 index 00000000000..739cb2367e0 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols @@ -0,0 +1,60 @@ +//// [tests/cases/compiler/pnpTypeRootsResolution.ts] //// + +=== /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts === +export interface Request { +>Request : Symbol(Request, Decl(index.d.ts, 0, 0)) + + params: Record; +>params : Symbol(Request.params, Decl(index.d.ts, 0, 26)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + query: Record; +>query : Symbol(Request.query, Decl(index.d.ts, 1, 34)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +} + +export interface Response { +>Response : Symbol(Response, Decl(index.d.ts, 3, 1)) + + send(body: Record): void; +>send : Symbol(Response.send, Decl(index.d.ts, 5, 27)) +>body : Symbol(body, Decl(index.d.ts, 6, 7)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + json(body: Record): void; +>json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) +>body : Symbol(body, Decl(index.d.ts, 7, 7)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +} + +export declare function createServer(): Record; +>createServer : Symbol(createServer, Decl(index.d.ts, 8, 1)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +=== /src/index.ts === +// Test that TypeScript can resolve @types packages through PnP +import type { Request, Response } from 'server-lib'; +>Request : Symbol(Request, Decl(index.ts, 1, 13)) +>Response : Symbol(Response, Decl(index.ts, 1, 22)) + +import { createServer } from 'server-lib'; +>createServer : Symbol(createServer, Decl(index.ts, 2, 8)) + +export function handleRequest(req: Request, res: Response): void { +>handleRequest : Symbol(handleRequest, Decl(index.ts, 2, 42)) +>req : Symbol(req, Decl(index.ts, 4, 30)) +>Request : Symbol(Request, Decl(index.ts, 1, 13)) +>res : Symbol(res, Decl(index.ts, 4, 43)) +>Response : Symbol(Response, Decl(index.ts, 1, 22)) + + res.json({ data: 'Hello, world!' }); +>res.json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) +>res : Symbol(res, Decl(index.ts, 4, 43)) +>json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) +>data : Symbol(data, Decl(index.ts, 5, 12)) +} + +export const server = createServer(); +>server : Symbol(server, Decl(index.ts, 8, 12)) +>createServer : Symbol(createServer, Decl(index.ts, 2, 8)) + diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types new file mode 100644 index 00000000000..963f0b9c689 --- /dev/null +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/pnpTypeRootsResolution.ts] //// + +=== /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts === +export interface Request { + params: Record; +>params : Record + + query: Record; +>query : Record +} + +export interface Response { + send(body: Record): void; +>send : (body: Record) => void +>body : Record + + json(body: Record): void; +>json : (body: Record) => void +>body : Record +} + +export declare function createServer(): Record; +>createServer : () => Record + +=== /src/index.ts === +// Test that TypeScript can resolve @types packages through PnP +import type { Request, Response } from 'server-lib'; +>Request : Request +>Response : Response + +import { createServer } from 'server-lib'; +>createServer : () => Record + +export function handleRequest(req: Request, res: Response): void { +>handleRequest : (req: Request, res: Response) => void +>req : Request +>res : Response + + res.json({ data: 'Hello, world!' }); +>res.json({ data: 'Hello, world!' }) : void +>res.json : (body: Record) => void +>res : Response +>json : (body: Record) => void +>{ data: 'Hello, world!' } : { data: string; } +>data : string +>'Hello, world!' : "Hello, world!" +} + +export const server = createServer(); +>server : Record +>createServer() : Record +>createServer : () => Record + diff --git a/testdata/tests/cases/compiler/pnpDeclarationEmitWorkspace.ts b/testdata/tests/cases/compiler/pnpDeclarationEmitWorkspace.ts new file mode 100644 index 00000000000..a40f396867a --- /dev/null +++ b/testdata/tests/cases/compiler/pnpDeclarationEmitWorkspace.ts @@ -0,0 +1,110 @@ +// @strict: true +// @declaration: true +// @currentDirectory: /src + +// @filename: /.pnp.cjs +module.exports = {}; + +// @filename: /.pnp.data.json +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "workspace:packages/package-a"] + ] + }] + ]], + ["package-a", [ + ["workspace:packages/package-a", { + "packageLocation": "./packages/package-a/", + "packageDependencies": [] + }] + ]] + ] +} + +// @filename: /package.json +{ + "name": "project", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "package-a": "workspace:*" + } +} + +// @filename: /tsconfig.json +{ + "compilerOptions": { + "declaration": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"] +} + +// @filename: /packages/package-a/package.json +{ + "name": "package-a", + "exports": { + "./other-subpath": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "dependencies": { + "package-b": "workspace:*" + } +} + +// @filename: /packages/package-a/index.d.ts +export interface BaseConfig { + timeout: number; + retries: number; +} + +export interface DataOptions { + format: "json" | "xml"; + encoding: string; +} + +export interface ServiceConfig extends BaseConfig { + endpoint: string; + options: DataOptions; +} + +export type ConfigFactory = (endpoint: string) => ServiceConfig; + +export declare function createServiceConfig(endpoint: string): ServiceConfig; + +// @filename: /packages/package-a/index.js +exports.initializeService = function(url) {}; + + +// @filename: /src/index.ts +import type { ServiceConfig, ConfigFactory } from 'package-a/other-subpath'; +import { createServiceConfig } from 'package-a/other-subpath'; + +export function initializeService(url: string): ServiceConfig { + return createServiceConfig(url); +} + +export const factory = createServiceConfig; + +export interface AppConfig { + service: ServiceConfig; + debug: boolean; +} diff --git a/testdata/tests/cases/compiler/pnpSimpleTest.ts b/testdata/tests/cases/compiler/pnpSimpleTest.ts new file mode 100644 index 00000000000..7c4b2603ee5 --- /dev/null +++ b/testdata/tests/cases/compiler/pnpSimpleTest.ts @@ -0,0 +1,97 @@ +// @strict: true + +// @filename: /.pnp.cjs +module.exports = {}; + +// @filename: /.pnp.data.json +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "npm:1.0.0"], + ["package-b", "npm:2.0.0"] + ] + }] + ]], + ["package-a", [ + ["npm:1.0.0", { + "packageLocation": "./.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/", + "packageDependencies": [] + }] + ]], + ["package-b", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/", + "packageDependencies": [] + }] + ]] + ] +} + +// @filename: package.json +{ + "name": "project", + "dependencies": { + "package-a": "npm:1.0.0", + "package-b": "npm:2.0.0" + } +} + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/package.json +{ + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": "./index.js" + }, + "types": "index.d.ts" +} + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.js +exports.helperA = function(value) { + return "Helper A: " + value; +}; + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts +export declare function helperA(value: string): string; + +// @filename: /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/package.json +{ + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.js" + }, + "types": "index.d.ts" +} + +// @filename: /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.js +exports.helperB = function(value) { + return "Helper B: " + value; +}; + +// @filename: /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts +export declare function helperB(value: number): string; + +// @filename: /src/index.ts +// Workspace package that imports both third-party dependencies +import { helperA } from 'package-a'; +import { helperB } from 'package-b'; + +export function processData(text: string, num: number): string { + const resultA = helperA(text); + const resultB = helperB(num); + return `${resultA} | ${resultB}`; +} \ No newline at end of file diff --git a/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts new file mode 100644 index 00000000000..41fdc6d77e7 --- /dev/null +++ b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts @@ -0,0 +1,117 @@ +// @strict: true + +// @filename: /.pnp.cjs +module.exports = {}; + +// @filename: /.pnp.data.json +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "workspace:packages/package-a"] + ] + }] + ]], + ["package-a", [ + ["workspace:packages/package-a", { + "packageLocation": "./packages/package-a/", + "packageDependencies": [ + ["package-b", "workspace:packages/package-b"] + ] + }] + ]], + ["package-b", [ + ["workspace:packages/package-b", { + "packageLocation": "./packages/package-b/", + "packageDependencies": [] + }] + ]] + ] +} + +// @filename: /package.json +{ + "name": "project", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "package-a": "workspace:packages/package-a" + } +} + +// @filename: /packages/package-a/package.json +{ + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": "./index.ts" + }, + "dependencies": { + "package-b": "workspace:packages/package-b" + } +} + +// @filename: /packages/package-a/index.ts +import type { ConfigOptions } from 'package-b'; + +export interface HelperResult { + message: string; + config: ConfigOptions; +} + +export function helperA(value: string, config: ConfigOptions): HelperResult { + return { + message: "Helper A: " + value, + config: config + }; +} + +// @filename: /packages/package-b/package.json +{ + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.ts" + } +} + +// @filename: /packages/package-b/index.ts +export interface ConfigOptions { + enabled: boolean; + timeout: number; +} + +export function helperB(value: number): string { + return "Helper B: " + value; +} + +// @filename: /src/index.ts +// Test that the project can import package-a directly +// package-a's types depend on package-b's types (ConfigOptions) +import { helperA } from 'package-a'; +import type { HelperResult } from 'package-a'; +import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency + +export function useDirectDependency(text: string): HelperResult { + const config: ConfigOptions = { enabled: true, timeout: 5000 }; + return helperA(text, config); +} + +// Test that the project CANNOT import package-b directly even though package-a uses it +// This should cause an error since package-b is not in project's dependencies +export function attemptDirectImport(): ConfigOptions { + return { enabled: false, timeout: 1000 }; +} diff --git a/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts new file mode 100644 index 00000000000..85153441532 --- /dev/null +++ b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts @@ -0,0 +1,91 @@ +// @strict: true + +// @filename: /.pnp.cjs +module.exports = {}; + +// @filename: /.pnp.data.json +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["server-lib", "npm:2.0.0"], + ["@types/server-lib", "npm:2.0.0"] + ] + }] + ]], + ["server-lib", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/server-lib-npm-2.0.0-ijkl9012/node_modules/server-lib/", + "packageDependencies": [] + }] + ]], + ["@types/server-lib", [ + ["npm:2.0.0", { + "packageLocation": "./.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/", + "packageDependencies": [ + ["@types/runtime", "npm:3.0.0"] + ] + }] + ]] + ] +} + +// @filename: /package.json +{ + "name": "project", + "dependencies": { + "server-lib": "2.0.0" + }, + "devDependencies": { + "@types/server-lib": "2.0.0", + } +} + +// @filename: /.yarn/cache/server-lib-npm-2.0.0-ijkl9012/node_modules/server-lib/package.json +{ + "name": "server-lib", + "version": "2.0.0" +} + +// @filename: /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/package.json +{ + "name": "@types/server-lib", + "version": "2.0.0", + "types": "index.d.ts" +} + +// @filename: /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts +export interface Request { + params: Record; + query: Record; +} + +export interface Response { + send(body: Record): void; + json(body: Record): void; +} + +export declare function createServer(): Record; + +// @filename: /src/index.ts +// Test that TypeScript can resolve @types packages through PnP +import type { Request, Response } from 'server-lib'; +import { createServer } from 'server-lib'; + +export function handleRequest(req: Request, res: Response): void { + res.json({ data: 'Hello, world!' }); +} + +export const server = createServer(); From 9aa7f3ea205c249d188c2c07bb5810851e64055a Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Fri, 31 Oct 2025 13:47:57 +0100 Subject: [PATCH 06/32] Fix pnpvfs test in windows --- internal/vfs/pnpvfs/pnpvfs.go | 16 ++++++++++++++++ internal/vfs/pnpvfs/pnpvfs_test.go | 28 +++++++++++++--------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index d88894a21f2..06e21d7972b 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -233,3 +233,19 @@ func makeVirtualPath(basePath string, hash string, targetPath string) string { return path.Join(basePath, hash, strconv.Itoa(depth), subPath) } + +func (pnpFS *pnpFS) ClearCache() error { + pnpFS.cacheReaderMutex.Lock() + defer pnpFS.cacheReaderMutex.Unlock() + + for _, reader := range pnpFS.cachedZipReadersMap { + err := reader.Close() + if err != nil { + return err + } + } + + pnpFS.cachedZipReadersMap = make(map[string]*zip.ReadCloser) + + return nil +} diff --git a/internal/vfs/pnpvfs/pnpvfs_test.go b/internal/vfs/pnpvfs/pnpvfs_test.go index f5d12fa775f..78249ef3ca7 100644 --- a/internal/vfs/pnpvfs/pnpvfs_test.go +++ b/internal/vfs/pnpvfs/pnpvfs_test.go @@ -2,7 +2,6 @@ package pnpvfs_test import ( "archive/zip" - "fmt" "os" "strings" "testing" @@ -16,7 +15,7 @@ import ( "gotest.tools/v3/assert" ) -func createTestZip(t *testing.T, files map[string]string) string { +func createTestZip(t *testing.T, files map[string]string) (string, vfs.FS) { t.Helper() tmpDir := t.TempDir() @@ -36,7 +35,14 @@ func createTestZip(t *testing.T, files map[string]string) string { assert.NilError(t, err) } - return zipPath + fs := pnpvfs.From(osvfs.FS()) + + t.Cleanup(func() { + errClear := fs.ClearCache() + assert.NilError(t, errClear) + }) + + return zipPath, fs } func TestPnpVfs_BasicFileOperations(t *testing.T) { @@ -85,15 +91,8 @@ func TestPnpVfs_ZipFileDetection(t *testing.T) { "package.json": `{"name": "test-project"}`, } - zipPath := createTestZip(t, zipFiles) - - underlyingFS := vfstest.FromMap(map[string]string{ - zipPath: "zip content placeholder", - }, true) + zipPath, fs := createTestZip(t, zipFiles) - fs := pnpvfs.From(underlyingFS) - - fmt.Println(zipPath) assert.Assert(t, fs.FileExists(zipPath)) zipInternalPath := zipPath + "/src/index.ts" @@ -137,10 +136,10 @@ func TestPnpVfs_ErrorHandling(t *testing.T) { zipFiles := map[string]string{ "src/index.ts": "export const hello = 'world';", } - zipPath := createTestZip(t, zipFiles) + zipPath, zipFS := createTestZip(t, zipFiles) testutil.AssertPanics(t, func() { - _ = fs.WriteFile(zipPath+"/src/index.ts", "hello, world", false) + _ = zipFS.WriteFile(zipPath+"/src/index.ts", "hello, world", false) }, "cannot write to zip file") }) } @@ -249,8 +248,7 @@ func TestPnpVfs_RealZipIntegration(t *testing.T) { "tsconfig.json": `{"compilerOptions": {"target": "es2020"}}`, } - zipPath := createTestZip(t, zipFiles) - fs := pnpvfs.From(osvfs.FS()) + zipPath, fs := createTestZip(t, zipFiles) assert.Assert(t, fs.FileExists(zipPath)) From 6e2eaff0392be6aa4abea0cfbc03d22a3c14d6ef Mon Sep 17 00:00:00 2001 From: gun-yu <163322737+gun-yu@users.noreply.github.com> Date: Sun, 2 Nov 2025 18:52:20 +0900 Subject: [PATCH 07/32] add pnp error handling and test (#3) * add pnpapi test * remove cycle dependency * add error handling * add error message * apply error message * add error bubbling * code clean up * remove useless test * add empty findBrokenPeerDependencies * early return * change function name * apply code review * merge duplicate logic * apply collect usage * apply codereview * apply fromConfig --- internal/core/compileroptions.go | 20 +- internal/diagnostics/diagnostics_generated.go | 18 + .../diagnostics/extraDiagnosticMessages.json | 36 + internal/module/resolver.go | 28 +- internal/pnp/manifestparser.go | 52 +- internal/pnp/pnp.go | 8 +- internal/pnp/pnpapi.go | 81 +- internal/pnp/pnpapi_test.go | 152 + testdata/fixtures/pnp/pnp-yarn-v3.cjs | 10815 ++++++++++++++++ testdata/fixtures/pnp/pnp-yarn-v4.cjs | 7429 +++++++++++ testdata/fixtures/pnp/test-expectations.json | 378 + 11 files changed, 18952 insertions(+), 65 deletions(-) create mode 100644 internal/pnp/pnpapi_test.go create mode 100644 testdata/fixtures/pnp/pnp-yarn-v3.cjs create mode 100644 testdata/fixtures/pnp/pnp-yarn-v4.cjs create mode 100644 testdata/fixtures/pnp/test-expectations.json diff --git a/internal/core/compileroptions.go b/internal/core/compileroptions.go index 17b51ba5c3f..f8956ae3031 100644 --- a/internal/core/compileroptions.go +++ b/internal/core/compileroptions.go @@ -6,7 +6,6 @@ import ( "sync" "github.com/microsoft/typescript-go/internal/collections" - "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" ) @@ -301,10 +300,17 @@ func (options *CompilerOptions) GetStrictOptionValue(value Tristate) bool { return options.Strict == TSTrue } -func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string, pnpApi *pnp.PnpApi) (result []string, fromConfig bool) { +func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string) (result []string, fromConfig bool) { if options.TypeRoots != nil { return options.TypeRoots, true } + baseDir := options.GetBaseDirFromOptions(currentDirectory) + + nmTypes, nmFromConfig := options.GetNodeModulesTypeRoots(baseDir) + return nmTypes, nmFromConfig +} + +func (options *CompilerOptions) GetBaseDirFromOptions(currentDirectory string) string { var baseDir string if options.ConfigFilePath != "" { baseDir = tspath.GetDirectoryPath(options.ConfigFilePath) @@ -316,15 +322,7 @@ func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string, p panic("cannot get effective type roots without a config file path or current directory") } } - - nmTypes, nmFromConfig := options.GetNodeModulesTypeRoots(baseDir) - - if pnpApi != nil { - typeRoots, fromConfig := pnpApi.AppendPnpTypeRoots(nmTypes, baseDir, nmFromConfig) - return typeRoots, fromConfig - } - - return nmTypes, nmFromConfig + return baseDir } func (options *CompilerOptions) GetNodeModulesTypeRoots(baseDir string) (result []string, fromConfig bool) { diff --git a/internal/diagnostics/diagnostics_generated.go b/internal/diagnostics/diagnostics_generated.go index 8f62d2b8d2e..daa33790c35 100644 --- a/internal/diagnostics/diagnostics_generated.go +++ b/internal/diagnostics/diagnostics_generated.go @@ -4253,3 +4253,21 @@ var Do_not_print_diagnostics = &Message{code: 100000, category: CategoryMessage, var Run_in_single_threaded_mode = &Message{code: 100001, category: CategoryMessage, key: "Run_in_single_threaded_mode_100001", text: "Run in single threaded mode."} var Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory = &Message{code: 100002, category: CategoryMessage, key: "Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory_100002", text: "Generate pprof CPU/memory profiles to the given directory."} + +var Your_application_tried_to_access_0_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_0_isn_t_otherwise_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2 = &Message{code: 100003, category: CategoryError, key: "Your_application_tried_to_access_0_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_r_100003", text: "Your application tried to access '{0}'. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since '{0}' isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: {0}{1}\nRequired by: {2}"} + +var X_0_tried_to_access_1_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_1_isn_t_otherwise_declared_in_0_s_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_2_Required_by_Colon_3 = &Message{code: 100004, category: CategoryError, key: "_0_tried_to_access_1_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_run_100004", text: "{0} tried to access '{1}'. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since '{1}' isn't otherwise declared in {0}'s dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: {1}{2}\nRequired by: {3}"} + +var Your_application_tried_to_access_0_but_it_isn_t_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2 = &Message{code: 100005, category: CategoryError, key: "Your_application_tried_to_access_0_but_it_isn_t_declared_in_your_dependencies_this_makes_the_require_100005", text: "Your application tried to access '{0}', but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: {0}{1}\nRequired by: {2}"} + +var Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_satisfy_the_requirement_Use_a_devDependency_if_needed_Required_package_Colon_0_Required_by_Colon_1 = &Message{code: 100006, category: CategoryError, key: "Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_s_100006", text: "Your application tried to access '{0}' (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed.\n\nRequired package: {0}\nRequired by: {1}"} + +var X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2 = &Message{code: 100007, category: CategoryError, key: "_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application__100007", text: "{0} tried to access '{1}' (a peer dependency) but it isn't provided by its ancestors/your application; this makes the require call ambiguous and unsound.\n\nRequired package: {1}\nRequired by: {2}"} + +var X_no_PnP_manifest_found = &Message{code: 100008, category: CategoryError, key: "no_PnP_manifest_found_100008", text: "no PnP manifest found"} + +var X_no_package_found_for_path_0 = &Message{code: 100009, category: CategoryError, key: "no_package_found_for_path_0_100009", text: "no package found for path '{0}'"} + +var Empty_specifier_Colon_0 = &Message{code: 100010, category: CategoryError, key: "Empty_specifier_Colon_0_100010", text: "Empty specifier: '{0}'"} + +var Invalid_specifier_Colon_0 = &Message{code: 100011, category: CategoryError, key: "Invalid_specifier_Colon_0_100011", text: "Invalid specifier: '{0}'"} diff --git a/internal/diagnostics/extraDiagnosticMessages.json b/internal/diagnostics/extraDiagnosticMessages.json index 109a1bdfd5b..2a1c5b80fb1 100644 --- a/internal/diagnostics/extraDiagnosticMessages.json +++ b/internal/diagnostics/extraDiagnosticMessages.json @@ -34,5 +34,41 @@ "Project '{0}' is out of date because it has errors.": { "category": "Message", "code": 6423 + }, + "Your application tried to access '{0}'. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since '{0}' isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: {0}{1}\nRequired by: {2}": { + "category": "Error", + "code": 100003 + }, + "{0} tried to access '{1}'. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since '{1}' isn't otherwise declared in {0}'s dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: {1}{2}\nRequired by: {3}": { + "category": "Error", + "code": 100004 + }, + "Your application tried to access '{0}', but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: {0}{1}\nRequired by: {2}": { + "category": "Error", + "code": 100005 + }, + "Your application tried to access '{0}' (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed.\n\nRequired package: {0}\nRequired by: {1}": { + "category": "Error", + "code": 100006 + }, + "{0} tried to access '{1}' (a peer dependency) but it isn't provided by its ancestors/your application; this makes the require call ambiguous and unsound.\n\nRequired package: {1}\nRequired by: {2}": { + "category": "Error", + "code": 100007 + }, + "no PnP manifest found": { + "category": "Error", + "code": 100008 + }, + "no package found for path '{0}'": { + "category": "Error", + "code": 100009 + }, + "Empty specifier: '{0}'": { + "category": "Error", + "code": 100010 + }, + "Invalid specifier: '{0}'": { + "category": "Error", + "code": 100011 } } diff --git a/internal/module/resolver.go b/internal/module/resolver.go index 0f31ac568c9..f8c4f95a03f 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -207,7 +207,10 @@ func (r *Resolver) ResolveTypeReferenceDirective( compilerOptions := GetCompilerOptionsWithRedirect(r.compilerOptions, redirectedReference) containingDirectory := tspath.GetDirectoryPath(containingFile) - typeRoots, fromConfig := compilerOptions.GetEffectiveTypeRoots(r.host.GetCurrentDirectory(), r.host.PnpApi()) + typeRoots, fromConfig := compilerOptions.GetEffectiveTypeRoots(r.host.GetCurrentDirectory()) + if pnpApi := r.host.PnpApi(); pnpApi != nil { + typeRoots, fromConfig = pnpApi.AppendPnpTypeRoots(typeRoots, r.host.GetCurrentDirectory(), compilerOptions, fromConfig) + } if traceBuilder != nil { traceBuilder.write(diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2.Format(typeReferenceDirectiveName, containingFile, strings.Join(typeRoots, ","))) traceBuilder.traceResolutionUsingProjectReference(redirectedReference) @@ -983,8 +986,13 @@ func (r *resolutionState) loadModuleFromPnpResolution(ext extensions, moduleName if pnpApi != nil { packageName, rest := ParsePackageName(moduleName) - // TODO: bubble up yarn resolution errors, instead of _ - packageDirectory, _ := pnpApi.ResolveToUnqualified(packageName, issuer) + packageDirectory, err := pnpApi.ResolveToUnqualified(packageName, issuer) + if err != nil { + if r.tracer != nil { + r.tracer.write(err.Error()) + } + return nil + } if packageDirectory != "" { candidate := tspath.NormalizePath(tspath.CombinePaths(packageDirectory, rest)) return r.loadModuleFromSpecificNodeModulesDirectoryImpl(ext, true /* nodeModulesDirectoryExists */, candidate, rest, packageDirectory) @@ -1790,7 +1798,14 @@ func (r *resolutionState) readPackageJsonPeerDependencies(packageJsonInfo *packa var peerDependencyPath string if pnpApi != nil { - peerDependencyPath, _ = pnpApi.ResolveToUnqualified(name, packageDirectory) + var err error + peerDependencyPath, err = pnpApi.ResolveToUnqualified(name, packageDirectory) + if err != nil { + if r.tracer != nil { + r.tracer.write(err.Error()) + } + continue + } } if peerDependencyPath == "" { @@ -2040,7 +2055,10 @@ func GetAutomaticTypeDirectiveNames(options *core.CompilerOptions, host Resoluti } var result []string - typeRoots, _ := options.GetEffectiveTypeRoots(host.GetCurrentDirectory(), host.PnpApi()) + typeRoots, fromConfig := options.GetEffectiveTypeRoots(host.GetCurrentDirectory()) + if pnpApi := host.PnpApi(); pnpApi != nil { + typeRoots, fromConfig = pnpApi.AppendPnpTypeRoots(typeRoots, host.GetCurrentDirectory(), options, fromConfig) + } for _, root := range typeRoots { if host.FS().DirectoryExists(root) { for _, typeDirectivePath := range host.FS().GetAccessibleEntries(root).Directories { diff --git a/internal/pnp/manifestparser.go b/internal/pnp/manifestparser.go index 8e75f2edc68..23a7975cd25 100644 --- a/internal/pnp/manifestparser.go +++ b/internal/pnp/manifestparser.go @@ -9,6 +9,7 @@ import ( "github.com/dlclark/regexp2" "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs" ) type LinkType string @@ -74,40 +75,47 @@ type PnpManifestData struct { packageRegistryTrie *PackageRegistryTrie } -func parseManifestFromPath(fs PnpApiFS, manifestDir string) (*PnpManifestData, error) { +func parseManifestFromPath(fs vfs.FS, manifestDir string) (*PnpManifestData, error) { pnpDataString := "" data, ok := fs.ReadFile(tspath.CombinePaths(manifestDir, ".pnp.data.json")) if ok { pnpDataString = data } else { - pnpScriptString, ok := fs.ReadFile(tspath.CombinePaths(manifestDir, ".pnp.cjs")) - if !ok { - return nil, errors.New("failed to read .pnp.cjs file") + dataString, err := extractPnpDataStringFromPath(fs, tspath.CombinePaths(manifestDir, ".pnp.cjs")) + if err != nil { + return nil, err } + pnpDataString = dataString + } - manifestRegex := regexp2.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`, regexp2.None) - matches, err := manifestRegex.FindStringMatch(pnpScriptString) - if err != nil || matches == nil { - return nil, errors.New("We failed to locate the PnP data payload inside its manifest file. Did you manually edit the file?") - } + return parseManifestFromData(pnpDataString, manifestDir) +} - start := matches.Index + matches.Length - var b strings.Builder - b.Grow(len(pnpScriptString)) - for i := start; i < len(pnpScriptString); i++ { - if pnpScriptString[i] == '\'' { - break - } +func extractPnpDataStringFromPath(fs vfs.FS, path string) (string, error) { + pnpScriptString, ok := fs.ReadFile(path) + if !ok { + return "", errors.New("failed to read file: " + path) + } + manifestRegex := regexp2.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`, regexp2.None) + matches, err := manifestRegex.FindStringMatch(pnpScriptString) + if err != nil || matches == nil { + return "", errors.New("we failed to locate the PnP data payload inside its manifest file. Did you manually edit the file?") + } - if pnpScriptString[i] != '\\' { - b.WriteByte(pnpScriptString[i]) - } + start := matches.Index + matches.Length + var b strings.Builder + b.Grow(len(pnpScriptString)) + for i := start; i < len(pnpScriptString); i++ { + if pnpScriptString[i] == '\'' { + break } - pnpDataString = b.String() - } - return parseManifestFromData(pnpDataString, manifestDir) + if pnpScriptString[i] != '\\' { + b.WriteByte(pnpScriptString[i]) + } + } + return b.String(), nil } func parseManifestFromData(pnpDataString string, manifestDir string) (*PnpManifestData, error) { diff --git a/internal/pnp/pnp.go b/internal/pnp/pnp.go index dccf186c226..c1ef2598dde 100644 --- a/internal/pnp/pnp.go +++ b/internal/pnp/pnp.go @@ -1,8 +1,12 @@ package pnp -import "strings" +import ( + "strings" -func InitPnpApi(fs PnpApiFS, filePath string) *PnpApi { + "github.com/microsoft/typescript-go/internal/vfs" +) + +func InitPnpApi(fs vfs.FS, filePath string) *PnpApi { pnpApi := &PnpApi{fs: fs, url: filePath} manifestData, err := pnpApi.findClosestPnpManifest() diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index eb33849b5a6..2950ae84db9 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -8,26 +8,42 @@ package pnp * * The full specification is available at https://yarnpkg.com/advanced/pnp-spec */ - import ( "errors" - "fmt" + "slices" "strings" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/diagnostics" "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs" ) type PnpApi struct { - fs PnpApiFS + fs vfs.FS url string manifest *PnpManifestData } -// FS abstraction used by the PnpApi to access the file system -// We can't use the vfs.FS interface because it creates an import cycle: core -> pnp -> vfs -> core -type PnpApiFS interface { - FileExists(path string) bool - ReadFile(path string) (contents string, ok bool) +func isNodeJSBuiltin(name string) bool { + return core.NodeCoreModules()[name] +} + +func isDependencyTreeRoot(m *PnpManifestData, loc *Locator) bool { + return slices.Contains(m.dependencyTreeRoots, *loc) +} + +func viaSuffix(specifier string, ident string) string { + if ident != specifier { + return ident + " (via \"" + specifier + "\")" + } + return "" +} + +// TODO: implement this from yarn sourcecode +// https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-pnp/sources/loader/makeApi.ts#L458 +func findBrokenPeerDependencies(specifier string, parent *Locator) []Locator { + return []Locator{} } func (p *PnpApi) RefreshManifest() error { @@ -56,13 +72,13 @@ func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (stri ident, modulePath, err := p.ParseBareIdentifier(specifier) if err != nil { // Skipping resolution - return "", nil + return "", err } parentLocator, err := p.FindLocator(parentPath) if err != nil || parentLocator == nil { // Skipping resolution - return "", nil + return "", err } parentPkg := p.GetPackage(parentLocator) @@ -96,20 +112,34 @@ func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (stri } } - // undeclared dependency if referenceOrAlias == nil { - if parentLocator.Name == "" { - return "", fmt.Errorf("Your application tried to access %s, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", ident, ident, parentPath) + if isNodeJSBuiltin(specifier) { + if isDependencyTreeRoot(p.manifest, parentLocator) { + return "", errors.New(diagnostics.Your_application_tried_to_access_0_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_0_isn_t_otherwise_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2.Format(ident, ident, viaSuffix(specifier, ident), parentPath)) + } + return "", errors.New(diagnostics.X_0_tried_to_access_1_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_1_isn_t_otherwise_declared_in_0_s_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_2_Required_by_Colon_3.Format(parentLocator.Name, ident, ident, parentLocator.Name, ident, viaSuffix(specifier, ident), parentPath)) + } + + if isDependencyTreeRoot(p.manifest, parentLocator) { + return "", errors.New(diagnostics.Your_application_tried_to_access_0_but_it_isn_t_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2.Format(ident, ident, viaSuffix(specifier, ident), parentPath)) + } + + brokenAncestors := findBrokenPeerDependencies(specifier, parentLocator) + allBrokenAreRoots := len(brokenAncestors) > 0 + if allBrokenAreRoots { + for _, brokenAncestor := range brokenAncestors { + if !isDependencyTreeRoot(p.manifest, &brokenAncestor) { + allBrokenAreRoots = false + break + } + } } - return "", fmt.Errorf("%s tried to access %s, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", parentLocator.Name, ident, ident, parentPath) - } - // unfulfilled peer dependency - if !referenceOrAlias.IsAlias() && referenceOrAlias.Reference == "" { - if parentLocator.Name == "" { - return "", fmt.Errorf("Your application tried to access %s (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed.\n\nRequired package: %s\nRequired by: %s", ident, ident, parentPath) + if len(brokenAncestors) > 0 && allBrokenAreRoots { + return "", errors.New(diagnostics.Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_satisfy_the_requirement_Use_a_devDependency_if_needed_Required_package_Colon_0_Required_by_Colon_1.Format(ident, ident, parentPath)) + } else { + return "", errors.New(diagnostics.X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2.Format(parentLocator.Name, ident, ident, parentPath)) } - return "", fmt.Errorf("%s tried to access %s (a peer dependency) but it isn't provided by its ancestors/your application; this makes the require call ambiguous and unsound.\n\nRequired package: %s\nRequired by: %s", parentLocator.Name, ident, ident, parentPath) } var dependencyPkg *PackageInfo @@ -132,7 +162,7 @@ func (p *PnpApi) findClosestPnpManifest() (*PnpManifestData, error) { } if tspath.IsDiskPathRoot(directoryPath) { - return nil, errors.New("no PnP manifest found") + return nil, errors.New(diagnostics.X_no_PnP_manifest_found.Format()) } directoryPath = tspath.GetDirectoryPath(directoryPath) @@ -191,7 +221,7 @@ func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { } if bestLocator == nil { - return nil, fmt.Errorf("no package found for path %s", relativePath) + return nil, errors.New(diagnostics.X_no_package_found_for_path_0.Format(relativePath)) } return bestLocator, nil @@ -223,14 +253,14 @@ func (p *PnpApi) ResolveViaFallback(name string) *PackageDependency { func (p *PnpApi) ParseBareIdentifier(specifier string) (ident string, modulePath string, err error) { if len(specifier) == 0 { - return "", "", fmt.Errorf("Empty specifier: %s", specifier) + return "", "", errors.New(diagnostics.Empty_specifier_Colon_0.Format(specifier)) } firstSlash := strings.Index(specifier, "/") if specifier[0] == '@' { if firstSlash == -1 { - return "", "", fmt.Errorf("Invalid specifier: %s", specifier) + return "", "", errors.New(diagnostics.Invalid_specifier_Colon_0.Format(specifier)) } secondSlash := strings.Index(specifier[firstSlash+1:], "/") @@ -326,7 +356,8 @@ func (p *PnpApi) IsInPnpModule(fromFileName string, toFileName string) bool { return fromLocator != nil && toLocator != nil && fromLocator.Name != toLocator.Name } -func (p *PnpApi) AppendPnpTypeRoots(nmTypes []string, baseDir string, nmFromConfig bool) ([]string, bool) { +func (p *PnpApi) AppendPnpTypeRoots(nmTypes []string, currentDirectory string, compilerOptions *core.CompilerOptions, nmFromConfig bool) ([]string, bool) { + baseDir := compilerOptions.GetBaseDirFromOptions(currentDirectory) pnpTypes := p.GetPnpTypeRoots(baseDir) if len(nmTypes) > 0 { diff --git a/internal/pnp/pnpapi_test.go b/internal/pnp/pnpapi_test.go new file mode 100644 index 00000000000..22839517f1d --- /dev/null +++ b/internal/pnp/pnpapi_test.go @@ -0,0 +1,152 @@ +package pnp + +import ( + "os" + "path/filepath" + "testing" + + "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" + "github.com/microsoft/typescript-go/internal/repo" + "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs/osvfs" +) + +type TestSuite struct { + Manifest jsontext.Value `json:"manifest"` + Tests []TestCase `json:"tests"` +} + +type TestCase struct { + Imported string `json:"imported"` + Importer string `json:"importer"` + Expected string `json:"expected"` + It string `json:"it"` +} + +func TestLoadPnPManifest(t *testing.T) { + t.Parallel() + cases := []struct { + fileName string + path string + msg string + }{ + {"pnp-yarn-v3.cjs", filepath.Join(repo.TestDataPath, "fixtures", "pnp", "pnp-yarn-v3.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 3"}, + {"pnp-yarn-v4.cjs", filepath.Join(repo.TestDataPath, "fixtures", "pnp", "pnp-yarn-v4.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 4"}, + } + + for _, tc := range cases { + t.Run(tc.path, func(t *testing.T) { + t.Parallel() + + fs := osvfs.FS() + pnpDataString, err := extractPnpDataStringFromPath(fs, tc.path) + if err != nil { + t.Fatalf("failed to parse manifest: %v", err) + } + _, err = parseManifestFromData(pnpDataString, tspath.GetDirectoryPath(tc.path)) + if err != nil { + t.Fatalf("failed to parse manifest: %v", err) + } + }) + } +} + +func TestResolveUnqualified(t *testing.T) { + t.Parallel() + expectationsPath := filepath.Join(repo.TestDataPath, "fixtures", "pnp", "test-expectations.json") + + content, err := os.ReadFile(expectationsPath) + if err != nil { + t.Fatalf("Assertion failed: Expected the expectations to be found: %v", err) + } + + var suites []TestSuite + if err = json.Unmarshal(content, &suites); err != nil { + t.Fatalf("Assertion failed: Expected the expectations to be loaded: %v", err) + } + + for si := range suites { + if si != 0 { + continue + } + testSuite := &suites[si] + + rawManifest := &testSuite.Manifest + manifest, err := parseManifestFromData(rawManifest.String(), "/path/to/project/.pnp.cjs") + if err != nil { + t.Fatalf("failed to init pnp manifest: %v", err) + } + + for _, tc := range testSuite.Tests { + parent := filepath.Join(tc.Importer, "fooo") + pnpApi := &PnpApi{fs: osvfs.FS(), url: "/path/to/project/.pnp.cjs", manifest: manifest} + + t.Run(tc.It, func(t *testing.T) { + t.Parallel() + res, unqualifiedErr := pnpApi.ResolveToUnqualified(tc.Imported, parent) + + switch { + case unqualifiedErr == nil && res != "": + if res != tc.Expected { + t.Fatalf("'%s': expected resolved path %q, got %q", tc.It, tc.Expected, res) + } + } + }) + } + } +} + +func TestParseSinglePackageName(t *testing.T) { + t.Parallel() + pnpApi := &PnpApi{} + name, _, err := pnpApi.ParseBareIdentifier("pkg") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if name != "pkg" { + t.Fatalf("expected name %q, got %q", "pkg", name) + } +} + +func TestParseScopedPackageName(t *testing.T) { + t.Parallel() + pnpApi := &PnpApi{} + name, _, err := pnpApi.ParseBareIdentifier("@scope/pkg") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if name != "@scope/pkg" { + t.Fatalf("expected name %q, got %q", "@scope/pkg", name) + } +} + +func TestParsePackageNameWithLongSubpath(t *testing.T) { + t.Parallel() + pnpApi := &PnpApi{} + name, modulePath, err := pnpApi.ParseBareIdentifier("pkg/a/b/c/index.js") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if name != "pkg" { + t.Fatalf("expected name %q, got %q", "pkg", name) + } + if modulePath != "/a/b/c/index.js" { + t.Fatalf("expected modulePath=%q, got %q", "a/b/c/index.js", modulePath) + } +} + +func TestParseScopedPackageWithLongSubpath(t *testing.T) { + t.Parallel() + pnpApi := &PnpApi{} + name, modulePath, err := pnpApi.ParseBareIdentifier("@scope/pkg/a/b/c/index.js") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if name != "@scope/pkg" { + t.Fatalf("expected name %q, got %q", "@scope/pkg", name) + } + if modulePath != "/a/b/c/index.js" { + t.Fatalf("expected modulePath=%q, got %q", "a/b/c/index.js", modulePath) + } +} diff --git a/testdata/fixtures/pnp/pnp-yarn-v3.cjs b/testdata/fixtures/pnp/pnp-yarn-v3.cjs new file mode 100644 index 00000000000..0e6fd459fb1 --- /dev/null +++ b/testdata/fixtures/pnp/pnp-yarn-v3.cjs @@ -0,0 +1,10815 @@ +#!/usr/bin/env node +/* eslint-disable */ +"use strict"; + +function $$SETUP_STATE(hydrateRuntimeState, basePath) { + return hydrateRuntimeState(JSON.parse('{\ + "__info": [\ + "This file is automatically generated. Do not touch it, or risk",\ + "your modifications being lost. We also recommend you not to read",\ + "it either without using the @yarnpkg/pnp package, as the data layout",\ + "is entirely unspecified and WILL change from a version to another."\ + ],\ + "dependencyTreeRoots": [\ + {\ + "name": "tmp.trDEa5gPrG",\ + "reference": "workspace:."\ + }\ + ],\ + "enableTopLevelFallback": true,\ + "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ + "fallbackExclusionList": [\ + ["tmp.trDEa5gPrG", ["workspace:."]]\ + ],\ + "fallbackPool": [\ + ],\ + "packageRegistryData": [\ + [null, [\ + [null, {\ + "packageLocation": "./",\ + "packageDependencies": [\ + ],\ + "linkType": "SOFT"\ + }]\ + ]],\ + ["tmp.trDEa5gPrG", [\ + ["workspace:.", {\ + "packageLocation": "./",\ + "packageDependencies": [\ + ["tmp.trDEa5gPrG", "workspace:."]\ + ],\ + "linkType": "SOFT"\ + }]\ + ]]\ + ]\ + }'), {basePath: basePath || __dirname}); + } + +const fs = require('fs'); +const path = require('path'); +const require$$0 = require('module'); +const StringDecoder = require('string_decoder'); +const url = require('url'); +const os = require('os'); +const nodeUtils = require('util'); +const readline = require('readline'); +const assert = require('assert'); +const stream = require('stream'); +const zlib = require('zlib'); +const events = require('events'); + +const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e }; + +function _interopNamespace(e) { + if (e && e.__esModule) return e; + const n = Object.create(null); + if (e) { + for (const k in e) { + if (k !== 'default') { + const d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: () => e[k] + }); + } + } + } + n.default = e; + return Object.freeze(n); +} + +const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); +const path__default = /*#__PURE__*/_interopDefaultLegacy(path); +const require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); +const StringDecoder__default = /*#__PURE__*/_interopDefaultLegacy(StringDecoder); +const nodeUtils__namespace = /*#__PURE__*/_interopNamespace(nodeUtils); +const assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); +const zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib); + +const S_IFMT = 61440; +const S_IFDIR = 16384; +const S_IFREG = 32768; +const S_IFLNK = 40960; +const SAFE_TIME = 456789e3; + +const DEFAULT_MODE = S_IFREG | 420; +class StatEntry { + constructor() { + this.uid = 0; + this.gid = 0; + this.size = 0; + this.blksize = 0; + this.atimeMs = 0; + this.mtimeMs = 0; + this.ctimeMs = 0; + this.birthtimeMs = 0; + this.atime = new Date(0); + this.mtime = new Date(0); + this.ctime = new Date(0); + this.birthtime = new Date(0); + this.dev = 0; + this.ino = 0; + this.mode = DEFAULT_MODE; + this.nlink = 1; + this.rdev = 0; + this.blocks = 1; + } + isBlockDevice() { + return false; + } + isCharacterDevice() { + return false; + } + isDirectory() { + return (this.mode & S_IFMT) === S_IFDIR; + } + isFIFO() { + return false; + } + isFile() { + return (this.mode & S_IFMT) === S_IFREG; + } + isSocket() { + return false; + } + isSymbolicLink() { + return (this.mode & S_IFMT) === S_IFLNK; + } +} +class BigIntStatsEntry { + constructor() { + this.uid = BigInt(0); + this.gid = BigInt(0); + this.size = BigInt(0); + this.blksize = BigInt(0); + this.atimeMs = BigInt(0); + this.mtimeMs = BigInt(0); + this.ctimeMs = BigInt(0); + this.birthtimeMs = BigInt(0); + this.atimeNs = BigInt(0); + this.mtimeNs = BigInt(0); + this.ctimeNs = BigInt(0); + this.birthtimeNs = BigInt(0); + this.atime = new Date(0); + this.mtime = new Date(0); + this.ctime = new Date(0); + this.birthtime = new Date(0); + this.dev = BigInt(0); + this.ino = BigInt(0); + this.mode = BigInt(DEFAULT_MODE); + this.nlink = BigInt(1); + this.rdev = BigInt(0); + this.blocks = BigInt(1); + } + isBlockDevice() { + return false; + } + isCharacterDevice() { + return false; + } + isDirectory() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFDIR); + } + isFIFO() { + return false; + } + isFile() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFREG); + } + isSocket() { + return false; + } + isSymbolicLink() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFLNK); + } +} +function makeDefaultStats() { + return new StatEntry(); +} +function clearStats(stats) { + for (const key in stats) { + if (Object.prototype.hasOwnProperty.call(stats, key)) { + const element = stats[key]; + if (typeof element === `number`) { + stats[key] = 0; + } else if (typeof element === `bigint`) { + stats[key] = BigInt(0); + } else if (nodeUtils__namespace.types.isDate(element)) { + stats[key] = new Date(0); + } + } + } + return stats; +} +function convertToBigIntStats(stats) { + const bigintStats = new BigIntStatsEntry(); + for (const key in stats) { + if (Object.prototype.hasOwnProperty.call(stats, key)) { + const element = stats[key]; + if (typeof element === `number`) { + bigintStats[key] = BigInt(element); + } else if (nodeUtils__namespace.types.isDate(element)) { + bigintStats[key] = new Date(element); + } + } + } + bigintStats.atimeNs = bigintStats.atimeMs * BigInt(1e6); + bigintStats.mtimeNs = bigintStats.mtimeMs * BigInt(1e6); + bigintStats.ctimeNs = bigintStats.ctimeMs * BigInt(1e6); + bigintStats.birthtimeNs = bigintStats.birthtimeMs * BigInt(1e6); + return bigintStats; +} +function areStatsEqual(a, b) { + if (a.atimeMs !== b.atimeMs) + return false; + if (a.birthtimeMs !== b.birthtimeMs) + return false; + if (a.blksize !== b.blksize) + return false; + if (a.blocks !== b.blocks) + return false; + if (a.ctimeMs !== b.ctimeMs) + return false; + if (a.dev !== b.dev) + return false; + if (a.gid !== b.gid) + return false; + if (a.ino !== b.ino) + return false; + if (a.isBlockDevice() !== b.isBlockDevice()) + return false; + if (a.isCharacterDevice() !== b.isCharacterDevice()) + return false; + if (a.isDirectory() !== b.isDirectory()) + return false; + if (a.isFIFO() !== b.isFIFO()) + return false; + if (a.isFile() !== b.isFile()) + return false; + if (a.isSocket() !== b.isSocket()) + return false; + if (a.isSymbolicLink() !== b.isSymbolicLink()) + return false; + if (a.mode !== b.mode) + return false; + if (a.mtimeMs !== b.mtimeMs) + return false; + if (a.nlink !== b.nlink) + return false; + if (a.rdev !== b.rdev) + return false; + if (a.size !== b.size) + return false; + if (a.uid !== b.uid) + return false; + const aN = a; + const bN = b; + if (aN.atimeNs !== bN.atimeNs) + return false; + if (aN.mtimeNs !== bN.mtimeNs) + return false; + if (aN.ctimeNs !== bN.ctimeNs) + return false; + if (aN.birthtimeNs !== bN.birthtimeNs) + return false; + return true; +} + +const PortablePath = { + root: `/`, + dot: `.`, + parent: `..` +}; +const Filename = { + nodeModules: `node_modules`, + manifest: `package.json`, + lockfile: `yarn.lock`, + virtual: `__virtual__`, + pnpJs: `.pnp.js`, + pnpCjs: `.pnp.cjs`, + rc: `.yarnrc.yml` +}; +const npath = Object.create(path__default.default); +const ppath = Object.create(path__default.default.posix); +npath.cwd = () => process.cwd(); +ppath.cwd = () => toPortablePath(process.cwd()); +ppath.resolve = (...segments) => { + if (segments.length > 0 && ppath.isAbsolute(segments[0])) { + return path__default.default.posix.resolve(...segments); + } else { + return path__default.default.posix.resolve(ppath.cwd(), ...segments); + } +}; +const contains = function(pathUtils, from, to) { + from = pathUtils.normalize(from); + to = pathUtils.normalize(to); + if (from === to) + return `.`; + if (!from.endsWith(pathUtils.sep)) + from = from + pathUtils.sep; + if (to.startsWith(from)) { + return to.slice(from.length); + } else { + return null; + } +}; +npath.fromPortablePath = fromPortablePath; +npath.toPortablePath = toPortablePath; +npath.contains = (from, to) => contains(npath, from, to); +ppath.contains = (from, to) => contains(ppath, from, to); +const WINDOWS_PATH_REGEXP = /^([a-zA-Z]:.*)$/; +const UNC_WINDOWS_PATH_REGEXP = /^\/\/(\.\/)?(.*)$/; +const PORTABLE_PATH_REGEXP = /^\/([a-zA-Z]:.*)$/; +const UNC_PORTABLE_PATH_REGEXP = /^\/unc\/(\.dot\/)?(.*)$/; +function fromPortablePath(p) { + if (process.platform !== `win32`) + return p; + let portablePathMatch, uncPortablePathMatch; + if (portablePathMatch = p.match(PORTABLE_PATH_REGEXP)) + p = portablePathMatch[1]; + else if (uncPortablePathMatch = p.match(UNC_PORTABLE_PATH_REGEXP)) + p = `\\\\${uncPortablePathMatch[1] ? `.\\` : ``}${uncPortablePathMatch[2]}`; + else + return p; + return p.replace(/\//g, `\\`); +} +function toPortablePath(p) { + if (process.platform !== `win32`) + return p; + p = p.replace(/\\/g, `/`); + let windowsPathMatch, uncWindowsPathMatch; + if (windowsPathMatch = p.match(WINDOWS_PATH_REGEXP)) + p = `/${windowsPathMatch[1]}`; + else if (uncWindowsPathMatch = p.match(UNC_WINDOWS_PATH_REGEXP)) + p = `/unc/${uncWindowsPathMatch[1] ? `.dot/` : ``}${uncWindowsPathMatch[2]}`; + return p; +} +function convertPath(targetPathUtils, sourcePath) { + return targetPathUtils === npath ? fromPortablePath(sourcePath) : toPortablePath(sourcePath); +} + +const defaultTime = new Date(SAFE_TIME * 1e3); +async function copyPromise(destinationFs, destination, sourceFs, source, opts) { + const normalizedDestination = destinationFs.pathUtils.normalize(destination); + const normalizedSource = sourceFs.pathUtils.normalize(source); + const prelayout = []; + const postlayout = []; + const { atime, mtime } = opts.stableTime ? { atime: defaultTime, mtime: defaultTime } : await sourceFs.lstatPromise(normalizedSource); + await destinationFs.mkdirpPromise(destinationFs.pathUtils.dirname(destination), { utimes: [atime, mtime] }); + const updateTime = typeof destinationFs.lutimesPromise === `function` ? destinationFs.lutimesPromise.bind(destinationFs) : destinationFs.utimesPromise.bind(destinationFs); + await copyImpl(prelayout, postlayout, updateTime, destinationFs, normalizedDestination, sourceFs, normalizedSource, { ...opts, didParentExist: true }); + for (const operation of prelayout) + await operation(); + await Promise.all(postlayout.map((operation) => { + return operation(); + })); +} +async function copyImpl(prelayout, postlayout, updateTime, destinationFs, destination, sourceFs, source, opts) { + var _a, _b; + const destinationStat = opts.didParentExist ? await maybeLStat(destinationFs, destination) : null; + const sourceStat = await sourceFs.lstatPromise(source); + const { atime, mtime } = opts.stableTime ? { atime: defaultTime, mtime: defaultTime } : sourceStat; + let updated; + switch (true) { + case sourceStat.isDirectory(): + { + updated = await copyFolder(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + case sourceStat.isFile(): + { + updated = await copyFile(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + case sourceStat.isSymbolicLink(): + { + updated = await copySymlink(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + default: + { + throw new Error(`Unsupported file type (${sourceStat.mode})`); + } + } + if (updated || ((_a = destinationStat == null ? void 0 : destinationStat.mtime) == null ? void 0 : _a.getTime()) !== mtime.getTime() || ((_b = destinationStat == null ? void 0 : destinationStat.atime) == null ? void 0 : _b.getTime()) !== atime.getTime()) { + postlayout.push(() => updateTime(destination, atime, mtime)); + updated = true; + } + if (destinationStat === null || (destinationStat.mode & 511) !== (sourceStat.mode & 511)) { + postlayout.push(() => destinationFs.chmodPromise(destination, sourceStat.mode & 511)); + updated = true; + } + return updated; +} +async function maybeLStat(baseFs, p) { + try { + return await baseFs.lstatPromise(p); + } catch (e) { + return null; + } +} +async function copyFolder(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + if (destinationStat !== null && !destinationStat.isDirectory()) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + let updated = false; + if (destinationStat === null) { + prelayout.push(async () => { + try { + await destinationFs.mkdirPromise(destination, { mode: sourceStat.mode }); + } catch (err) { + if (err.code !== `EEXIST`) { + throw err; + } + } + }); + updated = true; + } + const entries = await sourceFs.readdirPromise(source); + const nextOpts = opts.didParentExist && !destinationStat ? { ...opts, didParentExist: false } : opts; + if (opts.stableSort) { + for (const entry of entries.sort()) { + if (await copyImpl(prelayout, postlayout, updateTime, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts)) { + updated = true; + } + } + } else { + const entriesUpdateStatus = await Promise.all(entries.map(async (entry) => { + await copyImpl(prelayout, postlayout, updateTime, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts); + })); + if (entriesUpdateStatus.some((status) => status)) { + updated = true; + } + } + return updated; +} +const isCloneSupportedCache = /* @__PURE__ */ new WeakMap(); +function makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy) { + return async () => { + await opFs.linkPromise(source, destination); + if (linkStrategy === "readOnly" /* ReadOnly */) { + sourceStat.mode &= ~146; + await opFs.chmodPromise(destination, sourceStat.mode); + } + }; +} +function makeCloneLinkOperation(opFs, destination, source, sourceStat, linkStrategy) { + const isCloneSupported = isCloneSupportedCache.get(opFs); + if (typeof isCloneSupported === `undefined`) { + return async () => { + try { + await opFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE_FORCE); + isCloneSupportedCache.set(opFs, true); + } catch (err) { + if (err.code === `ENOSYS` || err.code === `ENOTSUP`) { + isCloneSupportedCache.set(opFs, false); + await makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy)(); + } else { + throw err; + } + } + }; + } else { + if (isCloneSupported) { + return async () => opFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE_FORCE); + } else { + return makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy); + } + } +} +async function copyFile(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + var _a; + if (destinationStat !== null) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + const linkStrategy = (_a = opts.linkStrategy) != null ? _a : null; + const op = destinationFs === sourceFs ? linkStrategy !== null ? makeCloneLinkOperation(destinationFs, destination, source, sourceStat, linkStrategy) : async () => destinationFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE) : linkStrategy !== null ? makeLinkOperation(destinationFs, destination, source, sourceStat, linkStrategy) : async () => destinationFs.writeFilePromise(destination, await sourceFs.readFilePromise(source)); + prelayout.push(async () => op()); + return true; +} +async function copySymlink(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + if (destinationStat !== null) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + prelayout.push(async () => { + await destinationFs.symlinkPromise(convertPath(destinationFs.pathUtils, await sourceFs.readlinkPromise(source)), destination); + }); + return true; +} + +function makeError$1(code, message) { + return Object.assign(new Error(`${code}: ${message}`), { code }); +} +function EBUSY(message) { + return makeError$1(`EBUSY`, message); +} +function ENOSYS(message, reason) { + return makeError$1(`ENOSYS`, `${message}, ${reason}`); +} +function EINVAL(reason) { + return makeError$1(`EINVAL`, `invalid argument, ${reason}`); +} +function EBADF(reason) { + return makeError$1(`EBADF`, `bad file descriptor, ${reason}`); +} +function ENOENT(reason) { + return makeError$1(`ENOENT`, `no such file or directory, ${reason}`); +} +function ENOTDIR(reason) { + return makeError$1(`ENOTDIR`, `not a directory, ${reason}`); +} +function EISDIR(reason) { + return makeError$1(`EISDIR`, `illegal operation on a directory, ${reason}`); +} +function EEXIST(reason) { + return makeError$1(`EEXIST`, `file already exists, ${reason}`); +} +function EROFS(reason) { + return makeError$1(`EROFS`, `read-only filesystem, ${reason}`); +} +function ENOTEMPTY(reason) { + return makeError$1(`ENOTEMPTY`, `directory not empty, ${reason}`); +} +function EOPNOTSUPP(reason) { + return makeError$1(`EOPNOTSUPP`, `operation not supported, ${reason}`); +} +function ERR_DIR_CLOSED() { + return makeError$1(`ERR_DIR_CLOSED`, `Directory handle was closed`); +} +class LibzipError extends Error { + constructor(message, code) { + super(message); + this.name = `Libzip Error`; + this.code = code; + } +} + +class CustomDir { + constructor(path, nextDirent, opts = {}) { + this.path = path; + this.nextDirent = nextDirent; + this.opts = opts; + this.closed = false; + } + throwIfClosed() { + if (this.closed) { + throw ERR_DIR_CLOSED(); + } + } + async *[Symbol.asyncIterator]() { + try { + let dirent; + while ((dirent = await this.read()) !== null) { + yield dirent; + } + } finally { + await this.close(); + } + } + read(cb) { + const dirent = this.readSync(); + if (typeof cb !== `undefined`) + return cb(null, dirent); + return Promise.resolve(dirent); + } + readSync() { + this.throwIfClosed(); + return this.nextDirent(); + } + close(cb) { + this.closeSync(); + if (typeof cb !== `undefined`) + return cb(null); + return Promise.resolve(); + } + closeSync() { + var _a, _b; + this.throwIfClosed(); + (_b = (_a = this.opts).onClose) == null ? void 0 : _b.call(_a); + this.closed = true; + } +} +function opendir(fakeFs, path, entries, opts) { + const nextDirent = () => { + const filename = entries.shift(); + if (typeof filename === `undefined`) + return null; + return Object.assign(fakeFs.statSync(fakeFs.pathUtils.join(path, filename)), { + name: filename + }); + }; + return new CustomDir(path, nextDirent, opts); +} + +class FakeFS { + constructor(pathUtils) { + this.pathUtils = pathUtils; + } + async *genTraversePromise(init, { stableSort = false } = {}) { + const stack = [init]; + while (stack.length > 0) { + const p = stack.shift(); + const entry = await this.lstatPromise(p); + if (entry.isDirectory()) { + const entries = await this.readdirPromise(p); + if (stableSort) { + for (const entry2 of entries.sort()) { + stack.push(this.pathUtils.join(p, entry2)); + } + } else { + throw new Error(`Not supported`); + } + } else { + yield p; + } + } + } + async removePromise(p, { recursive = true, maxRetries = 5 } = {}) { + let stat; + try { + stat = await this.lstatPromise(p); + } catch (error) { + if (error.code === `ENOENT`) { + return; + } else { + throw error; + } + } + if (stat.isDirectory()) { + if (recursive) { + const entries = await this.readdirPromise(p); + await Promise.all(entries.map((entry) => { + return this.removePromise(this.pathUtils.resolve(p, entry)); + })); + } + for (let t = 0; t <= maxRetries; t++) { + try { + await this.rmdirPromise(p); + break; + } catch (error) { + if (error.code !== `EBUSY` && error.code !== `ENOTEMPTY`) { + throw error; + } else if (t < maxRetries) { + await new Promise((resolve) => setTimeout(resolve, t * 100)); + } + } + } + } else { + await this.unlinkPromise(p); + } + } + removeSync(p, { recursive = true } = {}) { + let stat; + try { + stat = this.lstatSync(p); + } catch (error) { + if (error.code === `ENOENT`) { + return; + } else { + throw error; + } + } + if (stat.isDirectory()) { + if (recursive) + for (const entry of this.readdirSync(p)) + this.removeSync(this.pathUtils.resolve(p, entry)); + this.rmdirSync(p); + } else { + this.unlinkSync(p); + } + } + async mkdirpPromise(p, { chmod, utimes } = {}) { + p = this.resolve(p); + if (p === this.pathUtils.dirname(p)) + return void 0; + const parts = p.split(this.pathUtils.sep); + let createdDirectory; + for (let u = 2; u <= parts.length; ++u) { + const subPath = parts.slice(0, u).join(this.pathUtils.sep); + if (!this.existsSync(subPath)) { + try { + await this.mkdirPromise(subPath); + } catch (error) { + if (error.code === `EEXIST`) { + continue; + } else { + throw error; + } + } + createdDirectory != null ? createdDirectory : createdDirectory = subPath; + if (chmod != null) + await this.chmodPromise(subPath, chmod); + if (utimes != null) { + await this.utimesPromise(subPath, utimes[0], utimes[1]); + } else { + const parentStat = await this.statPromise(this.pathUtils.dirname(subPath)); + await this.utimesPromise(subPath, parentStat.atime, parentStat.mtime); + } + } + } + return createdDirectory; + } + mkdirpSync(p, { chmod, utimes } = {}) { + p = this.resolve(p); + if (p === this.pathUtils.dirname(p)) + return void 0; + const parts = p.split(this.pathUtils.sep); + let createdDirectory; + for (let u = 2; u <= parts.length; ++u) { + const subPath = parts.slice(0, u).join(this.pathUtils.sep); + if (!this.existsSync(subPath)) { + try { + this.mkdirSync(subPath); + } catch (error) { + if (error.code === `EEXIST`) { + continue; + } else { + throw error; + } + } + createdDirectory != null ? createdDirectory : createdDirectory = subPath; + if (chmod != null) + this.chmodSync(subPath, chmod); + if (utimes != null) { + this.utimesSync(subPath, utimes[0], utimes[1]); + } else { + const parentStat = this.statSync(this.pathUtils.dirname(subPath)); + this.utimesSync(subPath, parentStat.atime, parentStat.mtime); + } + } + } + return createdDirectory; + } + async copyPromise(destination, source, { baseFs = this, overwrite = true, stableSort = false, stableTime = false, linkStrategy = null } = {}) { + return await copyPromise(this, destination, baseFs, source, { overwrite, stableSort, stableTime, linkStrategy }); + } + copySync(destination, source, { baseFs = this, overwrite = true } = {}) { + const stat = baseFs.lstatSync(source); + const exists = this.existsSync(destination); + if (stat.isDirectory()) { + this.mkdirpSync(destination); + const directoryListing = baseFs.readdirSync(source); + for (const entry of directoryListing) { + this.copySync(this.pathUtils.join(destination, entry), baseFs.pathUtils.join(source, entry), { baseFs, overwrite }); + } + } else if (stat.isFile()) { + if (!exists || overwrite) { + if (exists) + this.removeSync(destination); + const content = baseFs.readFileSync(source); + this.writeFileSync(destination, content); + } + } else if (stat.isSymbolicLink()) { + if (!exists || overwrite) { + if (exists) + this.removeSync(destination); + const target = baseFs.readlinkSync(source); + this.symlinkSync(convertPath(this.pathUtils, target), destination); + } + } else { + throw new Error(`Unsupported file type (file: ${source}, mode: 0o${stat.mode.toString(8).padStart(6, `0`)})`); + } + const mode = stat.mode & 511; + this.chmodSync(destination, mode); + } + async changeFilePromise(p, content, opts = {}) { + if (Buffer.isBuffer(content)) { + return this.changeFileBufferPromise(p, content, opts); + } else { + return this.changeFileTextPromise(p, content, opts); + } + } + async changeFileBufferPromise(p, content, { mode } = {}) { + let current = Buffer.alloc(0); + try { + current = await this.readFilePromise(p); + } catch (error) { + } + if (Buffer.compare(current, content) === 0) + return; + await this.writeFilePromise(p, content, { mode }); + } + async changeFileTextPromise(p, content, { automaticNewlines, mode } = {}) { + let current = ``; + try { + current = await this.readFilePromise(p, `utf8`); + } catch (error) { + } + const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; + if (current === normalizedContent) + return; + await this.writeFilePromise(p, normalizedContent, { mode }); + } + changeFileSync(p, content, opts = {}) { + if (Buffer.isBuffer(content)) { + return this.changeFileBufferSync(p, content, opts); + } else { + return this.changeFileTextSync(p, content, opts); + } + } + changeFileBufferSync(p, content, { mode } = {}) { + let current = Buffer.alloc(0); + try { + current = this.readFileSync(p); + } catch (error) { + } + if (Buffer.compare(current, content) === 0) + return; + this.writeFileSync(p, content, { mode }); + } + changeFileTextSync(p, content, { automaticNewlines = false, mode } = {}) { + let current = ``; + try { + current = this.readFileSync(p, `utf8`); + } catch (error) { + } + const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; + if (current === normalizedContent) + return; + this.writeFileSync(p, normalizedContent, { mode }); + } + async movePromise(fromP, toP) { + try { + await this.renamePromise(fromP, toP); + } catch (error) { + if (error.code === `EXDEV`) { + await this.copyPromise(toP, fromP); + await this.removePromise(fromP); + } else { + throw error; + } + } + } + moveSync(fromP, toP) { + try { + this.renameSync(fromP, toP); + } catch (error) { + if (error.code === `EXDEV`) { + this.copySync(toP, fromP); + this.removeSync(fromP); + } else { + throw error; + } + } + } + async lockPromise(affectedPath, callback) { + const lockPath = `${affectedPath}.flock`; + const interval = 1e3 / 60; + const startTime = Date.now(); + let fd = null; + const isAlive = async () => { + let pid; + try { + [pid] = await this.readJsonPromise(lockPath); + } catch (error) { + return Date.now() - startTime < 500; + } + try { + process.kill(pid, 0); + return true; + } catch (error) { + return false; + } + }; + while (fd === null) { + try { + fd = await this.openPromise(lockPath, `wx`); + } catch (error) { + if (error.code === `EEXIST`) { + if (!await isAlive()) { + try { + await this.unlinkPromise(lockPath); + continue; + } catch (error2) { + } + } + if (Date.now() - startTime < 60 * 1e3) { + await new Promise((resolve) => setTimeout(resolve, interval)); + } else { + throw new Error(`Couldn't acquire a lock in a reasonable time (via ${lockPath})`); + } + } else { + throw error; + } + } + } + await this.writePromise(fd, JSON.stringify([process.pid])); + try { + return await callback(); + } finally { + try { + await this.closePromise(fd); + await this.unlinkPromise(lockPath); + } catch (error) { + } + } + } + async readJsonPromise(p) { + const content = await this.readFilePromise(p, `utf8`); + try { + return JSON.parse(content); + } catch (error) { + error.message += ` (in ${p})`; + throw error; + } + } + readJsonSync(p) { + const content = this.readFileSync(p, `utf8`); + try { + return JSON.parse(content); + } catch (error) { + error.message += ` (in ${p})`; + throw error; + } + } + async writeJsonPromise(p, data) { + return await this.writeFilePromise(p, `${JSON.stringify(data, null, 2)} +`); + } + writeJsonSync(p, data) { + return this.writeFileSync(p, `${JSON.stringify(data, null, 2)} +`); + } + async preserveTimePromise(p, cb) { + const stat = await this.lstatPromise(p); + const result = await cb(); + if (typeof result !== `undefined`) + p = result; + if (this.lutimesPromise) { + await this.lutimesPromise(p, stat.atime, stat.mtime); + } else if (!stat.isSymbolicLink()) { + await this.utimesPromise(p, stat.atime, stat.mtime); + } + } + async preserveTimeSync(p, cb) { + const stat = this.lstatSync(p); + const result = cb(); + if (typeof result !== `undefined`) + p = result; + if (this.lutimesSync) { + this.lutimesSync(p, stat.atime, stat.mtime); + } else if (!stat.isSymbolicLink()) { + this.utimesSync(p, stat.atime, stat.mtime); + } + } +} +class BasePortableFakeFS extends FakeFS { + constructor() { + super(ppath); + } +} +function getEndOfLine(content) { + const matches = content.match(/\r?\n/g); + if (matches === null) + return os.EOL; + const crlf = matches.filter((nl) => nl === `\r +`).length; + const lf = matches.length - crlf; + return crlf > lf ? `\r +` : ` +`; +} +function normalizeLineEndings(originalContent, newContent) { + return newContent.replace(/\r?\n/g, getEndOfLine(originalContent)); +} + +class NodeFS extends BasePortableFakeFS { + constructor(realFs = fs__default.default) { + super(); + this.realFs = realFs; + if (typeof this.realFs.lutimes !== `undefined`) { + this.lutimesPromise = this.lutimesPromiseImpl; + this.lutimesSync = this.lutimesSyncImpl; + } + } + getExtractHint() { + return false; + } + getRealPath() { + return PortablePath.root; + } + resolve(p) { + return ppath.resolve(p); + } + async openPromise(p, flags, mode) { + return await new Promise((resolve, reject) => { + this.realFs.open(npath.fromPortablePath(p), flags, mode, this.makeCallback(resolve, reject)); + }); + } + openSync(p, flags, mode) { + return this.realFs.openSync(npath.fromPortablePath(p), flags, mode); + } + async opendirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (typeof opts !== `undefined`) { + this.realFs.opendir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.opendir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }).then((dir) => { + return Object.defineProperty(dir, `path`, { value: p, configurable: true, writable: true }); + }); + } + opendirSync(p, opts) { + const dir = typeof opts !== `undefined` ? this.realFs.opendirSync(npath.fromPortablePath(p), opts) : this.realFs.opendirSync(npath.fromPortablePath(p)); + return Object.defineProperty(dir, `path`, { value: p, configurable: true, writable: true }); + } + async readPromise(fd, buffer, offset = 0, length = 0, position = -1) { + return await new Promise((resolve, reject) => { + this.realFs.read(fd, buffer, offset, length, position, (error, bytesRead) => { + if (error) { + reject(error); + } else { + resolve(bytesRead); + } + }); + }); + } + readSync(fd, buffer, offset, length, position) { + return this.realFs.readSync(fd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + return await new Promise((resolve, reject) => { + if (typeof buffer === `string`) { + return this.realFs.write(fd, buffer, offset, this.makeCallback(resolve, reject)); + } else { + return this.realFs.write(fd, buffer, offset, length, position, this.makeCallback(resolve, reject)); + } + }); + } + writeSync(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.realFs.writeSync(fd, buffer, offset); + } else { + return this.realFs.writeSync(fd, buffer, offset, length, position); + } + } + async closePromise(fd) { + await new Promise((resolve, reject) => { + this.realFs.close(fd, this.makeCallback(resolve, reject)); + }); + } + closeSync(fd) { + this.realFs.closeSync(fd); + } + createReadStream(p, opts) { + const realPath = p !== null ? npath.fromPortablePath(p) : p; + return this.realFs.createReadStream(realPath, opts); + } + createWriteStream(p, opts) { + const realPath = p !== null ? npath.fromPortablePath(p) : p; + return this.realFs.createWriteStream(realPath, opts); + } + async realpathPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.realpath(npath.fromPortablePath(p), {}, this.makeCallback(resolve, reject)); + }).then((path) => { + return npath.toPortablePath(path); + }); + } + realpathSync(p) { + return npath.toPortablePath(this.realFs.realpathSync(npath.fromPortablePath(p), {})); + } + async existsPromise(p) { + return await new Promise((resolve) => { + this.realFs.exists(npath.fromPortablePath(p), resolve); + }); + } + accessSync(p, mode) { + return this.realFs.accessSync(npath.fromPortablePath(p), mode); + } + async accessPromise(p, mode) { + return await new Promise((resolve, reject) => { + this.realFs.access(npath.fromPortablePath(p), mode, this.makeCallback(resolve, reject)); + }); + } + existsSync(p) { + return this.realFs.existsSync(npath.fromPortablePath(p)); + } + async statPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.stat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.stat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + statSync(p, opts) { + if (opts) { + return this.realFs.statSync(npath.fromPortablePath(p), opts); + } else { + return this.realFs.statSync(npath.fromPortablePath(p)); + } + } + async fstatPromise(fd, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.fstat(fd, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.fstat(fd, this.makeCallback(resolve, reject)); + } + }); + } + fstatSync(fd, opts) { + if (opts) { + return this.realFs.fstatSync(fd, opts); + } else { + return this.realFs.fstatSync(fd); + } + } + async lstatPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.lstat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.lstat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + lstatSync(p, opts) { + if (opts) { + return this.realFs.lstatSync(npath.fromPortablePath(p), opts); + } else { + return this.realFs.lstatSync(npath.fromPortablePath(p)); + } + } + async fchmodPromise(fd, mask) { + return await new Promise((resolve, reject) => { + this.realFs.fchmod(fd, mask, this.makeCallback(resolve, reject)); + }); + } + fchmodSync(fd, mask) { + return this.realFs.fchmodSync(fd, mask); + } + async chmodPromise(p, mask) { + return await new Promise((resolve, reject) => { + this.realFs.chmod(npath.fromPortablePath(p), mask, this.makeCallback(resolve, reject)); + }); + } + chmodSync(p, mask) { + return this.realFs.chmodSync(npath.fromPortablePath(p), mask); + } + async fchownPromise(fd, uid, gid) { + return await new Promise((resolve, reject) => { + this.realFs.fchown(fd, uid, gid, this.makeCallback(resolve, reject)); + }); + } + fchownSync(fd, uid, gid) { + return this.realFs.fchownSync(fd, uid, gid); + } + async chownPromise(p, uid, gid) { + return await new Promise((resolve, reject) => { + this.realFs.chown(npath.fromPortablePath(p), uid, gid, this.makeCallback(resolve, reject)); + }); + } + chownSync(p, uid, gid) { + return this.realFs.chownSync(npath.fromPortablePath(p), uid, gid); + } + async renamePromise(oldP, newP) { + return await new Promise((resolve, reject) => { + this.realFs.rename(npath.fromPortablePath(oldP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); + }); + } + renameSync(oldP, newP) { + return this.realFs.renameSync(npath.fromPortablePath(oldP), npath.fromPortablePath(newP)); + } + async copyFilePromise(sourceP, destP, flags = 0) { + return await new Promise((resolve, reject) => { + this.realFs.copyFile(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags, this.makeCallback(resolve, reject)); + }); + } + copyFileSync(sourceP, destP, flags = 0) { + return this.realFs.copyFileSync(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags); + } + async appendFilePromise(p, content, opts) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.appendFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.appendFile(fsNativePath, content, this.makeCallback(resolve, reject)); + } + }); + } + appendFileSync(p, content, opts) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.appendFileSync(fsNativePath, content, opts); + } else { + this.realFs.appendFileSync(fsNativePath, content); + } + } + async writeFilePromise(p, content, opts) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.writeFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.writeFile(fsNativePath, content, this.makeCallback(resolve, reject)); + } + }); + } + writeFileSync(p, content, opts) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.writeFileSync(fsNativePath, content, opts); + } else { + this.realFs.writeFileSync(fsNativePath, content); + } + } + async unlinkPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.unlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + }); + } + unlinkSync(p) { + return this.realFs.unlinkSync(npath.fromPortablePath(p)); + } + async utimesPromise(p, atime, mtime) { + return await new Promise((resolve, reject) => { + this.realFs.utimes(npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); + }); + } + utimesSync(p, atime, mtime) { + this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); + } + async lutimesPromiseImpl(p, atime, mtime) { + const lutimes = this.realFs.lutimes; + if (typeof lutimes === `undefined`) + throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); + return await new Promise((resolve, reject) => { + lutimes.call(this.realFs, npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); + }); + } + lutimesSyncImpl(p, atime, mtime) { + const lutimesSync = this.realFs.lutimesSync; + if (typeof lutimesSync === `undefined`) + throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); + lutimesSync.call(this.realFs, npath.fromPortablePath(p), atime, mtime); + } + async mkdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + this.realFs.mkdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + }); + } + mkdirSync(p, opts) { + return this.realFs.mkdirSync(npath.fromPortablePath(p), opts); + } + async rmdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.rmdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.rmdir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + rmdirSync(p, opts) { + return this.realFs.rmdirSync(npath.fromPortablePath(p), opts); + } + async linkPromise(existingP, newP) { + return await new Promise((resolve, reject) => { + this.realFs.link(npath.fromPortablePath(existingP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); + }); + } + linkSync(existingP, newP) { + return this.realFs.linkSync(npath.fromPortablePath(existingP), npath.fromPortablePath(newP)); + } + async symlinkPromise(target, p, type) { + return await new Promise((resolve, reject) => { + this.realFs.symlink(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type, this.makeCallback(resolve, reject)); + }); + } + symlinkSync(target, p, type) { + return this.realFs.symlinkSync(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type); + } + async readFilePromise(p, encoding) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + this.realFs.readFile(fsNativePath, encoding, this.makeCallback(resolve, reject)); + }); + } + readFileSync(p, encoding) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + return this.realFs.readFileSync(fsNativePath, encoding); + } + async readdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts == null ? void 0 : opts.withFileTypes) { + this.realFs.readdir(npath.fromPortablePath(p), { withFileTypes: true }, this.makeCallback(resolve, reject)); + } else { + this.realFs.readdir(npath.fromPortablePath(p), this.makeCallback((value) => resolve(value), reject)); + } + }); + } + readdirSync(p, opts) { + if (opts == null ? void 0 : opts.withFileTypes) { + return this.realFs.readdirSync(npath.fromPortablePath(p), { withFileTypes: true }); + } else { + return this.realFs.readdirSync(npath.fromPortablePath(p)); + } + } + async readlinkPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.readlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + }).then((path) => { + return npath.toPortablePath(path); + }); + } + readlinkSync(p) { + return npath.toPortablePath(this.realFs.readlinkSync(npath.fromPortablePath(p))); + } + async truncatePromise(p, len) { + return await new Promise((resolve, reject) => { + this.realFs.truncate(npath.fromPortablePath(p), len, this.makeCallback(resolve, reject)); + }); + } + truncateSync(p, len) { + return this.realFs.truncateSync(npath.fromPortablePath(p), len); + } + async ftruncatePromise(fd, len) { + return await new Promise((resolve, reject) => { + this.realFs.ftruncate(fd, len, this.makeCallback(resolve, reject)); + }); + } + ftruncateSync(fd, len) { + return this.realFs.ftruncateSync(fd, len); + } + watch(p, a, b) { + return this.realFs.watch( + npath.fromPortablePath(p), + a, + b + ); + } + watchFile(p, a, b) { + return this.realFs.watchFile( + npath.fromPortablePath(p), + a, + b + ); + } + unwatchFile(p, cb) { + return this.realFs.unwatchFile(npath.fromPortablePath(p), cb); + } + makeCallback(resolve, reject) { + return (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }; + } +} + +function assertStatus(current, expected) { + if (current !== expected) { + throw new Error(`Invalid StatWatcher status: expected '${expected}', got '${current}'`); + } +} +class CustomStatWatcher extends events.EventEmitter { + constructor(fakeFs, path, { bigint = false } = {}) { + super(); + this.status = "ready" /* Ready */; + this.changeListeners = /* @__PURE__ */ new Map(); + this.startTimeout = null; + this.fakeFs = fakeFs; + this.path = path; + this.bigint = bigint; + this.lastStats = this.stat(); + } + static create(fakeFs, path, opts) { + const statWatcher = new CustomStatWatcher(fakeFs, path, opts); + statWatcher.start(); + return statWatcher; + } + start() { + assertStatus(this.status, "ready" /* Ready */); + this.status = "running" /* Running */; + this.startTimeout = setTimeout(() => { + this.startTimeout = null; + if (!this.fakeFs.existsSync(this.path)) { + this.emit("change" /* Change */, this.lastStats, this.lastStats); + } + }, 3); + } + stop() { + assertStatus(this.status, "running" /* Running */); + this.status = "stopped" /* Stopped */; + if (this.startTimeout !== null) { + clearTimeout(this.startTimeout); + this.startTimeout = null; + } + this.emit("stop" /* Stop */); + } + stat() { + try { + return this.fakeFs.statSync(this.path, { bigint: this.bigint }); + } catch (error) { + const statInstance = this.bigint ? new BigIntStatsEntry() : new StatEntry(); + return clearStats(statInstance); + } + } + makeInterval(opts) { + const interval = setInterval(() => { + const currentStats = this.stat(); + const previousStats = this.lastStats; + if (areStatsEqual(currentStats, previousStats)) + return; + this.lastStats = currentStats; + this.emit("change" /* Change */, currentStats, previousStats); + }, opts.interval); + return opts.persistent ? interval : interval.unref(); + } + registerChangeListener(listener, opts) { + this.addListener("change" /* Change */, listener); + this.changeListeners.set(listener, this.makeInterval(opts)); + } + unregisterChangeListener(listener) { + this.removeListener("change" /* Change */, listener); + const interval = this.changeListeners.get(listener); + if (typeof interval !== `undefined`) + clearInterval(interval); + this.changeListeners.delete(listener); + } + unregisterAllChangeListeners() { + for (const listener of this.changeListeners.keys()) { + this.unregisterChangeListener(listener); + } + } + hasChangeListeners() { + return this.changeListeners.size > 0; + } + ref() { + for (const interval of this.changeListeners.values()) + interval.ref(); + return this; + } + unref() { + for (const interval of this.changeListeners.values()) + interval.unref(); + return this; + } +} + +const statWatchersByFakeFS = /* @__PURE__ */ new WeakMap(); +function watchFile(fakeFs, path, a, b) { + let bigint; + let persistent; + let interval; + let listener; + switch (typeof a) { + case `function`: + { + bigint = false; + persistent = true; + interval = 5007; + listener = a; + } + break; + default: + { + ({ + bigint = false, + persistent = true, + interval = 5007 + } = a); + listener = b; + } + break; + } + let statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + statWatchersByFakeFS.set(fakeFs, statWatchers = /* @__PURE__ */ new Map()); + let statWatcher = statWatchers.get(path); + if (typeof statWatcher === `undefined`) { + statWatcher = CustomStatWatcher.create(fakeFs, path, { bigint }); + statWatchers.set(path, statWatcher); + } + statWatcher.registerChangeListener(listener, { persistent, interval }); + return statWatcher; +} +function unwatchFile(fakeFs, path, cb) { + const statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + return; + const statWatcher = statWatchers.get(path); + if (typeof statWatcher === `undefined`) + return; + if (typeof cb === `undefined`) + statWatcher.unregisterAllChangeListeners(); + else + statWatcher.unregisterChangeListener(cb); + if (!statWatcher.hasChangeListeners()) { + statWatcher.stop(); + statWatchers.delete(path); + } +} +function unwatchAllFiles(fakeFs) { + const statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + return; + for (const path of statWatchers.keys()) { + unwatchFile(fakeFs, path); + } +} + +const DEFAULT_COMPRESSION_LEVEL = `mixed`; +function toUnixTimestamp(time) { + if (typeof time === `string` && String(+time) === time) + return +time; + if (Number.isFinite(time)) { + if (time < 0) { + return Date.now() / 1e3; + } else { + return time; + } + } + if (nodeUtils.types.isDate(time)) + return time.getTime() / 1e3; + throw new Error(`Invalid time`); +} +function makeEmptyArchive() { + return Buffer.from([ + 80, + 75, + 5, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ]); +} +class ZipFS extends BasePortableFakeFS { + constructor(source, opts) { + super(); + this.lzSource = null; + this.listings = /* @__PURE__ */ new Map(); + this.entries = /* @__PURE__ */ new Map(); + this.fileSources = /* @__PURE__ */ new Map(); + this.fds = /* @__PURE__ */ new Map(); + this.nextFd = 0; + this.ready = false; + this.readOnly = false; + this.libzip = opts.libzip; + const pathOptions = opts; + this.level = typeof pathOptions.level !== `undefined` ? pathOptions.level : DEFAULT_COMPRESSION_LEVEL; + source != null ? source : source = makeEmptyArchive(); + if (typeof source === `string`) { + const { baseFs = new NodeFS() } = pathOptions; + this.baseFs = baseFs; + this.path = source; + } else { + this.path = null; + this.baseFs = null; + } + if (opts.stats) { + this.stats = opts.stats; + } else { + if (typeof source === `string`) { + try { + this.stats = this.baseFs.statSync(source); + } catch (error) { + if (error.code === `ENOENT` && pathOptions.create) { + this.stats = makeDefaultStats(); + } else { + throw error; + } + } + } else { + this.stats = makeDefaultStats(); + } + } + const errPtr = this.libzip.malloc(4); + try { + let flags = 0; + if (typeof source === `string` && pathOptions.create) + flags |= this.libzip.ZIP_CREATE | this.libzip.ZIP_TRUNCATE; + if (opts.readOnly) { + flags |= this.libzip.ZIP_RDONLY; + this.readOnly = true; + } + if (typeof source === `string`) { + this.zip = this.libzip.open(npath.fromPortablePath(source), flags, errPtr); + } else { + const lzSource = this.allocateUnattachedSource(source); + try { + this.zip = this.libzip.openFromSource(lzSource, flags, errPtr); + this.lzSource = lzSource; + } catch (error) { + this.libzip.source.free(lzSource); + throw error; + } + } + if (this.zip === 0) { + const error = this.libzip.struct.errorS(); + this.libzip.error.initWithCode(error, this.libzip.getValue(errPtr, `i32`)); + throw this.makeLibzipError(error); + } + } finally { + this.libzip.free(errPtr); + } + this.listings.set(PortablePath.root, /* @__PURE__ */ new Set()); + const entryCount = this.libzip.getNumEntries(this.zip, 0); + for (let t = 0; t < entryCount; ++t) { + const raw = this.libzip.getName(this.zip, t, 0); + if (ppath.isAbsolute(raw)) + continue; + const p = ppath.resolve(PortablePath.root, raw); + this.registerEntry(p, t); + if (raw.endsWith(`/`)) { + this.registerListing(p); + } + } + this.symlinkCount = this.libzip.ext.countSymlinks(this.zip); + if (this.symlinkCount === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.ready = true; + } + makeLibzipError(error) { + const errorCode = this.libzip.struct.errorCodeZip(error); + const strerror = this.libzip.error.strerror(error); + const libzipError = new LibzipError(strerror, this.libzip.errors[errorCode]); + if (errorCode === this.libzip.errors.ZIP_ER_CHANGED) + throw new Error(`Assertion failed: Unexpected libzip error: ${libzipError.message}`); + return libzipError; + } + getExtractHint(hints) { + for (const fileName of this.entries.keys()) { + const ext = this.pathUtils.extname(fileName); + if (hints.relevantExtensions.has(ext)) { + return true; + } + } + return false; + } + getAllFiles() { + return Array.from(this.entries.keys()); + } + getRealPath() { + if (!this.path) + throw new Error(`ZipFS don't have real paths when loaded from a buffer`); + return this.path; + } + getBufferAndClose() { + this.prepareClose(); + if (!this.lzSource) + throw new Error(`ZipFS was not created from a Buffer`); + if (this.entries.size === 0) { + this.discardAndClose(); + return makeEmptyArchive(); + } + try { + this.libzip.source.keep(this.lzSource); + if (this.libzip.close(this.zip) === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + if (this.libzip.source.open(this.lzSource) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_END) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + const size = this.libzip.source.tell(this.lzSource); + if (size === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_SET) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + const buffer = this.libzip.malloc(size); + if (!buffer) + throw new Error(`Couldn't allocate enough memory`); + try { + const rc = this.libzip.source.read(this.lzSource, buffer, size); + if (rc === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + else if (rc < size) + throw new Error(`Incomplete read`); + else if (rc > size) + throw new Error(`Overread`); + const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); + return Buffer.from(memory); + } finally { + this.libzip.free(buffer); + } + } finally { + this.libzip.source.close(this.lzSource); + this.libzip.source.free(this.lzSource); + this.ready = false; + } + } + prepareClose() { + if (!this.ready) + throw EBUSY(`archive closed, close`); + unwatchAllFiles(this); + } + saveAndClose() { + if (!this.path || !this.baseFs) + throw new Error(`ZipFS cannot be saved and must be discarded when loaded from a buffer`); + this.prepareClose(); + if (this.readOnly) { + this.discardAndClose(); + return; + } + const newMode = this.baseFs.existsSync(this.path) || this.stats.mode === DEFAULT_MODE ? void 0 : this.stats.mode; + if (this.entries.size === 0) { + this.discardAndClose(); + this.baseFs.writeFileSync(this.path, makeEmptyArchive(), { mode: newMode }); + } else { + const rc = this.libzip.close(this.zip); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + if (typeof newMode !== `undefined`) { + this.baseFs.chmodSync(this.path, newMode); + } + } + this.ready = false; + } + discardAndClose() { + this.prepareClose(); + this.libzip.discard(this.zip); + this.ready = false; + } + resolve(p) { + return ppath.resolve(PortablePath.root, p); + } + async openPromise(p, flags, mode) { + return this.openSync(p, flags, mode); + } + openSync(p, flags, mode) { + const fd = this.nextFd++; + this.fds.set(fd, { cursor: 0, p }); + return fd; + } + hasOpenFileHandles() { + return !!this.fds.size; + } + async opendirPromise(p, opts) { + return this.opendirSync(p, opts); + } + opendirSync(p, opts = {}) { + const resolvedP = this.resolveFilename(`opendir '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`opendir '${p}'`); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`opendir '${p}'`); + const entries = [...directoryListing]; + const fd = this.openSync(resolvedP, `r`); + const onClose = () => { + this.closeSync(fd); + }; + return opendir(this, resolvedP, entries, { onClose }); + } + async readPromise(fd, buffer, offset, length, position) { + return this.readSync(fd, buffer, offset, length, position); + } + readSync(fd, buffer, offset = 0, length = buffer.byteLength, position = -1) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + const realPosition = position === -1 || position === null ? entry.cursor : position; + const source = this.readFileSync(entry.p); + source.copy(buffer, offset, realPosition, realPosition + length); + const bytesRead = Math.max(0, Math.min(source.length - realPosition, length)); + if (position === -1 || position === null) + entry.cursor += bytesRead; + return bytesRead; + } + async writePromise(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.writeSync(fd, buffer, position); + } else { + return this.writeSync(fd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + throw new Error(`Unimplemented`); + } + async closePromise(fd) { + return this.closeSync(fd); + } + closeSync(fd) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + this.fds.delete(fd); + } + createReadStream(p, { encoding } = {}) { + if (p === null) + throw new Error(`Unimplemented`); + const fd = this.openSync(p, `r`); + const stream$1 = Object.assign( + new stream.PassThrough({ + emitClose: true, + autoDestroy: true, + destroy: (error, callback) => { + clearImmediate(immediate); + this.closeSync(fd); + callback(error); + } + }), + { + close() { + stream$1.destroy(); + }, + bytesRead: 0, + path: p + } + ); + const immediate = setImmediate(async () => { + try { + const data = await this.readFilePromise(p, encoding); + stream$1.bytesRead = data.length; + stream$1.end(data); + } catch (error) { + stream$1.destroy(error); + } + }); + return stream$1; + } + createWriteStream(p, { encoding } = {}) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (p === null) + throw new Error(`Unimplemented`); + const chunks = []; + const fd = this.openSync(p, `w`); + const stream$1 = Object.assign( + new stream.PassThrough({ + autoDestroy: true, + emitClose: true, + destroy: (error, callback) => { + try { + if (error) { + callback(error); + } else { + this.writeFileSync(p, Buffer.concat(chunks), encoding); + callback(null); + } + } catch (err) { + callback(err); + } finally { + this.closeSync(fd); + } + } + }), + { + bytesWritten: 0, + path: p, + close() { + stream$1.destroy(); + } + } + ); + stream$1.on(`data`, (chunk) => { + const chunkBuffer = Buffer.from(chunk); + stream$1.bytesWritten += chunkBuffer.length; + chunks.push(chunkBuffer); + }); + return stream$1; + } + async realpathPromise(p) { + return this.realpathSync(p); + } + realpathSync(p) { + const resolvedP = this.resolveFilename(`lstat '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`lstat '${p}'`); + return resolvedP; + } + async existsPromise(p) { + return this.existsSync(p); + } + existsSync(p) { + if (!this.ready) + throw EBUSY(`archive closed, existsSync '${p}'`); + if (this.symlinkCount === 0) { + const resolvedP2 = ppath.resolve(PortablePath.root, p); + return this.entries.has(resolvedP2) || this.listings.has(resolvedP2); + } + let resolvedP; + try { + resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, false); + } catch (error) { + return false; + } + if (resolvedP === void 0) + return false; + return this.entries.has(resolvedP) || this.listings.has(resolvedP); + } + async accessPromise(p, mode) { + return this.accessSync(p, mode); + } + accessSync(p, mode = fs.constants.F_OK) { + const resolvedP = this.resolveFilename(`access '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`access '${p}'`); + if (this.readOnly && mode & fs.constants.W_OK) { + throw EROFS(`access '${p}'`); + } + } + async statPromise(p, opts = { bigint: false }) { + if (opts.bigint) + return this.statSync(p, { bigint: true }); + return this.statSync(p); + } + statSync(p, opts = { bigint: false, throwIfNoEntry: true }) { + const resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, opts.throwIfNoEntry); + if (resolvedP === void 0) + return void 0; + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { + if (opts.throwIfNoEntry === false) + return void 0; + throw ENOENT(`stat '${p}'`); + } + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`stat '${p}'`); + return this.statImpl(`stat '${p}'`, resolvedP, opts); + } + async fstatPromise(fd, opts) { + return this.fstatSync(fd, opts); + } + fstatSync(fd, opts) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstatSync`); + const { p } = entry; + const resolvedP = this.resolveFilename(`stat '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`stat '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`stat '${p}'`); + return this.statImpl(`fstat '${p}'`, resolvedP, opts); + } + async lstatPromise(p, opts = { bigint: false }) { + if (opts.bigint) + return this.lstatSync(p, { bigint: true }); + return this.lstatSync(p); + } + lstatSync(p, opts = { bigint: false, throwIfNoEntry: true }) { + const resolvedP = this.resolveFilename(`lstat '${p}'`, p, false, opts.throwIfNoEntry); + if (resolvedP === void 0) + return void 0; + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { + if (opts.throwIfNoEntry === false) + return void 0; + throw ENOENT(`lstat '${p}'`); + } + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`lstat '${p}'`); + return this.statImpl(`lstat '${p}'`, resolvedP, opts); + } + statImpl(reason, p, opts = {}) { + const entry = this.entries.get(p); + if (typeof entry !== `undefined`) { + const stat = this.libzip.struct.statS(); + const rc = this.libzip.statIndex(this.zip, entry, 0, 0, stat); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const uid = this.stats.uid; + const gid = this.stats.gid; + const size = this.libzip.struct.statSize(stat) >>> 0; + const blksize = 512; + const blocks = Math.ceil(size / blksize); + const mtimeMs = (this.libzip.struct.statMtime(stat) >>> 0) * 1e3; + const atimeMs = mtimeMs; + const birthtimeMs = mtimeMs; + const ctimeMs = mtimeMs; + const atime = new Date(atimeMs); + const birthtime = new Date(birthtimeMs); + const ctime = new Date(ctimeMs); + const mtime = new Date(mtimeMs); + const type = this.listings.has(p) ? S_IFDIR : this.isSymbolicLink(entry) ? S_IFLNK : S_IFREG; + const defaultMode = type === S_IFDIR ? 493 : 420; + const mode = type | this.getUnixMode(entry, defaultMode) & 511; + const crc = this.libzip.struct.statCrc(stat); + const statInstance = Object.assign(new StatEntry(), { uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc }); + return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; + } + if (this.listings.has(p)) { + const uid = this.stats.uid; + const gid = this.stats.gid; + const size = 0; + const blksize = 512; + const blocks = 0; + const atimeMs = this.stats.mtimeMs; + const birthtimeMs = this.stats.mtimeMs; + const ctimeMs = this.stats.mtimeMs; + const mtimeMs = this.stats.mtimeMs; + const atime = new Date(atimeMs); + const birthtime = new Date(birthtimeMs); + const ctime = new Date(ctimeMs); + const mtime = new Date(mtimeMs); + const mode = S_IFDIR | 493; + const crc = 0; + const statInstance = Object.assign(new StatEntry(), { uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc }); + return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; + } + throw new Error(`Unreachable`); + } + getUnixMode(index, defaultMode) { + const rc = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; + if (opsys !== this.libzip.ZIP_OPSYS_UNIX) + return defaultMode; + return this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; + } + registerListing(p) { + const existingListing = this.listings.get(p); + if (existingListing) + return existingListing; + const parentListing = this.registerListing(ppath.dirname(p)); + parentListing.add(ppath.basename(p)); + const newListing = /* @__PURE__ */ new Set(); + this.listings.set(p, newListing); + return newListing; + } + registerEntry(p, index) { + const parentListing = this.registerListing(ppath.dirname(p)); + parentListing.add(ppath.basename(p)); + this.entries.set(p, index); + } + unregisterListing(p) { + this.listings.delete(p); + const parentListing = this.listings.get(ppath.dirname(p)); + parentListing == null ? void 0 : parentListing.delete(ppath.basename(p)); + } + unregisterEntry(p) { + this.unregisterListing(p); + const entry = this.entries.get(p); + this.entries.delete(p); + if (typeof entry === `undefined`) + return; + this.fileSources.delete(entry); + if (this.isSymbolicLink(entry)) { + this.symlinkCount--; + } + } + deleteEntry(p, index) { + this.unregisterEntry(p); + const rc = this.libzip.delete(this.zip, index); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + resolveFilename(reason, p, resolveLastComponent = true, throwIfNoEntry = true) { + if (!this.ready) + throw EBUSY(`archive closed, ${reason}`); + let resolvedP = ppath.resolve(PortablePath.root, p); + if (resolvedP === `/`) + return PortablePath.root; + const fileIndex = this.entries.get(resolvedP); + if (resolveLastComponent && fileIndex !== void 0) { + if (this.symlinkCount !== 0 && this.isSymbolicLink(fileIndex)) { + const target = this.getFileSource(fileIndex).toString(); + return this.resolveFilename(reason, ppath.resolve(ppath.dirname(resolvedP), target), true, throwIfNoEntry); + } else { + return resolvedP; + } + } + while (true) { + const parentP = this.resolveFilename(reason, ppath.dirname(resolvedP), true, throwIfNoEntry); + if (parentP === void 0) + return parentP; + const isDir = this.listings.has(parentP); + const doesExist = this.entries.has(parentP); + if (!isDir && !doesExist) { + if (throwIfNoEntry === false) + return void 0; + throw ENOENT(reason); + } + if (!isDir) + throw ENOTDIR(reason); + resolvedP = ppath.resolve(parentP, ppath.basename(resolvedP)); + if (!resolveLastComponent || this.symlinkCount === 0) + break; + const index = this.libzip.name.locate(this.zip, resolvedP.slice(1)); + if (index === -1) + break; + if (this.isSymbolicLink(index)) { + const target = this.getFileSource(index).toString(); + resolvedP = ppath.resolve(ppath.dirname(resolvedP), target); + } else { + break; + } + } + return resolvedP; + } + allocateBuffer(content) { + if (!Buffer.isBuffer(content)) + content = Buffer.from(content); + const buffer = this.libzip.malloc(content.byteLength); + if (!buffer) + throw new Error(`Couldn't allocate enough memory`); + const heap = new Uint8Array(this.libzip.HEAPU8.buffer, buffer, content.byteLength); + heap.set(content); + return { buffer, byteLength: content.byteLength }; + } + allocateUnattachedSource(content) { + const error = this.libzip.struct.errorS(); + const { buffer, byteLength } = this.allocateBuffer(content); + const source = this.libzip.source.fromUnattachedBuffer(buffer, byteLength, 0, true, error); + if (source === 0) { + this.libzip.free(error); + throw this.makeLibzipError(error); + } + return source; + } + allocateSource(content) { + const { buffer, byteLength } = this.allocateBuffer(content); + const source = this.libzip.source.fromBuffer(this.zip, buffer, byteLength, 0, true); + if (source === 0) { + this.libzip.free(buffer); + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + return source; + } + setFileSource(p, content) { + const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content); + const target = ppath.relative(PortablePath.root, p); + const lzSource = this.allocateSource(content); + try { + const newIndex = this.libzip.file.add(this.zip, target, lzSource, this.libzip.ZIP_FL_OVERWRITE); + if (newIndex === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + if (this.level !== `mixed`) { + const method = this.level === 0 ? this.libzip.ZIP_CM_STORE : this.libzip.ZIP_CM_DEFLATE; + const rc = this.libzip.file.setCompression(this.zip, newIndex, 0, method, this.level); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + this.fileSources.set(newIndex, buffer); + return newIndex; + } catch (error) { + this.libzip.source.free(lzSource); + throw error; + } + } + isSymbolicLink(index) { + if (this.symlinkCount === 0) + return false; + const attrs = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); + if (attrs === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; + if (opsys !== this.libzip.ZIP_OPSYS_UNIX) + return false; + const attributes = this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; + return (attributes & S_IFMT) === S_IFLNK; + } + getFileSource(index, opts = { asyncDecompress: false }) { + const cachedFileSource = this.fileSources.get(index); + if (typeof cachedFileSource !== `undefined`) + return cachedFileSource; + const stat = this.libzip.struct.statS(); + const rc = this.libzip.statIndex(this.zip, index, 0, 0, stat); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const size = this.libzip.struct.statCompSize(stat); + const compressionMethod = this.libzip.struct.statCompMethod(stat); + const buffer = this.libzip.malloc(size); + try { + const file = this.libzip.fopenIndex(this.zip, index, 0, this.libzip.ZIP_FL_COMPRESSED); + if (file === 0) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + try { + const rc2 = this.libzip.fread(file, buffer, size, 0); + if (rc2 === -1) + throw this.makeLibzipError(this.libzip.file.getError(file)); + else if (rc2 < size) + throw new Error(`Incomplete read`); + else if (rc2 > size) + throw new Error(`Overread`); + const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); + const data = Buffer.from(memory); + if (compressionMethod === 0) { + this.fileSources.set(index, data); + return data; + } else if (opts.asyncDecompress) { + return new Promise((resolve, reject) => { + zlib__default.default.inflateRaw(data, (error, result) => { + if (error) { + reject(error); + } else { + this.fileSources.set(index, result); + resolve(result); + } + }); + }); + } else { + const decompressedData = zlib__default.default.inflateRawSync(data); + this.fileSources.set(index, decompressedData); + return decompressedData; + } + } finally { + this.libzip.fclose(file); + } + } finally { + this.libzip.free(buffer); + } + } + async fchmodPromise(fd, mask) { + return this.chmodPromise(this.fdToPath(fd, `fchmod`), mask); + } + fchmodSync(fd, mask) { + return this.chmodSync(this.fdToPath(fd, `fchmodSync`), mask); + } + async chmodPromise(p, mask) { + return this.chmodSync(p, mask); + } + chmodSync(p, mask) { + if (this.readOnly) + throw EROFS(`chmod '${p}'`); + mask &= 493; + const resolvedP = this.resolveFilename(`chmod '${p}'`, p, false); + const entry = this.entries.get(resolvedP); + if (typeof entry === `undefined`) + throw new Error(`Assertion failed: The entry should have been registered (${resolvedP})`); + const oldMod = this.getUnixMode(entry, S_IFREG | 0); + const newMod = oldMod & ~511 | mask; + const rc = this.libzip.file.setExternalAttributes(this.zip, entry, 0, 0, this.libzip.ZIP_OPSYS_UNIX, newMod << 16); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + async fchownPromise(fd, uid, gid) { + return this.chownPromise(this.fdToPath(fd, `fchown`), uid, gid); + } + fchownSync(fd, uid, gid) { + return this.chownSync(this.fdToPath(fd, `fchownSync`), uid, gid); + } + async chownPromise(p, uid, gid) { + return this.chownSync(p, uid, gid); + } + chownSync(p, uid, gid) { + throw new Error(`Unimplemented`); + } + async renamePromise(oldP, newP) { + return this.renameSync(oldP, newP); + } + renameSync(oldP, newP) { + throw new Error(`Unimplemented`); + } + async copyFilePromise(sourceP, destP, flags) { + const { indexSource, indexDest, resolvedDestP } = this.prepareCopyFile(sourceP, destP, flags); + const source = await this.getFileSource(indexSource, { asyncDecompress: true }); + const newIndex = this.setFileSource(resolvedDestP, source); + if (newIndex !== indexDest) { + this.registerEntry(resolvedDestP, newIndex); + } + } + copyFileSync(sourceP, destP, flags = 0) { + const { indexSource, indexDest, resolvedDestP } = this.prepareCopyFile(sourceP, destP, flags); + const source = this.getFileSource(indexSource); + const newIndex = this.setFileSource(resolvedDestP, source); + if (newIndex !== indexDest) { + this.registerEntry(resolvedDestP, newIndex); + } + } + prepareCopyFile(sourceP, destP, flags = 0) { + if (this.readOnly) + throw EROFS(`copyfile '${sourceP} -> '${destP}'`); + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw ENOSYS(`unsupported clone operation`, `copyfile '${sourceP}' -> ${destP}'`); + const resolvedSourceP = this.resolveFilename(`copyfile '${sourceP} -> ${destP}'`, sourceP); + const indexSource = this.entries.get(resolvedSourceP); + if (typeof indexSource === `undefined`) + throw EINVAL(`copyfile '${sourceP}' -> '${destP}'`); + const resolvedDestP = this.resolveFilename(`copyfile '${sourceP}' -> ${destP}'`, destP); + const indexDest = this.entries.get(resolvedDestP); + if ((flags & (fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE_FORCE)) !== 0 && typeof indexDest !== `undefined`) + throw EEXIST(`copyfile '${sourceP}' -> '${destP}'`); + return { + indexSource, + resolvedDestP, + indexDest + }; + } + async appendFilePromise(p, content, opts) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (typeof opts === `undefined`) + opts = { flag: `a` }; + else if (typeof opts === `string`) + opts = { flag: `a`, encoding: opts }; + else if (typeof opts.flag === `undefined`) + opts = { flag: `a`, ...opts }; + return this.writeFilePromise(p, content, opts); + } + appendFileSync(p, content, opts = {}) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (typeof opts === `undefined`) + opts = { flag: `a` }; + else if (typeof opts === `string`) + opts = { flag: `a`, encoding: opts }; + else if (typeof opts.flag === `undefined`) + opts = { flag: `a`, ...opts }; + return this.writeFileSync(p, content, opts); + } + fdToPath(fd, reason) { + var _a; + const path = (_a = this.fds.get(fd)) == null ? void 0 : _a.p; + if (typeof path === `undefined`) + throw EBADF(reason); + return path; + } + async writeFilePromise(p, content, opts) { + const { encoding, mode, index, resolvedP } = this.prepareWriteFile(p, opts); + if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) + content = Buffer.concat([await this.getFileSource(index, { asyncDecompress: true }), Buffer.from(content)]); + if (encoding !== null) + content = content.toString(encoding); + const newIndex = this.setFileSource(resolvedP, content); + if (newIndex !== index) + this.registerEntry(resolvedP, newIndex); + if (mode !== null) { + await this.chmodPromise(resolvedP, mode); + } + } + writeFileSync(p, content, opts) { + const { encoding, mode, index, resolvedP } = this.prepareWriteFile(p, opts); + if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) + content = Buffer.concat([this.getFileSource(index), Buffer.from(content)]); + if (encoding !== null) + content = content.toString(encoding); + const newIndex = this.setFileSource(resolvedP, content); + if (newIndex !== index) + this.registerEntry(resolvedP, newIndex); + if (mode !== null) { + this.chmodSync(resolvedP, mode); + } + } + prepareWriteFile(p, opts) { + if (typeof p === `number`) + p = this.fdToPath(p, `read`); + if (this.readOnly) + throw EROFS(`open '${p}'`); + const resolvedP = this.resolveFilename(`open '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`open '${p}'`); + let encoding = null, mode = null; + if (typeof opts === `string`) { + encoding = opts; + } else if (typeof opts === `object`) { + ({ + encoding = null, + mode = null + } = opts); + } + const index = this.entries.get(resolvedP); + return { + encoding, + mode, + resolvedP, + index + }; + } + async unlinkPromise(p) { + return this.unlinkSync(p); + } + unlinkSync(p) { + if (this.readOnly) + throw EROFS(`unlink '${p}'`); + const resolvedP = this.resolveFilename(`unlink '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`unlink '${p}'`); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`unlink '${p}'`); + this.deleteEntry(resolvedP, index); + } + async utimesPromise(p, atime, mtime) { + return this.utimesSync(p, atime, mtime); + } + utimesSync(p, atime, mtime) { + if (this.readOnly) + throw EROFS(`utimes '${p}'`); + const resolvedP = this.resolveFilename(`utimes '${p}'`, p); + this.utimesImpl(resolvedP, mtime); + } + async lutimesPromise(p, atime, mtime) { + return this.lutimesSync(p, atime, mtime); + } + lutimesSync(p, atime, mtime) { + if (this.readOnly) + throw EROFS(`lutimes '${p}'`); + const resolvedP = this.resolveFilename(`utimes '${p}'`, p, false); + this.utimesImpl(resolvedP, mtime); + } + utimesImpl(resolvedP, mtime) { + if (this.listings.has(resolvedP)) { + if (!this.entries.has(resolvedP)) + this.hydrateDirectory(resolvedP); + } + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + const rc = this.libzip.file.setMtime(this.zip, entry, 0, toUnixTimestamp(mtime), 0); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + async mkdirPromise(p, opts) { + return this.mkdirSync(p, opts); + } + mkdirSync(p, { mode = 493, recursive = false } = {}) { + if (recursive) + return this.mkdirpSync(p, { chmod: mode }); + if (this.readOnly) + throw EROFS(`mkdir '${p}'`); + const resolvedP = this.resolveFilename(`mkdir '${p}'`, p); + if (this.entries.has(resolvedP) || this.listings.has(resolvedP)) + throw EEXIST(`mkdir '${p}'`); + this.hydrateDirectory(resolvedP); + this.chmodSync(resolvedP, mode); + return void 0; + } + async rmdirPromise(p, opts) { + return this.rmdirSync(p, opts); + } + rmdirSync(p, { recursive = false } = {}) { + if (this.readOnly) + throw EROFS(`rmdir '${p}'`); + if (recursive) { + this.removeSync(p); + return; + } + const resolvedP = this.resolveFilename(`rmdir '${p}'`, p); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`rmdir '${p}'`); + if (directoryListing.size > 0) + throw ENOTEMPTY(`rmdir '${p}'`); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`rmdir '${p}'`); + this.deleteEntry(p, index); + } + hydrateDirectory(resolvedP) { + const index = this.libzip.dir.add(this.zip, ppath.relative(PortablePath.root, resolvedP)); + if (index === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.registerListing(resolvedP); + this.registerEntry(resolvedP, index); + return index; + } + async linkPromise(existingP, newP) { + return this.linkSync(existingP, newP); + } + linkSync(existingP, newP) { + throw EOPNOTSUPP(`link '${existingP}' -> '${newP}'`); + } + async symlinkPromise(target, p) { + return this.symlinkSync(target, p); + } + symlinkSync(target, p) { + if (this.readOnly) + throw EROFS(`symlink '${target}' -> '${p}'`); + const resolvedP = this.resolveFilename(`symlink '${target}' -> '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`symlink '${target}' -> '${p}'`); + if (this.entries.has(resolvedP)) + throw EEXIST(`symlink '${target}' -> '${p}'`); + const index = this.setFileSource(resolvedP, target); + this.registerEntry(resolvedP, index); + const rc = this.libzip.file.setExternalAttributes(this.zip, index, 0, 0, this.libzip.ZIP_OPSYS_UNIX, (S_IFLNK | 511) << 16); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.symlinkCount += 1; + } + async readFilePromise(p, encoding) { + if (typeof encoding === `object`) + encoding = encoding ? encoding.encoding : void 0; + const data = await this.readFileBuffer(p, { asyncDecompress: true }); + return encoding ? data.toString(encoding) : data; + } + readFileSync(p, encoding) { + if (typeof encoding === `object`) + encoding = encoding ? encoding.encoding : void 0; + const data = this.readFileBuffer(p); + return encoding ? data.toString(encoding) : data; + } + readFileBuffer(p, opts = { asyncDecompress: false }) { + if (typeof p === `number`) + p = this.fdToPath(p, `read`); + const resolvedP = this.resolveFilename(`open '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`open '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`open '${p}'`); + if (this.listings.has(resolvedP)) + throw EISDIR(`read`); + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + return this.getFileSource(entry, opts); + } + async readdirPromise(p, opts) { + return this.readdirSync(p, opts); + } + readdirSync(p, opts) { + const resolvedP = this.resolveFilename(`scandir '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`scandir '${p}'`); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`scandir '${p}'`); + const entries = [...directoryListing]; + if (!(opts == null ? void 0 : opts.withFileTypes)) + return entries; + return entries.map((name) => { + return Object.assign(this.statImpl(`lstat`, ppath.join(p, name)), { + name + }); + }); + } + async readlinkPromise(p) { + const entry = this.prepareReadlink(p); + return (await this.getFileSource(entry, { asyncDecompress: true })).toString(); + } + readlinkSync(p) { + const entry = this.prepareReadlink(p); + return this.getFileSource(entry).toString(); + } + prepareReadlink(p) { + const resolvedP = this.resolveFilename(`readlink '${p}'`, p, false); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`readlink '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`open '${p}'`); + if (this.listings.has(resolvedP)) + throw EINVAL(`readlink '${p}'`); + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + if (!this.isSymbolicLink(entry)) + throw EINVAL(`readlink '${p}'`); + return entry; + } + async truncatePromise(p, len = 0) { + const resolvedP = this.resolveFilename(`open '${p}'`, p); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`open '${p}'`); + const source = await this.getFileSource(index, { asyncDecompress: true }); + const truncated = Buffer.alloc(len, 0); + source.copy(truncated); + return await this.writeFilePromise(p, truncated); + } + truncateSync(p, len = 0) { + const resolvedP = this.resolveFilename(`open '${p}'`, p); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`open '${p}'`); + const source = this.getFileSource(index); + const truncated = Buffer.alloc(len, 0); + source.copy(truncated); + return this.writeFileSync(p, truncated); + } + async ftruncatePromise(fd, len) { + return this.truncatePromise(this.fdToPath(fd, `ftruncate`), len); + } + ftruncateSync(fd, len) { + return this.truncateSync(this.fdToPath(fd, `ftruncateSync`), len); + } + watch(p, a, b) { + let persistent; + switch (typeof a) { + case `function`: + case `string`: + case `undefined`: + { + persistent = true; + } + break; + default: + { + ({ persistent = true } = a); + } + break; + } + if (!persistent) + return { on: () => { + }, close: () => { + } }; + const interval = setInterval(() => { + }, 24 * 60 * 60 * 1e3); + return { on: () => { + }, close: () => { + clearInterval(interval); + } }; + } + watchFile(p, a, b) { + const resolvedP = ppath.resolve(PortablePath.root, p); + return watchFile(this, resolvedP, a, b); + } + unwatchFile(p, cb) { + const resolvedP = ppath.resolve(PortablePath.root, p); + return unwatchFile(this, resolvedP, cb); + } +} + +class ProxiedFS extends FakeFS { + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + resolve(path) { + return this.mapFromBase(this.baseFs.resolve(this.mapToBase(path))); + } + getRealPath() { + return this.mapFromBase(this.baseFs.getRealPath()); + } + async openPromise(p, flags, mode) { + return this.baseFs.openPromise(this.mapToBase(p), flags, mode); + } + openSync(p, flags, mode) { + return this.baseFs.openSync(this.mapToBase(p), flags, mode); + } + async opendirPromise(p, opts) { + return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(p), opts), { path: p }); + } + opendirSync(p, opts) { + return Object.assign(this.baseFs.opendirSync(this.mapToBase(p), opts), { path: p }); + } + async readPromise(fd, buffer, offset, length, position) { + return await this.baseFs.readPromise(fd, buffer, offset, length, position); + } + readSync(fd, buffer, offset, length, position) { + return this.baseFs.readSync(fd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return await this.baseFs.writePromise(fd, buffer, offset); + } else { + return await this.baseFs.writePromise(fd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.baseFs.writeSync(fd, buffer, offset); + } else { + return this.baseFs.writeSync(fd, buffer, offset, length, position); + } + } + async closePromise(fd) { + return this.baseFs.closePromise(fd); + } + closeSync(fd) { + this.baseFs.closeSync(fd); + } + createReadStream(p, opts) { + return this.baseFs.createReadStream(p !== null ? this.mapToBase(p) : p, opts); + } + createWriteStream(p, opts) { + return this.baseFs.createWriteStream(p !== null ? this.mapToBase(p) : p, opts); + } + async realpathPromise(p) { + return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(p))); + } + realpathSync(p) { + return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(p))); + } + async existsPromise(p) { + return this.baseFs.existsPromise(this.mapToBase(p)); + } + existsSync(p) { + return this.baseFs.existsSync(this.mapToBase(p)); + } + accessSync(p, mode) { + return this.baseFs.accessSync(this.mapToBase(p), mode); + } + async accessPromise(p, mode) { + return this.baseFs.accessPromise(this.mapToBase(p), mode); + } + async statPromise(p, opts) { + return this.baseFs.statPromise(this.mapToBase(p), opts); + } + statSync(p, opts) { + return this.baseFs.statSync(this.mapToBase(p), opts); + } + async fstatPromise(fd, opts) { + return this.baseFs.fstatPromise(fd, opts); + } + fstatSync(fd, opts) { + return this.baseFs.fstatSync(fd, opts); + } + lstatPromise(p, opts) { + return this.baseFs.lstatPromise(this.mapToBase(p), opts); + } + lstatSync(p, opts) { + return this.baseFs.lstatSync(this.mapToBase(p), opts); + } + async fchmodPromise(fd, mask) { + return this.baseFs.fchmodPromise(fd, mask); + } + fchmodSync(fd, mask) { + return this.baseFs.fchmodSync(fd, mask); + } + async chmodPromise(p, mask) { + return this.baseFs.chmodPromise(this.mapToBase(p), mask); + } + chmodSync(p, mask) { + return this.baseFs.chmodSync(this.mapToBase(p), mask); + } + async fchownPromise(fd, uid, gid) { + return this.baseFs.fchownPromise(fd, uid, gid); + } + fchownSync(fd, uid, gid) { + return this.baseFs.fchownSync(fd, uid, gid); + } + async chownPromise(p, uid, gid) { + return this.baseFs.chownPromise(this.mapToBase(p), uid, gid); + } + chownSync(p, uid, gid) { + return this.baseFs.chownSync(this.mapToBase(p), uid, gid); + } + async renamePromise(oldP, newP) { + return this.baseFs.renamePromise(this.mapToBase(oldP), this.mapToBase(newP)); + } + renameSync(oldP, newP) { + return this.baseFs.renameSync(this.mapToBase(oldP), this.mapToBase(newP)); + } + async copyFilePromise(sourceP, destP, flags = 0) { + return this.baseFs.copyFilePromise(this.mapToBase(sourceP), this.mapToBase(destP), flags); + } + copyFileSync(sourceP, destP, flags = 0) { + return this.baseFs.copyFileSync(this.mapToBase(sourceP), this.mapToBase(destP), flags); + } + async appendFilePromise(p, content, opts) { + return this.baseFs.appendFilePromise(this.fsMapToBase(p), content, opts); + } + appendFileSync(p, content, opts) { + return this.baseFs.appendFileSync(this.fsMapToBase(p), content, opts); + } + async writeFilePromise(p, content, opts) { + return this.baseFs.writeFilePromise(this.fsMapToBase(p), content, opts); + } + writeFileSync(p, content, opts) { + return this.baseFs.writeFileSync(this.fsMapToBase(p), content, opts); + } + async unlinkPromise(p) { + return this.baseFs.unlinkPromise(this.mapToBase(p)); + } + unlinkSync(p) { + return this.baseFs.unlinkSync(this.mapToBase(p)); + } + async utimesPromise(p, atime, mtime) { + return this.baseFs.utimesPromise(this.mapToBase(p), atime, mtime); + } + utimesSync(p, atime, mtime) { + return this.baseFs.utimesSync(this.mapToBase(p), atime, mtime); + } + async mkdirPromise(p, opts) { + return this.baseFs.mkdirPromise(this.mapToBase(p), opts); + } + mkdirSync(p, opts) { + return this.baseFs.mkdirSync(this.mapToBase(p), opts); + } + async rmdirPromise(p, opts) { + return this.baseFs.rmdirPromise(this.mapToBase(p), opts); + } + rmdirSync(p, opts) { + return this.baseFs.rmdirSync(this.mapToBase(p), opts); + } + async linkPromise(existingP, newP) { + return this.baseFs.linkPromise(this.mapToBase(existingP), this.mapToBase(newP)); + } + linkSync(existingP, newP) { + return this.baseFs.linkSync(this.mapToBase(existingP), this.mapToBase(newP)); + } + async symlinkPromise(target, p, type) { + const mappedP = this.mapToBase(p); + if (this.pathUtils.isAbsolute(target)) + return this.baseFs.symlinkPromise(this.mapToBase(target), mappedP, type); + const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); + const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); + return this.baseFs.symlinkPromise(mappedTarget, mappedP, type); + } + symlinkSync(target, p, type) { + const mappedP = this.mapToBase(p); + if (this.pathUtils.isAbsolute(target)) + return this.baseFs.symlinkSync(this.mapToBase(target), mappedP, type); + const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); + const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); + return this.baseFs.symlinkSync(mappedTarget, mappedP, type); + } + async readFilePromise(p, encoding) { + if (encoding === `utf8`) { + return this.baseFs.readFilePromise(this.fsMapToBase(p), encoding); + } else { + return this.baseFs.readFilePromise(this.fsMapToBase(p), encoding); + } + } + readFileSync(p, encoding) { + if (encoding === `utf8`) { + return this.baseFs.readFileSync(this.fsMapToBase(p), encoding); + } else { + return this.baseFs.readFileSync(this.fsMapToBase(p), encoding); + } + } + async readdirPromise(p, opts) { + return this.baseFs.readdirPromise(this.mapToBase(p), opts); + } + readdirSync(p, opts) { + return this.baseFs.readdirSync(this.mapToBase(p), opts); + } + async readlinkPromise(p) { + return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(p))); + } + readlinkSync(p) { + return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(p))); + } + async truncatePromise(p, len) { + return this.baseFs.truncatePromise(this.mapToBase(p), len); + } + truncateSync(p, len) { + return this.baseFs.truncateSync(this.mapToBase(p), len); + } + async ftruncatePromise(fd, len) { + return this.baseFs.ftruncatePromise(fd, len); + } + ftruncateSync(fd, len) { + return this.baseFs.ftruncateSync(fd, len); + } + watch(p, a, b) { + return this.baseFs.watch( + this.mapToBase(p), + a, + b + ); + } + watchFile(p, a, b) { + return this.baseFs.watchFile( + this.mapToBase(p), + a, + b + ); + } + unwatchFile(p, cb) { + return this.baseFs.unwatchFile(this.mapToBase(p), cb); + } + fsMapToBase(p) { + if (typeof p === `number`) { + return p; + } else { + return this.mapToBase(p); + } + } +} + +class PosixFS extends ProxiedFS { + constructor(baseFs) { + super(npath); + this.baseFs = baseFs; + } + mapFromBase(path) { + return npath.fromPortablePath(path); + } + mapToBase(path) { + return npath.toPortablePath(path); + } +} + +const NUMBER_REGEXP = /^[0-9]+$/; +const VIRTUAL_REGEXP = /^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/; +const VALID_COMPONENT = /^([^/]+-)?[a-f0-9]+$/; +class VirtualFS extends ProxiedFS { + constructor({ baseFs = new NodeFS() } = {}) { + super(ppath); + this.baseFs = baseFs; + } + static makeVirtualPath(base, component, to) { + if (ppath.basename(base) !== `__virtual__`) + throw new Error(`Assertion failed: Virtual folders must be named "__virtual__"`); + if (!ppath.basename(component).match(VALID_COMPONENT)) + throw new Error(`Assertion failed: Virtual components must be ended by an hexadecimal hash`); + const target = ppath.relative(ppath.dirname(base), to); + const segments = target.split(`/`); + let depth = 0; + while (depth < segments.length && segments[depth] === `..`) + depth += 1; + const finalSegments = segments.slice(depth); + const fullVirtualPath = ppath.join(base, component, String(depth), ...finalSegments); + return fullVirtualPath; + } + static resolveVirtual(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match || !match[3] && match[5]) + return p; + const target = ppath.dirname(match[1]); + if (!match[3] || !match[4]) + return target; + const isnum = NUMBER_REGEXP.test(match[4]); + if (!isnum) + return p; + const depth = Number(match[4]); + const backstep = `../`.repeat(depth); + const subpath = match[5] || `.`; + return VirtualFS.resolveVirtual(ppath.join(target, backstep, subpath)); + } + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + getRealPath() { + return this.baseFs.getRealPath(); + } + realpathSync(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match) + return this.baseFs.realpathSync(p); + if (!match[5]) + return p; + const realpath = this.baseFs.realpathSync(this.mapToBase(p)); + return VirtualFS.makeVirtualPath(match[1], match[3], realpath); + } + async realpathPromise(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match) + return await this.baseFs.realpathPromise(p); + if (!match[5]) + return p; + const realpath = await this.baseFs.realpathPromise(this.mapToBase(p)); + return VirtualFS.makeVirtualPath(match[1], match[3], realpath); + } + mapToBase(p) { + if (p === ``) + return p; + if (this.pathUtils.isAbsolute(p)) + return VirtualFS.resolveVirtual(p); + const resolvedRoot = VirtualFS.resolveVirtual(this.baseFs.resolve(PortablePath.dot)); + const resolvedP = VirtualFS.resolveVirtual(this.baseFs.resolve(p)); + return ppath.relative(resolvedRoot, resolvedP) || PortablePath.dot; + } + mapFromBase(p) { + return p; + } +} + +const ZIP_MASK = 4278190080; +const ZIP_MAGIC = 704643072; +const getArchivePart = (path, extension) => { + let idx = path.indexOf(extension); + if (idx <= 0) + return null; + let nextCharIdx = idx; + while (idx >= 0) { + nextCharIdx = idx + extension.length; + if (path[nextCharIdx] === ppath.sep) + break; + if (path[idx - 1] === ppath.sep) + return null; + idx = path.indexOf(extension, nextCharIdx); + } + if (path.length > nextCharIdx && path[nextCharIdx] !== ppath.sep) + return null; + return path.slice(0, nextCharIdx); +}; +class ZipOpenFS extends BasePortableFakeFS { + constructor({ libzip, baseFs = new NodeFS(), filter = null, maxOpenFiles = Infinity, readOnlyArchives = false, useCache = true, maxAge = 5e3, fileExtensions = null }) { + super(); + this.fdMap = /* @__PURE__ */ new Map(); + this.nextFd = 3; + this.isZip = /* @__PURE__ */ new Set(); + this.notZip = /* @__PURE__ */ new Set(); + this.realPaths = /* @__PURE__ */ new Map(); + this.limitOpenFilesTimeout = null; + this.libzipFactory = typeof libzip !== `function` ? () => libzip : libzip; + this.baseFs = baseFs; + this.zipInstances = useCache ? /* @__PURE__ */ new Map() : null; + this.filter = filter; + this.maxOpenFiles = maxOpenFiles; + this.readOnlyArchives = readOnlyArchives; + this.maxAge = maxAge; + this.fileExtensions = fileExtensions; + } + static async openPromise(fn, opts) { + const zipOpenFs = new ZipOpenFS(opts); + try { + return await fn(zipOpenFs); + } finally { + zipOpenFs.saveAndClose(); + } + } + get libzip() { + if (typeof this.libzipInstance === `undefined`) + this.libzipInstance = this.libzipFactory(); + return this.libzipInstance; + } + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + getRealPath() { + return this.baseFs.getRealPath(); + } + saveAndClose() { + unwatchAllFiles(this); + if (this.zipInstances) { + for (const [path, { zipFs }] of this.zipInstances.entries()) { + zipFs.saveAndClose(); + this.zipInstances.delete(path); + } + } + } + discardAndClose() { + unwatchAllFiles(this); + if (this.zipInstances) { + for (const [path, { zipFs }] of this.zipInstances.entries()) { + zipFs.discardAndClose(); + this.zipInstances.delete(path); + } + } + } + resolve(p) { + return this.baseFs.resolve(p); + } + remapFd(zipFs, fd) { + const remappedFd = this.nextFd++ | ZIP_MAGIC; + this.fdMap.set(remappedFd, [zipFs, fd]); + return remappedFd; + } + async openPromise(p, flags, mode) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.openPromise(p, flags, mode); + }, async (zipFs, { subPath }) => { + return this.remapFd(zipFs, await zipFs.openPromise(subPath, flags, mode)); + }); + } + openSync(p, flags, mode) { + return this.makeCallSync(p, () => { + return this.baseFs.openSync(p, flags, mode); + }, (zipFs, { subPath }) => { + return this.remapFd(zipFs, zipFs.openSync(subPath, flags, mode)); + }); + } + async opendirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.opendirPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.opendirPromise(subPath, opts); + }, { + requireSubpath: false + }); + } + opendirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.opendirSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.opendirSync(subPath, opts); + }, { + requireSubpath: false + }); + } + async readPromise(fd, buffer, offset, length, position) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return await this.baseFs.readPromise(fd, buffer, offset, length, position); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + const [zipFs, realFd] = entry; + return await zipFs.readPromise(realFd, buffer, offset, length, position); + } + readSync(fd, buffer, offset, length, position) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.readSync(fd, buffer, offset, length, position); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`readSync`); + const [zipFs, realFd] = entry; + return zipFs.readSync(realFd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) { + if (typeof buffer === `string`) { + return await this.baseFs.writePromise(fd, buffer, offset); + } else { + return await this.baseFs.writePromise(fd, buffer, offset, length, position); + } + } + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`write`); + const [zipFs, realFd] = entry; + if (typeof buffer === `string`) { + return await zipFs.writePromise(realFd, buffer, offset); + } else { + return await zipFs.writePromise(realFd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) { + if (typeof buffer === `string`) { + return this.baseFs.writeSync(fd, buffer, offset); + } else { + return this.baseFs.writeSync(fd, buffer, offset, length, position); + } + } + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`writeSync`); + const [zipFs, realFd] = entry; + if (typeof buffer === `string`) { + return zipFs.writeSync(realFd, buffer, offset); + } else { + return zipFs.writeSync(realFd, buffer, offset, length, position); + } + } + async closePromise(fd) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return await this.baseFs.closePromise(fd); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`close`); + this.fdMap.delete(fd); + const [zipFs, realFd] = entry; + return await zipFs.closePromise(realFd); + } + closeSync(fd) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.closeSync(fd); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`closeSync`); + this.fdMap.delete(fd); + const [zipFs, realFd] = entry; + return zipFs.closeSync(realFd); + } + createReadStream(p, opts) { + if (p === null) + return this.baseFs.createReadStream(p, opts); + return this.makeCallSync(p, () => { + return this.baseFs.createReadStream(p, opts); + }, (zipFs, { archivePath, subPath }) => { + const stream = zipFs.createReadStream(subPath, opts); + stream.path = npath.fromPortablePath(this.pathUtils.join(archivePath, subPath)); + return stream; + }); + } + createWriteStream(p, opts) { + if (p === null) + return this.baseFs.createWriteStream(p, opts); + return this.makeCallSync(p, () => { + return this.baseFs.createWriteStream(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.createWriteStream(subPath, opts); + }); + } + async realpathPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.realpathPromise(p); + }, async (zipFs, { archivePath, subPath }) => { + let realArchivePath = this.realPaths.get(archivePath); + if (typeof realArchivePath === `undefined`) { + realArchivePath = await this.baseFs.realpathPromise(archivePath); + this.realPaths.set(archivePath, realArchivePath); + } + return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, await zipFs.realpathPromise(subPath))); + }); + } + realpathSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.realpathSync(p); + }, (zipFs, { archivePath, subPath }) => { + let realArchivePath = this.realPaths.get(archivePath); + if (typeof realArchivePath === `undefined`) { + realArchivePath = this.baseFs.realpathSync(archivePath); + this.realPaths.set(archivePath, realArchivePath); + } + return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, zipFs.realpathSync(subPath))); + }); + } + async existsPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.existsPromise(p); + }, async (zipFs, { subPath }) => { + return await zipFs.existsPromise(subPath); + }); + } + existsSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.existsSync(p); + }, (zipFs, { subPath }) => { + return zipFs.existsSync(subPath); + }); + } + async accessPromise(p, mode) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.accessPromise(p, mode); + }, async (zipFs, { subPath }) => { + return await zipFs.accessPromise(subPath, mode); + }); + } + accessSync(p, mode) { + return this.makeCallSync(p, () => { + return this.baseFs.accessSync(p, mode); + }, (zipFs, { subPath }) => { + return zipFs.accessSync(subPath, mode); + }); + } + async statPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.statPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.statPromise(subPath, opts); + }); + } + statSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.statSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.statSync(subPath, opts); + }); + } + async fstatPromise(fd, opts) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fstatPromise(fd, opts); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstat`); + const [zipFs, realFd] = entry; + return zipFs.fstatPromise(realFd, opts); + } + fstatSync(fd, opts) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fstatSync(fd, opts); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstatSync`); + const [zipFs, realFd] = entry; + return zipFs.fstatSync(realFd, opts); + } + async lstatPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.lstatPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.lstatPromise(subPath, opts); + }); + } + lstatSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.lstatSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.lstatSync(subPath, opts); + }); + } + async fchmodPromise(fd, mask) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fchmodPromise(fd, mask); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchmod`); + const [zipFs, realFd] = entry; + return zipFs.fchmodPromise(realFd, mask); + } + fchmodSync(fd, mask) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fchmodSync(fd, mask); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchmodSync`); + const [zipFs, realFd] = entry; + return zipFs.fchmodSync(realFd, mask); + } + async chmodPromise(p, mask) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.chmodPromise(p, mask); + }, async (zipFs, { subPath }) => { + return await zipFs.chmodPromise(subPath, mask); + }); + } + chmodSync(p, mask) { + return this.makeCallSync(p, () => { + return this.baseFs.chmodSync(p, mask); + }, (zipFs, { subPath }) => { + return zipFs.chmodSync(subPath, mask); + }); + } + async fchownPromise(fd, uid, gid) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fchownPromise(fd, uid, gid); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchown`); + const [zipFs, realFd] = entry; + return zipFs.fchownPromise(realFd, uid, gid); + } + fchownSync(fd, uid, gid) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.fchownSync(fd, uid, gid); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchownSync`); + const [zipFs, realFd] = entry; + return zipFs.fchownSync(realFd, uid, gid); + } + async chownPromise(p, uid, gid) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.chownPromise(p, uid, gid); + }, async (zipFs, { subPath }) => { + return await zipFs.chownPromise(subPath, uid, gid); + }); + } + chownSync(p, uid, gid) { + return this.makeCallSync(p, () => { + return this.baseFs.chownSync(p, uid, gid); + }, (zipFs, { subPath }) => { + return zipFs.chownSync(subPath, uid, gid); + }); + } + async renamePromise(oldP, newP) { + return await this.makeCallPromise(oldP, async () => { + return await this.makeCallPromise(newP, async () => { + return await this.baseFs.renamePromise(oldP, newP); + }, async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }); + }, async (zipFsO, { subPath: subPathO }) => { + return await this.makeCallPromise(newP, async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }, async (zipFsN, { subPath: subPathN }) => { + if (zipFsO !== zipFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + } else { + return await zipFsO.renamePromise(subPathO, subPathN); + } + }); + }); + } + renameSync(oldP, newP) { + return this.makeCallSync(oldP, () => { + return this.makeCallSync(newP, () => { + return this.baseFs.renameSync(oldP, newP); + }, () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }); + }, (zipFsO, { subPath: subPathO }) => { + return this.makeCallSync(newP, () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }, (zipFsN, { subPath: subPathN }) => { + if (zipFsO !== zipFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + } else { + return zipFsO.renameSync(subPathO, subPathN); + } + }); + }); + } + async copyFilePromise(sourceP, destP, flags = 0) { + const fallback = async (sourceFs, sourceP2, destFs, destP2) => { + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), { code: `EXDEV` }); + if (flags & fs.constants.COPYFILE_EXCL && await this.existsPromise(sourceP2)) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EEXIST` }); + let content; + try { + content = await sourceFs.readFilePromise(sourceP2); + } catch (error) { + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EINVAL` }); + } + await destFs.writeFilePromise(destP2, content); + }; + return await this.makeCallPromise(sourceP, async () => { + return await this.makeCallPromise(destP, async () => { + return await this.baseFs.copyFilePromise(sourceP, destP, flags); + }, async (zipFsD, { subPath: subPathD }) => { + return await fallback(this.baseFs, sourceP, zipFsD, subPathD); + }); + }, async (zipFsS, { subPath: subPathS }) => { + return await this.makeCallPromise(destP, async () => { + return await fallback(zipFsS, subPathS, this.baseFs, destP); + }, async (zipFsD, { subPath: subPathD }) => { + if (zipFsS !== zipFsD) { + return await fallback(zipFsS, subPathS, zipFsD, subPathD); + } else { + return await zipFsS.copyFilePromise(subPathS, subPathD, flags); + } + }); + }); + } + copyFileSync(sourceP, destP, flags = 0) { + const fallback = (sourceFs, sourceP2, destFs, destP2) => { + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), { code: `EXDEV` }); + if (flags & fs.constants.COPYFILE_EXCL && this.existsSync(sourceP2)) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EEXIST` }); + let content; + try { + content = sourceFs.readFileSync(sourceP2); + } catch (error) { + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EINVAL` }); + } + destFs.writeFileSync(destP2, content); + }; + return this.makeCallSync(sourceP, () => { + return this.makeCallSync(destP, () => { + return this.baseFs.copyFileSync(sourceP, destP, flags); + }, (zipFsD, { subPath: subPathD }) => { + return fallback(this.baseFs, sourceP, zipFsD, subPathD); + }); + }, (zipFsS, { subPath: subPathS }) => { + return this.makeCallSync(destP, () => { + return fallback(zipFsS, subPathS, this.baseFs, destP); + }, (zipFsD, { subPath: subPathD }) => { + if (zipFsS !== zipFsD) { + return fallback(zipFsS, subPathS, zipFsD, subPathD); + } else { + return zipFsS.copyFileSync(subPathS, subPathD, flags); + } + }); + }); + } + async appendFilePromise(p, content, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.appendFilePromise(p, content, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.appendFilePromise(subPath, content, opts); + }); + } + appendFileSync(p, content, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.appendFileSync(p, content, opts); + }, (zipFs, { subPath }) => { + return zipFs.appendFileSync(subPath, content, opts); + }); + } + async writeFilePromise(p, content, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.writeFilePromise(p, content, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.writeFilePromise(subPath, content, opts); + }); + } + writeFileSync(p, content, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.writeFileSync(p, content, opts); + }, (zipFs, { subPath }) => { + return zipFs.writeFileSync(subPath, content, opts); + }); + } + async unlinkPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.unlinkPromise(p); + }, async (zipFs, { subPath }) => { + return await zipFs.unlinkPromise(subPath); + }); + } + unlinkSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.unlinkSync(p); + }, (zipFs, { subPath }) => { + return zipFs.unlinkSync(subPath); + }); + } + async utimesPromise(p, atime, mtime) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.utimesPromise(p, atime, mtime); + }, async (zipFs, { subPath }) => { + return await zipFs.utimesPromise(subPath, atime, mtime); + }); + } + utimesSync(p, atime, mtime) { + return this.makeCallSync(p, () => { + return this.baseFs.utimesSync(p, atime, mtime); + }, (zipFs, { subPath }) => { + return zipFs.utimesSync(subPath, atime, mtime); + }); + } + async mkdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.mkdirPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.mkdirPromise(subPath, opts); + }); + } + mkdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.mkdirSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.mkdirSync(subPath, opts); + }); + } + async rmdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.rmdirPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.rmdirPromise(subPath, opts); + }); + } + rmdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.rmdirSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.rmdirSync(subPath, opts); + }); + } + async linkPromise(existingP, newP) { + return await this.makeCallPromise(newP, async () => { + return await this.baseFs.linkPromise(existingP, newP); + }, async (zipFs, { subPath }) => { + return await zipFs.linkPromise(existingP, subPath); + }); + } + linkSync(existingP, newP) { + return this.makeCallSync(newP, () => { + return this.baseFs.linkSync(existingP, newP); + }, (zipFs, { subPath }) => { + return zipFs.linkSync(existingP, subPath); + }); + } + async symlinkPromise(target, p, type) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.symlinkPromise(target, p, type); + }, async (zipFs, { subPath }) => { + return await zipFs.symlinkPromise(target, subPath); + }); + } + symlinkSync(target, p, type) { + return this.makeCallSync(p, () => { + return this.baseFs.symlinkSync(target, p, type); + }, (zipFs, { subPath }) => { + return zipFs.symlinkSync(target, subPath); + }); + } + async readFilePromise(p, encoding) { + return this.makeCallPromise(p, async () => { + switch (encoding) { + case `utf8`: + return await this.baseFs.readFilePromise(p, encoding); + default: + return await this.baseFs.readFilePromise(p, encoding); + } + }, async (zipFs, { subPath }) => { + return await zipFs.readFilePromise(subPath, encoding); + }); + } + readFileSync(p, encoding) { + return this.makeCallSync(p, () => { + switch (encoding) { + case `utf8`: + return this.baseFs.readFileSync(p, encoding); + default: + return this.baseFs.readFileSync(p, encoding); + } + }, (zipFs, { subPath }) => { + return zipFs.readFileSync(subPath, encoding); + }); + } + async readdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.readdirPromise(p, opts); + }, async (zipFs, { subPath }) => { + return await zipFs.readdirPromise(subPath, opts); + }, { + requireSubpath: false + }); + } + readdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.readdirSync(p, opts); + }, (zipFs, { subPath }) => { + return zipFs.readdirSync(subPath, opts); + }, { + requireSubpath: false + }); + } + async readlinkPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.readlinkPromise(p); + }, async (zipFs, { subPath }) => { + return await zipFs.readlinkPromise(subPath); + }); + } + readlinkSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.readlinkSync(p); + }, (zipFs, { subPath }) => { + return zipFs.readlinkSync(subPath); + }); + } + async truncatePromise(p, len) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.truncatePromise(p, len); + }, async (zipFs, { subPath }) => { + return await zipFs.truncatePromise(subPath, len); + }); + } + truncateSync(p, len) { + return this.makeCallSync(p, () => { + return this.baseFs.truncateSync(p, len); + }, (zipFs, { subPath }) => { + return zipFs.truncateSync(subPath, len); + }); + } + async ftruncatePromise(fd, len) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.ftruncatePromise(fd, len); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`ftruncate`); + const [zipFs, realFd] = entry; + return zipFs.ftruncatePromise(realFd, len); + } + ftruncateSync(fd, len) { + if ((fd & ZIP_MASK) !== ZIP_MAGIC) + return this.baseFs.ftruncateSync(fd, len); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`ftruncateSync`); + const [zipFs, realFd] = entry; + return zipFs.ftruncateSync(realFd, len); + } + watch(p, a, b) { + return this.makeCallSync(p, () => { + return this.baseFs.watch( + p, + a, + b + ); + }, (zipFs, { subPath }) => { + return zipFs.watch( + subPath, + a, + b + ); + }); + } + watchFile(p, a, b) { + return this.makeCallSync(p, () => { + return this.baseFs.watchFile( + p, + a, + b + ); + }, () => { + return watchFile(this, p, a, b); + }); + } + unwatchFile(p, cb) { + return this.makeCallSync(p, () => { + return this.baseFs.unwatchFile(p, cb); + }, () => { + return unwatchFile(this, p, cb); + }); + } + async makeCallPromise(p, discard, accept, { requireSubpath = true } = {}) { + if (typeof p !== `string`) + return await discard(); + const normalizedP = this.resolve(p); + const zipInfo = this.findZip(normalizedP); + if (!zipInfo) + return await discard(); + if (requireSubpath && zipInfo.subPath === `/`) + return await discard(); + return await this.getZipPromise(zipInfo.archivePath, async (zipFs) => await accept(zipFs, zipInfo)); + } + makeCallSync(p, discard, accept, { requireSubpath = true } = {}) { + if (typeof p !== `string`) + return discard(); + const normalizedP = this.resolve(p); + const zipInfo = this.findZip(normalizedP); + if (!zipInfo) + return discard(); + if (requireSubpath && zipInfo.subPath === `/`) + return discard(); + return this.getZipSync(zipInfo.archivePath, (zipFs) => accept(zipFs, zipInfo)); + } + findZip(p) { + if (this.filter && !this.filter.test(p)) + return null; + let filePath = ``; + while (true) { + const pathPartWithArchive = p.substring(filePath.length); + let archivePart; + if (!this.fileExtensions) { + archivePart = getArchivePart(pathPartWithArchive, `.zip`); + } else { + for (const ext of this.fileExtensions) { + archivePart = getArchivePart(pathPartWithArchive, ext); + if (archivePart) { + break; + } + } + } + if (!archivePart) + return null; + filePath = this.pathUtils.join(filePath, archivePart); + if (this.isZip.has(filePath) === false) { + if (this.notZip.has(filePath)) + continue; + try { + if (!this.baseFs.lstatSync(filePath).isFile()) { + this.notZip.add(filePath); + continue; + } + } catch { + return null; + } + this.isZip.add(filePath); + } + return { + archivePath: filePath, + subPath: this.pathUtils.join(PortablePath.root, p.substring(filePath.length)) + }; + } + } + limitOpenFiles(max) { + if (this.zipInstances === null) + return; + const now = Date.now(); + let nextExpiresAt = now + this.maxAge; + let closeCount = max === null ? 0 : this.zipInstances.size - max; + for (const [path, { zipFs, expiresAt, refCount }] of this.zipInstances.entries()) { + if (refCount !== 0 || zipFs.hasOpenFileHandles()) { + continue; + } else if (now >= expiresAt) { + zipFs.saveAndClose(); + this.zipInstances.delete(path); + closeCount -= 1; + continue; + } else if (max === null || closeCount <= 0) { + nextExpiresAt = expiresAt; + break; + } + zipFs.saveAndClose(); + this.zipInstances.delete(path); + closeCount -= 1; + } + if (this.limitOpenFilesTimeout === null && (max === null && this.zipInstances.size > 0 || max !== null)) { + this.limitOpenFilesTimeout = setTimeout(() => { + this.limitOpenFilesTimeout = null; + this.limitOpenFiles(null); + }, nextExpiresAt - now).unref(); + } + } + async getZipPromise(p, accept) { + const getZipOptions = async () => ({ + baseFs: this.baseFs, + libzip: this.libzip, + readOnly: this.readOnlyArchives, + stats: await this.baseFs.statPromise(p) + }); + if (this.zipInstances) { + let cachedZipFs = this.zipInstances.get(p); + if (!cachedZipFs) { + const zipOptions = await getZipOptions(); + cachedZipFs = this.zipInstances.get(p); + if (!cachedZipFs) { + cachedZipFs = { + zipFs: new ZipFS(p, zipOptions), + expiresAt: 0, + refCount: 0 + }; + } + } + this.zipInstances.delete(p); + this.limitOpenFiles(this.maxOpenFiles - 1); + this.zipInstances.set(p, cachedZipFs); + cachedZipFs.expiresAt = Date.now() + this.maxAge; + cachedZipFs.refCount += 1; + try { + return await accept(cachedZipFs.zipFs); + } finally { + cachedZipFs.refCount -= 1; + } + } else { + const zipFs = new ZipFS(p, await getZipOptions()); + try { + return await accept(zipFs); + } finally { + zipFs.saveAndClose(); + } + } + } + getZipSync(p, accept) { + const getZipOptions = () => ({ + baseFs: this.baseFs, + libzip: this.libzip, + readOnly: this.readOnlyArchives, + stats: this.baseFs.statSync(p) + }); + if (this.zipInstances) { + let cachedZipFs = this.zipInstances.get(p); + if (!cachedZipFs) { + cachedZipFs = { + zipFs: new ZipFS(p, getZipOptions()), + expiresAt: 0, + refCount: 0 + }; + } + this.zipInstances.delete(p); + this.limitOpenFiles(this.maxOpenFiles - 1); + this.zipInstances.set(p, cachedZipFs); + cachedZipFs.expiresAt = Date.now() + this.maxAge; + return accept(cachedZipFs.zipFs); + } else { + const zipFs = new ZipFS(p, getZipOptions()); + try { + return accept(zipFs); + } finally { + zipFs.saveAndClose(); + } + } + } +} + +class NodePathFS extends ProxiedFS { + constructor(baseFs) { + super(npath); + this.baseFs = baseFs; + } + mapFromBase(path) { + return path; + } + mapToBase(path) { + if (typeof path === `string`) + return path; + if (path instanceof url.URL) + return url.fileURLToPath(path); + if (Buffer.isBuffer(path)) { + const str = path.toString(); + if (Buffer.byteLength(str) !== path.byteLength) + throw new Error(`Non-utf8 buffers are not supported at the moment. Please upvote the following issue if you encounter this error: https://github.com/yarnpkg/berry/issues/4942`); + return str; + } + throw new Error(`Unsupported path type: ${nodeUtils.inspect(path)}`); + } +} + +var _a, _b, _c, _d; +const kBaseFs = Symbol(`kBaseFs`); +const kFd = Symbol(`kFd`); +const kClosePromise = Symbol(`kClosePromise`); +const kCloseResolve = Symbol(`kCloseResolve`); +const kCloseReject = Symbol(`kCloseReject`); +const kRefs = Symbol(`kRefs`); +const kRef = Symbol(`kRef`); +const kUnref = Symbol(`kUnref`); +class FileHandle { + constructor(fd, baseFs) { + this[_a] = 1; + this[_b] = void 0; + this[_c] = void 0; + this[_d] = void 0; + this[kBaseFs] = baseFs; + this[kFd] = fd; + } + get fd() { + return this[kFd]; + } + async appendFile(data, options) { + var _a2; + try { + this[kRef](this.appendFile); + const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; + return await this[kBaseFs].appendFilePromise(this.fd, data, encoding ? { encoding } : void 0); + } finally { + this[kUnref](); + } + } + async chown(uid, gid) { + try { + this[kRef](this.chown); + return await this[kBaseFs].fchownPromise(this.fd, uid, gid); + } finally { + this[kUnref](); + } + } + async chmod(mode) { + try { + this[kRef](this.chmod); + return await this[kBaseFs].fchmodPromise(this.fd, mode); + } finally { + this[kUnref](); + } + } + createReadStream(options) { + return this[kBaseFs].createReadStream(null, { ...options, fd: this.fd }); + } + createWriteStream(options) { + return this[kBaseFs].createWriteStream(null, { ...options, fd: this.fd }); + } + datasync() { + throw new Error(`Method not implemented.`); + } + sync() { + throw new Error(`Method not implemented.`); + } + async read(bufferOrOptions, offset, length, position) { + var _a2, _b2, _c2; + try { + this[kRef](this.read); + let buffer; + if (!Buffer.isBuffer(bufferOrOptions)) { + bufferOrOptions != null ? bufferOrOptions : bufferOrOptions = {}; + buffer = (_a2 = bufferOrOptions.buffer) != null ? _a2 : Buffer.alloc(16384); + offset = bufferOrOptions.offset || 0; + length = (_b2 = bufferOrOptions.length) != null ? _b2 : buffer.byteLength; + position = (_c2 = bufferOrOptions.position) != null ? _c2 : null; + } else { + buffer = bufferOrOptions; + } + offset != null ? offset : offset = 0; + length != null ? length : length = 0; + if (length === 0) { + return { + bytesRead: length, + buffer + }; + } + const bytesRead = await this[kBaseFs].readPromise(this.fd, buffer, offset, length, position); + return { + bytesRead, + buffer + }; + } finally { + this[kUnref](); + } + } + async readFile(options) { + var _a2; + try { + this[kRef](this.readFile); + const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; + return await this[kBaseFs].readFilePromise(this.fd, encoding); + } finally { + this[kUnref](); + } + } + readLines(options) { + return readline.createInterface({ + input: this.createReadStream(options), + crlfDelay: Infinity + }); + } + async stat(opts) { + try { + this[kRef](this.stat); + return await this[kBaseFs].fstatPromise(this.fd, opts); + } finally { + this[kUnref](); + } + } + async truncate(len) { + try { + this[kRef](this.truncate); + return await this[kBaseFs].ftruncatePromise(this.fd, len); + } finally { + this[kUnref](); + } + } + utimes(atime, mtime) { + throw new Error(`Method not implemented.`); + } + async writeFile(data, options) { + var _a2; + try { + this[kRef](this.writeFile); + const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; + await this[kBaseFs].writeFilePromise(this.fd, data, encoding); + } finally { + this[kUnref](); + } + } + async write(...args) { + try { + this[kRef](this.write); + if (ArrayBuffer.isView(args[0])) { + const [buffer, offset, length, position] = args; + const bytesWritten = await this[kBaseFs].writePromise(this.fd, buffer, offset != null ? offset : void 0, length != null ? length : void 0, position != null ? position : void 0); + return { bytesWritten, buffer }; + } else { + const [data, position, encoding] = args; + const bytesWritten = await this[kBaseFs].writePromise(this.fd, data, position, encoding); + return { bytesWritten, buffer: data }; + } + } finally { + this[kUnref](); + } + } + async writev(buffers, position) { + try { + this[kRef](this.writev); + let bytesWritten = 0; + if (typeof position !== `undefined`) { + for (const buffer of buffers) { + const writeResult = await this.write(buffer, void 0, void 0, position); + bytesWritten += writeResult.bytesWritten; + position += writeResult.bytesWritten; + } + } else { + for (const buffer of buffers) { + const writeResult = await this.write(buffer); + bytesWritten += writeResult.bytesWritten; + } + } + return { + buffers, + bytesWritten + }; + } finally { + this[kUnref](); + } + } + readv(buffers, position) { + throw new Error(`Method not implemented.`); + } + close() { + if (this[kFd] === -1) + return Promise.resolve(); + if (this[kClosePromise]) + return this[kClosePromise]; + this[kRefs]--; + if (this[kRefs] === 0) { + const fd = this[kFd]; + this[kFd] = -1; + this[kClosePromise] = this[kBaseFs].closePromise(fd).finally(() => { + this[kClosePromise] = void 0; + }); + } else { + this[kClosePromise] = new Promise((resolve, reject) => { + this[kCloseResolve] = resolve; + this[kCloseReject] = reject; + }).finally(() => { + this[kClosePromise] = void 0; + this[kCloseReject] = void 0; + this[kCloseResolve] = void 0; + }); + } + return this[kClosePromise]; + } + [(_a = kRefs, _b = kClosePromise, _c = kCloseResolve, _d = kCloseReject, kRef)](caller) { + if (this[kFd] === -1) { + const err = new Error(`file closed`); + err.code = `EBADF`; + err.syscall = caller.name; + throw err; + } + this[kRefs]++; + } + [kUnref]() { + this[kRefs]--; + if (this[kRefs] === 0) { + const fd = this[kFd]; + this[kFd] = -1; + this[kBaseFs].closePromise(fd).then(this[kCloseResolve], this[kCloseReject]); + } + } +} + +const SYNC_IMPLEMENTATIONS = /* @__PURE__ */ new Set([ + `accessSync`, + `appendFileSync`, + `createReadStream`, + `createWriteStream`, + `chmodSync`, + `fchmodSync`, + `chownSync`, + `fchownSync`, + `closeSync`, + `copyFileSync`, + `linkSync`, + `lstatSync`, + `fstatSync`, + `lutimesSync`, + `mkdirSync`, + `openSync`, + `opendirSync`, + `readlinkSync`, + `readFileSync`, + `readdirSync`, + `readlinkSync`, + `realpathSync`, + `renameSync`, + `rmdirSync`, + `statSync`, + `symlinkSync`, + `truncateSync`, + `ftruncateSync`, + `unlinkSync`, + `unwatchFile`, + `utimesSync`, + `watch`, + `watchFile`, + `writeFileSync`, + `writeSync` +]); +const ASYNC_IMPLEMENTATIONS = /* @__PURE__ */ new Set([ + `accessPromise`, + `appendFilePromise`, + `fchmodPromise`, + `chmodPromise`, + `fchownPromise`, + `chownPromise`, + `closePromise`, + `copyFilePromise`, + `linkPromise`, + `fstatPromise`, + `lstatPromise`, + `lutimesPromise`, + `mkdirPromise`, + `openPromise`, + `opendirPromise`, + `readdirPromise`, + `realpathPromise`, + `readFilePromise`, + `readdirPromise`, + `readlinkPromise`, + `renamePromise`, + `rmdirPromise`, + `statPromise`, + `symlinkPromise`, + `truncatePromise`, + `ftruncatePromise`, + `unlinkPromise`, + `utimesPromise`, + `writeFilePromise`, + `writeSync` +]); +function patchFs(patchedFs, fakeFs) { + fakeFs = new NodePathFS(fakeFs); + const setupFn = (target, name, replacement) => { + const orig = target[name]; + target[name] = replacement; + if (typeof (orig == null ? void 0 : orig[nodeUtils.promisify.custom]) !== `undefined`) { + replacement[nodeUtils.promisify.custom] = orig[nodeUtils.promisify.custom]; + } + }; + { + setupFn(patchedFs, `exists`, (p, ...args) => { + const hasCallback = typeof args[args.length - 1] === `function`; + const callback = hasCallback ? args.pop() : () => { + }; + process.nextTick(() => { + fakeFs.existsPromise(p).then((exists) => { + callback(exists); + }, () => { + callback(false); + }); + }); + }); + setupFn(patchedFs, `read`, (...args) => { + let [fd, buffer, offset, length, position, callback] = args; + if (args.length <= 3) { + let options = {}; + if (args.length < 3) { + callback = args[1]; + } else { + options = args[1]; + callback = args[2]; + } + ({ + buffer = Buffer.alloc(16384), + offset = 0, + length = buffer.byteLength, + position + } = options); + } + if (offset == null) + offset = 0; + length |= 0; + if (length === 0) { + process.nextTick(() => { + callback(null, 0, buffer); + }); + return; + } + if (position == null) + position = -1; + process.nextTick(() => { + fakeFs.readPromise(fd, buffer, offset, length, position).then((bytesRead) => { + callback(null, bytesRead, buffer); + }, (error) => { + callback(error, 0, buffer); + }); + }); + }); + for (const fnName of ASYNC_IMPLEMENTATIONS) { + const origName = fnName.replace(/Promise$/, ``); + if (typeof patchedFs[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + const wrapper = (...args) => { + const hasCallback = typeof args[args.length - 1] === `function`; + const callback = hasCallback ? args.pop() : () => { + }; + process.nextTick(() => { + fakeImpl.apply(fakeFs, args).then((result) => { + callback(null, result); + }, (error) => { + callback(error); + }); + }); + }; + setupFn(patchedFs, origName, wrapper); + } + patchedFs.realpath.native = patchedFs.realpath; + } + { + setupFn(patchedFs, `existsSync`, (p) => { + try { + return fakeFs.existsSync(p); + } catch (error) { + return false; + } + }); + setupFn(patchedFs, `readSync`, (...args) => { + let [fd, buffer, offset, length, position] = args; + if (args.length <= 3) { + const options = args[2] || {}; + ({ offset = 0, length = buffer.byteLength, position } = options); + } + if (offset == null) + offset = 0; + length |= 0; + if (length === 0) + return 0; + if (position == null) + position = -1; + return fakeFs.readSync(fd, buffer, offset, length, position); + }); + for (const fnName of SYNC_IMPLEMENTATIONS) { + const origName = fnName; + if (typeof patchedFs[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + setupFn(patchedFs, origName, fakeImpl.bind(fakeFs)); + } + patchedFs.realpathSync.native = patchedFs.realpathSync; + } + { + const origEmitWarning = process.emitWarning; + process.emitWarning = () => { + }; + let patchedFsPromises; + try { + patchedFsPromises = patchedFs.promises; + } finally { + process.emitWarning = origEmitWarning; + } + if (typeof patchedFsPromises !== `undefined`) { + for (const fnName of ASYNC_IMPLEMENTATIONS) { + const origName = fnName.replace(/Promise$/, ``); + if (typeof patchedFsPromises[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + if (fnName === `open`) + continue; + setupFn(patchedFsPromises, origName, (pathLike, ...args) => { + if (pathLike instanceof FileHandle) { + return pathLike[origName].apply(pathLike, args); + } else { + return fakeImpl.call(fakeFs, pathLike, ...args); + } + }); + } + setupFn(patchedFsPromises, `open`, async (...args) => { + const fd = await fakeFs.openPromise(...args); + return new FileHandle(fd, fakeFs); + }); + } + } + { + patchedFs.read[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { + const res = fakeFs.readPromise(fd, buffer, ...args); + return { bytesRead: await res, buffer }; + }; + patchedFs.write[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { + const res = fakeFs.writePromise(fd, buffer, ...args); + return { bytesWritten: await res, buffer }; + }; + } +} + +var libzipSync = {exports: {}}; + +(function (module, exports) { +var frozenFs = Object.assign({}, fs__default.default); +var createModule = function() { + var _scriptDir = void 0; + if (typeof __filename !== "undefined") + _scriptDir = _scriptDir || __filename; + return function(createModule2) { + createModule2 = createModule2 || {}; + var Module = typeof createModule2 !== "undefined" ? createModule2 : {}; + var readyPromiseResolve, readyPromiseReject; + Module["ready"] = new Promise(function(resolve, reject) { + readyPromiseResolve = resolve; + readyPromiseReject = reject; + }); + var moduleOverrides = {}; + var key; + for (key in Module) { + if (Module.hasOwnProperty(key)) { + moduleOverrides[key] = Module[key]; + } + } + var scriptDirectory = ""; + function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; + } + var read_, readBinary; + var nodeFS; + var nodePath; + { + { + scriptDirectory = __dirname + "/"; + } + read_ = function shell_read(filename, binary) { + var ret = tryParseAsDataURI(filename); + if (ret) { + return binary ? ret : ret.toString(); + } + if (!nodeFS) + nodeFS = frozenFs; + if (!nodePath) + nodePath = path__default.default; + filename = nodePath["normalize"](filename); + return nodeFS["readFileSync"](filename, binary ? null : "utf8"); + }; + readBinary = function readBinary2(filename) { + var ret = read_(filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; + }; + if (process["argv"].length > 1) { + process["argv"][1].replace(/\\/g, "/"); + } + process["argv"].slice(2); + Module["inspect"] = function() { + return "[Emscripten Module object]"; + }; + } + var out = Module["print"] || console.log.bind(console); + var err = Module["printErr"] || console.warn.bind(console); + for (key in moduleOverrides) { + if (moduleOverrides.hasOwnProperty(key)) { + Module[key] = moduleOverrides[key]; + } + } + moduleOverrides = null; + if (Module["arguments"]) + ; + if (Module["thisProgram"]) + ; + if (Module["quit"]) + ; + var STACK_ALIGN = 16; + function alignMemory(size, factor) { + if (!factor) + factor = STACK_ALIGN; + return Math.ceil(size / factor) * factor; + } + var wasmBinary; + if (Module["wasmBinary"]) + wasmBinary = Module["wasmBinary"]; + Module["noExitRuntime"] || true; + if (typeof WebAssembly !== "object") { + abort("no native wasm support detected"); + } + function getValue(ptr, type, noSafe) { + type = type || "i8"; + if (type.charAt(type.length - 1) === "*") + type = "i32"; + switch (type) { + case "i1": + return HEAP8[ptr >> 0]; + case "i8": + return HEAP8[ptr >> 0]; + case "i16": + return HEAP16[ptr >> 1]; + case "i32": + return HEAP32[ptr >> 2]; + case "i64": + return HEAP32[ptr >> 2]; + case "float": + return HEAPF32[ptr >> 2]; + case "double": + return HEAPF64[ptr >> 3]; + default: + abort("invalid type for getValue: " + type); + } + return null; + } + var wasmMemory; + var ABORT = false; + function assert(condition, text) { + if (!condition) { + abort("Assertion failed: " + text); + } + } + function getCFunc(ident) { + var func = Module["_" + ident]; + assert( + func, + "Cannot call unknown function " + ident + ", make sure it is exported" + ); + return func; + } + function ccall(ident, returnType, argTypes, args, opts) { + var toC = { + string: function(str) { + var ret2 = 0; + if (str !== null && str !== void 0 && str !== 0) { + var len = (str.length << 2) + 1; + ret2 = stackAlloc(len); + stringToUTF8(str, ret2, len); + } + return ret2; + }, + array: function(arr) { + var ret2 = stackAlloc(arr.length); + writeArrayToMemory(arr, ret2); + return ret2; + } + }; + function convertReturnValue(ret2) { + if (returnType === "string") + return UTF8ToString(ret2); + if (returnType === "boolean") + return Boolean(ret2); + return ret2; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) + stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func.apply(null, cArgs); + ret = convertReturnValue(ret); + if (stack !== 0) + stackRestore(stack); + return ret; + } + function cwrap(ident, returnType, argTypes, opts) { + argTypes = argTypes || []; + var numericArgs = argTypes.every(function(type) { + return type === "number"; + }); + var numericRet = returnType !== "string"; + if (numericRet && numericArgs && !opts) { + return getCFunc(ident); + } + return function() { + return ccall(ident, returnType, argTypes, arguments); + }; + } + var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : void 0; + function UTF8ArrayToString(heap, idx, maxBytesToRead) { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + while (heap[endPtr] && !(endPtr >= endIdx)) + ++endPtr; + if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { + return UTF8Decoder.decode(heap.subarray(idx, endPtr)); + } else { + var str = ""; + while (idx < endPtr) { + var u0 = heap[idx++]; + if (!(u0 & 128)) { + str += String.fromCharCode(u0); + continue; + } + var u1 = heap[idx++] & 63; + if ((u0 & 224) == 192) { + str += String.fromCharCode((u0 & 31) << 6 | u1); + continue; + } + var u2 = heap[idx++] & 63; + if ((u0 & 240) == 224) { + u0 = (u0 & 15) << 12 | u1 << 6 | u2; + } else { + u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63; + } + if (u0 < 65536) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 65536; + str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); + } + } + } + return str; + } + function UTF8ToString(ptr, maxBytesToRead) { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; + } + function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + if (!(maxBytesToWrite > 0)) + return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = 65536 + ((u & 1023) << 10) | u1 & 1023; + } + if (u <= 127) { + if (outIdx >= endIdx) + break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) + break; + heap[outIdx++] = 192 | u >> 6; + heap[outIdx++] = 128 | u & 63; + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) + break; + heap[outIdx++] = 224 | u >> 12; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } else { + if (outIdx + 3 >= endIdx) + break; + heap[outIdx++] = 240 | u >> 18; + heap[outIdx++] = 128 | u >> 12 & 63; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } + } + heap[outIdx] = 0; + return outIdx - startIdx; + } + function stringToUTF8(str, outPtr, maxBytesToWrite) { + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + } + function lengthBytesUTF8(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) + u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; + if (u <= 127) + ++len; + else if (u <= 2047) + len += 2; + else if (u <= 65535) + len += 3; + else + len += 4; + } + return len; + } + function allocateUTF8(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) + stringToUTF8Array(str, HEAP8, ret, size); + return ret; + } + function writeArrayToMemory(array, buffer2) { + HEAP8.set(array, buffer2); + } + function alignUp(x, multiple) { + if (x % multiple > 0) { + x += multiple - x % multiple; + } + return x; + } + var buffer, HEAP8, HEAPU8, HEAP16, HEAP32, HEAPF32, HEAPF64; + function updateGlobalBufferAndViews(buf) { + buffer = buf; + Module["HEAP8"] = HEAP8 = new Int8Array(buf); + Module["HEAP16"] = HEAP16 = new Int16Array(buf); + Module["HEAP32"] = HEAP32 = new Int32Array(buf); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf); + Module["HEAPU16"] = new Uint16Array(buf); + Module["HEAPU32"] = new Uint32Array(buf); + Module["HEAPF32"] = HEAPF32 = new Float32Array(buf); + Module["HEAPF64"] = HEAPF64 = new Float64Array(buf); + } + Module["INITIAL_MEMORY"] || 16777216; + var wasmTable; + var __ATPRERUN__ = []; + var __ATINIT__ = []; + var __ATPOSTRUN__ = []; + function preRun() { + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") + Module["preRun"] = [Module["preRun"]]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); + } + function initRuntime() { + if (!Module["noFSInit"] && !FS.init.initialized) + FS.init(); + callRuntimeCallbacks(__ATINIT__); + } + function postRun() { + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") + Module["postRun"] = [Module["postRun"]]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + callRuntimeCallbacks(__ATPOSTRUN__); + } + function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); + } + function addOnInit(cb) { + __ATINIT__.unshift(cb); + } + function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); + } + var runDependencies = 0; + var dependenciesFulfilled = null; + function addRunDependency(id) { + runDependencies++; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + } + function removeRunDependency(id) { + runDependencies--; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } + } + Module["preloadedImages"] = {}; + Module["preloadedAudios"] = {}; + function abort(what) { + if (Module["onAbort"]) { + Module["onAbort"](what); + } + what += ""; + err(what); + ABORT = true; + what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; + var e = new WebAssembly.RuntimeError(what); + readyPromiseReject(e); + throw e; + } + var dataURIPrefix = "data:application/octet-stream;base64,"; + function isDataURI(filename) { + return filename.startsWith(dataURIPrefix); + } + var wasmBinaryFile = "data:application/octet-stream;base64,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ACgCFC0AAiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQADIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAQgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABSAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAGIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAcgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAJIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAogACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACyAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAMIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAA0gACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ADiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAPIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhRBEGo2AhQgACAAKAIIQQFrIgE2AgggAQ0ACyAAIAAoAhhB8f8DcDYCGCAAIAAoAgxB8f8DcDYCDAwBCwsgACgCEARAA0AgACgCEEEQTwRAIAAgACgCEEEQazYCECAAIAAoAhQtAAAgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AASAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQACIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAMgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAFIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAYgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AByAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAIIAAoAhhqNgIYIAAgACgCGCAAKAIMajYC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NgIYIAEoAgxCADcDICABKAIMQgA3AyggASgCDEEANgIwIAEoAgxBADYCNCABKAIMQQA2AjggASgCDEEANgI8IAEoAgxBADsBQCABKAIMQYCA2I14NgJEIAEoAgxCADcDSCABKAIMQQA7AVAgASgCDEEAOwFSIAEoAgxBADYCVAvSEwEBfyMAQbABayIDJAAgAyAANgKoASADIAE2AqQBIAMgAjYCoAEgA0EANgKQASADIAMoAqQBKAIwQQAQOjYClAEgAyADKAKkASgCOEEAEDo2ApgBAkACQAJAAkAgAygClAFBAkYEQCADKAKYAUEBRg0BCyADKAKUAUEBRgRAIAMoApgBQQJGDQELIAMoApQBQQJHDQEgAygCmAFBAkcNAQsgAygCpAEiACAALwEMQYAQcjsBDAwBCyADKAKkASIAIAAvAQxB/+8DcTsBDCADKAKUAUECRgRAIANB9eABIAMoAqQBKAIwIAMoAqgBQQhqEI4BNgKQASADKAKQAUUEQCADQX82AqwBDAMLCwJAIAMoAqABQYACcQ0AIAMoApgBQQJHDQAgA0H1xgEgAygCpAEoAjggAygCqAFBCGoQjgE2AkggAygCSEUEQCADKAKQARAjIANBfzYCrAEMAwsgAygCSCADKAKQATYCACADIAMoAkg2ApABCwsCQCADKAKkAS8BUkUEQCADKAKkASIAIAAvAQxB/v8DcTsBDAwBCyADKAKkASIAIAAvAQxBAXI7AQwLIAMgAygCpAEgAygCoAEQZUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBApNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBQgAygCkAEQIyADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAtIAMoAhwgAygCpAEpAyAQLQwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLQsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAtCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC0LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIcEBYgAygCkAEQIyADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQVTYCjAEgAygCHBAWIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECk2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAgsgAygCEEECEB8gAygCEEG9EkECEEEgAygCECADKAKkAS8BUkH/AXEQlgEgAygCECADKAKkASgCEEH//wNxEB8CfyMAQRBrIgAgAygCEDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIQEBYgAygCkAEQIyADQX82AqwBDAILIANBgbICQQcgA0EVakGABhBVNgIMIAMoAhAQFiADKAIMIAMoApABNgIAIAMgAygCDDYCkAELIAMgA0HQAGpCLhApIgA2AkwgAEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAQsgAygCTEHxEkH2EiADKAKgAUGAAnEbQQQQQSADKAKgAUGAAnFFBEAgAygCTCADLQCGAUEBcQR/QS0FIAMoAqQBLwEIC0H//wNxEB8LIAMoAkwgAy0AhgFBAXEEf0EtBSADKAKkAS8BCgtB//8DcRAfIAMoAkwgAygCpAEvAQwQHwJAIAMtAIUBQQFxBEAgAygCTEHjABAfDAELIAMoAkwgAygCpAEoAhBB//8DcRAfCyADKAKkASgCFCADQZ4BaiADQZwBahCNASADKAJMIAMvAZ4BEB8gAygCTCADLwGcARAfAkACQCADLQCFAUEBcUUNACADKAKkASkDKEIUWg0AIAMoAkxBABAhDAELIAMoAkwgAygCpAEoAhgQIQsCQAJAIAMoAqABQYACcUGAAkcNACADKAKkASkDIEL/////D1QEQCADKAKkASkDKEL/////D1QNAQsgAygCTEF/ECEgAygCTEF/ECEMAQsCQCADKAKkASkDIEL/////D1QEQCADKAJMIAMoAqQBKQMgpxAhDAELIAMoAkxBfxAhCwJAIAMoAqQBKQMoQv////8PVARAIAMoAkwgAygCpAEpAyinECEMAQsgAygCTEF/ECELCyADKAJMIAMoAqQBKAIwEFFB//8DcRAfIAMgAygCpAEoAjQgAygCoAEQkgFB//8DcSADKAKQAUGABhCSAUH//wNxajYCiAEgAygCTCADKAKIAUH//wNxEB8gAygCoAFBgAJxRQRAIAMoAkwgAygCpAEoAjgQUUH//wNxEB8gAygCTCADKAKkASgCPEH//wNxEB8gAygCTCADKAKkAS8BQBAfIAMoAkwgAygCpAEoAkQQIQJAIAMoAqQBKQNIQv////8PVARAIAMoAkwgAygCpAEpA0inECEMAQsgAygCTEF/ECELCwJ/IwBBEGsiACADKAJMNgIMIAAoAgwtAABBAXFFCwRAIAMoAqgBQQhqQRRBABAUIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCqAEgA0HQAGoCfiMAQRBrIgAgAygCTDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCTBAWIAMoApABECMgA0F/NgKsAQwBCyADKAJMEBYgAygCpAEoAjAEQCADKAKoASADKAKkASgCMBCFAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEEQCADKAKoASADKAKQAUGABhCRAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEQIyADKAKkASgCNARAIAMoAqgBIAMoAqQBKAI0IAMoAqABEJEBQQBIBEAgA0F/NgKsAQwCCwsgAygCoAFBgAJxRQRAIAMoAqQBKAI4BEAgAygCqAEgAygCpAEoAjgQhQFBAEgEQCADQX82AqwBDAMLCwsgAyADLQCHAUEBcTYCrAELIAMoAqwBIQAgA0GwAWokACAAC+ACAQF/IwBBIGsiBCQAIAQgADsBGiAEIAE7ARggBCACNgIUIAQgAzYCECAEQRAQGCIANgIMAkAg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AAAgAygCHEHcFmogAygCDEECdGooAgAgAygCHEHYKGpqLQAASg0ADAELIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhxB3BZqIAMoAgxBAnRqKAIANgIAIAMgAygCDDYCFCADIAMoAgxBAXQ2AgwMAQsLIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhA2AgAL1xMBA38jAEEwayICJAAgAiAANgIsIAIgATYCKCACIAIoAigoAgA2AiQgAiACKAIoKAIIKAIANgIgIAIgAigCKCgCCCgCDDYCHCACQX82AhAgAigCLEEANgLQKCACKAIsQb0ENgLUKCACQQA2AhgDQCACKAIYIAIoAhxIBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUEBazYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAU4EQCACKAIsIAIoAiQgAigCGBB5IAIgAigCGEEBazYCGAwBCwsgAiACKAIcNgIMA0AgAiACKAIsKALgFjYCGCACKAIsQdwWaiEBIAIoAiwiAygC0CghACADIABBAWs2AtAoIAIoAiwgAEECdCABaigCADYC4BYgAigCLCACKAIkQQEQeSACIAIoAiwoAuAWNgIUIAIoAhghASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIUIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQQFrIQAgBCAANgLUKCAA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AQsgAigCCEEANgIAIAIoAghCADcDECACKAIIQgA3AwggAigCCEIANwMgIAIoAghCADcDGCACKAIIQQA2AiggAigCCEEAOgAsIAIoAgggAikDECACKAIMEI8BQQFxRQRAIAIoAggQJSACQQA2AhwMAQsgAiACKAIINgIcCyACKAIcIQEgAkEgaiQAIAEL1gIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADQQxqQgQQKTYCCAJAIAMoAghFBEAgA0F/NgIcDAELA0AgAygCFARAIAMoAhQoAgQgAygCEHFBgAZxBEAgAygCCEIAECwaIAMoAgggAygCFC8BCBAfIAMoAgggAygCFC8BChAfAn8jAEEQayIAIAMoAgg2AgwgACgCDC0AAEEBcUULBEAgAygCGEEIakEUQQAQFCADKAIIEBYgA0F/NgIcDAQLIAMoAhggA0EMakIEEDZBAEgEQCADKAIIEBYgA0F/NgIcDAQLIAMoAhQvAQoEQCADKAIYIAMoAhQoAgwgAygCFC8BCq0QNkEASARAIAMoAggQFiADQX82AhwMBQsLCyADIAMoAhQoAgA2AhQMAQsLIAMoAggQFiADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtoAQF/IwBBEGsiAiAANgIMIAIgATYCCCACQQA7AQYDQCACKAIMBEAgAigCDCgCBCACKAIIcUGABnEEQCACIAIoAgwvAQogAi8BBkEEamo7AQYLIAIgAigCDCgCADYCDAwBCwsgAi8BBgvwAQEBfyMAQRBrIgEkACABIAA2AgwgASABKAIMNgIIIAFBADYCBANAIAEoAgwEQAJAAkAgASgCDC8BCEH1xgFGDQAgASgCDC8BCEH14AFGDQAgASgCDC8BCEGBsgJGDQAgASgCDC8BCEEBRw0BCyABIAEoAgwoAgA2AgAgASgCCCABKAIMRgRAIAEgASgCADYCCAsgASgCDEEANgIAIAEoAgwQIyABKAIEBEAgASgCBCABKAIANgIACyABIAEoAgA2AgwMAgsgASABKAIMNgIEIAEgASgCDCgCADYCDAwBCwsgASgCCCEAIAFBEGokACAAC7IEAQF/IwBBQGoiBSQAIAUgADYCOCAFIAE7ATYgBSACNgIwIAUgAzYCLCAFIAQ2AiggBSAFKAI4IAUvATatECkiADYCJAJAIABFBEAgBSgCKEEOQQAQFCAFQQA6AD8MAQsgBUEANgIgIAVBADYCGANAAn8jAEEQayIAIAUoAiQ2AgwgACgCDC0AAEEBcQsEfyAFKAIkEDBCBFoFQQALQQFxBEAgBSAFKAIkEB07ARYgBSAFKAIkEB07ARQgBSAFKAIkIAUvARStEB42AhAgBSgCEEUEQCAFKAIoQRVBABAUIAUoAiQQFiAFKAIYECMgBUEAOgA/DAMLIAUgBS8BFiAFLwEUIAUoAhAgBSgCMBBVIgA2AhwgAEUEQCAFKAIoQQ5BABAUIAUoAiQQFiAFKAIYECMgBUEAOgA/DAMLAkAgBSgCGARAIAUoAiAgBSgCHDYCACAFIAUoAhw2AiAMAQsgBSAFKAIcIgA2AiAgBSAANgIYCwwBCwsgBSgCJBBHQQFxRQRAIAUgBSgCJBAwPgIMIAUgBSgCJCAFKAIMrRAeNgIIAkACQCAFKAIMQQRPDQAgBSgCCEUNACAFKAIIQZEVIAUoAgwQT0UNAQsgBSgCKEEVQQAQFCAFKAIkEBYgBSgCGBAjIAVBADoAPwwCCwsgBSgCJBAWAkAgBSgCLARAIAUoAiwgBSgCGDYCAAwBCyAFKAIYECMLIAVBAToAPwsgBS0AP0EBcSEAIAVBQGskACAAC+8CAQF/IwBBIGsiAiQAIAIgADYCGCACIAE2AhQCQCACKAIYRQRAIAIgAigCFDYCHAwBCyACIAIoAhg2AggDQCACKAIIKAIABEAgAiACKAIIKAIANgIIDAELCwNAIAIoAhQEQCACIAIoAhQoAgA2AhAgAkEANgIEIAIgAigCGDYCDANAAkAgAigCDEUNAAJAIAIoAgwvAQggAigCFC8BCEcNACACKAIMLwEKIAIoAhQvAQpHDQAgAigCDC8BCgRAIAIoAgwoAgwgAigCFCgCDCACKAIMLwEKEE8NAQsgAigCDCIAIAAoAgQgAigCFCgCBEGABnFyNgIEIAJBATYCBAwBCyACIAIoAgwoAgA2AgwMAQsLIAIoAhRBADYCAAJAIAIoAgQEQCACKAIUECMMAQsgAigCCCACKAIUIgA2AgAgAiAANgIICyACIAIoAhA2AhQMAQsLIAIgAigCGDYCHAsgAigCHCEAIAJBIGokACAAC18BAX8jAEEQayICJAAgAiAANgIIIAIgAToAByACIAIoAghCARAeNgIAAkAgAigCAEUEQCACQX82AgwMAQsgAigCACACLQAHOgAAIAJBADYCDAsgAigCDBogAkEQaiQAC1QBAX8jAEEQayIBJAAgASAANgIIIAEgASgCCEIBEB42AgQCQCABKAIERQRAIAFBADoADwwBCyABIAEoAgQtAAA6AA8LIAEtAA8hACABQRBqJAAgAAucBgECfyMAQSBrIgIkACACIAA2AhggAiABNwMQAkAgAikDECACKAIYKQMwWgRAIAIoAhhBCGpBEkEAEBQgAkF/NgIcDAELIAIoAhgoAhhBAnEEQCACKAIYQQhqQRlBABAUIAJBfzYCHAwBCyACIAIoAhggAikDEEEAIAIoAhhBCGoQTSIANgIMIABFBEAgAkF/NgIcDAELIAIoAhgoAlAgAigCDCACKAIYQQhqEFlBAXFFBEAgAkF/NgIcDAELAn8gAigCGCEDIAIpAxAhASMAQTBrIgAkACAAIAM2AiggACABNwMgIABBATYCHAJAIAApAyAgACgCKCkDMFoEQCAAKAIoQQhqQRJBABAUIABBfzYCLAwBCwJAIAAoAhwNACAAKAIoKAJAIAApAyCnQQR0aigCBEUNACAAKAIoKAJAIAApAyCnQQR0aigCBCgCAEECcUUNAAJAIAAoAigoAkAgACkDIKdBBHRqKAIABEAgACAAKAIoIAApAyBBCCAAKAIoQQhqEE0iAzYCDCADRQRAIABBfzYCLAwECyAAIAAoAiggACgCDEEAQQAQWDcDEAJAIAApAxBCAFMNACAAKQMQIAApAyBRDQAgACgCKEEIakEKQQAQFCAAQX82AiwMBAsMAQsgAEEANgIMCyAAIAAoAiggACkDIEEAIAAoAihBCGoQTSIDNgIIIANFBEAgAEF/NgIsDAILIAAoAgwEQCAAKAIoKAJQIAAoAgwgACkDIEEAIAAoAihBCGoQdEEBcUUEQCAAQX82AiwMAwsLIAAoAigoAlAgACgCCCAAKAIoQQhqEFlBAXFFBEAgACgCKCgCUCAAKAIMQQAQWRogAEF/NgIsDAILCyAAKAIoKAJAIAApAyCnQQR0aigCBBA3IAAoAigoAkAgACkDIKdBBHRqQQA2AgQgACgCKCgCQCAAKQMgp0EEdGoQXiAAQQA2AiwLIAAoAiwhAyAAQTBqJAAgAwsEQCACQX82AhwMAQsgAigCGCgCQCACKQMQp0EEdGpBAToADCACQQA2AhwLIAIoAhwhACACQSBqJAAgAAulBAEBfyMAQTBrIgUkACAFIAA2AiggBSABNwMgIAUgAjYCHCAFIAM6ABsgBSAENgIUAkAgBSgCKCAFKQMgQQBBABA/RQRAIAVBfzYCLAwBCyAFKAIoKAIYQQJxBEAgBSgCKEEIakEZQQAQFCAFQX82AiwMAQsgBSAFKAIoKAJAIAUpAyCnQQR0ajYCECAFAn8gBSgCECgCAARAIAUoAhAoAgAvAQhBCHYMAQtBAws6AAsgBQJ/IAUoAhAoAgAEQCAFKAIQKAIAKAJEDAELQYCA2I14CzYCBEEBIQAgBSAFLQAbIAUtAAtGBH8gBSgCFCAFKAIERwVBAQtBAXE2AgwCQCAFKAIMBEAgBSgCECgCBEUEQCAFKAIQKAIAEEAhACAFKAIQIAA2AgQgAEUEQCAFKAIoQQhqQQ5BABAUIAVBfzYCLAwECwsgBSgCECgCBCAFKAIQKAIELwEIQf8BcSAFLQAbQQh0cjsBCCAFKAIQKAIEIAUoAhQ2AkQgBSgCECgCBCIAIAAoAgBBEHI2AgAMAQsgBSgCECgCBARAIAUoAhAoAgQiACAAKAIAQW9xNgIAAkAgBSgCECgCBCgCAEUEQCAFKAIQKAIEEDcgBSgCEEEANgIEDAELIAUoAhAoAgQgBSgCECgCBC8BCEH/AXEgBS0AC0EIdHI7AQggBSgCECgCBCAFKAIENgJECwsLIAVBADYCLAsgBSgCLCEAIAVBMGokACAAC90PAgF/AX4jAEFAaiIEJAAgBCAANgI0IARCfzcDKCAEIAE2AiQgBCACNgIgIAQgAzYCHAJAIAQoAjQoAhhBAnEEQCAEKAI0QQhqQRlBABAUIARCfzcDOAwBCyAEIAQoAjQpAzA3AxAgBCkDKEJ/UQRAIARCfzcDCCAEKAIcQYDAAHEEQCAEIAQoAjQgBCgCJCAEKAIcQQAQWDcDCAsgBCkDCEJ/UQRAIAQoAjQhASMAQUBqIgAkACAAIAE2AjQCQCAAKAI0KQM4IAAoAjQpAzBCAXxYBEAgACAAKAI0KQM4NwMYIAAgACkDGEIBhjcDEAJAIAApAxBCEFQEQCAAQhA3AxAMAQsgACkDEEKACFYEQCAAQoAINwMQCwsgACAAKQMQIAApAxh8NwMYIAAgACkDGKdBBHStNwMIIAApAwggACgCNCkDOKdBBHStVARAIAAoAjRBCGpBDkEAEBQgAEJ/NwM4DAILIAAgACgCNCgCQCAAKQMYp0EEdBBONgIkIAAoAiRFBEAgACgCNEEIakEOQQAQFCAAQn83AzgMAgsgACgCNCAAKAIkNgJAIAAoAjQgACkDGDcDOAsgACgCNCIBKQMwIQUgASAFQgF8NwMwIAAgBTcDKCAAKAI0KAJAIAApAyinQQR0ahC1ASAAIAApAyg3AzgLIAApAzghBSAAQUBrJAAgBCAFNwMIIAVCAFMEQCAEQn83AzgMAwsLIAQgBCkDCDcDKAsCQCAEKAIkRQ0AIAQoAjQhASAEKQMoIQUgBCgCJCECIAQoAhwhAyMAQUBqIgAkACAAIAE2AjggACAFNwMwIAAgAjYCLCAAIAM2AigCQCAAKQMwIAAoAjgpAzBaBEAgACgCOEEIakESQQAQFCAAQX82AjwMAQsgACgCOCgCGEECcQRAIAAoAjhBCGpBGUEAEBQgAEF/NgI8DAELAkACQCAAKAIsRQ0AIAAoAiwsAABFDQAgACAAKAIsIAAoAiwQLkH//wNxIAAoAiggACgCOEEIahBQIgE2AiAgAUUEQCAAQX82AjwMAwsCQCAAKAIoQYAwcQ0AIAAoAiBBABA6QQNHDQAgACgCIEECNgIICwwBCyAAQQA2AiALIAAgACgCOCAAKAIsQQBBABBYIgU3AxACQCAFQgBTDQAgACkDECAAKQMwUQ0AIAAoAiAQJCAAKAI4QQhqQQpBABAUIABBfzYCPAwBCwJAIAApAxBCAFMNACAAKQMQIAApAzBSDQAgACgCIBAkIABBADYCPAwBCyAAIAAoAjgoAkAgACkDMKdBBHRqNgIkAkAgACgCJCgCAARAIAAgACgCJCgCACgCMCAAKAIgEIYBQQBHOgAfDAELIABBADoAHwsCQCAALQAfQQFxDQAgACgCJCgCBA0AIAAoAiQoAgAQQCEBIAAoAiQgATYCBCABRQRAIAAoAjhBCGpBDkEAEBQgACgCIBAkIABBfzYCPAwCCwsgAAJ/IAAtAB9BAXEEQCAAKAIkKAIAKAIwDAELIAAoAiALQQBBACAAKAI4QQhqEEYiATYCCCABRQRAIAAoAiAQJCAAQX82AjwMAQsCQCAAKAIkKAIEBEAgACAAKAIkKAIEKAIwNgIEDAELAkAgACgCJCgCAARAIAAgACgCJCgCACgCMDYCBAwBCyAAQQA2AgQLCwJAIAAoAgQEQCAAIAAoAgRBAEEAIAAoAjhBCGoQRiIBNgIMIAFFBEAgACgCIBAkIABBfzYCPAwDCwwBCyAAQQA2AgwLIAAoAjgoAlAgACgCCCAAKQMwQQAgACgCOEEIahB0QQFxRQRAIAAoAiAQJCAAQX82AjwMAQsgACgCDARAIAAoAjgoAlAgACgCDEEAEFkaCwJAIAAtAB9BAXEEQCAAKAIkKAIEBEAgACgCJCgCBCgCAEECcQRAIAAoAiQoAgQoAjAQJCAAKAIkKAIEIgEgASgCAEF9cTYCAAJAIAAoAiQoAgQoAgBFBEAgACgCJCgCBBA3IAAoAiRBADYCBAwBCyAAKAIkKAIEIAAoAiQoAgAoAjA2AjALCwsgACgCIBAkDAELIAAoAiQoAgQoAgBBAnEEQCAAKAIkKAIEKAIwECQLIAAoAiQoAgQiASABKAIAQQJyNgIAIAAoAiQoAgQgACgCIDYCMAsgAEEANgI8CyAAKAI8IQEgAEFAayQAIAFFDQAgBCgCNCkDMCAEKQMQUgRAIAQoAjQoAkAgBCkDKKdBBHRqEHcgBCgCNCAEKQMQNwMwCyAEQn83AzgMAQsgBCgCNCgCQCAEKQMop0EEdGoQXgJAIAQoAjQoAkAgBCkDKKdBBHRqKAIARQ0AIAQoAjQoAkAgBCkDKKdBBHRqKAIEBEAgBCgCNCgCQCAEKQMop0EEdGooAgQoAgBBAXENAQsgBCgCNCgCQCAEKQMop0EEdGooAgRFBEAgBCgCNCgCQCAEKQMop0EEdGooAgAQQCEAIAQoAjQoAkAgBCkDKKdBBHRqIAA2AgQgAEUEQCAEKAI0QQhqQQ5BABAUIARCfzcDOAwDCwsgBCgCNCgCQCAEKQMop0EEdGooAgRBfjYCECAEKAI0KAJAIAQpAyinQQR0aigCBCIAIAAoAgBBAXI2AgALIAQoAjQoAkAgBCkDKKdBBHRqIAQoAiA2AgggBCAEKQMoNwM4CyAEKQM4IQUgBEFAayQAIAULqgEBAX8jAEEwayICJAAgAiAANgIoIAIgATcDICACQQA2AhwCQAJAIAIoAigoAiRBAUYEQCACKAIcRQ0BIAIoAhxBAUYNASACKAIcQQJGDQELIAIoAihBDGpBEkEAEBQgAkF/NgIsDAELIAIgAikDIDcDCCACIAIoAhw2AhAgAkF/QQAgAigCKCACQQhqQhBBDBAgQgBTGzYCLAsgAigCLCEAIAJBMGokACAAC6UyAwZ/AX4BfCMAQeAAayIEJAAgBCAANgJYIAQgATYCVCAEIAI2AlACQAJAIAQoAlRBAE4EQCAEKAJYDQELIAQoAlBBEkEAEBQgBEEANgJcDAELIAQgBCgCVDYCTCMAQRBrIgAgBCgCWDYCDCAEIAAoAgwpAxg3A0BB4JoBKQMAQn9RBEAgBEF/NgIUIARBAzYCECAEQQc2AgwgBEEGNgIIIARBAjYCBCAEQQE2AgBB4JoBQQAgBBA0NwMAIARBfzYCNCAEQQ82AjAgBEENNgIsIARBDDYCKCAEQQo2AiQgBEEJNgIgQeiaAUEIIARBIGoQNDcDAAtB4JoBKQMAIAQpA0BB4JoBKQMAg1IEQCAEKAJQQRxBABAUIARBADYCXAwBC0HomgEpAwAgBCkDQEHomgEpAwCDUgRAIAQgBCgCTEEQcjYCTAsgBCgCTEEYcUEYRgRAIAQoAlBBGUEAEBQgBEEANgJcDAELIAQoAlghASAEKAJQIQIjAEHQAGsiACQAIAAgATYCSCAAIAI2AkQgAEEIahA7AkAgACgCSCAAQQhqEDkEQCMAQRBrIgEgACgCSDYCDCAAIAEoAgxBDGo2AgQjAEEQayIBIAAoAgQ2AgwCQCABKAIMKAIAQQVHDQAjAEEQayIBIAAoAgQ2AgwgASgCDCgCBEEsRw0AIABBADYCTAwCCyAAKAJEIAAoAgQQRSAAQX82AkwMAQsgAEEBNgJMCyAAKAJMIQEgAEHQAGokACAEIAE2AjwCQAJAAkAgBCgCPEEBag4CAAECCyAEQQA2AlwMAgsgBCgCTEEBcUUEQCAEKAJQQQlBABAUIARBADYCXAwCCyAEIAQoAlggBCgCTCAEKAJQEGk2AlwMAQsgBCgCTEECcQRAIAQoAlBBCkEAEBQgBEEANgJcDAELIAQoAlgQSEEASARAIAQoAlAgBCgCWBAXIARBADYCXAwBCwJAIAQoAkxBCHEEQCAEIAQoAlggBCgCTCAEKAJQEGk2AjgMAQsgBCgCWCEAIAQoAkwhASAEKAJQIQIjAEHwAGsiAyQAIAMgADYCaCADIAE2AmQgAyACNgJgIANBIGoQOwJAIAMoAmggA0EgahA5QQBIBEAgAygCYCADKAJoEBcgA0EANgJsDAELIAMpAyBCBINQBEAgAygCYEEEQYoBEBQgA0EANgJsDAELIAMgAykDODcDGCADIAMoAmggAygCZCADKAJgEGkiADYCXCAARQRAIANBADYCbAwBCwJAIAMpAxhQRQ0AIAMoAmgQngFBAXFFDQAgAyADKAJcNgJsDAELIAMoAlwhACADKQMYIQkjAEHgAGsiAiQAIAIgADYCWCACIAk3A1ACQCACKQNQQhZUBEAgAigCWEEIakETQQAQFCACQQA2AlwMAQsgAgJ+IAIpA1BCqoAEVARAIAIpA1AMAQtCqoAECzcDMCACKAJYKAIAQgAgAikDMH1BAhAnQQBIBEAjAEEQayIAIAIoAlgoAgA2AgwgAiAAKAIMQQxqNgIIAkACfyMAQRBrIgAgAigCCDYCDCAAKAIMKAIAQQRGCwRAIwBBEGsiACACKAIINgIMIAAoAgwoAgRBFkYNAQsgAigCWEEIaiACKAIIEEUgAkEANgJcDAILCyACIAIoAlgoAgAQSSIJNwM4IAlCAFMEQCACKAJYQQhqIAIoAlgoAgAQFyACQQA2AlwMAQsgAiACKAJYKAIAIAIpAzBBACACKAJYQQhqEEIiADYCDCAARQRAIAJBADYCXAwBCyACQn83AyAgAkEANgJMIAIpAzBCqoAEWgRAIAIoAgxCFBAsGgsgAkEQakETQQAQFCACIAIoAgxCABAeNgJEA0ACQCACKAJEIQEgAigCDBAwQhJ9pyEFIwBBIGsiACQAIAAgATYCGCAAIAU2AhQgAEHsEjYCECAAQQQ2AgwCQAJAIAAoAhQgACgCDE8EQCAAKAIMDQELIABBADYCHAwBCyAAIAAoAhhBAWs2AggDQAJAIAAgACgCCEEBaiAAKAIQLQAAIAAoAhggACgCCGsgACgCFCAAKAIMa2oQqwEiATYCCCABRQ0AIAAoAghBAWogACgCEEEBaiAAKAIMQQFrEE8NASAAIAAoAgg2AhwMAgsLIABBADYCHAsgACgCHCEBIABBIGokACACIAE2AkQgAUUNACACKAIMIAIoAkQCfyMAQRBrIgAgAigCDDYCDCAAKAIMKAIEC2usECwaIAIoAlghASACKAIMIQUgAikDOCEJIwBB8ABrIgAkACAAIAE2AmggACAFNgJkIAAgCTcDWCAAIAJBEGo2AlQjAEEQayIBIAAoAmQ2AgwgAAJ+IAEoAgwtAABBAXEEQCABKAIMKQMQDAELQgALNwMwAkAgACgCZBAwQhZUBEAgACgCVEETQQAQFCAAQQA2AmwMAQsgACgCZEIEEB4oAABB0JaVMEcEQCAAKAJUQRNBABAUIABBADYCbAwBCwJAAkAgACkDMEIUVA0AIwBBEGsiASAAKAJkNgIMIAEoAgwoAgQgACkDMKdqQRRrKAAAQdCWmThHDQAgACgCZCAAKQMwQhR9ECwaIAAoAmgoAgAhBSAAKAJkIQYgACkDWCEJIAAoAmgoAhQhByAAKAJUIQgjAEGwAWsiASQAIAEgBTYCqAEgASAGNgKkASABIAk3A5gBIAEgBzYClAEgASAINgKQASMAQRBrIgUgASgCpAE2AgwgAQJ+IAUoAgwtAABBAXEEQCAFKAIMKQMQDAELQgALNwMYIAEoAqQBQgQQHhogASABKAKkARAdQf//A3E2AhAgASABKAKkARAdQf//A3E2AgggASABKAKkARAxNwM4AkAgASkDOEL///////////8AVgRAIAEoApABQQRBFhAUIAFBADYCrAEMAQsgASkDOEI4fCABKQMYIAEpA5gBfFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELAkACQCABKQM4IAEpA5gBVA0AIAEpAzhCOHwgASkDmAECfiMAQRBrIgUgASgCpAE2AgwgBSgCDCkDCAt8Vg0AIAEoAqQBIAEpAzggASkDmAF9ECwaIAFBADoAFwwBCyABKAKoASABKQM4QQAQJ0EASARAIAEoApABIAEoAqgBEBcgAUEANgKsAQwCCyABIAEoAqgBQjggAUFAayABKAKQARBCIgU2AqQBIAVFBEAgAUEANgKsAQwCCyABQQE6ABcLIAEoAqQBQgQQHigAAEHQlpkwRwRAIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELIAEgASgCpAEQMTcDMAJAIAEoApQBQQRxRQ0AIAEpAzAgASkDOHxCDHwgASkDmAEgASkDGHxRDQAgASgCkAFBFUEAEBQgAS0AF0EBcQRAIAEoAqQBEBYLIAFBADYCrAEMAQsgASgCpAFCBBAeGiABIAEoAqQBECo2AgwgASABKAKkARAqNgIEIAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AyggASABKAKkARAxNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AzAgASABKAKkARAxNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCQASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQMEIWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJI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ECADQcgAEBgiADYCDAJAIABFBEAgAygCEEEBQbSbASgCABAUIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAACzgBAX8jAEEQayIBIAA2AgwgASgCDEEANgIAIAEoAgxBADYCBCABKAIMQQA2AgggASgCDEEAOgAMC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEF0gAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQdhogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQdhogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBdIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHgEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIc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DQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQLgJ/IAEoAqQBBEAgASgCpAEQLkECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAsIAEEBQTgQfwszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMI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ADYCtC0gASgCFEEERgRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQEQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUECNgIcDAILIAFBAzYCHAwBCyABKAIYKAKgLQRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQAQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUEANgIcDAILCyABQQE2AhwLIAEoAhwhAiABQSBqJAAgAgwBCwJ/IAAoAiwoAogBQQNGBEAgACgCLCECIAAoAjQhAyMAQTBrIgEkACABIAI2AiggASADNgIkAkADQAJAIAEoAigoAnRBggJNBEAgASgCKBBcAkAgASgCKCgCdEGCAksNACABKAIkDQAgAUEANgIsDAQLIAEoAigoAnRFDQELIAEoAihBADYCYAJAIAEoAigoAnRBA0kNACABKAIoKAJsRQ0AIAEgASgCKCgCOCABKAIoKAJsakEBazYCGCABIAEoAhgtAAA2AhwgASgCHCECIAEgASgCGCIDQQFqNgIYAkAgAy0AASACRw0AIAEoAhwhAiABIAEoAhgiA0EBajYCGCADLQABIAJHDQAgASgCHCECIAEgASgCGCIDQQFqNgIYIAMtAAEgAkcNACABIAEoAigoAjggASgCKCgCbGpBggJqNgIUA0AgASgCHCECIAEgASgCGCIDQQFqNgIYAn9BACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABog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AS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIIQQNrNgIIIAEoAghBAksNAAsLIAEoAggEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEoAghBAUsEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAACwsMAgsgASgCDEHAAHFFBEAgASABKAIgIAEvARIgASgCLEEBIAEoAgx0QQFrcWpBAnRqKAEANgEQDAELCyAB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AG5hbgAvZGV2L3VyYW5kb20AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoAGluZgBpbnZhbGlkIHdpbmRvdyBzaXplAFJlYWQtb25seSBhcmNoaXZlAE5vdCBhIHppcCBhcmNoaXZlAFJlc291cmNlIHN0aWxsIGluIHVzZQBNYWxsb2MgZmFpbHVyZQBpbnZhbGlkIGJsb2NrIHR5cGUARmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUAQ2FuJ3Qgb3BlbiBmaWxlAE5vIHN1Y2ggZmlsZQBQcmVtYXR1cmUgZW5kIG9mIGZpbGUAQ2FuJ3QgcmVtb3ZlIGZpbGUAaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlAGludmFsaWQgZGlzdGFuY2UgY29kZQB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABzdHJlYW0gZW5kAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAE11bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQAT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQARW5jcnlwdGlvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABFbnRyeSBoYXMgYmVlbiBkZWxldGVkAENvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZABDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQARW50cnkgaGFzIGJlZW4gY2hhbmdlZABObyBwYXNzd29yZCBwcm92aWRlZABXcm9uZyBwYXNzd29yZCBwcm92aWRlZABVbmtub3duIGVycm9yICVkAHJiAHIrYgByd2EAJXMuWFhYWFhYAE5BTgBJTkYAQUUAMS4yLjExAC9wcm9jL3NlbGYvZmQvAC4AKG51bGwpADogAFBLBgcA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0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8="; + if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); + } + function getBinary(file) { + try { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + var binary = tryParseAsDataURI(file); + if (binary) { + return binary; + } + if (readBinary) { + return readBinary(file); + } else { + throw "sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"; + } + } catch (err2) { + abort(err2); + } + } + function instantiateSync(file, info) { + var instance; + var module2; + var binary; + try { + binary = getBinary(file); + module2 = new WebAssembly.Module(binary); + instance = new WebAssembly.Instance(module2, info); + } catch (e) { + var str = e.toString(); + err("failed to compile wasm module: " + str); + if (str.includes("imported Memory") || str.includes("memory import")) { + err( + "Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)." + ); + } + throw e; + } + return [instance, module2]; + } + function createWasm() { + var info = { a: asmLibraryArg }; + function receiveInstance(instance, module2) { + var exports3 = instance.exports; + Module["asm"] = exports3; + wasmMemory = Module["asm"]["u"]; + updateGlobalBufferAndViews(wasmMemory.buffer); + wasmTable = Module["asm"]["pa"]; + addOnInit(Module["asm"]["v"]); + removeRunDependency(); + } + addRunDependency(); + if (Module["instantiateWasm"]) { + try { + var exports2 = Module["instantiateWasm"](info, receiveInstance); + return exports2; + } catch (e) { + err("Module.instantiateWasm callback failed with error: " + e); + return false; + } + } + var result = instantiateSync(wasmBinaryFile, info); + receiveInstance(result[0]); + return Module["asm"]; + } + var tempDouble; + var tempI64; + function callRuntimeCallbacks(callbacks) { + while (callbacks.length > 0) { + var callback = callbacks.shift(); + if (typeof callback == "function") { + callback(Module); + continue; + } + var func = callback.func; + if (typeof func === "number") { + if (callback.arg === void 0) { + wasmTable.get(func)(); + } else { + wasmTable.get(func)(callback.arg); + } + } else { + func(callback.arg === void 0 ? null : callback.arg); + } + } + } + function _gmtime_r(time, tmPtr) { + var date = new Date(HEAP32[time >> 2] * 1e3); + HEAP32[tmPtr >> 2] = date.getUTCSeconds(); + HEAP32[tmPtr + 4 >> 2] = date.getUTCMinutes(); + HEAP32[tmPtr + 8 >> 2] = date.getUTCHours(); + HEAP32[tmPtr + 12 >> 2] = date.getUTCDate(); + HEAP32[tmPtr + 16 >> 2] = date.getUTCMonth(); + HEAP32[tmPtr + 20 >> 2] = date.getUTCFullYear() - 1900; + HEAP32[tmPtr + 24 >> 2] = date.getUTCDay(); + HEAP32[tmPtr + 36 >> 2] = 0; + HEAP32[tmPtr + 32 >> 2] = 0; + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; + HEAP32[tmPtr + 28 >> 2] = yday; + if (!_gmtime_r.GMTString) + _gmtime_r.GMTString = allocateUTF8("GMT"); + HEAP32[tmPtr + 40 >> 2] = _gmtime_r.GMTString; + return tmPtr; + } + function ___gmtime_r(a0, a1) { + return _gmtime_r(a0, a1); + } + var PATH = { + splitPath: function(filename) { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: function(parts, allowAboveRoot) { + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === ".") { + parts.splice(i, 1); + } else if (last === "..") { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + if (allowAboveRoot) { + for (; up; up--) { + parts.unshift(".."); + } + } + return parts; + }, + normalize: function(path) { + var isAbsolute = path.charAt(0) === "/", trailingSlash = path.substr(-1) === "/"; + path = PATH.normalizeArray( + path.split("/").filter(function(p) { + return !!p; + }), + !isAbsolute + ).join("/"); + if (!path && !isAbsolute) { + path = "."; + } + if (path && trailingSlash) { + path += "/"; + } + return (isAbsolute ? "/" : "") + path; + }, + dirname: function(path) { + var result = PATH.splitPath(path), root = result[0], dir = result[1]; + if (!root && !dir) { + return "."; + } + if (dir) { + dir = dir.substr(0, dir.length - 1); + } + return root + dir; + }, + basename: function(path) { + if (path === "/") + return "/"; + path = PATH.normalize(path); + path = path.replace(/\/$/, ""); + var lastSlash = path.lastIndexOf("/"); + if (lastSlash === -1) + return path; + return path.substr(lastSlash + 1); + }, + extname: function(path) { + return PATH.splitPath(path)[3]; + }, + join: function() { + var paths = Array.prototype.slice.call(arguments, 0); + return PATH.normalize(paths.join("/")); + }, + join2: function(l, r) { + return PATH.normalize(l + "/" + r); + } + }; + function getRandomDevice() { + { + try { + var crypto_module = require("crypto"); + return function() { + return crypto_module["randomBytes"](1)[0]; + }; + } catch (e) { + } + } + return function() { + abort("randomDevice"); + }; + } + var PATH_FS = { + resolve: function() { + var resolvedPath = "", resolvedAbsolute = false; + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = i >= 0 ? arguments[i] : FS.cwd(); + if (typeof path !== "string") { + throw new TypeError("Arguments to path.resolve must be strings"); + } else if (!path) { + return ""; + } + resolvedPath = path + "/" + resolvedPath; + resolvedAbsolute = path.charAt(0) === "/"; + } + resolvedPath = PATH.normalizeArray( + resolvedPath.split("/").filter(function(p) { + return !!p; + }), + !resolvedAbsolute + ).join("/"); + return (resolvedAbsolute ? "/" : "") + resolvedPath || "."; + }, + relative: function(from, to) { + from = PATH_FS.resolve(from).substr(1); + to = PATH_FS.resolve(to).substr(1); + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== "") + break; + } + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== "") + break; + } + if (start > end) + return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split("/")); + var toParts = trim(to.split("/")); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push(".."); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join("/"); + } + }; + var TTY = { + ttys: [], + init: function() { + }, + shutdown: function() { + }, + register: function(dev, ops) { + TTY.ttys[dev] = { input: [], output: [], ops }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open: function(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close: function(stream) { + stream.tty.ops.flush(stream.tty); + }, + flush: function(stream) { + stream.tty.ops.flush(stream.tty); + }, + read: function(stream, buffer2, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === void 0 && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === void 0) + break; + bytesRead++; + buffer2[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: function(stream, buffer2, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer2[offset + i]); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }, + default_tty_ops: { + get_char: function(tty) { + if (!tty.input.length) { + var result = null; + { + var BUFSIZE = 256; + var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE); + var bytesRead = 0; + try { + bytesRead = nodeFS.readSync( + process.stdin.fd, + buf, + 0, + BUFSIZE, + null + ); + } catch (e) { + if (e.toString().includes("EOF")) + bytesRead = 0; + else + throw e; + } + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString("utf-8"); + } else { + result = null; + } + } + if (!result) { + return null; + } + tty.input = intArrayFromString(result, true); + } + return tty.input.shift(); + }, + put_char: function(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) + tty.output.push(val); + } + }, + flush: function(tty) { + if (tty.output && tty.output.length > 0) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + } + }, + default_tty1_ops: { + put_char: function(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) + tty.output.push(val); + } + }, + flush: function(tty) { + if (tty.output && tty.output.length > 0) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + } + } + }; + function mmapAlloc(size) { + var alignedSize = alignMemory(size, 65536); + var ptr = _malloc(alignedSize); + while (size < alignedSize) + HEAP8[ptr + size++] = 0; + return ptr; + } + var MEMFS = { + ops_table: null, + mount: function(mount) { + return MEMFS.createNode(null, "/", 16384 | 511, 0); + }, + createNode: function(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + throw new FS.ErrnoError(63); + } + if (!MEMFS.ops_table) { + MEMFS.ops_table = { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { llseek: MEMFS.stream_ops.llseek } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + allocate: MEMFS.stream_ops.allocate, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + } + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + node.usedBytes = 0; + node.contents = null; + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.timestamp = Date.now(); + if (parent) { + parent.contents[name] = node; + parent.timestamp = node.timestamp; + } + return node; + }, + getFileDataAsTypedArray: function(node) { + if (!node.contents) + return new Uint8Array(0); + if (node.contents.subarray) + return node.contents.subarray(0, node.usedBytes); + return new Uint8Array(node.contents); + }, + expandFileStorage: function(node, newCapacity) { + var prevCapacity = node.contents ? node.contents.length : 0; + if (prevCapacity >= newCapacity) + return; + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max( + newCapacity, + prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0 + ); + if (prevCapacity != 0) + newCapacity = Math.max(newCapacity, 256); + var oldContents = node.contents; + node.contents = new Uint8Array(newCapacity); + if (node.usedBytes > 0) + node.contents.set(oldContents.subarray(0, node.usedBytes), 0); + }, + resizeFileStorage: function(node, newSize) { + if (node.usedBytes == newSize) + return; + if (newSize == 0) { + node.contents = null; + node.usedBytes = 0; + } else { + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + if (oldContents) { + node.contents.set( + oldContents.subarray(0, Math.min(newSize, node.usedBytes)) + ); + } + node.usedBytes = newSize; + } + }, + node_ops: { + getattr: function(node) { + var attr = {}; + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.timestamp); + attr.mtime = new Date(node.timestamp); + attr.ctime = new Date(node.timestamp); + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr: function(node, attr) { + if (attr.mode !== void 0) { + node.mode = attr.mode; + } + if (attr.timestamp !== void 0) { + node.timestamp = attr.timestamp; + } + if (attr.size !== void 0) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup: function(parent, name) { + throw FS.genericErrors[44]; + }, + mknod: function(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename: function(old_node, new_dir, new_name) { + if (FS.isDir(old_node.mode)) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) { + } + if (new_node) { + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + } + delete old_node.parent.contents[old_node.name]; + old_node.parent.timestamp = Date.now(); + old_node.name = new_name; + new_dir.contents[new_name] = old_node; + new_dir.timestamp = old_node.parent.timestamp; + old_node.parent = new_dir; + }, + unlink: function(parent, name) { + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + rmdir: function(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + readdir: function(node) { + var entries = [".", ".."]; + for (var key2 in node.contents) { + if (!node.contents.hasOwnProperty(key2)) { + continue; + } + entries.push(key2); + } + return entries; + }, + symlink: function(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); + node.link = oldpath; + return node; + }, + readlink: function(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + } + }, + stream_ops: { + read: function(stream, buffer2, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) + return 0; + var size = Math.min(stream.node.usedBytes - position, length); + if (size > 8 && contents.subarray) { + buffer2.set(contents.subarray(position, position + size), offset); + } else { + for (var i = 0; i < size; i++) + buffer2[offset + i] = contents[position + i]; + } + return size; + }, + write: function(stream, buffer2, offset, length, position, canOwn) { + if (buffer2.buffer === HEAP8.buffer) { + canOwn = false; + } + if (!length) + return 0; + var node = stream.node; + node.timestamp = Date.now(); + if (buffer2.subarray && (!node.contents || node.contents.subarray)) { + if (canOwn) { + node.contents = buffer2.subarray(offset, offset + length); + node.usedBytes = length; + return length; + } else if (node.usedBytes === 0 && position === 0) { + node.contents = buffer2.slice(offset, offset + length); + node.usedBytes = length; + return length; + } else if (position + length <= node.usedBytes) { + node.contents.set( + buffer2.subarray(offset, offset + length), + position + ); + return length; + } + } + MEMFS.expandFileStorage(node, position + length); + if (node.contents.subarray && buffer2.subarray) { + node.contents.set( + buffer2.subarray(offset, offset + length), + position + ); + } else { + for (var i = 0; i < length; i++) { + node.contents[position + i] = buffer2[offset + i]; + } + } + node.usedBytes = Math.max(node.usedBytes, position + length); + return length; + }, + llseek: function(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + allocate: function(stream, offset, length) { + MEMFS.expandFileStorage(stream.node, offset + length); + stream.node.usedBytes = Math.max( + stream.node.usedBytes, + offset + length + ); + }, + mmap: function(stream, address, length, position, prot, flags) { + if (address !== 0) { + throw new FS.ErrnoError(28); + } + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + if (!(flags & 2) && contents.buffer === buffer) { + allocated = false; + ptr = contents.byteOffset; + } else { + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call( + contents, + position, + position + length + ); + } + } + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + HEAP8.set(contents, ptr); + } + return { ptr, allocated }; + }, + msync: function(stream, buffer2, offset, length, mmapFlags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (mmapFlags & 2) { + return 0; + } + MEMFS.stream_ops.write( + stream, + buffer2, + 0, + length, + offset, + false + ); + return 0; + } + } + }; + var ERRNO_CODES = { + EPERM: 63, + ENOENT: 44, + ESRCH: 71, + EINTR: 27, + EIO: 29, + ENXIO: 60, + E2BIG: 1, + ENOEXEC: 45, + EBADF: 8, + ECHILD: 12, + EAGAIN: 6, + EWOULDBLOCK: 6, + ENOMEM: 48, + EACCES: 2, + EFAULT: 21, + ENOTBLK: 105, + EBUSY: 10, + EEXIST: 20, + EXDEV: 75, + ENODEV: 43, + ENOTDIR: 54, + EISDIR: 31, + EINVAL: 28, + ENFILE: 41, + EMFILE: 33, + ENOTTY: 59, + ETXTBSY: 74, + EFBIG: 22, + ENOSPC: 51, + ESPIPE: 70, + EROFS: 69, + EMLINK: 34, + EPIPE: 64, + EDOM: 18, + ERANGE: 68, + ENOMSG: 49, + EIDRM: 24, + ECHRNG: 106, + EL2NSYNC: 156, + EL3HLT: 107, + EL3RST: 108, + ELNRNG: 109, + EUNATCH: 110, + ENOCSI: 111, + EL2HLT: 112, + EDEADLK: 16, + ENOLCK: 46, + EBADE: 113, + EBADR: 114, + EXFULL: 115, + ENOANO: 104, + EBADRQC: 103, + EBADSLT: 102, + EDEADLOCK: 16, + EBFONT: 101, + ENOSTR: 100, + ENODATA: 116, + ETIME: 117, + ENOSR: 118, + ENONET: 119, + ENOPKG: 120, + EREMOTE: 121, + ENOLINK: 47, + EADV: 122, + ESRMNT: 123, + ECOMM: 124, + EPROTO: 65, + EMULTIHOP: 36, + EDOTDOT: 125, + EBADMSG: 9, + ENOTUNIQ: 126, + EBADFD: 127, + EREMCHG: 128, + ELIBACC: 129, + ELIBBAD: 130, + ELIBSCN: 131, + ELIBMAX: 132, + ELIBEXEC: 133, + ENOSYS: 52, + ENOTEMPTY: 55, + ENAMETOOLONG: 37, + ELOOP: 32, + EOPNOTSUPP: 138, + EPFNOSUPPORT: 139, + ECONNRESET: 15, + ENOBUFS: 42, + EAFNOSUPPORT: 5, + EPROTOTYPE: 67, + ENOTSOCK: 57, + ENOPROTOOPT: 50, + ESHUTDOWN: 140, + ECONNREFUSED: 14, + EADDRINUSE: 3, + ECONNABORTED: 13, + ENETUNREACH: 40, + ENETDOWN: 38, + ETIMEDOUT: 73, + EHOSTDOWN: 142, + EHOSTUNREACH: 23, + EINPROGRESS: 26, + EALREADY: 7, + EDESTADDRREQ: 17, + EMSGSIZE: 35, + EPROTONOSUPPORT: 66, + ESOCKTNOSUPPORT: 137, + EADDRNOTAVAIL: 4, + ENETRESET: 39, + EISCONN: 30, + ENOTCONN: 53, + ETOOMANYREFS: 141, + EUSERS: 136, + EDQUOT: 19, + ESTALE: 72, + ENOTSUP: 138, + ENOMEDIUM: 148, + EILSEQ: 25, + EOVERFLOW: 61, + ECANCELED: 11, + ENOTRECOVERABLE: 56, + EOWNERDEAD: 62, + ESTRPIPE: 135 + }; + var NODEFS = { + isWindows: false, + staticInit: function() { + NODEFS.isWindows = !!process.platform.match(/^win/); + var flags = { fs: fs.constants }; + if (flags["fs"]) { + flags = flags["fs"]; + } + NODEFS.flagsForNodeMap = { + 1024: flags["O_APPEND"], + 64: flags["O_CREAT"], + 128: flags["O_EXCL"], + 256: flags["O_NOCTTY"], + 0: flags["O_RDONLY"], + 2: flags["O_RDWR"], + 4096: flags["O_SYNC"], + 512: flags["O_TRUNC"], + 1: flags["O_WRONLY"] + }; + }, + bufferFrom: function(arrayBuffer) { + return Buffer["alloc"] ? Buffer.from(arrayBuffer) : new Buffer(arrayBuffer); + }, + convertNodeCode: function(e) { + var code = e.code; + return ERRNO_CODES[code]; + }, + mount: function(mount) { + return NODEFS.createNode(null, "/", NODEFS.getMode(mount.opts.root), 0); + }, + createNode: function(parent, name, mode, dev) { + if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { + throw new FS.ErrnoError(28); + } + var node = FS.createNode(parent, name, mode); + node.node_ops = NODEFS.node_ops; + node.stream_ops = NODEFS.stream_ops; + return node; + }, + getMode: function(path) { + var stat; + try { + stat = fs.lstatSync(path); + if (NODEFS.isWindows) { + stat.mode = stat.mode | (stat.mode & 292) >> 2; + } + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + return stat.mode; + }, + realPath: function(node) { + var parts = []; + while (node.parent !== node) { + parts.push(node.name); + node = node.parent; + } + parts.push(node.mount.opts.root); + parts.reverse(); + return PATH.join.apply(null, parts); + }, + flagsForNode: function(flags) { + flags &= ~2097152; + flags &= ~2048; + flags &= ~32768; + flags &= ~524288; + var newFlags = 0; + for (var k in NODEFS.flagsForNodeMap) { + if (flags & k) { + newFlags |= NODEFS.flagsForNodeMap[k]; + flags ^= k; + } + } + if (!flags) { + return newFlags; + } else { + throw new FS.ErrnoError(28); + } + }, + node_ops: { + getattr: function(node) { + var path = NODEFS.realPath(node); + var stat; + try { + stat = fs.lstatSync(path); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + if (NODEFS.isWindows && !stat.blksize) { + stat.blksize = 4096; + } + if (NODEFS.isWindows && !stat.blocks) { + stat.blocks = (stat.size + stat.blksize - 1) / stat.blksize | 0; + } + return { + dev: stat.dev, + ino: stat.ino, + mode: stat.mode, + nlink: stat.nlink, + uid: stat.uid, + gid: stat.gid, + rdev: stat.rdev, + size: stat.size, + atime: stat.atime, + mtime: stat.mtime, + ctime: stat.ctime, + blksize: stat.blksize, + blocks: stat.blocks + }; + }, + setattr: function(node, attr) { + var path = NODEFS.realPath(node); + try { + if (attr.mode !== void 0) { + fs.chmodSync(path, attr.mode); + node.mode = attr.mode; + } + if (attr.timestamp !== void 0) { + var date = new Date(attr.timestamp); + fs.utimesSync(path, date, date); + } + if (attr.size !== void 0) { + fs.truncateSync(path, attr.size); + } + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + lookup: function(parent, name) { + var path = PATH.join2(NODEFS.realPath(parent), name); + var mode = NODEFS.getMode(path); + return NODEFS.createNode(parent, name, mode); + }, + mknod: function(parent, name, mode, dev) { + var node = NODEFS.createNode(parent, name, mode, dev); + var path = NODEFS.realPath(node); + try { + if (FS.isDir(node.mode)) { + fs.mkdirSync(path, node.mode); + } else { + fs.writeFileSync(path, "", { mode: node.mode }); + } + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + return node; + }, + rename: function(oldNode, newDir, newName) { + var oldPath = NODEFS.realPath(oldNode); + var newPath = PATH.join2(NODEFS.realPath(newDir), newName); + try { + fs.renameSync(oldPath, newPath); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + oldNode.name = newName; + }, + unlink: function(parent, name) { + var path = PATH.join2(NODEFS.realPath(parent), name); + try { + fs.unlinkSync(path); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + rmdir: function(parent, name) { + var path = PATH.join2(NODEFS.realPath(parent), name); + try { + fs.rmdirSync(path); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + readdir: function(node) { + var path = NODEFS.realPath(node); + try { + return fs.readdirSync(path); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + symlink: function(parent, newName, oldPath) { + var newPath = PATH.join2(NODEFS.realPath(parent), newName); + try { + fs.symlinkSync(oldPath, newPath); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + readlink: function(node) { + var path = NODEFS.realPath(node); + try { + path = fs.readlinkSync(path); + path = NODEJS_PATH.relative( + NODEJS_PATH.resolve(node.mount.opts.root), + path + ); + return path; + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + } + }, + stream_ops: { + open: function(stream) { + var path = NODEFS.realPath(stream.node); + try { + if (FS.isFile(stream.node.mode)) { + stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags)); + } + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + close: function(stream) { + try { + if (FS.isFile(stream.node.mode) && stream.nfd) { + fs.closeSync(stream.nfd); + } + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + read: function(stream, buffer2, offset, length, position) { + if (length === 0) + return 0; + try { + return fs.readSync( + stream.nfd, + NODEFS.bufferFrom(buffer2.buffer), + offset, + length, + position + ); + } catch (e) { + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + write: function(stream, buffer2, offset, length, position) { + try { + return fs.writeSync( + stream.nfd, + NODEFS.bufferFrom(buffer2.buffer), + offset, + length, + position + ); + } catch (e) { + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + }, + llseek: function(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + try { + var stat = fs.fstatSync(stream.nfd); + position += stat.size; + } catch (e) { + throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); + } + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + mmap: function(stream, address, length, position, prot, flags) { + if (address !== 0) { + throw new FS.ErrnoError(28); + } + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr = mmapAlloc(length); + NODEFS.stream_ops.read(stream, HEAP8, ptr, length, position); + return { ptr, allocated: true }; + }, + msync: function(stream, buffer2, offset, length, mmapFlags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (mmapFlags & 2) { + return 0; + } + NODEFS.stream_ops.write( + stream, + buffer2, + 0, + length, + offset, + false + ); + return 0; + } + } + }; + var NODERAWFS = { + lookupPath: function(path) { + return { path, node: { mode: NODEFS.getMode(path) } }; + }, + createStandardStreams: function() { + FS.streams[0] = { + fd: 0, + nfd: 0, + position: 0, + path: "", + flags: 0, + tty: true, + seekable: false + }; + for (var i = 1; i < 3; i++) { + FS.streams[i] = { + fd: i, + nfd: i, + position: 0, + path: "", + flags: 577, + tty: true, + seekable: false + }; + } + }, + cwd: function() { + return process.cwd(); + }, + chdir: function() { + process.chdir.apply(void 0, arguments); + }, + mknod: function(path, mode) { + if (FS.isDir(path)) { + fs.mkdirSync(path, mode); + } else { + fs.writeFileSync(path, "", { mode }); + } + }, + mkdir: function() { + fs.mkdirSync.apply(void 0, arguments); + }, + symlink: function() { + fs.symlinkSync.apply(void 0, arguments); + }, + rename: function() { + fs.renameSync.apply(void 0, arguments); + }, + rmdir: function() { + fs.rmdirSync.apply(void 0, arguments); + }, + readdir: function() { + fs.readdirSync.apply(void 0, arguments); + }, + unlink: function() { + fs.unlinkSync.apply(void 0, arguments); + }, + readlink: function() { + return fs.readlinkSync.apply(void 0, arguments); + }, + stat: function() { + return fs.statSync.apply(void 0, arguments); + }, + lstat: function() { + return fs.lstatSync.apply(void 0, arguments); + }, + chmod: function() { + fs.chmodSync.apply(void 0, arguments); + }, + fchmod: function() { + fs.fchmodSync.apply(void 0, arguments); + }, + chown: function() { + fs.chownSync.apply(void 0, arguments); + }, + fchown: function() { + fs.fchownSync.apply(void 0, arguments); + }, + truncate: function() { + fs.truncateSync.apply(void 0, arguments); + }, + ftruncate: function(fd, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + fs.ftruncateSync.apply(void 0, arguments); + }, + utime: function() { + fs.utimesSync.apply(void 0, arguments); + }, + open: function(path, flags, mode, suggestFD) { + if (typeof flags === "string") { + flags = VFS.modeStringToFlags(flags); + } + var nfd = fs.openSync(path, NODEFS.flagsForNode(flags), mode); + var fd = suggestFD != null ? suggestFD : FS.nextfd(nfd); + var stream = { + fd, + nfd, + position: 0, + path, + flags, + seekable: true + }; + FS.streams[fd] = stream; + return stream; + }, + close: function(stream) { + if (!stream.stream_ops) { + fs.closeSync(stream.nfd); + } + FS.closeStream(stream.fd); + }, + llseek: function(stream, offset, whence) { + if (stream.stream_ops) { + return VFS.llseek(stream, offset, whence); + } + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + position += fs.fstatSync(stream.nfd).size; + } else if (whence !== 0) { + throw new FS.ErrnoError(ERRNO_CODES.EINVAL); + } + if (position < 0) { + throw new FS.ErrnoError(ERRNO_CODES.EINVAL); + } + stream.position = position; + return position; + }, + read: function(stream, buffer2, offset, length, position) { + if (stream.stream_ops) { + return VFS.read(stream, buffer2, offset, length, position); + } + var seeking = typeof position !== "undefined"; + if (!seeking && stream.seekable) + position = stream.position; + var bytesRead = fs.readSync( + stream.nfd, + NODEFS.bufferFrom(buffer2.buffer), + offset, + length, + position + ); + if (!seeking) + stream.position += bytesRead; + return bytesRead; + }, + write: function(stream, buffer2, offset, length, position) { + if (stream.stream_ops) { + return VFS.write(stream, buffer2, offset, length, position); + } + if (stream.flags & +"1024") { + FS.llseek(stream, 0, +"2"); + } + var seeking = typeof position !== "undefined"; + if (!seeking && stream.seekable) + position = stream.position; + var bytesWritten = fs.writeSync( + stream.nfd, + NODEFS.bufferFrom(buffer2.buffer), + offset, + length, + position + ); + if (!seeking) + stream.position += bytesWritten; + return bytesWritten; + }, + allocate: function() { + throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); + }, + mmap: function(stream, address, length, position, prot, flags) { + if (stream.stream_ops) { + return VFS.mmap(stream, address, length, position, prot, flags); + } + if (address !== 0) { + throw new FS.ErrnoError(28); + } + var ptr = mmapAlloc(length); + FS.read(stream, HEAP8, ptr, length, position); + return { ptr, allocated: true }; + }, + msync: function(stream, buffer2, offset, length, mmapFlags) { + if (stream.stream_ops) { + return VFS.msync(stream, buffer2, offset, length, mmapFlags); + } + if (mmapFlags & 2) { + return 0; + } + FS.write(stream, buffer2, 0, length, offset); + return 0; + }, + munmap: function() { + return 0; + }, + ioctl: function() { + throw new FS.ErrnoError(ERRNO_CODES.ENOTTY); + } + }; + var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: "/", + initialized: false, + ignorePermissions: true, + trackingDelegate: {}, + tracking: { openFlags: { READ: 1, WRITE: 2 } }, + ErrnoError: null, + genericErrors: {}, + filesystems: null, + syncFSRequests: 0, + lookupPath: function(path, opts) { + path = PATH_FS.resolve(FS.cwd(), path); + opts = opts || {}; + if (!path) + return { path: "", node: null }; + var defaults = { follow_mount: true, recurse_count: 0 }; + for (var key2 in defaults) { + if (opts[key2] === void 0) { + opts[key2] = defaults[key2]; + } + } + if (opts.recurse_count > 8) { + throw new FS.ErrnoError(32); + } + var parts = PATH.normalizeArray( + path.split("/").filter(function(p) { + return !!p; + }), + false + ); + var current = FS.root; + var current_path = "/"; + for (var i = 0; i < parts.length; i++) { + var islast = i === parts.length - 1; + if (islast && opts.parent) { + break; + } + current = FS.lookupNode(current, parts[i]); + current_path = PATH.join2(current_path, parts[i]); + if (FS.isMountpoint(current)) { + if (!islast || islast && opts.follow_mount) { + current = current.mounted.root; + } + } + if (!islast || opts.follow) { + var count = 0; + while (FS.isLink(current.mode)) { + var link = FS.readlink(current_path); + current_path = PATH_FS.resolve(PATH.dirname(current_path), link); + var lookup = FS.lookupPath(current_path, { + recurse_count: opts.recurse_count + }); + current = lookup.node; + if (count++ > 40) { + throw new FS.ErrnoError(32); + } + } + } + } + return { path: current_path, node: current }; + }, + getPath: function(node) { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) + return mount; + return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path; + } + path = path ? node.name + "/" + path : node.name; + node = node.parent; + } + }, + hashName: function(parentid, name) { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = (hash << 5) - hash + name.charCodeAt(i) | 0; + } + return (parentid + hash >>> 0) % FS.nameTable.length; + }, + hashAddNode: function(node) { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode: function(node) { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; + } + current = current.name_next; + } + } + }, + lookupNode: function(parent, name) { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode, parent); + } + var hash = FS.hashName(parent.id, name); + for (var node = FS.nameTable[hash]; node; node = node.name_next) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + return FS.lookup(parent, name); + }, + createNode: function(parent, name, mode, rdev) { + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode: function(node) { + FS.hashRemoveNode(node); + }, + isRoot: function(node) { + return node === node.parent; + }, + isMountpoint: function(node) { + return !!node.mounted; + }, + isFile: function(mode) { + return (mode & 61440) === 32768; + }, + isDir: function(mode) { + return (mode & 61440) === 16384; + }, + isLink: function(mode) { + return (mode & 61440) === 40960; + }, + isChrdev: function(mode) { + return (mode & 61440) === 8192; + }, + isBlkdev: function(mode) { + return (mode & 61440) === 24576; + }, + isFIFO: function(mode) { + return (mode & 61440) === 4096; + }, + isSocket: function(mode) { + return (mode & 49152) === 49152; + }, + flagModes: { r: 0, "r+": 2, w: 577, "w+": 578, a: 1089, "a+": 1090 }, + modeStringToFlags: function(str) { + var flags = FS.flagModes[str]; + if (typeof flags === "undefined") { + throw new Error("Unknown file open mode: " + str); + } + return flags; + }, + flagsToPermissionString: function(flag) { + var perms = ["r", "w", "rw"][flag & 3]; + if (flag & 512) { + perms += "w"; + } + return perms; + }, + nodePermissions: function(node, perms) { + if (FS.ignorePermissions) { + return 0; + } + if (perms.includes("r") && !(node.mode & 292)) { + return 2; + } else if (perms.includes("w") && !(node.mode & 146)) { + return 2; + } else if (perms.includes("x") && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup: function(dir) { + var errCode = FS.nodePermissions(dir, "x"); + if (errCode) + return errCode; + if (!dir.node_ops.lookup) + return 2; + return 0; + }, + mayCreate: function(dir, name) { + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) { + } + return FS.nodePermissions(dir, "wx"); + }, + mayDelete: function(dir, name, isdir) { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, "wx"); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else { + if (FS.isDir(node.mode)) { + return 31; + } + } + return 0; + }, + mayOpen: function(node, flags) { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } else if (FS.isDir(node.mode)) { + if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { + return 31; + } + } + return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); + }, + MAX_OPEN_FDS: 4096, + nextfd: function(fd_start, fd_end) { + fd_start = fd_start || 0; + fd_end = fd_end || FS.MAX_OPEN_FDS; + for (var fd = fd_start; fd <= fd_end; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStream: function(fd) { + return FS.streams[fd]; + }, + createStream: function(stream, fd_start, fd_end) { + if (!FS.FSStream) { + FS.FSStream = function() { + }; + FS.FSStream.prototype = { + object: { + get: function() { + return this.node; + }, + set: function(val) { + this.node = val; + } + }, + isRead: { + get: function() { + return (this.flags & 2097155) !== 1; + } + }, + isWrite: { + get: function() { + return (this.flags & 2097155) !== 0; + } + }, + isAppend: { + get: function() { + return this.flags & 1024; + } + } + }; + } + var newStream = new FS.FSStream(); + for (var p in stream) { + newStream[p] = stream[p]; + } + stream = newStream; + var fd = FS.nextfd(fd_start, fd_end); + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream: function(fd) { + FS.streams[fd] = null; + }, + chrdev_stream_ops: { + open: function(stream) { + var device = FS.getDevice(stream.node.rdev); + stream.stream_ops = device.stream_ops; + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + }, + llseek: function() { + throw new FS.ErrnoError(70); + } + }, + major: function(dev) { + return dev >> 8; + }, + minor: function(dev) { + return dev & 255; + }, + makedev: function(ma, mi) { + return ma << 8 | mi; + }, + registerDevice: function(dev, ops) { + FS.devices[dev] = { stream_ops: ops }; + }, + getDevice: function(dev) { + return FS.devices[dev]; + }, + getMounts: function(mount) { + var mounts = []; + var check = [mount]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push.apply(check, m.mounts); + } + return mounts; + }, + syncfs: function(populate, callback) { + if (typeof populate === "function") { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err( + "warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work" + ); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + mounts.forEach(function(mount) { + if (!mount.type.syncfs) { + return done(null); + } + mount.type.syncfs(mount, populate, done); + }); + }, + mount: function(type, opts, mountpoint) { + var root = mountpoint === "/"; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); + mountpoint = lookup.path; + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type, + opts, + mountpoint, + mounts: [] + }; + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + node.mounted = mount; + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount: function(mountpoint) { + var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + Object.keys(FS.nameTable).forEach(function(hash) { + var current = FS.nameTable[hash]; + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + }); + node.mounted = null; + var idx = node.mount.mounts.indexOf(mount); + node.mount.mounts.splice(idx, 1); + }, + lookup: function(parent, name) { + return parent.node_ops.lookup(parent, name); + }, + mknod: function(path, mode, dev) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name || name === "." || name === "..") { + throw new FS.ErrnoError(28); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + create: function(path, mode) { + mode = mode !== void 0 ? mode : 438; + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir: function(path, mode) { + mode = mode !== void 0 ? mode : 511; + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree: function(path, mode) { + var dirs = path.split("/"); + var d = ""; + for (var i = 0; i < dirs.length; ++i) { + if (!dirs[i]) + continue; + d += "/" + dirs[i]; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) + throw e; + } + } + }, + mkdev: function(path, mode, dev) { + if (typeof dev === "undefined") { + dev = mode; + mode = 438; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink: function(oldpath, newpath) { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename: function(old_path, new_path) { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + var lookup, old_dir, new_dir; + lookup = FS.lookupPath(old_path, { parent: true }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { parent: true }); + new_dir = lookup.node; + if (!old_dir || !new_dir) + throw new FS.ErrnoError(44); + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + var old_node = FS.lookupNode(old_dir, old_name); + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(28); + } + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(55); + } + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) { + } + if (old_node === new_node) { + return; + } + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { + throw new FS.ErrnoError(10); + } + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + try { + if (FS.trackingDelegate["willMovePath"]) { + FS.trackingDelegate["willMovePath"](old_path, new_path); + } + } catch (e) { + err( + "FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message + ); + } + FS.hashRemoveNode(old_node); + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + } catch (e) { + throw e; + } finally { + FS.hashAddNode(old_node); + } + try { + if (FS.trackingDelegate["onMovePath"]) + FS.trackingDelegate["onMovePath"](old_path, new_path); + } catch (e) { + err( + "FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message + ); + } + }, + rmdir: function(path) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + try { + if (FS.trackingDelegate["willDeletePath"]) { + FS.trackingDelegate["willDeletePath"](path); + } + } catch (e) { + err( + "FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message + ); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + try { + if (FS.trackingDelegate["onDeletePath"]) + FS.trackingDelegate["onDeletePath"](path); + } catch (e) { + err( + "FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message + ); + } + }, + readdir: function(path) { + var lookup = FS.lookupPath(path, { follow: true }); + var node = lookup.node; + if (!node.node_ops.readdir) { + throw new FS.ErrnoError(54); + } + return node.node_ops.readdir(node); + }, + unlink: function(path) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + try { + if (FS.trackingDelegate["willDeletePath"]) { + FS.trackingDelegate["willDeletePath"](path); + } + } catch (e) { + err( + "FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message + ); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + try { + if (FS.trackingDelegate["onDeletePath"]) + FS.trackingDelegate["onDeletePath"](path); + } catch (e) { + err( + "FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message + ); + } + }, + readlink: function(path) { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return PATH_FS.resolve( + FS.getPath(link.parent), + link.node_ops.readlink(link) + ); + }, + stat: function(path, dontFollow) { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + var node = lookup.node; + if (!node) { + throw new FS.ErrnoError(44); + } + if (!node.node_ops.getattr) { + throw new FS.ErrnoError(63); + } + return node.node_ops.getattr(node); + }, + lstat: function(path) { + return FS.stat(path, true); + }, + chmod: function(path, mode, dontFollow) { + var node; + if (typeof path === "string") { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + mode: mode & 4095 | node.mode & ~4095, + timestamp: Date.now() + }); + }, + lchmod: function(path, mode) { + FS.chmod(path, mode, true); + }, + fchmod: function(fd, mode) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + FS.chmod(stream.node, mode); + }, + chown: function(path, uid, gid, dontFollow) { + var node; + if (typeof path === "string") { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { timestamp: Date.now() }); + }, + lchown: function(path, uid, gid) { + FS.chown(path, uid, gid, true); + }, + fchown: function(fd, uid, gid) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + FS.chown(stream.node, uid, gid); + }, + truncate: function(path, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path === "string") { + var lookup = FS.lookupPath(path, { follow: true }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + node.node_ops.setattr(node, { size: len, timestamp: Date.now() }); + }, + ftruncate: function(fd, len) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.truncate(stream.node, len); + }, + utime: function(path, atime, mtime) { + var lookup = FS.lookupPath(path, { follow: true }); + var node = lookup.node; + node.node_ops.setattr(node, { timestamp: Math.max(atime, mtime) }); + }, + open: function(path, flags, mode, fd_start, fd_end) { + if (path === "") { + throw new FS.ErrnoError(44); + } + flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags; + mode = typeof mode === "undefined" ? 438 : mode; + if (flags & 64) { + mode = mode & 4095 | 32768; + } else { + mode = 0; + } + var node; + if (typeof path === "object") { + node = path; + } else { + path = PATH.normalize(path); + try { + var lookup = FS.lookupPath(path, { follow: !(flags & 131072) }); + node = lookup.node; + } catch (e) { + } + } + var created = false; + if (flags & 64) { + if (node) { + if (flags & 128) { + throw new FS.ErrnoError(20); + } + } else { + node = FS.mknod(path, mode, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + if (flags & 65536 && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + if (flags & 512) { + FS.truncate(node, 0); + } + flags &= ~(128 | 512 | 131072); + var stream = FS.createStream( + { + node, + path: FS.getPath(node), + flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + ungotten: [], + error: false + }, + fd_start, + fd_end + ); + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (Module["logReadFiles"] && !(flags & 1)) { + if (!FS.readFiles) + FS.readFiles = {}; + if (!(path in FS.readFiles)) { + FS.readFiles[path] = 1; + err("FS.trackingDelegate error on read file: " + path); + } + } + try { + if (FS.trackingDelegate["onOpenFile"]) { + var trackingFlags = 0; + if ((flags & 2097155) !== 1) { + trackingFlags |= FS.tracking.openFlags.READ; + } + if ((flags & 2097155) !== 0) { + trackingFlags |= FS.tracking.openFlags.WRITE; + } + FS.trackingDelegate["onOpenFile"](path, trackingFlags); + } + } catch (e) { + err( + "FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message + ); + } + return stream; + }, + close: function(stream) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) + stream.getdents = null; + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed: function(stream) { + return stream.fd === null; + }, + llseek: function(stream, offset, whence) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read: function(stream, buffer2, offset, length, position) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position !== "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read( + stream, + buffer2, + offset, + length, + position + ); + if (!seeking) + stream.position += bytesRead; + return bytesRead; + }, + write: function(stream, buffer2, offset, length, position, canOwn) { + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + FS.llseek(stream, 0, 2); + } + var seeking = typeof position !== "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write( + stream, + buffer2, + offset, + length, + position, + canOwn + ); + if (!seeking) + stream.position += bytesWritten; + try { + if (stream.path && FS.trackingDelegate["onWriteToFile"]) + FS.trackingDelegate["onWriteToFile"](stream.path); + } catch (e) { + err( + "FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message + ); + } + return bytesWritten; + }, + allocate: function(stream, offset, length) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (offset < 0 || length <= 0) { + throw new FS.ErrnoError(28); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (!stream.stream_ops.allocate) { + throw new FS.ErrnoError(138); + } + stream.stream_ops.allocate(stream, offset, length); + }, + mmap: function(stream, address, length, position, prot, flags) { + if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + return stream.stream_ops.mmap( + stream, + address, + length, + position, + prot, + flags + ); + }, + msync: function(stream, buffer2, offset, length, mmapFlags) { + if (!stream || !stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync( + stream, + buffer2, + offset, + length, + mmapFlags + ); + }, + munmap: function(stream) { + return 0; + }, + ioctl: function(stream, cmd, arg) { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile: function(path, opts) { + opts = opts || {}; + opts.flags = opts.flags || 0; + opts.encoding = opts.encoding || "binary"; + if (opts.encoding !== "utf8" && opts.encoding !== "binary") { + throw new Error('Invalid encoding type "' + opts.encoding + '"'); + } + var ret; + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === "utf8") { + ret = UTF8ArrayToString(buf, 0); + } else if (opts.encoding === "binary") { + ret = buf; + } + FS.close(stream); + return ret; + }, + writeFile: function(path, data, opts) { + opts = opts || {}; + opts.flags = opts.flags || 577; + var stream = FS.open(path, opts.flags, opts.mode); + if (typeof data === "string") { + var buf = new Uint8Array(lengthBytesUTF8(data) + 1); + var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); + FS.write(stream, buf, 0, actualNumBytes, void 0, opts.canOwn); + } else if (ArrayBuffer.isView(data)) { + FS.write(stream, data, 0, data.byteLength, void 0, opts.canOwn); + } else { + throw new Error("Unsupported data type"); + } + FS.close(stream); + }, + cwd: function() { + return FS.currentPath; + }, + chdir: function(path) { + var lookup = FS.lookupPath(path, { follow: true }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, "x"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories: function() { + FS.mkdir("/tmp"); + FS.mkdir("/home"); + FS.mkdir("/home/web_user"); + }, + createDefaultDevices: function() { + FS.mkdir("/dev"); + FS.registerDevice(FS.makedev(1, 3), { + read: function() { + return 0; + }, + write: function(stream, buffer2, offset, length, pos) { + return length; + } + }); + FS.mkdev("/dev/null", FS.makedev(1, 3)); + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev("/dev/tty", FS.makedev(5, 0)); + FS.mkdev("/dev/tty1", FS.makedev(6, 0)); + var random_device = getRandomDevice(); + FS.createDevice("/dev", "random", random_device); + FS.createDevice("/dev", "urandom", random_device); + FS.mkdir("/dev/shm"); + FS.mkdir("/dev/shm/tmp"); + }, + createSpecialDirectories: function() { + FS.mkdir("/proc"); + var proc_self = FS.mkdir("/proc/self"); + FS.mkdir("/proc/self/fd"); + FS.mount( + { + mount: function() { + var node = FS.createNode(proc_self, "fd", 16384 | 511, 73); + node.node_ops = { + lookup: function(parent, name) { + var fd = +name; + var stream = FS.getStream(fd); + if (!stream) + throw new FS.ErrnoError(8); + var ret = { + parent: null, + mount: { mountpoint: "fake" }, + node_ops: { + readlink: function() { + return stream.path; + } + } + }; + ret.parent = ret; + return ret; + } + }; + return node; + } + }, + {}, + "/proc/self/fd" + ); + }, + createStandardStreams: function() { + if (Module["stdin"]) { + FS.createDevice("/dev", "stdin", Module["stdin"]); + } else { + FS.symlink("/dev/tty", "/dev/stdin"); + } + if (Module["stdout"]) { + FS.createDevice("/dev", "stdout", null, Module["stdout"]); + } else { + FS.symlink("/dev/tty", "/dev/stdout"); + } + if (Module["stderr"]) { + FS.createDevice("/dev", "stderr", null, Module["stderr"]); + } else { + FS.symlink("/dev/tty1", "/dev/stderr"); + } + FS.open("/dev/stdin", 0); + FS.open("/dev/stdout", 1); + FS.open("/dev/stderr", 1); + }, + ensureErrnoError: function() { + if (FS.ErrnoError) + return; + FS.ErrnoError = function ErrnoError(errno, node) { + this.node = node; + this.setErrno = function(errno2) { + this.errno = errno2; + }; + this.setErrno(errno); + this.message = "FS error"; + }; + FS.ErrnoError.prototype = new Error(); + FS.ErrnoError.prototype.constructor = FS.ErrnoError; + [44].forEach(function(code) { + FS.genericErrors[code] = new FS.ErrnoError(code); + FS.genericErrors[code].stack = ""; + }); + }, + staticInit: function() { + FS.ensureErrnoError(); + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, "/"); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { MEMFS, NODEFS }; + }, + init: function(input, output, error) { + FS.init.initialized = true; + FS.ensureErrnoError(); + Module["stdin"] = input || Module["stdin"]; + Module["stdout"] = output || Module["stdout"]; + Module["stderr"] = error || Module["stderr"]; + FS.createStandardStreams(); + }, + quit: function() { + FS.init.initialized = false; + var fflush = Module["_fflush"]; + if (fflush) + fflush(0); + for (var i = 0; i < FS.streams.length; i++) { + var stream = FS.streams[i]; + if (!stream) { + continue; + } + FS.close(stream); + } + }, + getMode: function(canRead, canWrite) { + var mode = 0; + if (canRead) + mode |= 292 | 73; + if (canWrite) + mode |= 146; + return mode; + }, + findObject: function(path, dontResolveLastLink) { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (ret.exists) { + return ret.object; + } else { + return null; + } + }, + analyzePath: function(path, dontResolveLastLink) { + try { + var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); + path = lookup.path; + } catch (e) { + } + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { parent: true }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === "/"; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath: function(parent, path, canRead, canWrite) { + parent = typeof parent === "string" ? parent : FS.getPath(parent); + var parts = path.split("/").reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) + continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) { + } + parent = current; + } + return current; + }, + createFile: function(parent, name, properties, canRead, canWrite) { + var path = PATH.join2( + typeof parent === "string" ? parent : FS.getPath(parent), + name + ); + var mode = FS.getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { + var path = name ? PATH.join2( + typeof parent === "string" ? parent : FS.getPath(parent), + name + ) : parent; + var mode = FS.getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + if (typeof data === "string") { + var arr = new Array(data.length); + for (var i = 0, len = data.length; i < len; ++i) + arr[i] = data.charCodeAt(i); + data = arr; + } + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + return node; + }, + createDevice: function(parent, name, input, output) { + var path = PATH.join2( + typeof parent === "string" ? parent : FS.getPath(parent), + name + ); + var mode = FS.getMode(!!input, !!output); + if (!FS.createDevice.major) + FS.createDevice.major = 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + FS.registerDevice(dev, { + open: function(stream) { + stream.seekable = false; + }, + close: function(stream) { + if (output && output.buffer && output.buffer.length) { + output(10); + } + }, + read: function(stream, buffer2, offset, length, pos) { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === void 0 && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === void 0) + break; + bytesRead++; + buffer2[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write: function(stream, buffer2, offset, length, pos) { + for (var i = 0; i < length; i++) { + try { + output(buffer2[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile: function(obj) { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) + return true; + if (read_) { + try { + obj.contents = intArrayFromString(read_(obj.url), true); + obj.usedBytes = obj.contents.length; + } catch (e) { + throw new FS.ErrnoError(29); + } + } else { + throw new Error("Cannot load without read() or XMLHttpRequest."); + } + }, + createLazyFile: function(parent, name, url, canRead, canWrite) { + var properties; { + var properties = { isDevice: false, url }; + } + var node = FS.createFile(parent, name, properties, canRead, canWrite); + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + Object.defineProperties(node, { + usedBytes: { + get: function() { + return this.contents.length; + } + } + }); + var stream_ops = {}; + var keys = Object.keys(node.stream_ops); + keys.forEach(function(key2) { + var fn = node.stream_ops[key2]; + stream_ops[key2] = function forceLoadLazyFile() { + FS.forceLoadFile(node); + return fn.apply(null, arguments); + }; + }); + stream_ops.read = function stream_ops_read(stream, buffer2, offset, length, position) { + FS.forceLoadFile(node); + var contents = stream.node.contents; + if (position >= contents.length) + return 0; + var size = Math.min(contents.length - position, length); + if (contents.slice) { + for (var i = 0; i < size; i++) { + buffer2[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + buffer2[offset + i] = contents.get(position + i); + } + } + return size; + }; + node.stream_ops = stream_ops; + return node; + }, + createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { + Browser.init(); + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + function processData(byteArray) { + function finish(byteArray2) { + if (preFinish) + preFinish(); + if (!dontCreateFile) { + FS.createDataFile( + parent, + name, + byteArray2, + canRead, + canWrite, + canOwn + ); + } + if (onload) + onload(); + removeRunDependency(); + } + var handled = false; + Module["preloadPlugins"].forEach(function(plugin) { + if (handled) + return; + if (plugin["canHandle"](fullname)) { + plugin["handle"](byteArray, fullname, finish, function() { + if (onerror) + onerror(); + removeRunDependency(); + }); + handled = true; + } + }); + if (!handled) + finish(byteArray); + } + addRunDependency(); + if (typeof url == "string") { + Browser.asyncLoad( + url, + function(byteArray) { + processData(byteArray); + }, + onerror + ); + } else { + processData(url); + } + }, + indexedDB: function() { + return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + }, + DB_NAME: function() { + return "EM_FS_" + window.location.pathname; + }, + DB_VERSION: 20, + DB_STORE_NAME: "FILE_DATA", + saveFilesToDB: function(paths, onload, onerror) { + onload = onload || function() { + }; + onerror = onerror || function() { + }; + var indexedDB = FS.indexedDB(); + try { + var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); + } catch (e) { + return onerror(e); + } + openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { + out("creating db"); + var db = openRequest.result; + db.createObjectStore(FS.DB_STORE_NAME); + }; + openRequest.onsuccess = function openRequest_onsuccess() { + var db = openRequest.result; + var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite"); + var files = transaction.objectStore(FS.DB_STORE_NAME); + var ok = 0, fail = 0, total = paths.length; + function finish() { + if (fail == 0) + onload(); + else + onerror(); + } + paths.forEach(function(path) { + var putRequest = files.put( + FS.analyzePath(path).object.contents, + path + ); + putRequest.onsuccess = function putRequest_onsuccess() { + ok++; + if (ok + fail == total) + finish(); + }; + putRequest.onerror = function putRequest_onerror() { + fail++; + if (ok + fail == total) + finish(); + }; + }); + transaction.onerror = onerror; + }; + openRequest.onerror = onerror; + }, + loadFilesFromDB: function(paths, onload, onerror) { + onload = onload || function() { + }; + onerror = onerror || function() { + }; + var indexedDB = FS.indexedDB(); + try { + var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); + } catch (e) { + return onerror(e); + } + openRequest.onupgradeneeded = onerror; + openRequest.onsuccess = function openRequest_onsuccess() { + var db = openRequest.result; + try { + var transaction = db.transaction([FS.DB_STORE_NAME], "readonly"); + } catch (e) { + onerror(e); + return; + } + var files = transaction.objectStore(FS.DB_STORE_NAME); + var ok = 0, fail = 0, total = paths.length; + function finish() { + if (fail == 0) + onload(); + else + onerror(); + } + paths.forEach(function(path) { + var getRequest = files.get(path); + getRequest.onsuccess = function getRequest_onsuccess() { + if (FS.analyzePath(path).exists) { + FS.unlink(path); + } + FS.createDataFile( + PATH.dirname(path), + PATH.basename(path), + getRequest.result, + true, + true, + true + ); + ok++; + if (ok + fail == total) + finish(); + }; + getRequest.onerror = function getRequest_onerror() { + fail++; + if (ok + fail == total) + finish(); + }; + }); + transaction.onerror = onerror; + }; + openRequest.onerror = onerror; + } + }; + var SYSCALLS = { + mappings: {}, + DEFAULT_POLLMASK: 5, + umask: 511, + calculateAt: function(dirfd, path, allowEmpty) { + if (path[0] === "/") { + return path; + } + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = FS.getStream(dirfd); + if (!dirstream) + throw new FS.ErrnoError(8); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return PATH.join2(dir, path); + }, + doStat: function(func, path, buf) { + try { + var stat = func(path); + } catch (e) { + if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { + return -54; + } + throw e; + } + HEAP32[buf >> 2] = stat.dev; + HEAP32[buf + 4 >> 2] = 0; + HEAP32[buf + 8 >> 2] = stat.ino; + HEAP32[buf + 12 >> 2] = stat.mode; + HEAP32[buf + 16 >> 2] = stat.nlink; + HEAP32[buf + 20 >> 2] = stat.uid; + HEAP32[buf + 24 >> 2] = stat.gid; + HEAP32[buf + 28 >> 2] = stat.rdev; + HEAP32[buf + 32 >> 2] = 0; + tempI64 = [ + stat.size >>> 0, + (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 : 0) + ], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1]; + HEAP32[buf + 48 >> 2] = 4096; + HEAP32[buf + 52 >> 2] = stat.blocks; + HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0; + HEAP32[buf + 60 >> 2] = 0; + HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0; + HEAP32[buf + 68 >> 2] = 0; + HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0; + HEAP32[buf + 76 >> 2] = 0; + tempI64 = [ + stat.ino >>> 0, + (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 : 0) + ], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1]; + return 0; + }, + doMsync: function(addr, stream, len, flags, offset) { + var buffer2 = HEAPU8.slice(addr, addr + len); + FS.msync(stream, buffer2, offset, len, flags); + }, + doMkdir: function(path, mode) { + path = PATH.normalize(path); + if (path[path.length - 1] === "/") + path = path.substr(0, path.length - 1); + FS.mkdir(path, mode, 0); + return 0; + }, + doMknod: function(path, mode, dev) { + switch (mode & 61440) { + case 32768: + case 8192: + case 24576: + case 4096: + case 49152: + break; + default: + return -28; + } + FS.mknod(path, mode, dev); + return 0; + }, + doReadlink: function(path, buf, bufsize) { + if (bufsize <= 0) + return -28; + var ret = FS.readlink(path); + var len = Math.min(bufsize, lengthBytesUTF8(ret)); + var endChar = HEAP8[buf + len]; + stringToUTF8(ret, buf, bufsize + 1); + HEAP8[buf + len] = endChar; + return len; + }, + doAccess: function(path, amode) { + if (amode & ~7) { + return -28; + } + var node; + var lookup = FS.lookupPath(path, { follow: true }); + node = lookup.node; + if (!node) { + return -44; + } + var perms = ""; + if (amode & 4) + perms += "r"; + if (amode & 2) + perms += "w"; + if (amode & 1) + perms += "x"; + if (perms && FS.nodePermissions(node, perms)) { + return -2; + } + return 0; + }, + doDup: function(path, flags, suggestFD) { + var suggest = FS.getStream(suggestFD); + if (suggest) + FS.close(suggest); + return FS.open(path, flags, 0, suggestFD, suggestFD).fd; + }, + doReadv: function(stream, iov, iovcnt, offset) { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAP32[iov + i * 8 >> 2]; + var len = HEAP32[iov + (i * 8 + 4) >> 2]; + var curr = FS.read(stream, HEAP8, ptr, len, offset); + if (curr < 0) + return -1; + ret += curr; + if (curr < len) + break; + } + return ret; + }, + doWritev: function(stream, iov, iovcnt, offset) { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAP32[iov + i * 8 >> 2]; + var len = HEAP32[iov + (i * 8 + 4) >> 2]; + var curr = FS.write(stream, HEAP8, ptr, len, offset); + if (curr < 0) + return -1; + ret += curr; + } + return ret; + }, + varargs: void 0, + get: function() { + SYSCALLS.varargs += 4; + var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; + return ret; + }, + getStr: function(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + getStreamFromFD: function(fd) { + var stream = FS.getStream(fd); + if (!stream) + throw new FS.ErrnoError(8); + return stream; + }, + get64: function(low, high) { + return low; + } + }; + function ___sys_chmod(path, mode) { + try { + path = SYSCALLS.getStr(path); + FS.chmod(path, mode); + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function setErrNo(value) { + HEAP32[___errno_location() >> 2] = value; + return value; + } + function ___sys_fcntl64(fd, cmd, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: { + var arg = SYSCALLS.get(); + if (arg < 0) { + return -28; + } + var newStream; + newStream = FS.open(stream.path, stream.flags, 0, arg); + return newStream.fd; + } + case 1: + case 2: + return 0; + case 3: + return stream.flags; + case 4: { + var arg = SYSCALLS.get(); + stream.flags |= arg; + return 0; + } + case 12: { + var arg = SYSCALLS.get(); + var offset = 0; + HEAP16[arg + offset >> 1] = 2; + return 0; + } + case 13: + case 14: + return 0; + case 16: + case 8: + return -28; + case 9: + setErrNo(28); + return -1; + default: { + return -28; + } + } + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_fstat64(fd, buf) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + return SYSCALLS.doStat(FS.stat, stream.path, buf); + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_ioctl(fd, op, varargs) { + SYSCALLS.varargs = varargs; + try { + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: + case 21505: { + if (!stream.tty) + return -59; + return 0; + } + case 21510: + case 21511: + case 21512: + case 21506: + case 21507: + case 21508: { + if (!stream.tty) + return -59; + return 0; + } + case 21519: { + if (!stream.tty) + return -59; + var argp = SYSCALLS.get(); + HEAP32[argp >> 2] = 0; + return 0; + } + case 21520: { + if (!stream.tty) + return -59; + return -28; + } + case 21531: { + var argp = SYSCALLS.get(); + return FS.ioctl(stream, op, argp); + } + case 21523: { + if (!stream.tty) + return -59; + return 0; + } + case 21524: { + if (!stream.tty) + return -59; + return 0; + } + default: + abort("bad ioctl syscall " + op); + } + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_open(path, flags, varargs) { + SYSCALLS.varargs = varargs; + try { + var pathname = SYSCALLS.getStr(path); + var mode = varargs ? SYSCALLS.get() : 0; + var stream = FS.open(pathname, flags, mode); + return stream.fd; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_rename(old_path, new_path) { + try { + old_path = SYSCALLS.getStr(old_path); + new_path = SYSCALLS.getStr(new_path); + FS.rename(old_path, new_path); + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_rmdir(path) { + try { + path = SYSCALLS.getStr(path); + FS.rmdir(path); + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_stat64(path, buf) { + try { + path = SYSCALLS.getStr(path); + return SYSCALLS.doStat(FS.stat, path, buf); + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function ___sys_unlink(path) { + try { + path = SYSCALLS.getStr(path); + FS.unlink(path); + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return -e.errno; + } + } + function _emscripten_memcpy_big(dest, src, num) { + HEAPU8.copyWithin(dest, src, src + num); + } + function emscripten_realloc_buffer(size) { + try { + wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16); + updateGlobalBufferAndViews(wasmMemory.buffer); + return 1; + } catch (e) { + } + } + function _emscripten_resize_heap(requestedSize) { + var oldSize = HEAPU8.length; + requestedSize = requestedSize >>> 0; + var maxHeapSize = 2147483648; + if (requestedSize > maxHeapSize) { + return false; + } + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); + overGrownHeapSize = Math.min( + overGrownHeapSize, + requestedSize + 100663296 + ); + var newSize = Math.min( + maxHeapSize, + alignUp(Math.max(requestedSize, overGrownHeapSize), 65536) + ); + var replacement = emscripten_realloc_buffer(newSize); + if (replacement) { + return true; + } + } + return false; + } + function _fd_close(fd) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return e.errno; + } + } + function _fd_fdstat_get(fd, pbuf) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var type = stream.tty ? 2 : FS.isDir(stream.mode) ? 3 : FS.isLink(stream.mode) ? 7 : 4; + HEAP8[pbuf >> 0] = type; + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return e.errno; + } + } + function _fd_read(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = SYSCALLS.doReadv(stream, iov, iovcnt); + HEAP32[pnum >> 2] = num; + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return e.errno; + } + } + function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var HIGH_OFFSET = 4294967296; + var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0); + var DOUBLE_LIMIT = 9007199254740992; + if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) { + return -61; + } + FS.llseek(stream, offset, whence); + tempI64 = [ + stream.position >>> 0, + (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil( + (tempDouble - +(~~tempDouble >>> 0)) / 4294967296 + ) >>> 0 : 0) + ], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1]; + if (stream.getdents && offset === 0 && whence === 0) + stream.getdents = null; + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return e.errno; + } + } + function _fd_write(fd, iov, iovcnt, pnum) { + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = SYSCALLS.doWritev(stream, iov, iovcnt); + HEAP32[pnum >> 2] = num; + return 0; + } catch (e) { + if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) + abort(e); + return e.errno; + } + } + function _setTempRet0(val) { + } + function _time(ptr) { + var ret = Date.now() / 1e3 | 0; + if (ptr) { + HEAP32[ptr >> 2] = ret; + } + return ret; + } + function _tzset() { + if (_tzset.called) + return; + _tzset.called = true; + var currentYear = new Date().getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + HEAP32[__get_timezone() >> 2] = stdTimezoneOffset * 60; + HEAP32[__get_daylight() >> 2] = Number(winterOffset != summerOffset); + function extractZone(date) { + var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); + return match ? match[1] : "GMT"; + } + var winterName = extractZone(winter); + var summerName = extractZone(summer); + var winterNamePtr = allocateUTF8(winterName); + var summerNamePtr = allocateUTF8(summerName); + if (summerOffset < winterOffset) { + HEAP32[__get_tzname() >> 2] = winterNamePtr; + HEAP32[__get_tzname() + 4 >> 2] = summerNamePtr; + } else { + HEAP32[__get_tzname() >> 2] = summerNamePtr; + HEAP32[__get_tzname() + 4 >> 2] = winterNamePtr; + } + } + function _timegm(tmPtr) { + _tzset(); + var time = Date.UTC( + HEAP32[tmPtr + 20 >> 2] + 1900, + HEAP32[tmPtr + 16 >> 2], + HEAP32[tmPtr + 12 >> 2], + HEAP32[tmPtr + 8 >> 2], + HEAP32[tmPtr + 4 >> 2], + HEAP32[tmPtr >> 2], + 0 + ); + var date = new Date(time); + HEAP32[tmPtr + 24 >> 2] = date.getUTCDay(); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; + HEAP32[tmPtr + 28 >> 2] = yday; + return date.getTime() / 1e3 | 0; + } + var FSNode = function(parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.mounted = null; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.node_ops = {}; + this.stream_ops = {}; + this.rdev = rdev; + }; + var readMode = 292 | 73; + var writeMode = 146; + Object.defineProperties(FSNode.prototype, { + read: { + get: function() { + return (this.mode & readMode) === readMode; + }, + set: function(val) { + val ? this.mode |= readMode : this.mode &= ~readMode; + } + }, + write: { + get: function() { + return (this.mode & writeMode) === writeMode; + }, + set: function(val) { + val ? this.mode |= writeMode : this.mode &= ~writeMode; + } + }, + isFolder: { + get: function() { + return FS.isDir(this.mode); + } + }, + isDevice: { + get: function() { + return FS.isChrdev(this.mode); + } + } + }); + FS.FSNode = FSNode; + FS.staticInit(); + { + var fs = frozenFs; + var NODEJS_PATH = path__default.default; + NODEFS.staticInit(); + } + { + var _wrapNodeError = function(func) { + return function() { + try { + return func.apply(this, arguments); + } catch (e) { + if (!e.code) + throw e; + throw new FS.ErrnoError(ERRNO_CODES[e.code]); + } + }; + }; + var VFS = Object.assign({}, FS); + for (var _key in NODERAWFS) + FS[_key] = _wrapNodeError(NODERAWFS[_key]); + } + function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array( + stringy, + u8array, + 0, + u8array.length + ); + if (dontAddNull) + u8array.length = numBytesWritten; + return u8array; + } + function intArrayFromBase64(s) { + { + var buf; + try { + buf = Buffer.from(s, "base64"); + } catch (_) { + buf = new Buffer(s, "base64"); + } + return new Uint8Array( + buf["buffer"], + buf["byteOffset"], + buf["byteLength"] + ); + } + } + function tryParseAsDataURI(filename) { + if (!isDataURI(filename)) { + return; + } + return intArrayFromBase64(filename.slice(dataURIPrefix.length)); + } + var asmLibraryArg = { + s: ___gmtime_r, + p: ___sys_chmod, + e: ___sys_fcntl64, + k: ___sys_fstat64, + o: ___sys_ioctl, + q: ___sys_open, + i: ___sys_rename, + r: ___sys_rmdir, + c: ___sys_stat64, + h: ___sys_unlink, + l: _emscripten_memcpy_big, + m: _emscripten_resize_heap, + f: _fd_close, + j: _fd_fdstat_get, + g: _fd_read, + n: _fd_seek, + d: _fd_write, + a: _setTempRet0, + b: _time, + t: _timegm + }; + var asm = createWasm(); + Module["___wasm_call_ctors"] = asm["v"]; + Module["_zip_ext_count_symlinks"] = asm["w"]; + Module["_zip_file_get_external_attributes"] = asm["x"]; + Module["_zipstruct_stat"] = asm["y"]; + Module["_zipstruct_statS"] = asm["z"]; + Module["_zipstruct_stat_name"] = asm["A"]; + Module["_zipstruct_stat_index"] = asm["B"]; + Module["_zipstruct_stat_size"] = asm["C"]; + Module["_zipstruct_stat_mtime"] = asm["D"]; + Module["_zipstruct_stat_crc"] = asm["E"]; + Module["_zipstruct_error"] = asm["F"]; + Module["_zipstruct_errorS"] = asm["G"]; + Module["_zipstruct_error_code_zip"] = asm["H"]; + Module["_zipstruct_stat_comp_size"] = asm["I"]; + Module["_zipstruct_stat_comp_method"] = asm["J"]; + Module["_zip_close"] = asm["K"]; + Module["_zip_delete"] = asm["L"]; + Module["_zip_dir_add"] = asm["M"]; + Module["_zip_discard"] = asm["N"]; + Module["_zip_error_init_with_code"] = asm["O"]; + Module["_zip_get_error"] = asm["P"]; + Module["_zip_file_get_error"] = asm["Q"]; + Module["_zip_error_strerror"] = asm["R"]; + Module["_zip_fclose"] = asm["S"]; + Module["_zip_file_add"] = asm["T"]; + Module["_free"] = asm["U"]; + var _malloc = Module["_malloc"] = asm["V"]; + var ___errno_location = Module["___errno_location"] = asm["W"]; + Module["_zip_source_error"] = asm["X"]; + Module["_zip_source_seek"] = asm["Y"]; + Module["_zip_file_set_external_attributes"] = asm["Z"]; + Module["_zip_file_set_mtime"] = asm["_"]; + Module["_zip_fopen"] = asm["$"]; + Module["_zip_fopen_index"] = asm["aa"]; + Module["_zip_fread"] = asm["ba"]; + Module["_zip_get_name"] = asm["ca"]; + Module["_zip_get_num_entries"] = asm["da"]; + Module["_zip_source_read"] = asm["ea"]; + Module["_zip_name_locate"] = asm["fa"]; + Module["_zip_open"] = asm["ga"]; + Module["_zip_open_from_source"] = asm["ha"]; + Module["_zip_set_file_compression"] = asm["ia"]; + Module["_zip_source_buffer"] = asm["ja"]; + Module["_zip_source_buffer_create"] = asm["ka"]; + Module["_zip_source_close"] = asm["la"]; + Module["_zip_source_free"] = asm["ma"]; + Module["_zip_source_keep"] = asm["na"]; + Module["_zip_source_open"] = asm["oa"]; + Module["_zip_source_set_mtime"] = asm["qa"]; + Module["_zip_source_tell"] = asm["ra"]; + Module["_zip_stat"] = asm["sa"]; + Module["_zip_stat_index"] = asm["ta"]; + var __get_tzname = Module["__get_tzname"] = asm["ua"]; + var __get_daylight = Module["__get_daylight"] = asm["va"]; + var __get_timezone = Module["__get_timezone"] = asm["wa"]; + var stackSave = Module["stackSave"] = asm["xa"]; + var stackRestore = Module["stackRestore"] = asm["ya"]; + var stackAlloc = Module["stackAlloc"] = asm["za"]; + Module["cwrap"] = cwrap; + Module["getValue"] = getValue; + var calledRun; + dependenciesFulfilled = function runCaller() { + if (!calledRun) + run(); + if (!calledRun) + dependenciesFulfilled = runCaller; + }; + function run(args) { + if (runDependencies > 0) { + return; + } + preRun(); + if (runDependencies > 0) { + return; + } + function doRun() { + if (calledRun) + return; + calledRun = true; + Module["calledRun"] = true; + if (ABORT) + return; + initRuntime(); + readyPromiseResolve(Module); + if (Module["onRuntimeInitialized"]) + Module["onRuntimeInitialized"](); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + setTimeout(function() { + setTimeout(function() { + Module["setStatus"](""); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + } + Module["run"] = run; + if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") + Module["preInit"] = [Module["preInit"]]; + while (Module["preInit"].length > 0) { + Module["preInit"].pop()(); + } + } + run(); + return createModule2; + }; +}(); +module.exports = createModule; +}(libzipSync)); + +const createModule = libzipSync.exports; + +const number64 = [ + `number`, + `number` +]; +var Errors = /* @__PURE__ */ ((Errors2) => { + Errors2[Errors2["ZIP_ER_OK"] = 0] = "ZIP_ER_OK"; + Errors2[Errors2["ZIP_ER_MULTIDISK"] = 1] = "ZIP_ER_MULTIDISK"; + Errors2[Errors2["ZIP_ER_RENAME"] = 2] = "ZIP_ER_RENAME"; + Errors2[Errors2["ZIP_ER_CLOSE"] = 3] = "ZIP_ER_CLOSE"; + Errors2[Errors2["ZIP_ER_SEEK"] = 4] = "ZIP_ER_SEEK"; + Errors2[Errors2["ZIP_ER_READ"] = 5] = "ZIP_ER_READ"; + Errors2[Errors2["ZIP_ER_WRITE"] = 6] = "ZIP_ER_WRITE"; + Errors2[Errors2["ZIP_ER_CRC"] = 7] = "ZIP_ER_CRC"; + Errors2[Errors2["ZIP_ER_ZIPCLOSED"] = 8] = "ZIP_ER_ZIPCLOSED"; + Errors2[Errors2["ZIP_ER_NOENT"] = 9] = "ZIP_ER_NOENT"; + Errors2[Errors2["ZIP_ER_EXISTS"] = 10] = "ZIP_ER_EXISTS"; + Errors2[Errors2["ZIP_ER_OPEN"] = 11] = "ZIP_ER_OPEN"; + Errors2[Errors2["ZIP_ER_TMPOPEN"] = 12] = "ZIP_ER_TMPOPEN"; + Errors2[Errors2["ZIP_ER_ZLIB"] = 13] = "ZIP_ER_ZLIB"; + Errors2[Errors2["ZIP_ER_MEMORY"] = 14] = "ZIP_ER_MEMORY"; + Errors2[Errors2["ZIP_ER_CHANGED"] = 15] = "ZIP_ER_CHANGED"; + Errors2[Errors2["ZIP_ER_COMPNOTSUPP"] = 16] = "ZIP_ER_COMPNOTSUPP"; + Errors2[Errors2["ZIP_ER_EOF"] = 17] = "ZIP_ER_EOF"; + Errors2[Errors2["ZIP_ER_INVAL"] = 18] = "ZIP_ER_INVAL"; + Errors2[Errors2["ZIP_ER_NOZIP"] = 19] = "ZIP_ER_NOZIP"; + Errors2[Errors2["ZIP_ER_INTERNAL"] = 20] = "ZIP_ER_INTERNAL"; + Errors2[Errors2["ZIP_ER_INCONS"] = 21] = "ZIP_ER_INCONS"; + Errors2[Errors2["ZIP_ER_REMOVE"] = 22] = "ZIP_ER_REMOVE"; + Errors2[Errors2["ZIP_ER_DELETED"] = 23] = "ZIP_ER_DELETED"; + Errors2[Errors2["ZIP_ER_ENCRNOTSUPP"] = 24] = "ZIP_ER_ENCRNOTSUPP"; + Errors2[Errors2["ZIP_ER_RDONLY"] = 25] = "ZIP_ER_RDONLY"; + Errors2[Errors2["ZIP_ER_NOPASSWD"] = 26] = "ZIP_ER_NOPASSWD"; + Errors2[Errors2["ZIP_ER_WRONGPASSWD"] = 27] = "ZIP_ER_WRONGPASSWD"; + Errors2[Errors2["ZIP_ER_OPNOTSUPP"] = 28] = "ZIP_ER_OPNOTSUPP"; + Errors2[Errors2["ZIP_ER_INUSE"] = 29] = "ZIP_ER_INUSE"; + Errors2[Errors2["ZIP_ER_TELL"] = 30] = "ZIP_ER_TELL"; + Errors2[Errors2["ZIP_ER_COMPRESSED_DATA"] = 31] = "ZIP_ER_COMPRESSED_DATA"; + return Errors2; +})(Errors || {}); +const makeInterface = (libzip) => ({ + get HEAP8() { + return libzip.HEAP8; + }, + get HEAPU8() { + return libzip.HEAPU8; + }, + errors: Errors, + SEEK_SET: 0, + SEEK_CUR: 1, + SEEK_END: 2, + ZIP_CHECKCONS: 4, + ZIP_CREATE: 1, + ZIP_EXCL: 2, + ZIP_TRUNCATE: 8, + ZIP_RDONLY: 16, + ZIP_FL_OVERWRITE: 8192, + ZIP_FL_COMPRESSED: 4, + ZIP_OPSYS_DOS: 0, + ZIP_OPSYS_AMIGA: 1, + ZIP_OPSYS_OPENVMS: 2, + ZIP_OPSYS_UNIX: 3, + ZIP_OPSYS_VM_CMS: 4, + ZIP_OPSYS_ATARI_ST: 5, + ZIP_OPSYS_OS_2: 6, + ZIP_OPSYS_MACINTOSH: 7, + ZIP_OPSYS_Z_SYSTEM: 8, + ZIP_OPSYS_CPM: 9, + ZIP_OPSYS_WINDOWS_NTFS: 10, + ZIP_OPSYS_MVS: 11, + ZIP_OPSYS_VSE: 12, + ZIP_OPSYS_ACORN_RISC: 13, + ZIP_OPSYS_VFAT: 14, + ZIP_OPSYS_ALTERNATE_MVS: 15, + ZIP_OPSYS_BEOS: 16, + ZIP_OPSYS_TANDEM: 17, + ZIP_OPSYS_OS_400: 18, + ZIP_OPSYS_OS_X: 19, + ZIP_CM_DEFAULT: -1, + ZIP_CM_STORE: 0, + ZIP_CM_DEFLATE: 8, + uint08S: libzip._malloc(1), + uint16S: libzip._malloc(2), + uint32S: libzip._malloc(4), + uint64S: libzip._malloc(8), + malloc: libzip._malloc, + free: libzip._free, + getValue: libzip.getValue, + open: libzip.cwrap(`zip_open`, `number`, [`string`, `number`, `number`]), + openFromSource: libzip.cwrap(`zip_open_from_source`, `number`, [`number`, `number`, `number`]), + close: libzip.cwrap(`zip_close`, `number`, [`number`]), + discard: libzip.cwrap(`zip_discard`, null, [`number`]), + getError: libzip.cwrap(`zip_get_error`, `number`, [`number`]), + getName: libzip.cwrap(`zip_get_name`, `string`, [`number`, `number`, `number`]), + getNumEntries: libzip.cwrap(`zip_get_num_entries`, `number`, [`number`, `number`]), + delete: libzip.cwrap(`zip_delete`, `number`, [`number`, `number`]), + stat: libzip.cwrap(`zip_stat`, `number`, [`number`, `string`, `number`, `number`]), + statIndex: libzip.cwrap(`zip_stat_index`, `number`, [`number`, ...number64, `number`, `number`]), + fopen: libzip.cwrap(`zip_fopen`, `number`, [`number`, `string`, `number`]), + fopenIndex: libzip.cwrap(`zip_fopen_index`, `number`, [`number`, ...number64, `number`]), + fread: libzip.cwrap(`zip_fread`, `number`, [`number`, `number`, `number`, `number`]), + fclose: libzip.cwrap(`zip_fclose`, `number`, [`number`]), + dir: { + add: libzip.cwrap(`zip_dir_add`, `number`, [`number`, `string`]) + }, + file: { + add: libzip.cwrap(`zip_file_add`, `number`, [`number`, `string`, `number`, `number`]), + getError: libzip.cwrap(`zip_file_get_error`, `number`, [`number`]), + getExternalAttributes: libzip.cwrap(`zip_file_get_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), + setExternalAttributes: libzip.cwrap(`zip_file_set_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), + setMtime: libzip.cwrap(`zip_file_set_mtime`, `number`, [`number`, ...number64, `number`, `number`]), + setCompression: libzip.cwrap(`zip_set_file_compression`, `number`, [`number`, ...number64, `number`, `number`]) + }, + ext: { + countSymlinks: libzip.cwrap(`zip_ext_count_symlinks`, `number`, [`number`]) + }, + error: { + initWithCode: libzip.cwrap(`zip_error_init_with_code`, null, [`number`, `number`]), + strerror: libzip.cwrap(`zip_error_strerror`, `string`, [`number`]) + }, + name: { + locate: libzip.cwrap(`zip_name_locate`, `number`, [`number`, `string`, `number`]) + }, + source: { + fromUnattachedBuffer: libzip.cwrap(`zip_source_buffer_create`, `number`, [`number`, `number`, `number`, `number`]), + fromBuffer: libzip.cwrap(`zip_source_buffer`, `number`, [`number`, `number`, ...number64, `number`]), + free: libzip.cwrap(`zip_source_free`, null, [`number`]), + keep: libzip.cwrap(`zip_source_keep`, null, [`number`]), + open: libzip.cwrap(`zip_source_open`, `number`, [`number`]), + close: libzip.cwrap(`zip_source_close`, `number`, [`number`]), + seek: libzip.cwrap(`zip_source_seek`, `number`, [`number`, ...number64, `number`]), + tell: libzip.cwrap(`zip_source_tell`, `number`, [`number`]), + read: libzip.cwrap(`zip_source_read`, `number`, [`number`, `number`, `number`]), + error: libzip.cwrap(`zip_source_error`, `number`, [`number`]), + setMtime: libzip.cwrap(`zip_source_set_mtime`, `number`, [`number`, `number`]) + }, + struct: { + stat: libzip.cwrap(`zipstruct_stat`, `number`, []), + statS: libzip.cwrap(`zipstruct_statS`, `number`, []), + statName: libzip.cwrap(`zipstruct_stat_name`, `string`, [`number`]), + statIndex: libzip.cwrap(`zipstruct_stat_index`, `number`, [`number`]), + statSize: libzip.cwrap(`zipstruct_stat_size`, `number`, [`number`]), + statCompSize: libzip.cwrap(`zipstruct_stat_comp_size`, `number`, [`number`]), + statCompMethod: libzip.cwrap(`zipstruct_stat_comp_method`, `number`, [`number`]), + statMtime: libzip.cwrap(`zipstruct_stat_mtime`, `number`, [`number`]), + statCrc: libzip.cwrap(`zipstruct_stat_crc`, `number`, [`number`]), + error: libzip.cwrap(`zipstruct_error`, `number`, []), + errorS: libzip.cwrap(`zipstruct_errorS`, `number`, []), + errorCodeZip: libzip.cwrap(`zipstruct_error_code_zip`, `number`, [`number`]) + } +}); + +let mod = null; +function getLibzipSync() { + if (mod === null) + mod = makeInterface(createModule()); + return mod; +} + +var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => { + ErrorCode2["API_ERROR"] = `API_ERROR`; + ErrorCode2["BUILTIN_NODE_RESOLUTION_FAILED"] = `BUILTIN_NODE_RESOLUTION_FAILED`; + ErrorCode2["EXPORTS_RESOLUTION_FAILED"] = `EXPORTS_RESOLUTION_FAILED`; + ErrorCode2["MISSING_DEPENDENCY"] = `MISSING_DEPENDENCY`; + ErrorCode2["MISSING_PEER_DEPENDENCY"] = `MISSING_PEER_DEPENDENCY`; + ErrorCode2["QUALIFIED_PATH_RESOLUTION_FAILED"] = `QUALIFIED_PATH_RESOLUTION_FAILED`; + ErrorCode2["INTERNAL"] = `INTERNAL`; + ErrorCode2["UNDECLARED_DEPENDENCY"] = `UNDECLARED_DEPENDENCY`; + ErrorCode2["UNSUPPORTED"] = `UNSUPPORTED`; + return ErrorCode2; +})(ErrorCode || {}); +const MODULE_NOT_FOUND_ERRORS = /* @__PURE__ */ new Set([ + "BUILTIN_NODE_RESOLUTION_FAILED" /* BUILTIN_NODE_RESOLUTION_FAILED */, + "MISSING_DEPENDENCY" /* MISSING_DEPENDENCY */, + "MISSING_PEER_DEPENDENCY" /* MISSING_PEER_DEPENDENCY */, + "QUALIFIED_PATH_RESOLUTION_FAILED" /* QUALIFIED_PATH_RESOLUTION_FAILED */, + "UNDECLARED_DEPENDENCY" /* UNDECLARED_DEPENDENCY */ +]); +function makeError(pnpCode, message, data = {}, code) { + code != null ? code : code = MODULE_NOT_FOUND_ERRORS.has(pnpCode) ? `MODULE_NOT_FOUND` : pnpCode; + const propertySpec = { + configurable: true, + writable: true, + enumerable: false + }; + return Object.defineProperties(new Error(message), { + code: { + ...propertySpec, + value: code + }, + pnpCode: { + ...propertySpec, + value: pnpCode + }, + data: { + ...propertySpec, + value: data + } + }); +} +function getIssuerModule(parent) { + let issuer = parent; + while (issuer && (issuer.id === `[eval]` || issuer.id === `` || !issuer.filename)) + issuer = issuer.parent; + return issuer || null; +} +function getPathForDisplay(p) { + return npath.normalize(npath.fromPortablePath(p)); +} + +const [major, minor] = process.versions.node.split(`.`).map((value) => parseInt(value, 10)); +const WATCH_MODE_MESSAGE_USES_ARRAYS = major > 19 || major === 19 && minor >= 2 || major === 18 && minor >= 13; + +const builtinModules = new Set(require$$0.Module.builtinModules || Object.keys(process.binding(`natives`))); +const isBuiltinModule = (request) => request.startsWith(`node:`) || builtinModules.has(request); +function readPackageScope(checkPath) { + const rootSeparatorIndex = checkPath.indexOf(npath.sep); + let separatorIndex; + do { + separatorIndex = checkPath.lastIndexOf(npath.sep); + checkPath = checkPath.slice(0, separatorIndex); + if (checkPath.endsWith(`${npath.sep}node_modules`)) + return false; + const pjson = readPackage(checkPath + npath.sep); + if (pjson) { + return { + data: pjson, + path: checkPath + }; + } + } while (separatorIndex > rootSeparatorIndex); + return false; +} +function readPackage(requestPath) { + const jsonPath = npath.resolve(requestPath, `package.json`); + if (!fs__default.default.existsSync(jsonPath)) + return null; + return JSON.parse(fs__default.default.readFileSync(jsonPath, `utf8`)); +} +function ERR_REQUIRE_ESM(filename, parentPath = null) { + const basename = parentPath && path__default.default.basename(filename) === path__default.default.basename(parentPath) ? filename : path__default.default.basename(filename); + const msg = `require() of ES Module ${filename}${parentPath ? ` from ${parentPath}` : ``} not supported. +Instead change the require of ${basename} in ${parentPath} to a dynamic import() which is available in all CommonJS modules.`; + const err = new Error(msg); + err.code = `ERR_REQUIRE_ESM`; + return err; +} +function reportRequiredFilesToWatchMode(files) { + if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) { + files = files.map((filename) => npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename)))); + if (WATCH_MODE_MESSAGE_USES_ARRAYS) { + process.send({ "watch:require": files }); + } else { + for (const filename of files) { + process.send({ "watch:require": filename }); + } + } + } +} + +function applyPatch(pnpapi, opts) { + const defaultCache = {}; + let enableNativeHooks = true; + process.versions.pnp = String(pnpapi.VERSIONS.std); + const moduleExports = require$$0__default.default; + moduleExports.findPnpApi = (lookupSource) => { + const lookupPath = lookupSource instanceof url.URL ? url.fileURLToPath(lookupSource) : lookupSource; + const apiPath = opts.manager.findApiPathFor(lookupPath); + if (apiPath === null) + return null; + const apiEntry = opts.manager.getApiEntry(apiPath, true); + return apiEntry.instance.findPackageLocator(lookupPath) ? apiEntry.instance : null; + }; + function getRequireStack(parent) { + const requireStack = []; + for (let cursor = parent; cursor; cursor = cursor.parent) + requireStack.push(cursor.filename || cursor.id); + return requireStack; + } + const originalModuleLoad = require$$0.Module._load; + require$$0.Module._load = function(request, parent, isMain) { + if (!enableNativeHooks) + return originalModuleLoad.call(require$$0.Module, request, parent, isMain); + if (isBuiltinModule(request)) { + try { + enableNativeHooks = false; + return originalModuleLoad.call(require$$0.Module, request, parent, isMain); + } finally { + enableNativeHooks = true; + } + } + const parentApiPath = opts.manager.getApiPathFromParent(parent); + const parentApi = parentApiPath !== null ? opts.manager.getApiEntry(parentApiPath, true).instance : null; + if (parentApi === null) + return originalModuleLoad(request, parent, isMain); + if (request === `pnpapi`) + return parentApi; + const modulePath = require$$0.Module._resolveFilename(request, parent, isMain); + const isOwnedByRuntime = parentApi !== null ? parentApi.findPackageLocator(modulePath) !== null : false; + const moduleApiPath = isOwnedByRuntime ? parentApiPath : opts.manager.findApiPathFor(npath.dirname(modulePath)); + const entry = moduleApiPath !== null ? opts.manager.getApiEntry(moduleApiPath) : { instance: null, cache: defaultCache }; + const cacheEntry = entry.cache[modulePath]; + if (cacheEntry) { + if (cacheEntry.loaded === false && cacheEntry.isLoading !== true) { + try { + cacheEntry.isLoading = true; + if (isMain) { + process.mainModule = cacheEntry; + cacheEntry.id = `.`; + } + cacheEntry.load(modulePath); + } finally { + cacheEntry.isLoading = false; + } + } + return cacheEntry.exports; + } + const module = new require$$0.Module(modulePath, parent != null ? parent : void 0); + module.pnpApiPath = moduleApiPath; + reportRequiredFilesToWatchMode([modulePath]); + entry.cache[modulePath] = module; + if (isMain) { + process.mainModule = module; + module.id = `.`; + } + let hasThrown = true; + try { + module.isLoading = true; + module.load(modulePath); + hasThrown = false; + } finally { + module.isLoading = false; + if (hasThrown) { + delete require$$0.Module._cache[modulePath]; + } + } + return module.exports; + }; + function getIssuerSpecsFromPaths(paths) { + return paths.map((path) => ({ + apiPath: opts.manager.findApiPathFor(path), + path, + module: null + })); + } + function getIssuerSpecsFromModule(module) { + var _a; + if (module && module.id !== `` && module.id !== `internal/preload` && !module.parent && !module.filename && module.paths.length > 0) { + return [{ + apiPath: opts.manager.findApiPathFor(module.paths[0]), + path: module.paths[0], + module + }]; + } + const issuer = getIssuerModule(module); + if (issuer !== null) { + const path = npath.dirname(issuer.filename); + const apiPath = opts.manager.getApiPathFromParent(issuer); + return [{ apiPath, path, module }]; + } else { + const path = process.cwd(); + const apiPath = (_a = opts.manager.findApiPathFor(npath.join(path, `[file]`))) != null ? _a : opts.manager.getApiPathFromParent(null); + return [{ apiPath, path, module }]; + } + } + function makeFakeParent(path) { + const fakeParent = new require$$0.Module(``); + const fakeFilePath = npath.join(path, `[file]`); + fakeParent.paths = require$$0.Module._nodeModulePaths(fakeFilePath); + return fakeParent; + } + const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/; + const originalModuleResolveFilename = require$$0.Module._resolveFilename; + require$$0.Module._resolveFilename = function(request, parent, isMain, options) { + if (isBuiltinModule(request)) + return request; + if (!enableNativeHooks) + return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, options); + if (options && options.plugnplay === false) { + const { plugnplay, ...rest } = options; + const forwardedOptions = Object.keys(rest).length > 0 ? rest : void 0; + try { + enableNativeHooks = false; + return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, forwardedOptions); + } finally { + enableNativeHooks = true; + } + } + if (options) { + const optionNames = new Set(Object.keys(options)); + optionNames.delete(`paths`); + optionNames.delete(`plugnplay`); + if (optionNames.size > 0) { + throw makeError( + ErrorCode.UNSUPPORTED, + `Some options passed to require() aren't supported by PnP yet (${Array.from(optionNames).join(`, `)})` + ); + } + } + const issuerSpecs = options && options.paths ? getIssuerSpecsFromPaths(options.paths) : getIssuerSpecsFromModule(parent); + if (request.match(pathRegExp) === null) { + const parentDirectory = (parent == null ? void 0 : parent.filename) != null ? npath.dirname(parent.filename) : null; + const absoluteRequest = npath.isAbsolute(request) ? request : parentDirectory !== null ? npath.resolve(parentDirectory, request) : null; + if (absoluteRequest !== null) { + const apiPath = parentDirectory === npath.dirname(absoluteRequest) && (parent == null ? void 0 : parent.pnpApiPath) ? parent.pnpApiPath : opts.manager.findApiPathFor(absoluteRequest); + if (apiPath !== null) { + issuerSpecs.unshift({ + apiPath, + path: parentDirectory, + module: null + }); + } + } + } + let firstError; + for (const { apiPath, path, module } of issuerSpecs) { + let resolution; + const issuerApi = apiPath !== null ? opts.manager.getApiEntry(apiPath, true).instance : null; + try { + if (issuerApi !== null) { + resolution = issuerApi.resolveRequest(request, path !== null ? `${path}/` : null); + } else { + if (path === null) + throw new Error(`Assertion failed: Expected the path to be set`); + resolution = originalModuleResolveFilename.call(require$$0.Module, request, module || makeFakeParent(path), isMain); + } + } catch (error) { + firstError = firstError || error; + continue; + } + if (resolution !== null) { + return resolution; + } + } + const requireStack = getRequireStack(parent); + Object.defineProperty(firstError, `requireStack`, { + configurable: true, + writable: true, + enumerable: false, + value: requireStack + }); + if (requireStack.length > 0) + firstError.message += ` +Require stack: +- ${requireStack.join(` +- `)}`; + if (typeof firstError.pnpCode === `string`) + Error.captureStackTrace(firstError); + throw firstError; + }; + const originalFindPath = require$$0.Module._findPath; + require$$0.Module._findPath = function(request, paths, isMain) { + if (request === `pnpapi`) + return false; + if (!enableNativeHooks) + return originalFindPath.call(require$$0.Module, request, paths, isMain); + const isAbsolute = npath.isAbsolute(request); + if (isAbsolute) + paths = [``]; + else if (!paths || paths.length === 0) + return false; + for (const path of paths) { + let resolution; + try { + const pnpApiPath = opts.manager.findApiPathFor(isAbsolute ? request : path); + if (pnpApiPath !== null) { + const api = opts.manager.getApiEntry(pnpApiPath, true).instance; + resolution = api.resolveRequest(request, path) || false; + } else { + resolution = originalFindPath.call(require$$0.Module, request, [path], isMain); + } + } catch (error) { + continue; + } + if (resolution) { + return resolution; + } + } + return false; + }; + const originalExtensionJSFunction = require$$0.Module._extensions[`.js`]; + require$$0.Module._extensions[`.js`] = function(module, filename) { + var _a, _b; + if (filename.endsWith(`.js`)) { + const pkg = readPackageScope(filename); + if (pkg && ((_a = pkg.data) == null ? void 0 : _a.type) === `module`) { + const err = ERR_REQUIRE_ESM(filename, (_b = module.parent) == null ? void 0 : _b.filename); + Error.captureStackTrace(err); + throw err; + } + } + originalExtensionJSFunction.call(this, module, filename); + }; + const originalDlopen = process.dlopen; + process.dlopen = function(...args) { + const [module, filename, ...rest] = args; + return originalDlopen.call( + this, + module, + npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename))), + ...rest + ); + }; + const originalEmit = process.emit; + process.emit = function(name, data, ...args) { + if (name === `warning` && typeof data === `object` && data.name === `ExperimentalWarning` && (data.message.includes(`--experimental-loader`) || data.message.includes(`Custom ESM Loaders is an experimental feature`))) + return false; + return originalEmit.apply(process, arguments); + }; + patchFs(fs__default.default, new PosixFS(opts.fakeFs)); +} + +function hydrateRuntimeState(data, { basePath }) { + const portablePath = npath.toPortablePath(basePath); + const absolutePortablePath = ppath.resolve(portablePath); + const ignorePattern = data.ignorePatternData !== null ? new RegExp(data.ignorePatternData) : null; + const packageLocatorsByLocations = /* @__PURE__ */ new Map(); + const packageRegistry = new Map(data.packageRegistryData.map(([packageName, packageStoreData]) => { + return [packageName, new Map(packageStoreData.map(([packageReference, packageInformationData]) => { + var _a; + if (packageName === null !== (packageReference === null)) + throw new Error(`Assertion failed: The name and reference should be null, or neither should`); + const discardFromLookup = (_a = packageInformationData.discardFromLookup) != null ? _a : false; + const packageLocator = { name: packageName, reference: packageReference }; + const entry = packageLocatorsByLocations.get(packageInformationData.packageLocation); + if (!entry) { + packageLocatorsByLocations.set(packageInformationData.packageLocation, { locator: packageLocator, discardFromLookup }); + } else { + entry.discardFromLookup = entry.discardFromLookup && discardFromLookup; + if (!discardFromLookup) { + entry.locator = packageLocator; + } + } + let resolvedPackageLocation = null; + return [packageReference, { + packageDependencies: new Map(packageInformationData.packageDependencies), + packagePeers: new Set(packageInformationData.packagePeers), + linkType: packageInformationData.linkType, + discardFromLookup, + get packageLocation() { + return resolvedPackageLocation || (resolvedPackageLocation = ppath.join(absolutePortablePath, packageInformationData.packageLocation)); + } + }]; + }))]; + })); + const fallbackExclusionList = new Map(data.fallbackExclusionList.map(([packageName, packageReferences]) => { + return [packageName, new Set(packageReferences)]; + })); + const fallbackPool = new Map(data.fallbackPool); + const dependencyTreeRoots = data.dependencyTreeRoots; + const enableTopLevelFallback = data.enableTopLevelFallback; + return { + basePath: portablePath, + dependencyTreeRoots, + enableTopLevelFallback, + fallbackExclusionList, + fallbackPool, + ignorePattern, + packageLocatorsByLocations, + packageRegistry + }; +} + +/** + * @param {object} exports + * @param {Set} keys + */ +function loop(exports, keys) { + if (typeof exports === 'string') { + return exports; + } + + if (exports) { + let idx, tmp; + if (Array.isArray(exports)) { + for (idx=0; idx < exports.length; idx++) { + if (tmp = loop(exports[idx], keys)) return tmp; + } + } else { + for (idx in exports) { + if (keys.has(idx)) { + return loop(exports[idx], keys); + } + } + } + } +} + +/** + * @param {string} name The package name + * @param {string} entry The target entry, eg "." + * @param {number} [condition] Unmatched condition? + */ +function bail(name, entry, condition) { + throw new Error( + condition + ? `No known conditions for "${entry}" entry in "${name}" package` + : `Missing "${entry}" export in "${name}" package` + ); +} + +/** + * @param {string} name the package name + * @param {string} entry the target path/import + */ +function toName(name, entry) { + return entry === name ? '.' + : entry[0] === '.' ? entry + : entry.replace(new RegExp('^' + name + '\/'), './'); +} + +/** + * @param {object} pkg package.json contents + * @param {string} [entry] entry name or import path + * @param {object} [options] + * @param {boolean} [options.browser] + * @param {boolean} [options.require] + * @param {string[]} [options.conditions] + * @param {boolean} [options.unsafe] + */ +function resolve(pkg, entry='.', options={}) { + let { name, exports } = pkg; + + if (exports) { + let { browser, require, unsafe, conditions=[] } = options; + + let target = toName(name, entry); + if (target[0] !== '.') target = './' + target; + + if (typeof exports === 'string') { + return target === '.' ? exports : bail(name, target); + } + + let allows = new Set(['default', ...conditions]); + unsafe || allows.add(require ? 'require' : 'import'); + unsafe || allows.add(browser ? 'browser' : 'node'); + + let key, tmp, isSingle=false; + + for (key in exports) { + isSingle = key[0] !== '.'; + break; + } + + if (isSingle) { + return target === '.' + ? loop(exports, allows) || bail(name, target, 1) + : bail(name, target); + } + + if (tmp = exports[target]) { + return loop(tmp, allows) || bail(name, target, 1); + } + + for (key in exports) { + tmp = key[key.length - 1]; + if (tmp === '/' && target.startsWith(key)) { + return (tmp = loop(exports[key], allows)) + ? (tmp + target.substring(key.length)) + : bail(name, target, 1); + } + if (tmp === '*' && target.startsWith(key.slice(0, -1))) { + // do not trigger if no *content* to inject + if (target.substring(key.length - 1).length > 0) { + return (tmp = loop(exports[key], allows)) + ? tmp.replace('*', target.substring(key.length - 1)) + : bail(name, target, 1); + } + } + } + + return bail(name, target); + } +} + +const ArrayIsArray = Array.isArray; +const JSONStringify = JSON.stringify; +const ObjectGetOwnPropertyNames = Object.getOwnPropertyNames; +const ObjectPrototypeHasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); +const RegExpPrototypeExec = (obj, string) => RegExp.prototype.exec.call(obj, string); +const RegExpPrototypeSymbolReplace = (obj, ...rest) => RegExp.prototype[Symbol.replace].apply(obj, rest); +const StringPrototypeEndsWith = (str, ...rest) => String.prototype.endsWith.apply(str, rest); +const StringPrototypeIncludes = (str, ...rest) => String.prototype.includes.apply(str, rest); +const StringPrototypeLastIndexOf = (str, ...rest) => String.prototype.lastIndexOf.apply(str, rest); +const StringPrototypeIndexOf = (str, ...rest) => String.prototype.indexOf.apply(str, rest); +const StringPrototypeReplace = (str, ...rest) => String.prototype.replace.apply(str, rest); +const StringPrototypeSlice = (str, ...rest) => String.prototype.slice.apply(str, rest); +const StringPrototypeStartsWith = (str, ...rest) => String.prototype.startsWith.apply(str, rest); +const SafeMap = Map; +const JSONParse = JSON.parse; + +function createErrorType(code, messageCreator, errorType) { + return class extends errorType { + constructor(...args) { + super(messageCreator(...args)); + this.code = code; + this.name = `${errorType.name} [${code}]`; + } + }; +} +const ERR_PACKAGE_IMPORT_NOT_DEFINED = createErrorType( + `ERR_PACKAGE_IMPORT_NOT_DEFINED`, + (specifier, packagePath, base) => { + return `Package import specifier "${specifier}" is not defined${packagePath ? ` in package ${packagePath}package.json` : ``} imported from ${base}`; + }, + TypeError +); +const ERR_INVALID_MODULE_SPECIFIER = createErrorType( + `ERR_INVALID_MODULE_SPECIFIER`, + (request, reason, base = void 0) => { + return `Invalid module "${request}" ${reason}${base ? ` imported from ${base}` : ``}`; + }, + TypeError +); +const ERR_INVALID_PACKAGE_TARGET = createErrorType( + `ERR_INVALID_PACKAGE_TARGET`, + (pkgPath, key, target, isImport = false, base = void 0) => { + const relError = typeof target === `string` && !isImport && target.length && !StringPrototypeStartsWith(target, `./`); + if (key === `.`) { + assert__default.default(isImport === false); + return `Invalid "exports" main target ${JSONStringify(target)} defined in the package config ${pkgPath}package.json${base ? ` imported from ${base}` : ``}${relError ? `; targets must start with "./"` : ``}`; + } + return `Invalid "${isImport ? `imports` : `exports`}" target ${JSONStringify( + target + )} defined for '${key}' in the package config ${pkgPath}package.json${base ? ` imported from ${base}` : ``}${relError ? `; targets must start with "./"` : ``}`; + }, + Error +); +const ERR_INVALID_PACKAGE_CONFIG = createErrorType( + `ERR_INVALID_PACKAGE_CONFIG`, + (path, base, message) => { + return `Invalid package config ${path}${base ? ` while importing ${base}` : ``}${message ? `. ${message}` : ``}`; + }, + Error +); + +function filterOwnProperties(source, keys) { + const filtered = /* @__PURE__ */ Object.create(null); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (ObjectPrototypeHasOwnProperty(source, key)) { + filtered[key] = source[key]; + } + } + return filtered; +} + +const packageJSONCache = new SafeMap(); +function getPackageConfig(path, specifier, base, readFileSyncFn) { + const existing = packageJSONCache.get(path); + if (existing !== void 0) { + return existing; + } + const source = readFileSyncFn(path); + if (source === void 0) { + const packageConfig2 = { + pjsonPath: path, + exists: false, + main: void 0, + name: void 0, + type: "none", + exports: void 0, + imports: void 0 + }; + packageJSONCache.set(path, packageConfig2); + return packageConfig2; + } + let packageJSON; + try { + packageJSON = JSONParse(source); + } catch (error) { + throw new ERR_INVALID_PACKAGE_CONFIG( + path, + (base ? `"${specifier}" from ` : "") + url.fileURLToPath(base || specifier), + error.message + ); + } + let { imports, main, name, type } = filterOwnProperties(packageJSON, [ + "imports", + "main", + "name", + "type" + ]); + const exports = ObjectPrototypeHasOwnProperty(packageJSON, "exports") ? packageJSON.exports : void 0; + if (typeof imports !== "object" || imports === null) { + imports = void 0; + } + if (typeof main !== "string") { + main = void 0; + } + if (typeof name !== "string") { + name = void 0; + } + if (type !== "module" && type !== "commonjs") { + type = "none"; + } + const packageConfig = { + pjsonPath: path, + exists: true, + main, + name, + type, + exports, + imports + }; + packageJSONCache.set(path, packageConfig); + return packageConfig; +} +function getPackageScopeConfig(resolved, readFileSyncFn) { + let packageJSONUrl = new URL("./package.json", resolved); + while (true) { + const packageJSONPath2 = packageJSONUrl.pathname; + if (StringPrototypeEndsWith(packageJSONPath2, "node_modules/package.json")) { + break; + } + const packageConfig2 = getPackageConfig( + url.fileURLToPath(packageJSONUrl), + resolved, + void 0, + readFileSyncFn + ); + if (packageConfig2.exists) { + return packageConfig2; + } + const lastPackageJSONUrl = packageJSONUrl; + packageJSONUrl = new URL("../package.json", packageJSONUrl); + if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) { + break; + } + } + const packageJSONPath = url.fileURLToPath(packageJSONUrl); + const packageConfig = { + pjsonPath: packageJSONPath, + exists: false, + main: void 0, + name: void 0, + type: "none", + exports: void 0, + imports: void 0 + }; + packageJSONCache.set(packageJSONPath, packageConfig); + return packageConfig; +} + +/** + @license + Copyright Node.js contributors. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +function throwImportNotDefined(specifier, packageJSONUrl, base) { + throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, + packageJSONUrl && url.fileURLToPath(new URL(".", packageJSONUrl)), + url.fileURLToPath(base) + ); +} +function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) { + const reason = `request is not a valid subpath for the "${internal ? "imports" : "exports"}" resolution of ${url.fileURLToPath(packageJSONUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER( + subpath, + reason, + base && url.fileURLToPath(base) + ); +} +function throwInvalidPackageTarget(subpath, target, packageJSONUrl, internal, base) { + if (typeof target === "object" && target !== null) { + target = JSONStringify(target, null, ""); + } else { + target = `${target}`; + } + throw new ERR_INVALID_PACKAGE_TARGET( + url.fileURLToPath(new URL(".", packageJSONUrl)), + subpath, + target, + internal, + base && url.fileURLToPath(base) + ); +} +const invalidSegmentRegEx = /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i; +const patternRegEx = /\*/g; +function resolvePackageTargetString(target, subpath, match, packageJSONUrl, base, pattern, internal, conditions) { + if (subpath !== "" && !pattern && target[target.length - 1] !== "/") + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + if (!StringPrototypeStartsWith(target, "./")) { + if (internal && !StringPrototypeStartsWith(target, "../") && !StringPrototypeStartsWith(target, "/")) { + let isURL = false; + try { + new URL(target); + isURL = true; + } catch { + } + if (!isURL) { + const exportTarget = pattern ? RegExpPrototypeSymbolReplace(patternRegEx, target, () => subpath) : target + subpath; + return exportTarget; + } + } + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + } + if (RegExpPrototypeExec( + invalidSegmentRegEx, + StringPrototypeSlice(target, 2) + ) !== null) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + const resolved = new URL(target, packageJSONUrl); + const resolvedPath = resolved.pathname; + const packagePath = new URL(".", packageJSONUrl).pathname; + if (!StringPrototypeStartsWith(resolvedPath, packagePath)) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + if (subpath === "") + return resolved; + if (RegExpPrototypeExec(invalidSegmentRegEx, subpath) !== null) { + const request = pattern ? StringPrototypeReplace(match, "*", () => subpath) : match + subpath; + throwInvalidSubpath(request, packageJSONUrl, internal, base); + } + if (pattern) { + return new URL( + RegExpPrototypeSymbolReplace(patternRegEx, resolved.href, () => subpath) + ); + } + return new URL(subpath, resolved); +} +function isArrayIndex(key) { + const keyNum = +key; + if (`${keyNum}` !== key) + return false; + return keyNum >= 0 && keyNum < 4294967295; +} +function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, base, pattern, internal, conditions) { + if (typeof target === "string") { + return resolvePackageTargetString( + target, + subpath, + packageSubpath, + packageJSONUrl, + base, + pattern, + internal); + } else if (ArrayIsArray(target)) { + if (target.length === 0) { + return null; + } + let lastException; + for (let i = 0; i < target.length; i++) { + const targetItem = target[i]; + let resolveResult; + try { + resolveResult = resolvePackageTarget( + packageJSONUrl, + targetItem, + subpath, + packageSubpath, + base, + pattern, + internal, + conditions + ); + } catch (e) { + lastException = e; + if (e.code === "ERR_INVALID_PACKAGE_TARGET") { + continue; + } + throw e; + } + if (resolveResult === void 0) { + continue; + } + if (resolveResult === null) { + lastException = null; + continue; + } + return resolveResult; + } + if (lastException === void 0 || lastException === null) + return lastException; + throw lastException; + } else if (typeof target === "object" && target !== null) { + const keys = ObjectGetOwnPropertyNames(target); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (isArrayIndex(key)) { + throw new ERR_INVALID_PACKAGE_CONFIG( + url.fileURLToPath(packageJSONUrl), + base, + '"exports" cannot contain numeric property keys.' + ); + } + } + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key === "default" || conditions.has(key)) { + const conditionalTarget = target[key]; + const resolveResult = resolvePackageTarget( + packageJSONUrl, + conditionalTarget, + subpath, + packageSubpath, + base, + pattern, + internal, + conditions + ); + if (resolveResult === void 0) + continue; + return resolveResult; + } + } + return void 0; + } else if (target === null) { + return null; + } + throwInvalidPackageTarget( + packageSubpath, + target, + packageJSONUrl, + internal, + base + ); +} +function patternKeyCompare(a, b) { + const aPatternIndex = StringPrototypeIndexOf(a, "*"); + const bPatternIndex = StringPrototypeIndexOf(b, "*"); + const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; + const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; + if (baseLenA > baseLenB) + return -1; + if (baseLenB > baseLenA) + return 1; + if (aPatternIndex === -1) + return 1; + if (bPatternIndex === -1) + return -1; + if (a.length > b.length) + return -1; + if (b.length > a.length) + return 1; + return 0; +} +function packageImportsResolve({ + name, + base, + conditions, + readFileSyncFn +}) { + if (name === "#" || StringPrototypeStartsWith(name, "#/") || StringPrototypeEndsWith(name, "/")) { + const reason = "is not a valid internal imports specifier name"; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, url.fileURLToPath(base)); + } + let packageJSONUrl; + const packageConfig = getPackageScopeConfig(base, readFileSyncFn); + if (packageConfig.exists) { + packageJSONUrl = url.pathToFileURL(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (ObjectPrototypeHasOwnProperty(imports, name) && !StringPrototypeIncludes(name, "*")) { + const resolveResult = resolvePackageTarget( + packageJSONUrl, + imports[name], + "", + name, + base, + false, + true, + conditions + ); + if (resolveResult != null) { + return resolveResult; + } + } else { + let bestMatch = ""; + let bestMatchSubpath; + const keys = ObjectGetOwnPropertyNames(imports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const patternIndex = StringPrototypeIndexOf(key, "*"); + if (patternIndex !== -1 && StringPrototypeStartsWith( + name, + StringPrototypeSlice(key, 0, patternIndex) + )) { + const patternTrailer = StringPrototypeSlice(key, patternIndex + 1); + if (name.length >= key.length && StringPrototypeEndsWith(name, patternTrailer) && patternKeyCompare(bestMatch, key) === 1 && StringPrototypeLastIndexOf(key, "*") === patternIndex) { + bestMatch = key; + bestMatchSubpath = StringPrototypeSlice( + name, + patternIndex, + name.length - patternTrailer.length + ); + } + } + } + if (bestMatch) { + const target = imports[bestMatch]; + const resolveResult = resolvePackageTarget( + packageJSONUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + true, + conditions + ); + if (resolveResult != null) { + return resolveResult; + } + } + } + } + } + throwImportNotDefined(name, packageJSONUrl, base); +} + +const flagSymbol = Symbol('arg flag'); + +class ArgError extends Error { + constructor(msg, code) { + super(msg); + this.name = 'ArgError'; + this.code = code; + + Object.setPrototypeOf(this, ArgError.prototype); + } +} + +function arg( + opts, + { + argv = process.argv.slice(2), + permissive = false, + stopAtPositional = false + } = {} +) { + if (!opts) { + throw new ArgError( + 'argument specification object is required', + 'ARG_CONFIG_NO_SPEC' + ); + } + + const result = { _: [] }; + + const aliases = {}; + const handlers = {}; + + for (const key of Object.keys(opts)) { + if (!key) { + throw new ArgError( + 'argument key cannot be an empty string', + 'ARG_CONFIG_EMPTY_KEY' + ); + } + + if (key[0] !== '-') { + throw new ArgError( + `argument key must start with '-' but found: '${key}'`, + 'ARG_CONFIG_NONOPT_KEY' + ); + } + + if (key.length === 1) { + throw new ArgError( + `argument key must have a name; singular '-' keys are not allowed: ${key}`, + 'ARG_CONFIG_NONAME_KEY' + ); + } + + if (typeof opts[key] === 'string') { + aliases[key] = opts[key]; + continue; + } + + let type = opts[key]; + let isFlag = false; + + if ( + Array.isArray(type) && + type.length === 1 && + typeof type[0] === 'function' + ) { + const [fn] = type; + type = (value, name, prev = []) => { + prev.push(fn(value, name, prev[prev.length - 1])); + return prev; + }; + isFlag = fn === Boolean || fn[flagSymbol] === true; + } else if (typeof type === 'function') { + isFlag = type === Boolean || type[flagSymbol] === true; + } else { + throw new ArgError( + `type missing or not a function or valid array type: ${key}`, + 'ARG_CONFIG_VAD_TYPE' + ); + } + + if (key[1] !== '-' && key.length > 2) { + throw new ArgError( + `short argument keys (with a single hyphen) must have only one character: ${key}`, + 'ARG_CONFIG_SHORTOPT_TOOLONG' + ); + } + + handlers[key] = [type, isFlag]; + } + + for (let i = 0, len = argv.length; i < len; i++) { + const wholeArg = argv[i]; + + if (stopAtPositional && result._.length > 0) { + result._ = result._.concat(argv.slice(i)); + break; + } + + if (wholeArg === '--') { + result._ = result._.concat(argv.slice(i + 1)); + break; + } + + if (wholeArg.length > 1 && wholeArg[0] === '-') { + /* eslint-disable operator-linebreak */ + const separatedArguments = + wholeArg[1] === '-' || wholeArg.length === 2 + ? [wholeArg] + : wholeArg + .slice(1) + .split('') + .map((a) => `-${a}`); + /* eslint-enable operator-linebreak */ + + for (let j = 0; j < separatedArguments.length; j++) { + const arg = separatedArguments[j]; + const [originalArgName, argStr] = + arg[1] === '-' ? arg.split(/=(.*)/, 2) : [arg, undefined]; + + let argName = originalArgName; + while (argName in aliases) { + argName = aliases[argName]; + } + + if (!(argName in handlers)) { + if (permissive) { + result._.push(arg); + continue; + } else { + throw new ArgError( + `unknown or unexpected option: ${originalArgName}`, + 'ARG_UNKNOWN_OPTION' + ); + } + } + + const [type, isFlag] = handlers[argName]; + + if (!isFlag && j + 1 < separatedArguments.length) { + throw new ArgError( + `option requires argument (but was followed by another short argument): ${originalArgName}`, + 'ARG_MISSING_REQUIRED_SHORTARG' + ); + } + + if (isFlag) { + result[argName] = type(true, argName, result[argName]); + } else if (argStr === undefined) { + if ( + argv.length < i + 2 || + (argv[i + 1].length > 1 && + argv[i + 1][0] === '-' && + !( + argv[i + 1].match(/^-?\d*(\.(?=\d))?\d*$/) && + (type === Number || + // eslint-disable-next-line no-undef + (typeof BigInt !== 'undefined' && type === BigInt)) + )) + ) { + const extended = + originalArgName === argName ? '' : ` (alias for ${argName})`; + throw new ArgError( + `option requires argument: ${originalArgName}${extended}`, + 'ARG_MISSING_REQUIRED_LONGARG' + ); + } + + result[argName] = type(argv[i + 1], argName, result[argName]); + ++i; + } else { + result[argName] = type(argStr, argName, result[argName]); + } + } + } else { + result._.push(wholeArg); + } + } + + return result; +} + +arg.flag = (fn) => { + fn[flagSymbol] = true; + return fn; +}; + +// Utility types +arg.COUNT = arg.flag((v, name, existingCount) => (existingCount || 0) + 1); + +// Expose error class +arg.ArgError = ArgError; + +var arg_1 = arg; + +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +function getOptionValue(opt) { + parseOptions(); + return options[opt]; +} +let options; +function parseOptions() { + if (!options) { + options = { + "--conditions": [], + ...parseArgv(getNodeOptionsEnvArgv()), + ...parseArgv(process.execArgv) + }; + } +} +function parseArgv(argv) { + return arg_1( + { + "--conditions": [String], + "-C": "--conditions" + }, + { + argv, + permissive: true + } + ); +} +function getNodeOptionsEnvArgv() { + const errors = []; + const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || "", errors); + if (errors.length !== 0) ; + return envArgv; +} +function ParseNodeOptionsEnvVar(node_options, errors) { + const env_argv = []; + let is_in_string = false; + let will_start_new_arg = true; + for (let index = 0; index < node_options.length; ++index) { + let c = node_options[index]; + if (c === "\\" && is_in_string) { + if (index + 1 === node_options.length) { + errors.push("invalid value for NODE_OPTIONS (invalid escape)\n"); + return env_argv; + } else { + c = node_options[++index]; + } + } else if (c === " " && !is_in_string) { + will_start_new_arg = true; + continue; + } else if (c === '"') { + is_in_string = !is_in_string; + continue; + } + if (will_start_new_arg) { + env_argv.push(c); + will_start_new_arg = false; + } else { + env_argv[env_argv.length - 1] += c; + } + } + if (is_in_string) { + errors.push("invalid value for NODE_OPTIONS (unterminated string)\n"); + } + return env_argv; +} + +function makeApi(runtimeState, opts) { + const alwaysWarnOnFallback = Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK) > 0; + const debugLevel = Number(process.env.PNP_DEBUG_LEVEL); + const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/; + const isStrictRegExp = /^(\/|\.{1,2}(\/|$))/; + const isDirRegExp = /\/$/; + const isRelativeRegexp = /^\.{0,2}\//; + const topLevelLocator = { name: null, reference: null }; + const fallbackLocators = []; + const emittedWarnings = /* @__PURE__ */ new Set(); + if (runtimeState.enableTopLevelFallback === true) + fallbackLocators.push(topLevelLocator); + if (opts.compatibilityMode !== false) { + for (const name of [`react-scripts`, `gatsby`]) { + const packageStore = runtimeState.packageRegistry.get(name); + if (packageStore) { + for (const reference of packageStore.keys()) { + if (reference === null) { + throw new Error(`Assertion failed: This reference shouldn't be null`); + } else { + fallbackLocators.push({ name, reference }); + } + } + } + } + } + const { + ignorePattern, + packageRegistry, + packageLocatorsByLocations + } = runtimeState; + function makeLogEntry(name, args) { + return { + fn: name, + args, + error: null, + result: null + }; + } + function trace(entry) { + var _a, _b, _c, _d, _e, _f; + const colors = (_c = (_b = (_a = process.stderr) == null ? void 0 : _a.hasColors) == null ? void 0 : _b.call(_a)) != null ? _c : process.stdout.isTTY; + const c = (n, str) => `\x1B[${n}m${str}\x1B[0m`; + const error = entry.error; + if (error) + console.error(c(`31;1`, `\u2716 ${(_d = entry.error) == null ? void 0 : _d.message.replace(/\n.*/s, ``)}`)); + else + console.error(c(`33;1`, `\u203C Resolution`)); + if (entry.args.length > 0) + console.error(); + for (const arg of entry.args) + console.error(` ${c(`37;1`, `In \u2190`)} ${nodeUtils.inspect(arg, { colors, compact: true })}`); + if (entry.result) { + console.error(); + console.error(` ${c(`37;1`, `Out \u2192`)} ${nodeUtils.inspect(entry.result, { colors, compact: true })}`); + } + const stack = (_f = (_e = new Error().stack.match(/(?<=^ +)at.*/gm)) == null ? void 0 : _e.slice(2)) != null ? _f : []; + if (stack.length > 0) { + console.error(); + for (const line of stack) { + console.error(` ${c(`38;5;244`, line)}`); + } + } + console.error(); + } + function maybeLog(name, fn) { + if (opts.allowDebug === false) + return fn; + if (Number.isFinite(debugLevel)) { + if (debugLevel >= 2) { + return (...args) => { + const logEntry = makeLogEntry(name, args); + try { + return logEntry.result = fn(...args); + } catch (error) { + throw logEntry.error = error; + } finally { + trace(logEntry); + } + }; + } else if (debugLevel >= 1) { + return (...args) => { + try { + return fn(...args); + } catch (error) { + const logEntry = makeLogEntry(name, args); + logEntry.error = error; + trace(logEntry); + throw error; + } + }; + } + } + return fn; + } + function getPackageInformationSafe(packageLocator) { + const packageInformation = getPackageInformation(packageLocator); + if (!packageInformation) { + throw makeError( + ErrorCode.INTERNAL, + `Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)` + ); + } + return packageInformation; + } + function isDependencyTreeRoot(packageLocator) { + if (packageLocator.name === null) + return true; + for (const dependencyTreeRoot of runtimeState.dependencyTreeRoots) + if (dependencyTreeRoot.name === packageLocator.name && dependencyTreeRoot.reference === packageLocator.reference) + return true; + return false; + } + const defaultExportsConditions = /* @__PURE__ */ new Set([ + `default`, + `node`, + `require`, + ...getOptionValue(`--conditions`) + ]); + function applyNodeExportsResolution(unqualifiedPath, conditions = defaultExportsConditions) { + const locator = findPackageLocator(ppath.join(unqualifiedPath, `internal.js`), { + resolveIgnored: true, + includeDiscardFromLookup: true + }); + if (locator === null) { + throw makeError( + ErrorCode.INTERNAL, + `The locator that owns the "${unqualifiedPath}" path can't be found inside the dependency tree (this is probably an internal error)` + ); + } + const { packageLocation } = getPackageInformationSafe(locator); + const manifestPath = ppath.join(packageLocation, Filename.manifest); + if (!opts.fakeFs.existsSync(manifestPath)) + return null; + const pkgJson = JSON.parse(opts.fakeFs.readFileSync(manifestPath, `utf8`)); + let subpath = ppath.contains(packageLocation, unqualifiedPath); + if (subpath === null) { + throw makeError( + ErrorCode.INTERNAL, + `unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)` + ); + } + if (!isRelativeRegexp.test(subpath)) + subpath = `./${subpath}`; + let resolvedExport; + try { + resolvedExport = resolve(pkgJson, ppath.normalize(subpath), { + conditions, + unsafe: true + }); + } catch (error) { + throw makeError( + ErrorCode.EXPORTS_RESOLUTION_FAILED, + error.message, + { unqualifiedPath: getPathForDisplay(unqualifiedPath), locator, pkgJson, subpath: getPathForDisplay(subpath), conditions }, + `ERR_PACKAGE_PATH_NOT_EXPORTED` + ); + } + if (typeof resolvedExport === `string`) + return ppath.join(packageLocation, resolvedExport); + return null; + } + function applyNodeExtensionResolution(unqualifiedPath, candidates, { extensions }) { + let stat; + try { + candidates.push(unqualifiedPath); + stat = opts.fakeFs.statSync(unqualifiedPath); + } catch (error) { + } + if (stat && !stat.isDirectory()) + return opts.fakeFs.realpathSync(unqualifiedPath); + if (stat && stat.isDirectory()) { + let pkgJson; + try { + pkgJson = JSON.parse(opts.fakeFs.readFileSync(ppath.join(unqualifiedPath, Filename.manifest), `utf8`)); + } catch (error) { + } + let nextUnqualifiedPath; + if (pkgJson && pkgJson.main) + nextUnqualifiedPath = ppath.resolve(unqualifiedPath, pkgJson.main); + if (nextUnqualifiedPath && nextUnqualifiedPath !== unqualifiedPath) { + const resolution = applyNodeExtensionResolution(nextUnqualifiedPath, candidates, { extensions }); + if (resolution !== null) { + return resolution; + } + } + } + for (let i = 0, length = extensions.length; i < length; i++) { + const candidateFile = `${unqualifiedPath}${extensions[i]}`; + candidates.push(candidateFile); + if (opts.fakeFs.existsSync(candidateFile)) { + return candidateFile; + } + } + if (stat && stat.isDirectory()) { + for (let i = 0, length = extensions.length; i < length; i++) { + const candidateFile = ppath.format({ dir: unqualifiedPath, name: `index`, ext: extensions[i] }); + candidates.push(candidateFile); + if (opts.fakeFs.existsSync(candidateFile)) { + return candidateFile; + } + } + } + return null; + } + function makeFakeModule(path) { + const fakeModule = new require$$0.Module(path, null); + fakeModule.filename = path; + fakeModule.paths = require$$0.Module._nodeModulePaths(path); + return fakeModule; + } + function callNativeResolution(request, issuer) { + if (issuer.endsWith(`/`)) + issuer = ppath.join(issuer, `internal.js`); + return require$$0.Module._resolveFilename(npath.fromPortablePath(request), makeFakeModule(npath.fromPortablePath(issuer)), false, { plugnplay: false }); + } + function isPathIgnored(path) { + if (ignorePattern === null) + return false; + const subPath = ppath.contains(runtimeState.basePath, path); + if (subPath === null) + return false; + if (ignorePattern.test(subPath.replace(/\/$/, ``))) { + return true; + } else { + return false; + } + } + const VERSIONS = { std: 3, resolveVirtual: 1, getAllLocators: 1 }; + const topLevel = topLevelLocator; + function getPackageInformation({ name, reference }) { + const packageInformationStore = packageRegistry.get(name); + if (!packageInformationStore) + return null; + const packageInformation = packageInformationStore.get(reference); + if (!packageInformation) + return null; + return packageInformation; + } + function findPackageDependents({ name, reference }) { + const dependents = []; + for (const [dependentName, packageInformationStore] of packageRegistry) { + if (dependentName === null) + continue; + for (const [dependentReference, packageInformation] of packageInformationStore) { + if (dependentReference === null) + continue; + const dependencyReference = packageInformation.packageDependencies.get(name); + if (dependencyReference !== reference) + continue; + if (dependentName === name && dependentReference === reference) + continue; + dependents.push({ + name: dependentName, + reference: dependentReference + }); + } + } + return dependents; + } + function findBrokenPeerDependencies(dependency, initialPackage) { + const brokenPackages = /* @__PURE__ */ new Map(); + const alreadyVisited = /* @__PURE__ */ new Set(); + const traversal = (currentPackage) => { + const identifier = JSON.stringify(currentPackage.name); + if (alreadyVisited.has(identifier)) + return; + alreadyVisited.add(identifier); + const dependents = findPackageDependents(currentPackage); + for (const dependent of dependents) { + const dependentInformation = getPackageInformationSafe(dependent); + if (dependentInformation.packagePeers.has(dependency)) { + traversal(dependent); + } else { + let brokenSet = brokenPackages.get(dependent.name); + if (typeof brokenSet === `undefined`) + brokenPackages.set(dependent.name, brokenSet = /* @__PURE__ */ new Set()); + brokenSet.add(dependent.reference); + } + } + }; + traversal(initialPackage); + const brokenList = []; + for (const name of [...brokenPackages.keys()].sort()) + for (const reference of [...brokenPackages.get(name)].sort()) + brokenList.push({ name, reference }); + return brokenList; + } + function findPackageLocator(location, { resolveIgnored = false, includeDiscardFromLookup = false } = {}) { + if (isPathIgnored(location) && !resolveIgnored) + return null; + let relativeLocation = ppath.relative(runtimeState.basePath, location); + if (!relativeLocation.match(isStrictRegExp)) + relativeLocation = `./${relativeLocation}`; + if (!relativeLocation.endsWith(`/`)) + relativeLocation = `${relativeLocation}/`; + do { + const entry = packageLocatorsByLocations.get(relativeLocation); + if (typeof entry === `undefined` || entry.discardFromLookup && !includeDiscardFromLookup) { + relativeLocation = relativeLocation.substring(0, relativeLocation.lastIndexOf(`/`, relativeLocation.length - 2) + 1); + continue; + } + return entry.locator; + } while (relativeLocation !== ``); + return null; + } + function tryReadFile(filePath) { + try { + return opts.fakeFs.readFileSync(npath.toPortablePath(filePath), `utf8`); + } catch (err) { + if (err.code === `ENOENT`) + return void 0; + throw err; + } + } + function resolveToUnqualified(request, issuer, { considerBuiltins = true } = {}) { + if (request.startsWith(`#`)) + throw new Error(`resolveToUnqualified can not handle private import mappings`); + if (request === `pnpapi`) + return npath.toPortablePath(opts.pnpapiResolution); + if (considerBuiltins && isBuiltinModule(request)) + return null; + const requestForDisplay = getPathForDisplay(request); + const issuerForDisplay = issuer && getPathForDisplay(issuer); + if (issuer && isPathIgnored(issuer)) { + if (!ppath.isAbsolute(request) || findPackageLocator(request) === null) { + const result = callNativeResolution(request, issuer); + if (result === false) { + throw makeError( + ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED, + `The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${requestForDisplay}" +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + return npath.toPortablePath(result); + } + } + let unqualifiedPath; + const dependencyNameMatch = request.match(pathRegExp); + if (!dependencyNameMatch) { + if (ppath.isAbsolute(request)) { + unqualifiedPath = ppath.normalize(request); + } else { + if (!issuer) { + throw makeError( + ErrorCode.API_ERROR, + `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + const absoluteIssuer = ppath.resolve(issuer); + if (issuer.match(isDirRegExp)) { + unqualifiedPath = ppath.normalize(ppath.join(absoluteIssuer, request)); + } else { + unqualifiedPath = ppath.normalize(ppath.join(ppath.dirname(absoluteIssuer), request)); + } + } + } else { + if (!issuer) { + throw makeError( + ErrorCode.API_ERROR, + `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + const [, dependencyName, subPath] = dependencyNameMatch; + const issuerLocator = findPackageLocator(issuer); + if (!issuerLocator) { + const result = callNativeResolution(request, issuer); + if (result === false) { + throw makeError( + ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED, + `The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${requestForDisplay}" +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + return npath.toPortablePath(result); + } + const issuerInformation = getPackageInformationSafe(issuerLocator); + let dependencyReference = issuerInformation.packageDependencies.get(dependencyName); + let fallbackReference = null; + if (dependencyReference == null) { + if (issuerLocator.name !== null) { + const exclusionEntry = runtimeState.fallbackExclusionList.get(issuerLocator.name); + const canUseFallbacks = !exclusionEntry || !exclusionEntry.has(issuerLocator.reference); + if (canUseFallbacks) { + for (let t = 0, T = fallbackLocators.length; t < T; ++t) { + const fallbackInformation = getPackageInformationSafe(fallbackLocators[t]); + const reference = fallbackInformation.packageDependencies.get(dependencyName); + if (reference == null) + continue; + if (alwaysWarnOnFallback) + fallbackReference = reference; + else + dependencyReference = reference; + break; + } + if (runtimeState.enableTopLevelFallback) { + if (dependencyReference == null && fallbackReference === null) { + const reference = runtimeState.fallbackPool.get(dependencyName); + if (reference != null) { + fallbackReference = reference; + } + } + } + } + } + } + let error = null; + if (dependencyReference === null) { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `Your application tried to access ${dependencyName} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + const brokenAncestors = findBrokenPeerDependencies(dependencyName, issuerLocator); + if (brokenAncestors.every((ancestor) => isDependencyTreeRoot(ancestor))) { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} +`).join(``)} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors } + ); + } else { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) + +${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} +`).join(``)} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors } + ); + } + } + } else if (dependencyReference === void 0) { + if (!considerBuiltins && isBuiltinModule(request)) { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `Your application tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in ${issuerLocator.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName } + ); + } + } else { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `Your application tried to access ${dependencyName}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName } + ); + } + } + } + if (dependencyReference == null) { + if (fallbackReference === null || error === null) + throw error || new Error(`Assertion failed: Expected an error to have been set`); + dependencyReference = fallbackReference; + const message = error.message.replace(/\n.*/g, ``); + error.message = message; + if (!emittedWarnings.has(message) && debugLevel !== 0) { + emittedWarnings.add(message); + process.emitWarning(error); + } + } + const dependencyLocator = Array.isArray(dependencyReference) ? { name: dependencyReference[0], reference: dependencyReference[1] } : { name: dependencyName, reference: dependencyReference }; + const dependencyInformation = getPackageInformationSafe(dependencyLocator); + if (!dependencyInformation.packageLocation) { + throw makeError( + ErrorCode.MISSING_DEPENDENCY, + `A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${dependencyLocator.name}@${dependencyLocator.reference}${dependencyLocator.name !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyLocator: Object.assign({}, dependencyLocator) } + ); + } + const dependencyLocation = dependencyInformation.packageLocation; + if (subPath) { + unqualifiedPath = ppath.join(dependencyLocation, subPath); + } else { + unqualifiedPath = dependencyLocation; + } + } + return ppath.normalize(unqualifiedPath); + } + function resolveUnqualifiedExport(request, unqualifiedPath, conditions = defaultExportsConditions) { + if (isStrictRegExp.test(request)) + return unqualifiedPath; + const unqualifiedExportPath = applyNodeExportsResolution(unqualifiedPath, conditions); + if (unqualifiedExportPath) { + return ppath.normalize(unqualifiedExportPath); + } else { + return unqualifiedPath; + } + } + function resolveUnqualified(unqualifiedPath, { extensions = Object.keys(require$$0.Module._extensions) } = {}) { + var _a, _b; + const candidates = []; + const qualifiedPath = applyNodeExtensionResolution(unqualifiedPath, candidates, { extensions }); + if (qualifiedPath) { + return ppath.normalize(qualifiedPath); + } else { + reportRequiredFilesToWatchMode(candidates.map((candidate) => npath.fromPortablePath(candidate))); + const unqualifiedPathForDisplay = getPathForDisplay(unqualifiedPath); + const containingPackage = findPackageLocator(unqualifiedPath); + if (containingPackage) { + const { packageLocation } = getPackageInformationSafe(containingPackage); + let exists = true; + try { + opts.fakeFs.accessSync(packageLocation); + } catch (err) { + if ((err == null ? void 0 : err.code) === `ENOENT`) { + exists = false; + } else { + const readableError = ((_b = (_a = err == null ? void 0 : err.message) != null ? _a : err) != null ? _b : `empty exception thrown`).replace(/^[A-Z]/, ($0) => $0.toLowerCase()); + throw makeError(ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, `Required package exists but could not be accessed (${readableError}). + +Missing package: ${containingPackage.name}@${containingPackage.reference} +Expected package location: ${getPathForDisplay(packageLocation)} +`, { unqualifiedPath: unqualifiedPathForDisplay, extensions }); + } + } + if (!exists) { + const errorMessage = packageLocation.includes(`/unplugged/`) ? `Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).` : `Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.`; + throw makeError( + ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, + `${errorMessage} + +Missing package: ${containingPackage.name}@${containingPackage.reference} +Expected package location: ${getPathForDisplay(packageLocation)} +`, + { unqualifiedPath: unqualifiedPathForDisplay, extensions } + ); + } + } + throw makeError( + ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, + `Qualified path resolution failed: we looked for the following paths, but none could be accessed. + +Source path: ${unqualifiedPathForDisplay} +${candidates.map((candidate) => `Not found: ${getPathForDisplay(candidate)} +`).join(``)}`, + { unqualifiedPath: unqualifiedPathForDisplay, extensions } + ); + } + } + function resolvePrivateRequest(request, issuer, opts2) { + var _a; + if (!issuer) + throw new Error(`Assertion failed: An issuer is required to resolve private import mappings`); + const resolved = packageImportsResolve({ + name: request, + base: url.pathToFileURL(npath.fromPortablePath(issuer)), + conditions: (_a = opts2.conditions) != null ? _a : defaultExportsConditions, + readFileSyncFn: tryReadFile + }); + if (resolved instanceof URL) { + return resolveUnqualified(npath.toPortablePath(url.fileURLToPath(resolved)), { extensions: opts2.extensions }); + } else { + if (resolved.startsWith(`#`)) + throw new Error(`Mapping from one private import to another isn't allowed`); + return resolveRequest(resolved, issuer, opts2); + } + } + function resolveRequest(request, issuer, opts2 = {}) { + try { + if (request.startsWith(`#`)) + return resolvePrivateRequest(request, issuer, opts2); + const { considerBuiltins, extensions, conditions } = opts2; + const unqualifiedPath = resolveToUnqualified(request, issuer, { considerBuiltins }); + if (request === `pnpapi`) + return unqualifiedPath; + if (unqualifiedPath === null) + return null; + const isIssuerIgnored = () => issuer !== null ? isPathIgnored(issuer) : false; + const remappedPath = (!considerBuiltins || !isBuiltinModule(request)) && !isIssuerIgnored() ? resolveUnqualifiedExport(request, unqualifiedPath, conditions) : unqualifiedPath; + return resolveUnqualified(remappedPath, { extensions }); + } catch (error) { + if (Object.prototype.hasOwnProperty.call(error, `pnpCode`)) + Object.assign(error.data, { request: getPathForDisplay(request), issuer: issuer && getPathForDisplay(issuer) }); + throw error; + } + } + function resolveVirtual(request) { + const normalized = ppath.normalize(request); + const resolved = VirtualFS.resolveVirtual(normalized); + return resolved !== normalized ? resolved : null; + } + return { + VERSIONS, + topLevel, + getLocator: (name, referencish) => { + if (Array.isArray(referencish)) { + return { name: referencish[0], reference: referencish[1] }; + } else { + return { name, reference: referencish }; + } + }, + getDependencyTreeRoots: () => { + return [...runtimeState.dependencyTreeRoots]; + }, + getAllLocators() { + const locators = []; + for (const [name, entry] of packageRegistry) + for (const reference of entry.keys()) + if (name !== null && reference !== null) + locators.push({ name, reference }); + return locators; + }, + getPackageInformation: (locator) => { + const info = getPackageInformation(locator); + if (info === null) + return null; + const packageLocation = npath.fromPortablePath(info.packageLocation); + const nativeInfo = { ...info, packageLocation }; + return nativeInfo; + }, + findPackageLocator: (path) => { + return findPackageLocator(npath.toPortablePath(path)); + }, + resolveToUnqualified: maybeLog(`resolveToUnqualified`, (request, issuer, opts2) => { + const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; + const resolution = resolveToUnqualified(npath.toPortablePath(request), portableIssuer, opts2); + if (resolution === null) + return null; + return npath.fromPortablePath(resolution); + }), + resolveUnqualified: maybeLog(`resolveUnqualified`, (unqualifiedPath, opts2) => { + return npath.fromPortablePath(resolveUnqualified(npath.toPortablePath(unqualifiedPath), opts2)); + }), + resolveRequest: maybeLog(`resolveRequest`, (request, issuer, opts2) => { + const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; + const resolution = resolveRequest(npath.toPortablePath(request), portableIssuer, opts2); + if (resolution === null) + return null; + return npath.fromPortablePath(resolution); + }), + resolveVirtual: maybeLog(`resolveVirtual`, (path) => { + const result = resolveVirtual(npath.toPortablePath(path)); + if (result !== null) { + return npath.fromPortablePath(result); + } else { + return null; + } + }) + }; +} + +function makeManager(pnpapi, opts) { + const initialApiPath = npath.toPortablePath(pnpapi.resolveToUnqualified(`pnpapi`, null)); + const initialApiStats = opts.fakeFs.statSync(npath.toPortablePath(initialApiPath)); + const apiMetadata = /* @__PURE__ */ new Map([ + [initialApiPath, { + cache: require$$0.Module._cache, + instance: pnpapi, + stats: initialApiStats, + lastRefreshCheck: Date.now() + }] + ]); + function loadApiInstance(pnpApiPath) { + const nativePath = npath.fromPortablePath(pnpApiPath); + const module = new require$$0.Module(nativePath, null); + module.load(nativePath); + return module.exports; + } + function refreshApiEntry(pnpApiPath, apiEntry) { + const timeNow = Date.now(); + if (timeNow - apiEntry.lastRefreshCheck < 500) + return; + apiEntry.lastRefreshCheck = timeNow; + const stats = opts.fakeFs.statSync(pnpApiPath); + if (stats.mtime > apiEntry.stats.mtime) { + process.emitWarning(`[Warning] The runtime detected new informations in a PnP file; reloading the API instance (${npath.fromPortablePath(pnpApiPath)})`); + apiEntry.stats = stats; + apiEntry.instance = loadApiInstance(pnpApiPath); + } + } + function getApiEntry(pnpApiPath, refresh = false) { + let apiEntry = apiMetadata.get(pnpApiPath); + if (typeof apiEntry !== `undefined`) { + if (refresh) { + refreshApiEntry(pnpApiPath, apiEntry); + } + } else { + apiMetadata.set(pnpApiPath, apiEntry = { + cache: {}, + instance: loadApiInstance(pnpApiPath), + stats: opts.fakeFs.statSync(pnpApiPath), + lastRefreshCheck: Date.now() + }); + } + return apiEntry; + } + const findApiPathCache = /* @__PURE__ */ new Map(); + function addToCacheAndReturn(start, end, target) { + if (target !== null) + target = VirtualFS.resolveVirtual(target); + let curr; + let next = start; + do { + curr = next; + findApiPathCache.set(curr, target); + next = ppath.dirname(curr); + } while (curr !== end); + return target; + } + function findApiPathFor(modulePath) { + let bestCandidate = null; + for (const [apiPath, apiEntry] of apiMetadata) { + const locator = apiEntry.instance.findPackageLocator(modulePath); + if (!locator) + continue; + if (apiMetadata.size === 1) + return apiPath; + const packageInformation = apiEntry.instance.getPackageInformation(locator); + if (!packageInformation) + throw new Error(`Assertion failed: Couldn't get package information for '${modulePath}'`); + if (!bestCandidate) + bestCandidate = { packageLocation: packageInformation.packageLocation, apiPaths: [] }; + if (packageInformation.packageLocation === bestCandidate.packageLocation) { + bestCandidate.apiPaths.push(apiPath); + } else if (packageInformation.packageLocation.length > bestCandidate.packageLocation.length) { + bestCandidate = { packageLocation: packageInformation.packageLocation, apiPaths: [apiPath] }; + } + } + if (bestCandidate) { + if (bestCandidate.apiPaths.length === 1) + return bestCandidate.apiPaths[0]; + const controlSegment = bestCandidate.apiPaths.map((apiPath) => ` ${npath.fromPortablePath(apiPath)}`).join(` +`); + throw new Error(`Unable to locate pnpapi, the module '${modulePath}' is controlled by multiple pnpapi instances. +This is usually caused by using the global cache (enableGlobalCache: true) + +Controlled by: +${controlSegment} +`); + } + const start = ppath.resolve(npath.toPortablePath(modulePath)); + let curr; + let next = start; + do { + curr = next; + const cached = findApiPathCache.get(curr); + if (cached !== void 0) + return addToCacheAndReturn(start, curr, cached); + const cjsCandidate = ppath.join(curr, Filename.pnpCjs); + if (opts.fakeFs.existsSync(cjsCandidate) && opts.fakeFs.statSync(cjsCandidate).isFile()) + return addToCacheAndReturn(start, curr, cjsCandidate); + const legacyCjsCandidate = ppath.join(curr, Filename.pnpJs); + if (opts.fakeFs.existsSync(legacyCjsCandidate) && opts.fakeFs.statSync(legacyCjsCandidate).isFile()) + return addToCacheAndReturn(start, curr, legacyCjsCandidate); + next = ppath.dirname(curr); + } while (curr !== PortablePath.root); + return addToCacheAndReturn(start, curr, null); + } + function getApiPathFromParent(parent) { + if (parent == null) + return initialApiPath; + if (typeof parent.pnpApiPath === `undefined`) { + if (parent.filename !== null) { + return parent.pnpApiPath = findApiPathFor(parent.filename); + } else { + return initialApiPath; + } + } + if (parent.pnpApiPath !== null) + return parent.pnpApiPath; + return null; + } + return { + getApiPathFromParent, + findApiPathFor, + getApiEntry + }; +} + +const localFs = { ...fs__default.default }; +const nodeFs = new NodeFS(localFs); +const defaultRuntimeState = $$SETUP_STATE(hydrateRuntimeState); +const defaultPnpapiResolution = __filename; +const defaultFsLayer = new VirtualFS({ + baseFs: new ZipOpenFS({ + baseFs: nodeFs, + libzip: () => getLibzipSync(), + maxOpenFiles: 80, + readOnlyArchives: true + }) +}); +class DynamicFS extends ProxiedFS { + constructor() { + super(ppath); + this.baseFs = defaultFsLayer; + } + mapToBase(p) { + return p; + } + mapFromBase(p) { + return p; + } +} +const dynamicFsLayer = new DynamicFS(); +let manager; +const defaultApi = Object.assign(makeApi(defaultRuntimeState, { + fakeFs: dynamicFsLayer, + pnpapiResolution: defaultPnpapiResolution +}), { + makeApi: ({ + basePath = void 0, + fakeFs = dynamicFsLayer, + pnpapiResolution = defaultPnpapiResolution, + ...rest + }) => { + const apiRuntimeState = typeof basePath !== `undefined` ? $$SETUP_STATE(hydrateRuntimeState, basePath) : defaultRuntimeState; + return makeApi(apiRuntimeState, { + fakeFs, + pnpapiResolution, + ...rest + }); + }, + setup: (api) => { + applyPatch(api || defaultApi, { + fakeFs: defaultFsLayer, + manager + }); + dynamicFsLayer.baseFs = new NodeFS(fs__default.default); + } +}); +manager = makeManager(defaultApi, { + fakeFs: dynamicFsLayer +}); +if (module.parent && module.parent.id === `internal/preload`) { + defaultApi.setup(); + if (module.filename) { + delete require$$0__default.default._cache[module.filename]; + } +} +if (process.mainModule === module) { + const reportError = (code, message, data) => { + process.stdout.write(`${JSON.stringify([{ code, message, data }, null])} +`); + }; + const reportSuccess = (resolution) => { + process.stdout.write(`${JSON.stringify([null, resolution])} +`); + }; + const processResolution = (request, issuer) => { + try { + reportSuccess(defaultApi.resolveRequest(request, issuer)); + } catch (error) { + reportError(error.code, error.message, error.data); + } + }; + const processRequest = (data) => { + try { + const [request, issuer] = JSON.parse(data); + processResolution(request, issuer); + } catch (error) { + reportError(`INVALID_JSON`, error.message, error.data); + } + }; + if (process.argv.length > 2) { + if (process.argv.length !== 4) { + process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} +`); + process.exitCode = 64; + } else { + processResolution(process.argv[2], process.argv[3]); + } + } else { + let buffer = ``; + const decoder = new StringDecoder__default.default.StringDecoder(); + process.stdin.on(`data`, (chunk) => { + buffer += decoder.write(chunk); + do { + const index = buffer.indexOf(` +`); + if (index === -1) + break; + const line = buffer.slice(0, index); + buffer = buffer.slice(index + 1); + processRequest(line); + } while (true); + }); + } +} + +module.exports = defaultApi; diff --git a/testdata/fixtures/pnp/pnp-yarn-v4.cjs b/testdata/fixtures/pnp/pnp-yarn-v4.cjs new file mode 100644 index 00000000000..53539201e46 --- /dev/null +++ b/testdata/fixtures/pnp/pnp-yarn-v4.cjs @@ -0,0 +1,7429 @@ +#!/usr/bin/env node +/* eslint-disable */ +"use strict"; + +const RAW_RUNTIME_STATE = +'{\ + "__info": [\ + "This file is automatically generated. Do not touch it, or risk",\ + "your modifications being lost."\ + ],\ + "dependencyTreeRoots": [\ + {\ + "name": "tmp.trDEa5gPrG",\ + "reference": "workspace:."\ + }\ + ],\ + "enableTopLevelFallback": true,\ + "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ + "fallbackExclusionList": [\ + ["tmp.trDEa5gPrG", ["workspace:."]]\ + ],\ + "fallbackPool": [\ + ],\ + "packageRegistryData": [\ + [null, [\ + [null, {\ + "packageLocation": "./",\ + "packageDependencies": [\ + ],\ + "linkType": "SOFT"\ + }]\ + ]],\ + ["tmp.trDEa5gPrG", [\ + ["workspace:.", {\ + "packageLocation": "./",\ + "packageDependencies": [\ + ["tmp.trDEa5gPrG", "workspace:."]\ + ],\ + "linkType": "SOFT"\ + }]\ + ]]\ + ]\ +}'; + +function $$SETUP_STATE(hydrateRuntimeState, basePath) { + return hydrateRuntimeState(JSON.parse(RAW_RUNTIME_STATE), {basePath: basePath || __dirname}); +} + +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); +const os = require('os'); +const events = require('events'); +const nodeUtils = require('util'); +const stream = require('stream'); +const zlib = require('zlib'); +const require$$0 = require('module'); +const StringDecoder = require('string_decoder'); +const url = require('url'); +const readline = require('readline'); +const assert = require('assert'); + +const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e }; + +function _interopNamespace(e) { + if (e && e.__esModule) return e; + const n = Object.create(null); + if (e) { + for (const k in e) { + if (k !== 'default') { + const d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: () => e[k] + }); + } + } + } + n.default = e; + return Object.freeze(n); +} + +const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); +const path__default = /*#__PURE__*/_interopDefaultLegacy(path); +const nodeUtils__namespace = /*#__PURE__*/_interopNamespace(nodeUtils); +const zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib); +const require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); +const StringDecoder__default = /*#__PURE__*/_interopDefaultLegacy(StringDecoder); +const assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); + +const S_IFMT = 61440; +const S_IFDIR = 16384; +const S_IFREG = 32768; +const S_IFLNK = 40960; +const SAFE_TIME = 456789e3; + +function makeError$1(code, message) { + return Object.assign(new Error(`${code}: ${message}`), { code }); +} +function EBUSY(message) { + return makeError$1(`EBUSY`, message); +} +function ENOSYS(message, reason) { + return makeError$1(`ENOSYS`, `${message}, ${reason}`); +} +function EINVAL(reason) { + return makeError$1(`EINVAL`, `invalid argument, ${reason}`); +} +function EBADF(reason) { + return makeError$1(`EBADF`, `bad file descriptor, ${reason}`); +} +function ENOENT(reason) { + return makeError$1(`ENOENT`, `no such file or directory, ${reason}`); +} +function ENOTDIR(reason) { + return makeError$1(`ENOTDIR`, `not a directory, ${reason}`); +} +function EISDIR(reason) { + return makeError$1(`EISDIR`, `illegal operation on a directory, ${reason}`); +} +function EEXIST(reason) { + return makeError$1(`EEXIST`, `file already exists, ${reason}`); +} +function EROFS(reason) { + return makeError$1(`EROFS`, `read-only filesystem, ${reason}`); +} +function ENOTEMPTY(reason) { + return makeError$1(`ENOTEMPTY`, `directory not empty, ${reason}`); +} +function EOPNOTSUPP(reason) { + return makeError$1(`EOPNOTSUPP`, `operation not supported, ${reason}`); +} +function ERR_DIR_CLOSED() { + return makeError$1(`ERR_DIR_CLOSED`, `Directory handle was closed`); +} + +const DEFAULT_MODE = S_IFREG | 420; +class StatEntry { + constructor() { + this.uid = 0; + this.gid = 0; + this.size = 0; + this.blksize = 0; + this.atimeMs = 0; + this.mtimeMs = 0; + this.ctimeMs = 0; + this.birthtimeMs = 0; + this.atime = new Date(0); + this.mtime = new Date(0); + this.ctime = new Date(0); + this.birthtime = new Date(0); + this.dev = 0; + this.ino = 0; + this.mode = DEFAULT_MODE; + this.nlink = 1; + this.rdev = 0; + this.blocks = 1; + } + isBlockDevice() { + return false; + } + isCharacterDevice() { + return false; + } + isDirectory() { + return (this.mode & S_IFMT) === S_IFDIR; + } + isFIFO() { + return false; + } + isFile() { + return (this.mode & S_IFMT) === S_IFREG; + } + isSocket() { + return false; + } + isSymbolicLink() { + return (this.mode & S_IFMT) === S_IFLNK; + } +} +class BigIntStatsEntry { + constructor() { + this.uid = BigInt(0); + this.gid = BigInt(0); + this.size = BigInt(0); + this.blksize = BigInt(0); + this.atimeMs = BigInt(0); + this.mtimeMs = BigInt(0); + this.ctimeMs = BigInt(0); + this.birthtimeMs = BigInt(0); + this.atimeNs = BigInt(0); + this.mtimeNs = BigInt(0); + this.ctimeNs = BigInt(0); + this.birthtimeNs = BigInt(0); + this.atime = new Date(0); + this.mtime = new Date(0); + this.ctime = new Date(0); + this.birthtime = new Date(0); + this.dev = BigInt(0); + this.ino = BigInt(0); + this.mode = BigInt(DEFAULT_MODE); + this.nlink = BigInt(1); + this.rdev = BigInt(0); + this.blocks = BigInt(1); + } + isBlockDevice() { + return false; + } + isCharacterDevice() { + return false; + } + isDirectory() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFDIR); + } + isFIFO() { + return false; + } + isFile() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFREG); + } + isSocket() { + return false; + } + isSymbolicLink() { + return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFLNK); + } +} +function makeDefaultStats() { + return new StatEntry(); +} +function clearStats(stats) { + for (const key in stats) { + if (Object.prototype.hasOwnProperty.call(stats, key)) { + const element = stats[key]; + if (typeof element === `number`) { + stats[key] = 0; + } else if (typeof element === `bigint`) { + stats[key] = BigInt(0); + } else if (nodeUtils__namespace.types.isDate(element)) { + stats[key] = new Date(0); + } + } + } + return stats; +} +function convertToBigIntStats(stats) { + const bigintStats = new BigIntStatsEntry(); + for (const key in stats) { + if (Object.prototype.hasOwnProperty.call(stats, key)) { + const element = stats[key]; + if (typeof element === `number`) { + bigintStats[key] = BigInt(element); + } else if (nodeUtils__namespace.types.isDate(element)) { + bigintStats[key] = new Date(element); + } + } + } + bigintStats.atimeNs = bigintStats.atimeMs * BigInt(1e6); + bigintStats.mtimeNs = bigintStats.mtimeMs * BigInt(1e6); + bigintStats.ctimeNs = bigintStats.ctimeMs * BigInt(1e6); + bigintStats.birthtimeNs = bigintStats.birthtimeMs * BigInt(1e6); + return bigintStats; +} +function areStatsEqual(a, b) { + if (a.atimeMs !== b.atimeMs) + return false; + if (a.birthtimeMs !== b.birthtimeMs) + return false; + if (a.blksize !== b.blksize) + return false; + if (a.blocks !== b.blocks) + return false; + if (a.ctimeMs !== b.ctimeMs) + return false; + if (a.dev !== b.dev) + return false; + if (a.gid !== b.gid) + return false; + if (a.ino !== b.ino) + return false; + if (a.isBlockDevice() !== b.isBlockDevice()) + return false; + if (a.isCharacterDevice() !== b.isCharacterDevice()) + return false; + if (a.isDirectory() !== b.isDirectory()) + return false; + if (a.isFIFO() !== b.isFIFO()) + return false; + if (a.isFile() !== b.isFile()) + return false; + if (a.isSocket() !== b.isSocket()) + return false; + if (a.isSymbolicLink() !== b.isSymbolicLink()) + return false; + if (a.mode !== b.mode) + return false; + if (a.mtimeMs !== b.mtimeMs) + return false; + if (a.nlink !== b.nlink) + return false; + if (a.rdev !== b.rdev) + return false; + if (a.size !== b.size) + return false; + if (a.uid !== b.uid) + return false; + const aN = a; + const bN = b; + if (aN.atimeNs !== bN.atimeNs) + return false; + if (aN.mtimeNs !== bN.mtimeNs) + return false; + if (aN.ctimeNs !== bN.ctimeNs) + return false; + if (aN.birthtimeNs !== bN.birthtimeNs) + return false; + return true; +} + +const PortablePath = { + root: `/`, + dot: `.`, + parent: `..` +}; +const Filename = { + home: `~`, + nodeModules: `node_modules`, + manifest: `package.json`, + lockfile: `yarn.lock`, + virtual: `__virtual__`, + pnpJs: `.pnp.js`, + pnpCjs: `.pnp.cjs`, + pnpData: `.pnp.data.json`, + pnpEsmLoader: `.pnp.loader.mjs`, + rc: `.yarnrc.yml` +}; +const npath = Object.create(path__default.default); +const ppath = Object.create(path__default.default.posix); +npath.cwd = () => process.cwd(); +ppath.cwd = () => toPortablePath(process.cwd()); +ppath.resolve = (...segments) => { + if (segments.length > 0 && ppath.isAbsolute(segments[0])) { + return path__default.default.posix.resolve(...segments); + } else { + return path__default.default.posix.resolve(ppath.cwd(), ...segments); + } +}; +const contains = function(pathUtils, from, to) { + from = pathUtils.normalize(from); + to = pathUtils.normalize(to); + if (from === to) + return `.`; + if (!from.endsWith(pathUtils.sep)) + from = from + pathUtils.sep; + if (to.startsWith(from)) { + return to.slice(from.length); + } else { + return null; + } +}; +npath.fromPortablePath = fromPortablePath; +npath.toPortablePath = toPortablePath; +npath.contains = (from, to) => contains(npath, from, to); +ppath.contains = (from, to) => contains(ppath, from, to); +const WINDOWS_PATH_REGEXP = /^([a-zA-Z]:.*)$/; +const UNC_WINDOWS_PATH_REGEXP = /^\/\/(\.\/)?(.*)$/; +const PORTABLE_PATH_REGEXP = /^\/([a-zA-Z]:.*)$/; +const UNC_PORTABLE_PATH_REGEXP = /^\/unc\/(\.dot\/)?(.*)$/; +function fromPortablePath(p) { + if (process.platform !== `win32`) + return p; + let portablePathMatch, uncPortablePathMatch; + if (portablePathMatch = p.match(PORTABLE_PATH_REGEXP)) + p = portablePathMatch[1]; + else if (uncPortablePathMatch = p.match(UNC_PORTABLE_PATH_REGEXP)) + p = `\\\\${uncPortablePathMatch[1] ? `.\\` : ``}${uncPortablePathMatch[2]}`; + else + return p; + return p.replace(/\//g, `\\`); +} +function toPortablePath(p) { + if (process.platform !== `win32`) + return p; + p = p.replace(/\\/g, `/`); + let windowsPathMatch, uncWindowsPathMatch; + if (windowsPathMatch = p.match(WINDOWS_PATH_REGEXP)) + p = `/${windowsPathMatch[1]}`; + else if (uncWindowsPathMatch = p.match(UNC_WINDOWS_PATH_REGEXP)) + p = `/unc/${uncWindowsPathMatch[1] ? `.dot/` : ``}${uncWindowsPathMatch[2]}`; + return p; +} +function convertPath(targetPathUtils, sourcePath) { + return targetPathUtils === npath ? fromPortablePath(sourcePath) : toPortablePath(sourcePath); +} + +const defaultTime = new Date(SAFE_TIME * 1e3); +const defaultTimeMs = defaultTime.getTime(); +async function copyPromise(destinationFs, destination, sourceFs, source, opts) { + const normalizedDestination = destinationFs.pathUtils.normalize(destination); + const normalizedSource = sourceFs.pathUtils.normalize(source); + const prelayout = []; + const postlayout = []; + const { atime, mtime } = opts.stableTime ? { atime: defaultTime, mtime: defaultTime } : await sourceFs.lstatPromise(normalizedSource); + await destinationFs.mkdirpPromise(destinationFs.pathUtils.dirname(destination), { utimes: [atime, mtime] }); + await copyImpl(prelayout, postlayout, destinationFs, normalizedDestination, sourceFs, normalizedSource, { ...opts, didParentExist: true }); + for (const operation of prelayout) + await operation(); + await Promise.all(postlayout.map((operation) => { + return operation(); + })); +} +async function copyImpl(prelayout, postlayout, destinationFs, destination, sourceFs, source, opts) { + var _a, _b, _c; + const destinationStat = opts.didParentExist ? await maybeLStat(destinationFs, destination) : null; + const sourceStat = await sourceFs.lstatPromise(source); + const { atime, mtime } = opts.stableTime ? { atime: defaultTime, mtime: defaultTime } : sourceStat; + let updated; + switch (true) { + case sourceStat.isDirectory(): + { + updated = await copyFolder(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + case sourceStat.isFile(): + { + updated = await copyFile(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + case sourceStat.isSymbolicLink(): + { + updated = await copySymlink(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } + break; + default: + { + throw new Error(`Unsupported file type (${sourceStat.mode})`); + } + } + if (((_a = opts.linkStrategy) == null ? void 0 : _a.type) !== `HardlinkFromIndex` || !sourceStat.isFile()) { + if (updated || ((_b = destinationStat == null ? void 0 : destinationStat.mtime) == null ? void 0 : _b.getTime()) !== mtime.getTime() || ((_c = destinationStat == null ? void 0 : destinationStat.atime) == null ? void 0 : _c.getTime()) !== atime.getTime()) { + postlayout.push(() => destinationFs.lutimesPromise(destination, atime, mtime)); + updated = true; + } + if (destinationStat === null || (destinationStat.mode & 511) !== (sourceStat.mode & 511)) { + postlayout.push(() => destinationFs.chmodPromise(destination, sourceStat.mode & 511)); + updated = true; + } + } + return updated; +} +async function maybeLStat(baseFs, p) { + try { + return await baseFs.lstatPromise(p); + } catch (e) { + return null; + } +} +async function copyFolder(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + if (destinationStat !== null && !destinationStat.isDirectory()) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + let updated = false; + if (destinationStat === null) { + prelayout.push(async () => { + try { + await destinationFs.mkdirPromise(destination, { mode: sourceStat.mode }); + } catch (err) { + if (err.code !== `EEXIST`) { + throw err; + } + } + }); + updated = true; + } + const entries = await sourceFs.readdirPromise(source); + const nextOpts = opts.didParentExist && !destinationStat ? { ...opts, didParentExist: false } : opts; + if (opts.stableSort) { + for (const entry of entries.sort()) { + if (await copyImpl(prelayout, postlayout, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts)) { + updated = true; + } + } + } else { + const entriesUpdateStatus = await Promise.all(entries.map(async (entry) => { + await copyImpl(prelayout, postlayout, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts); + })); + if (entriesUpdateStatus.some((status) => status)) { + updated = true; + } + } + return updated; +} +async function copyFileViaIndex(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts, linkStrategy) { + const sourceHash = await sourceFs.checksumFilePromise(source, { algorithm: `sha1` }); + const indexPath = destinationFs.pathUtils.join(linkStrategy.indexPath, sourceHash.slice(0, 2), `${sourceHash}.dat`); + let AtomicBehavior; + ((AtomicBehavior2) => { + AtomicBehavior2[AtomicBehavior2["Lock"] = 0] = "Lock"; + AtomicBehavior2[AtomicBehavior2["Rename"] = 1] = "Rename"; + })(AtomicBehavior || (AtomicBehavior = {})); + let atomicBehavior = 1 /* Rename */; + let indexStat = await maybeLStat(destinationFs, indexPath); + if (destinationStat) { + const isDestinationHardlinkedFromIndex = indexStat && destinationStat.dev === indexStat.dev && destinationStat.ino === indexStat.ino; + const isIndexModified = (indexStat == null ? void 0 : indexStat.mtimeMs) !== defaultTimeMs; + if (isDestinationHardlinkedFromIndex) { + if (isIndexModified && linkStrategy.autoRepair) { + atomicBehavior = 0 /* Lock */; + indexStat = null; + } + } + if (!isDestinationHardlinkedFromIndex) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + } + const tempPath = !indexStat && atomicBehavior === 1 /* Rename */ ? `${indexPath}.${Math.floor(Math.random() * 4294967296).toString(16).padStart(8, `0`)}` : null; + let tempPathCleaned = false; + prelayout.push(async () => { + if (!indexStat) { + if (atomicBehavior === 0 /* Lock */) { + await destinationFs.lockPromise(indexPath, async () => { + const content = await sourceFs.readFilePromise(source); + await destinationFs.writeFilePromise(indexPath, content); + }); + } + if (atomicBehavior === 1 /* Rename */ && tempPath) { + const content = await sourceFs.readFilePromise(source); + await destinationFs.writeFilePromise(tempPath, content); + try { + await destinationFs.linkPromise(tempPath, indexPath); + } catch (err) { + if (err.code === `EEXIST`) { + tempPathCleaned = true; + await destinationFs.unlinkPromise(tempPath); + } else { + throw err; + } + } + } + } + if (!destinationStat) { + await destinationFs.linkPromise(indexPath, destination); + } + }); + postlayout.push(async () => { + if (!indexStat) + await destinationFs.lutimesPromise(indexPath, defaultTime, defaultTime); + if (tempPath && !tempPathCleaned) { + await destinationFs.unlinkPromise(tempPath); + } + }); + return false; +} +async function copyFileDirect(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + if (destinationStat !== null) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + prelayout.push(async () => { + const content = await sourceFs.readFilePromise(source); + await destinationFs.writeFilePromise(destination, content); + }); + return true; +} +async function copyFile(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + var _a; + if (((_a = opts.linkStrategy) == null ? void 0 : _a.type) === `HardlinkFromIndex`) { + return copyFileViaIndex(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts, opts.linkStrategy); + } else { + return copyFileDirect(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); + } +} +async function copySymlink(prelayout, postlayout, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { + if (destinationStat !== null) { + if (opts.overwrite) { + prelayout.push(async () => destinationFs.removePromise(destination)); + destinationStat = null; + } else { + return false; + } + } + prelayout.push(async () => { + await destinationFs.symlinkPromise(convertPath(destinationFs.pathUtils, await sourceFs.readlinkPromise(source)), destination); + }); + return true; +} + +class CustomDir { + constructor(path, nextDirent, opts = {}) { + this.path = path; + this.nextDirent = nextDirent; + this.opts = opts; + this.closed = false; + } + throwIfClosed() { + if (this.closed) { + throw ERR_DIR_CLOSED(); + } + } + async *[Symbol.asyncIterator]() { + try { + let dirent; + while ((dirent = await this.read()) !== null) { + yield dirent; + } + } finally { + await this.close(); + } + } + read(cb) { + const dirent = this.readSync(); + if (typeof cb !== `undefined`) + return cb(null, dirent); + return Promise.resolve(dirent); + } + readSync() { + this.throwIfClosed(); + return this.nextDirent(); + } + close(cb) { + this.closeSync(); + if (typeof cb !== `undefined`) + return cb(null); + return Promise.resolve(); + } + closeSync() { + var _a, _b; + this.throwIfClosed(); + (_b = (_a = this.opts).onClose) == null ? void 0 : _b.call(_a); + this.closed = true; + } +} +function opendir(fakeFs, path, entries, opts) { + const nextDirent = () => { + const filename = entries.shift(); + if (typeof filename === `undefined`) + return null; + return Object.assign(fakeFs.statSync(fakeFs.pathUtils.join(path, filename)), { + name: filename + }); + }; + return new CustomDir(path, nextDirent, opts); +} + +function assertStatus(current, expected) { + if (current !== expected) { + throw new Error(`Invalid StatWatcher status: expected '${expected}', got '${current}'`); + } +} +class CustomStatWatcher extends events.EventEmitter { + constructor(fakeFs, path, { bigint = false } = {}) { + super(); + this.status = "ready" /* Ready */; + this.changeListeners = /* @__PURE__ */ new Map(); + this.startTimeout = null; + this.fakeFs = fakeFs; + this.path = path; + this.bigint = bigint; + this.lastStats = this.stat(); + } + static create(fakeFs, path, opts) { + const statWatcher = new CustomStatWatcher(fakeFs, path, opts); + statWatcher.start(); + return statWatcher; + } + start() { + assertStatus(this.status, "ready" /* Ready */); + this.status = "running" /* Running */; + this.startTimeout = setTimeout(() => { + this.startTimeout = null; + if (!this.fakeFs.existsSync(this.path)) { + this.emit("change" /* Change */, this.lastStats, this.lastStats); + } + }, 3); + } + stop() { + assertStatus(this.status, "running" /* Running */); + this.status = "stopped" /* Stopped */; + if (this.startTimeout !== null) { + clearTimeout(this.startTimeout); + this.startTimeout = null; + } + this.emit("stop" /* Stop */); + } + stat() { + try { + return this.fakeFs.statSync(this.path, { bigint: this.bigint }); + } catch (error) { + const statInstance = this.bigint ? new BigIntStatsEntry() : new StatEntry(); + return clearStats(statInstance); + } + } + makeInterval(opts) { + const interval = setInterval(() => { + const currentStats = this.stat(); + const previousStats = this.lastStats; + if (areStatsEqual(currentStats, previousStats)) + return; + this.lastStats = currentStats; + this.emit("change" /* Change */, currentStats, previousStats); + }, opts.interval); + return opts.persistent ? interval : interval.unref(); + } + registerChangeListener(listener, opts) { + this.addListener("change" /* Change */, listener); + this.changeListeners.set(listener, this.makeInterval(opts)); + } + unregisterChangeListener(listener) { + this.removeListener("change" /* Change */, listener); + const interval = this.changeListeners.get(listener); + if (typeof interval !== `undefined`) + clearInterval(interval); + this.changeListeners.delete(listener); + } + unregisterAllChangeListeners() { + for (const listener of this.changeListeners.keys()) { + this.unregisterChangeListener(listener); + } + } + hasChangeListeners() { + return this.changeListeners.size > 0; + } + ref() { + for (const interval of this.changeListeners.values()) + interval.ref(); + return this; + } + unref() { + for (const interval of this.changeListeners.values()) + interval.unref(); + return this; + } +} + +const statWatchersByFakeFS = /* @__PURE__ */ new WeakMap(); +function watchFile(fakeFs, path, a, b) { + let bigint; + let persistent; + let interval; + let listener; + switch (typeof a) { + case `function`: + { + bigint = false; + persistent = true; + interval = 5007; + listener = a; + } + break; + default: + { + ({ + bigint = false, + persistent = true, + interval = 5007 + } = a); + listener = b; + } + break; + } + let statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + statWatchersByFakeFS.set(fakeFs, statWatchers = /* @__PURE__ */ new Map()); + let statWatcher = statWatchers.get(path); + if (typeof statWatcher === `undefined`) { + statWatcher = CustomStatWatcher.create(fakeFs, path, { bigint }); + statWatchers.set(path, statWatcher); + } + statWatcher.registerChangeListener(listener, { persistent, interval }); + return statWatcher; +} +function unwatchFile(fakeFs, path, cb) { + const statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + return; + const statWatcher = statWatchers.get(path); + if (typeof statWatcher === `undefined`) + return; + if (typeof cb === `undefined`) + statWatcher.unregisterAllChangeListeners(); + else + statWatcher.unregisterChangeListener(cb); + if (!statWatcher.hasChangeListeners()) { + statWatcher.stop(); + statWatchers.delete(path); + } +} +function unwatchAllFiles(fakeFs) { + const statWatchers = statWatchersByFakeFS.get(fakeFs); + if (typeof statWatchers === `undefined`) + return; + for (const path of statWatchers.keys()) { + unwatchFile(fakeFs, path); + } +} + +class FakeFS { + constructor(pathUtils) { + this.pathUtils = pathUtils; + } + async *genTraversePromise(init, { stableSort = false } = {}) { + const stack = [init]; + while (stack.length > 0) { + const p = stack.shift(); + const entry = await this.lstatPromise(p); + if (entry.isDirectory()) { + const entries = await this.readdirPromise(p); + if (stableSort) { + for (const entry2 of entries.sort()) { + stack.push(this.pathUtils.join(p, entry2)); + } + } else { + throw new Error(`Not supported`); + } + } else { + yield p; + } + } + } + async checksumFilePromise(path, { algorithm = `sha512` } = {}) { + const fd = await this.openPromise(path, `r`); + try { + const CHUNK_SIZE = 65536; + const chunk = Buffer.allocUnsafeSlow(CHUNK_SIZE); + const hash = crypto.createHash(algorithm); + let bytesRead = 0; + while ((bytesRead = await this.readPromise(fd, chunk, 0, CHUNK_SIZE)) !== 0) + hash.update(bytesRead === CHUNK_SIZE ? chunk : chunk.slice(0, bytesRead)); + return hash.digest(`hex`); + } finally { + await this.closePromise(fd); + } + } + async removePromise(p, { recursive = true, maxRetries = 5 } = {}) { + let stat; + try { + stat = await this.lstatPromise(p); + } catch (error) { + if (error.code === `ENOENT`) { + return; + } else { + throw error; + } + } + if (stat.isDirectory()) { + if (recursive) { + const entries = await this.readdirPromise(p); + await Promise.all(entries.map((entry) => { + return this.removePromise(this.pathUtils.resolve(p, entry)); + })); + } + for (let t = 0; t <= maxRetries; t++) { + try { + await this.rmdirPromise(p); + break; + } catch (error) { + if (error.code !== `EBUSY` && error.code !== `ENOTEMPTY`) { + throw error; + } else if (t < maxRetries) { + await new Promise((resolve) => setTimeout(resolve, t * 100)); + } + } + } + } else { + await this.unlinkPromise(p); + } + } + removeSync(p, { recursive = true } = {}) { + let stat; + try { + stat = this.lstatSync(p); + } catch (error) { + if (error.code === `ENOENT`) { + return; + } else { + throw error; + } + } + if (stat.isDirectory()) { + if (recursive) + for (const entry of this.readdirSync(p)) + this.removeSync(this.pathUtils.resolve(p, entry)); + this.rmdirSync(p); + } else { + this.unlinkSync(p); + } + } + async mkdirpPromise(p, { chmod, utimes } = {}) { + p = this.resolve(p); + if (p === this.pathUtils.dirname(p)) + return void 0; + const parts = p.split(this.pathUtils.sep); + let createdDirectory; + for (let u = 2; u <= parts.length; ++u) { + const subPath = parts.slice(0, u).join(this.pathUtils.sep); + if (!this.existsSync(subPath)) { + try { + await this.mkdirPromise(subPath); + } catch (error) { + if (error.code === `EEXIST`) { + continue; + } else { + throw error; + } + } + createdDirectory ?? (createdDirectory = subPath); + if (chmod != null) + await this.chmodPromise(subPath, chmod); + if (utimes != null) { + await this.utimesPromise(subPath, utimes[0], utimes[1]); + } else { + const parentStat = await this.statPromise(this.pathUtils.dirname(subPath)); + await this.utimesPromise(subPath, parentStat.atime, parentStat.mtime); + } + } + } + return createdDirectory; + } + mkdirpSync(p, { chmod, utimes } = {}) { + p = this.resolve(p); + if (p === this.pathUtils.dirname(p)) + return void 0; + const parts = p.split(this.pathUtils.sep); + let createdDirectory; + for (let u = 2; u <= parts.length; ++u) { + const subPath = parts.slice(0, u).join(this.pathUtils.sep); + if (!this.existsSync(subPath)) { + try { + this.mkdirSync(subPath); + } catch (error) { + if (error.code === `EEXIST`) { + continue; + } else { + throw error; + } + } + createdDirectory ?? (createdDirectory = subPath); + if (chmod != null) + this.chmodSync(subPath, chmod); + if (utimes != null) { + this.utimesSync(subPath, utimes[0], utimes[1]); + } else { + const parentStat = this.statSync(this.pathUtils.dirname(subPath)); + this.utimesSync(subPath, parentStat.atime, parentStat.mtime); + } + } + } + return createdDirectory; + } + async copyPromise(destination, source, { baseFs = this, overwrite = true, stableSort = false, stableTime = false, linkStrategy = null } = {}) { + return await copyPromise(this, destination, baseFs, source, { overwrite, stableSort, stableTime, linkStrategy }); + } + copySync(destination, source, { baseFs = this, overwrite = true } = {}) { + const stat = baseFs.lstatSync(source); + const exists = this.existsSync(destination); + if (stat.isDirectory()) { + this.mkdirpSync(destination); + const directoryListing = baseFs.readdirSync(source); + for (const entry of directoryListing) { + this.copySync(this.pathUtils.join(destination, entry), baseFs.pathUtils.join(source, entry), { baseFs, overwrite }); + } + } else if (stat.isFile()) { + if (!exists || overwrite) { + if (exists) + this.removeSync(destination); + const content = baseFs.readFileSync(source); + this.writeFileSync(destination, content); + } + } else if (stat.isSymbolicLink()) { + if (!exists || overwrite) { + if (exists) + this.removeSync(destination); + const target = baseFs.readlinkSync(source); + this.symlinkSync(convertPath(this.pathUtils, target), destination); + } + } else { + throw new Error(`Unsupported file type (file: ${source}, mode: 0o${stat.mode.toString(8).padStart(6, `0`)})`); + } + const mode = stat.mode & 511; + this.chmodSync(destination, mode); + } + async changeFilePromise(p, content, opts = {}) { + if (Buffer.isBuffer(content)) { + return this.changeFileBufferPromise(p, content, opts); + } else { + return this.changeFileTextPromise(p, content, opts); + } + } + async changeFileBufferPromise(p, content, { mode } = {}) { + let current = Buffer.alloc(0); + try { + current = await this.readFilePromise(p); + } catch (error) { + } + if (Buffer.compare(current, content) === 0) + return; + await this.writeFilePromise(p, content, { mode }); + } + async changeFileTextPromise(p, content, { automaticNewlines, mode } = {}) { + let current = ``; + try { + current = await this.readFilePromise(p, `utf8`); + } catch (error) { + } + const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; + if (current === normalizedContent) + return; + await this.writeFilePromise(p, normalizedContent, { mode }); + } + changeFileSync(p, content, opts = {}) { + if (Buffer.isBuffer(content)) { + return this.changeFileBufferSync(p, content, opts); + } else { + return this.changeFileTextSync(p, content, opts); + } + } + changeFileBufferSync(p, content, { mode } = {}) { + let current = Buffer.alloc(0); + try { + current = this.readFileSync(p); + } catch (error) { + } + if (Buffer.compare(current, content) === 0) + return; + this.writeFileSync(p, content, { mode }); + } + changeFileTextSync(p, content, { automaticNewlines = false, mode } = {}) { + let current = ``; + try { + current = this.readFileSync(p, `utf8`); + } catch (error) { + } + const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; + if (current === normalizedContent) + return; + this.writeFileSync(p, normalizedContent, { mode }); + } + async movePromise(fromP, toP) { + try { + await this.renamePromise(fromP, toP); + } catch (error) { + if (error.code === `EXDEV`) { + await this.copyPromise(toP, fromP); + await this.removePromise(fromP); + } else { + throw error; + } + } + } + moveSync(fromP, toP) { + try { + this.renameSync(fromP, toP); + } catch (error) { + if (error.code === `EXDEV`) { + this.copySync(toP, fromP); + this.removeSync(fromP); + } else { + throw error; + } + } + } + async lockPromise(affectedPath, callback) { + const lockPath = `${affectedPath}.flock`; + const interval = 1e3 / 60; + const startTime = Date.now(); + let fd = null; + const isAlive = async () => { + let pid; + try { + [pid] = await this.readJsonPromise(lockPath); + } catch (error) { + return Date.now() - startTime < 500; + } + try { + process.kill(pid, 0); + return true; + } catch (error) { + return false; + } + }; + while (fd === null) { + try { + fd = await this.openPromise(lockPath, `wx`); + } catch (error) { + if (error.code === `EEXIST`) { + if (!await isAlive()) { + try { + await this.unlinkPromise(lockPath); + continue; + } catch (error2) { + } + } + if (Date.now() - startTime < 60 * 1e3) { + await new Promise((resolve) => setTimeout(resolve, interval)); + } else { + throw new Error(`Couldn't acquire a lock in a reasonable time (via ${lockPath})`); + } + } else { + throw error; + } + } + } + await this.writePromise(fd, JSON.stringify([process.pid])); + try { + return await callback(); + } finally { + try { + await this.closePromise(fd); + await this.unlinkPromise(lockPath); + } catch (error) { + } + } + } + async readJsonPromise(p) { + const content = await this.readFilePromise(p, `utf8`); + try { + return JSON.parse(content); + } catch (error) { + error.message += ` (in ${p})`; + throw error; + } + } + readJsonSync(p) { + const content = this.readFileSync(p, `utf8`); + try { + return JSON.parse(content); + } catch (error) { + error.message += ` (in ${p})`; + throw error; + } + } + async writeJsonPromise(p, data) { + return await this.writeFilePromise(p, `${JSON.stringify(data, null, 2)} +`); + } + writeJsonSync(p, data) { + return this.writeFileSync(p, `${JSON.stringify(data, null, 2)} +`); + } + async preserveTimePromise(p, cb) { + const stat = await this.lstatPromise(p); + const result = await cb(); + if (typeof result !== `undefined`) + p = result; + await this.lutimesPromise(p, stat.atime, stat.mtime); + } + async preserveTimeSync(p, cb) { + const stat = this.lstatSync(p); + const result = cb(); + if (typeof result !== `undefined`) + p = result; + this.lutimesSync(p, stat.atime, stat.mtime); + } +} +class BasePortableFakeFS extends FakeFS { + constructor() { + super(ppath); + } +} +function getEndOfLine(content) { + const matches = content.match(/\r?\n/g); + if (matches === null) + return os.EOL; + const crlf = matches.filter((nl) => nl === `\r +`).length; + const lf = matches.length - crlf; + return crlf > lf ? `\r +` : ` +`; +} +function normalizeLineEndings(originalContent, newContent) { + return newContent.replace(/\r?\n/g, getEndOfLine(originalContent)); +} + +class ProxiedFS extends FakeFS { + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + resolve(path) { + return this.mapFromBase(this.baseFs.resolve(this.mapToBase(path))); + } + getRealPath() { + return this.mapFromBase(this.baseFs.getRealPath()); + } + async openPromise(p, flags, mode) { + return this.baseFs.openPromise(this.mapToBase(p), flags, mode); + } + openSync(p, flags, mode) { + return this.baseFs.openSync(this.mapToBase(p), flags, mode); + } + async opendirPromise(p, opts) { + return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(p), opts), { path: p }); + } + opendirSync(p, opts) { + return Object.assign(this.baseFs.opendirSync(this.mapToBase(p), opts), { path: p }); + } + async readPromise(fd, buffer, offset, length, position) { + return await this.baseFs.readPromise(fd, buffer, offset, length, position); + } + readSync(fd, buffer, offset, length, position) { + return this.baseFs.readSync(fd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return await this.baseFs.writePromise(fd, buffer, offset); + } else { + return await this.baseFs.writePromise(fd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.baseFs.writeSync(fd, buffer, offset); + } else { + return this.baseFs.writeSync(fd, buffer, offset, length, position); + } + } + async closePromise(fd) { + return this.baseFs.closePromise(fd); + } + closeSync(fd) { + this.baseFs.closeSync(fd); + } + createReadStream(p, opts) { + return this.baseFs.createReadStream(p !== null ? this.mapToBase(p) : p, opts); + } + createWriteStream(p, opts) { + return this.baseFs.createWriteStream(p !== null ? this.mapToBase(p) : p, opts); + } + async realpathPromise(p) { + return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(p))); + } + realpathSync(p) { + return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(p))); + } + async existsPromise(p) { + return this.baseFs.existsPromise(this.mapToBase(p)); + } + existsSync(p) { + return this.baseFs.existsSync(this.mapToBase(p)); + } + accessSync(p, mode) { + return this.baseFs.accessSync(this.mapToBase(p), mode); + } + async accessPromise(p, mode) { + return this.baseFs.accessPromise(this.mapToBase(p), mode); + } + async statPromise(p, opts) { + return this.baseFs.statPromise(this.mapToBase(p), opts); + } + statSync(p, opts) { + return this.baseFs.statSync(this.mapToBase(p), opts); + } + async fstatPromise(fd, opts) { + return this.baseFs.fstatPromise(fd, opts); + } + fstatSync(fd, opts) { + return this.baseFs.fstatSync(fd, opts); + } + lstatPromise(p, opts) { + return this.baseFs.lstatPromise(this.mapToBase(p), opts); + } + lstatSync(p, opts) { + return this.baseFs.lstatSync(this.mapToBase(p), opts); + } + async fchmodPromise(fd, mask) { + return this.baseFs.fchmodPromise(fd, mask); + } + fchmodSync(fd, mask) { + return this.baseFs.fchmodSync(fd, mask); + } + async chmodPromise(p, mask) { + return this.baseFs.chmodPromise(this.mapToBase(p), mask); + } + chmodSync(p, mask) { + return this.baseFs.chmodSync(this.mapToBase(p), mask); + } + async fchownPromise(fd, uid, gid) { + return this.baseFs.fchownPromise(fd, uid, gid); + } + fchownSync(fd, uid, gid) { + return this.baseFs.fchownSync(fd, uid, gid); + } + async chownPromise(p, uid, gid) { + return this.baseFs.chownPromise(this.mapToBase(p), uid, gid); + } + chownSync(p, uid, gid) { + return this.baseFs.chownSync(this.mapToBase(p), uid, gid); + } + async renamePromise(oldP, newP) { + return this.baseFs.renamePromise(this.mapToBase(oldP), this.mapToBase(newP)); + } + renameSync(oldP, newP) { + return this.baseFs.renameSync(this.mapToBase(oldP), this.mapToBase(newP)); + } + async copyFilePromise(sourceP, destP, flags = 0) { + return this.baseFs.copyFilePromise(this.mapToBase(sourceP), this.mapToBase(destP), flags); + } + copyFileSync(sourceP, destP, flags = 0) { + return this.baseFs.copyFileSync(this.mapToBase(sourceP), this.mapToBase(destP), flags); + } + async appendFilePromise(p, content, opts) { + return this.baseFs.appendFilePromise(this.fsMapToBase(p), content, opts); + } + appendFileSync(p, content, opts) { + return this.baseFs.appendFileSync(this.fsMapToBase(p), content, opts); + } + async writeFilePromise(p, content, opts) { + return this.baseFs.writeFilePromise(this.fsMapToBase(p), content, opts); + } + writeFileSync(p, content, opts) { + return this.baseFs.writeFileSync(this.fsMapToBase(p), content, opts); + } + async unlinkPromise(p) { + return this.baseFs.unlinkPromise(this.mapToBase(p)); + } + unlinkSync(p) { + return this.baseFs.unlinkSync(this.mapToBase(p)); + } + async utimesPromise(p, atime, mtime) { + return this.baseFs.utimesPromise(this.mapToBase(p), atime, mtime); + } + utimesSync(p, atime, mtime) { + return this.baseFs.utimesSync(this.mapToBase(p), atime, mtime); + } + async lutimesPromise(p, atime, mtime) { + return this.baseFs.lutimesPromise(this.mapToBase(p), atime, mtime); + } + lutimesSync(p, atime, mtime) { + return this.baseFs.lutimesSync(this.mapToBase(p), atime, mtime); + } + async mkdirPromise(p, opts) { + return this.baseFs.mkdirPromise(this.mapToBase(p), opts); + } + mkdirSync(p, opts) { + return this.baseFs.mkdirSync(this.mapToBase(p), opts); + } + async rmdirPromise(p, opts) { + return this.baseFs.rmdirPromise(this.mapToBase(p), opts); + } + rmdirSync(p, opts) { + return this.baseFs.rmdirSync(this.mapToBase(p), opts); + } + async linkPromise(existingP, newP) { + return this.baseFs.linkPromise(this.mapToBase(existingP), this.mapToBase(newP)); + } + linkSync(existingP, newP) { + return this.baseFs.linkSync(this.mapToBase(existingP), this.mapToBase(newP)); + } + async symlinkPromise(target, p, type) { + const mappedP = this.mapToBase(p); + if (this.pathUtils.isAbsolute(target)) + return this.baseFs.symlinkPromise(this.mapToBase(target), mappedP, type); + const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); + const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); + return this.baseFs.symlinkPromise(mappedTarget, mappedP, type); + } + symlinkSync(target, p, type) { + const mappedP = this.mapToBase(p); + if (this.pathUtils.isAbsolute(target)) + return this.baseFs.symlinkSync(this.mapToBase(target), mappedP, type); + const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); + const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); + return this.baseFs.symlinkSync(mappedTarget, mappedP, type); + } + async readFilePromise(p, encoding) { + return this.baseFs.readFilePromise(this.fsMapToBase(p), encoding); + } + readFileSync(p, encoding) { + return this.baseFs.readFileSync(this.fsMapToBase(p), encoding); + } + async readdirPromise(p, opts) { + return this.baseFs.readdirPromise(this.mapToBase(p), opts); + } + readdirSync(p, opts) { + return this.baseFs.readdirSync(this.mapToBase(p), opts); + } + async readlinkPromise(p) { + return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(p))); + } + readlinkSync(p) { + return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(p))); + } + async truncatePromise(p, len) { + return this.baseFs.truncatePromise(this.mapToBase(p), len); + } + truncateSync(p, len) { + return this.baseFs.truncateSync(this.mapToBase(p), len); + } + async ftruncatePromise(fd, len) { + return this.baseFs.ftruncatePromise(fd, len); + } + ftruncateSync(fd, len) { + return this.baseFs.ftruncateSync(fd, len); + } + watch(p, a, b) { + return this.baseFs.watch( + this.mapToBase(p), + a, + b + ); + } + watchFile(p, a, b) { + return this.baseFs.watchFile( + this.mapToBase(p), + a, + b + ); + } + unwatchFile(p, cb) { + return this.baseFs.unwatchFile(this.mapToBase(p), cb); + } + fsMapToBase(p) { + if (typeof p === `number`) { + return p; + } else { + return this.mapToBase(p); + } + } +} + +class NodeFS extends BasePortableFakeFS { + constructor(realFs = fs__default.default) { + super(); + this.realFs = realFs; + } + getExtractHint() { + return false; + } + getRealPath() { + return PortablePath.root; + } + resolve(p) { + return ppath.resolve(p); + } + async openPromise(p, flags, mode) { + return await new Promise((resolve, reject) => { + this.realFs.open(npath.fromPortablePath(p), flags, mode, this.makeCallback(resolve, reject)); + }); + } + openSync(p, flags, mode) { + return this.realFs.openSync(npath.fromPortablePath(p), flags, mode); + } + async opendirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (typeof opts !== `undefined`) { + this.realFs.opendir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.opendir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }).then((dir) => { + return Object.defineProperty(dir, `path`, { value: p, configurable: true, writable: true }); + }); + } + opendirSync(p, opts) { + const dir = typeof opts !== `undefined` ? this.realFs.opendirSync(npath.fromPortablePath(p), opts) : this.realFs.opendirSync(npath.fromPortablePath(p)); + return Object.defineProperty(dir, `path`, { value: p, configurable: true, writable: true }); + } + async readPromise(fd, buffer, offset = 0, length = 0, position = -1) { + return await new Promise((resolve, reject) => { + this.realFs.read(fd, buffer, offset, length, position, (error, bytesRead) => { + if (error) { + reject(error); + } else { + resolve(bytesRead); + } + }); + }); + } + readSync(fd, buffer, offset, length, position) { + return this.realFs.readSync(fd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + return await new Promise((resolve, reject) => { + if (typeof buffer === `string`) { + return this.realFs.write(fd, buffer, offset, this.makeCallback(resolve, reject)); + } else { + return this.realFs.write(fd, buffer, offset, length, position, this.makeCallback(resolve, reject)); + } + }); + } + writeSync(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.realFs.writeSync(fd, buffer, offset); + } else { + return this.realFs.writeSync(fd, buffer, offset, length, position); + } + } + async closePromise(fd) { + await new Promise((resolve, reject) => { + this.realFs.close(fd, this.makeCallback(resolve, reject)); + }); + } + closeSync(fd) { + this.realFs.closeSync(fd); + } + createReadStream(p, opts) { + const realPath = p !== null ? npath.fromPortablePath(p) : p; + return this.realFs.createReadStream(realPath, opts); + } + createWriteStream(p, opts) { + const realPath = p !== null ? npath.fromPortablePath(p) : p; + return this.realFs.createWriteStream(realPath, opts); + } + async realpathPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.realpath(npath.fromPortablePath(p), {}, this.makeCallback(resolve, reject)); + }).then((path) => { + return npath.toPortablePath(path); + }); + } + realpathSync(p) { + return npath.toPortablePath(this.realFs.realpathSync(npath.fromPortablePath(p), {})); + } + async existsPromise(p) { + return await new Promise((resolve) => { + this.realFs.exists(npath.fromPortablePath(p), resolve); + }); + } + accessSync(p, mode) { + return this.realFs.accessSync(npath.fromPortablePath(p), mode); + } + async accessPromise(p, mode) { + return await new Promise((resolve, reject) => { + this.realFs.access(npath.fromPortablePath(p), mode, this.makeCallback(resolve, reject)); + }); + } + existsSync(p) { + return this.realFs.existsSync(npath.fromPortablePath(p)); + } + async statPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.stat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.stat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + statSync(p, opts) { + if (opts) { + return this.realFs.statSync(npath.fromPortablePath(p), opts); + } else { + return this.realFs.statSync(npath.fromPortablePath(p)); + } + } + async fstatPromise(fd, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.fstat(fd, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.fstat(fd, this.makeCallback(resolve, reject)); + } + }); + } + fstatSync(fd, opts) { + if (opts) { + return this.realFs.fstatSync(fd, opts); + } else { + return this.realFs.fstatSync(fd); + } + } + async lstatPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.lstat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.lstat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + lstatSync(p, opts) { + if (opts) { + return this.realFs.lstatSync(npath.fromPortablePath(p), opts); + } else { + return this.realFs.lstatSync(npath.fromPortablePath(p)); + } + } + async fchmodPromise(fd, mask) { + return await new Promise((resolve, reject) => { + this.realFs.fchmod(fd, mask, this.makeCallback(resolve, reject)); + }); + } + fchmodSync(fd, mask) { + return this.realFs.fchmodSync(fd, mask); + } + async chmodPromise(p, mask) { + return await new Promise((resolve, reject) => { + this.realFs.chmod(npath.fromPortablePath(p), mask, this.makeCallback(resolve, reject)); + }); + } + chmodSync(p, mask) { + return this.realFs.chmodSync(npath.fromPortablePath(p), mask); + } + async fchownPromise(fd, uid, gid) { + return await new Promise((resolve, reject) => { + this.realFs.fchown(fd, uid, gid, this.makeCallback(resolve, reject)); + }); + } + fchownSync(fd, uid, gid) { + return this.realFs.fchownSync(fd, uid, gid); + } + async chownPromise(p, uid, gid) { + return await new Promise((resolve, reject) => { + this.realFs.chown(npath.fromPortablePath(p), uid, gid, this.makeCallback(resolve, reject)); + }); + } + chownSync(p, uid, gid) { + return this.realFs.chownSync(npath.fromPortablePath(p), uid, gid); + } + async renamePromise(oldP, newP) { + return await new Promise((resolve, reject) => { + this.realFs.rename(npath.fromPortablePath(oldP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); + }); + } + renameSync(oldP, newP) { + return this.realFs.renameSync(npath.fromPortablePath(oldP), npath.fromPortablePath(newP)); + } + async copyFilePromise(sourceP, destP, flags = 0) { + return await new Promise((resolve, reject) => { + this.realFs.copyFile(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags, this.makeCallback(resolve, reject)); + }); + } + copyFileSync(sourceP, destP, flags = 0) { + return this.realFs.copyFileSync(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags); + } + async appendFilePromise(p, content, opts) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.appendFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.appendFile(fsNativePath, content, this.makeCallback(resolve, reject)); + } + }); + } + appendFileSync(p, content, opts) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.appendFileSync(fsNativePath, content, opts); + } else { + this.realFs.appendFileSync(fsNativePath, content); + } + } + async writeFilePromise(p, content, opts) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.writeFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.writeFile(fsNativePath, content, this.makeCallback(resolve, reject)); + } + }); + } + writeFileSync(p, content, opts) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + if (opts) { + this.realFs.writeFileSync(fsNativePath, content, opts); + } else { + this.realFs.writeFileSync(fsNativePath, content); + } + } + async unlinkPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.unlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + }); + } + unlinkSync(p) { + return this.realFs.unlinkSync(npath.fromPortablePath(p)); + } + async utimesPromise(p, atime, mtime) { + return await new Promise((resolve, reject) => { + this.realFs.utimes(npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); + }); + } + utimesSync(p, atime, mtime) { + this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); + } + async lutimesPromise(p, atime, mtime) { + return await new Promise((resolve, reject) => { + this.realFs.lutimes(npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); + }); + } + lutimesSync(p, atime, mtime) { + this.realFs.lutimesSync(npath.fromPortablePath(p), atime, mtime); + } + async mkdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + this.realFs.mkdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + }); + } + mkdirSync(p, opts) { + return this.realFs.mkdirSync(npath.fromPortablePath(p), opts); + } + async rmdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts) { + this.realFs.rmdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); + } else { + this.realFs.rmdir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + } + }); + } + rmdirSync(p, opts) { + return this.realFs.rmdirSync(npath.fromPortablePath(p), opts); + } + async linkPromise(existingP, newP) { + return await new Promise((resolve, reject) => { + this.realFs.link(npath.fromPortablePath(existingP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); + }); + } + linkSync(existingP, newP) { + return this.realFs.linkSync(npath.fromPortablePath(existingP), npath.fromPortablePath(newP)); + } + async symlinkPromise(target, p, type) { + return await new Promise((resolve, reject) => { + this.realFs.symlink(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type, this.makeCallback(resolve, reject)); + }); + } + symlinkSync(target, p, type) { + return this.realFs.symlinkSync(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type); + } + async readFilePromise(p, encoding) { + return await new Promise((resolve, reject) => { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + this.realFs.readFile(fsNativePath, encoding, this.makeCallback(resolve, reject)); + }); + } + readFileSync(p, encoding) { + const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; + return this.realFs.readFileSync(fsNativePath, encoding); + } + async readdirPromise(p, opts) { + return await new Promise((resolve, reject) => { + if (opts == null ? void 0 : opts.withFileTypes) { + this.realFs.readdir(npath.fromPortablePath(p), { withFileTypes: true }, this.makeCallback(resolve, reject)); + } else { + this.realFs.readdir(npath.fromPortablePath(p), this.makeCallback((value) => resolve(value), reject)); + } + }); + } + readdirSync(p, opts) { + if (opts == null ? void 0 : opts.withFileTypes) { + return this.realFs.readdirSync(npath.fromPortablePath(p), { withFileTypes: true }); + } else { + return this.realFs.readdirSync(npath.fromPortablePath(p)); + } + } + async readlinkPromise(p) { + return await new Promise((resolve, reject) => { + this.realFs.readlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); + }).then((path) => { + return npath.toPortablePath(path); + }); + } + readlinkSync(p) { + return npath.toPortablePath(this.realFs.readlinkSync(npath.fromPortablePath(p))); + } + async truncatePromise(p, len) { + return await new Promise((resolve, reject) => { + this.realFs.truncate(npath.fromPortablePath(p), len, this.makeCallback(resolve, reject)); + }); + } + truncateSync(p, len) { + return this.realFs.truncateSync(npath.fromPortablePath(p), len); + } + async ftruncatePromise(fd, len) { + return await new Promise((resolve, reject) => { + this.realFs.ftruncate(fd, len, this.makeCallback(resolve, reject)); + }); + } + ftruncateSync(fd, len) { + return this.realFs.ftruncateSync(fd, len); + } + watch(p, a, b) { + return this.realFs.watch( + npath.fromPortablePath(p), + a, + b + ); + } + watchFile(p, a, b) { + return this.realFs.watchFile( + npath.fromPortablePath(p), + a, + b + ); + } + unwatchFile(p, cb) { + return this.realFs.unwatchFile(npath.fromPortablePath(p), cb); + } + makeCallback(resolve, reject) { + return (err, result) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }; + } +} + +const MOUNT_MASK = 4278190080; +class MountFS extends BasePortableFakeFS { + constructor({ baseFs = new NodeFS(), filter = null, magicByte = 42, maxOpenFiles = Infinity, useCache = true, maxAge = 5e3, typeCheck = fs.constants.S_IFREG, getMountPoint, factoryPromise, factorySync }) { + if (Math.floor(magicByte) !== magicByte || !(magicByte > 1 && magicByte <= 127)) + throw new Error(`The magic byte must be set to a round value between 1 and 127 included`); + super(); + this.fdMap = /* @__PURE__ */ new Map(); + this.nextFd = 3; + this.isMount = /* @__PURE__ */ new Set(); + this.notMount = /* @__PURE__ */ new Set(); + this.realPaths = /* @__PURE__ */ new Map(); + this.limitOpenFilesTimeout = null; + this.baseFs = baseFs; + this.mountInstances = useCache ? /* @__PURE__ */ new Map() : null; + this.factoryPromise = factoryPromise; + this.factorySync = factorySync; + this.filter = filter; + this.getMountPoint = getMountPoint; + this.magic = magicByte << 24; + this.maxAge = maxAge; + this.maxOpenFiles = maxOpenFiles; + this.typeCheck = typeCheck; + } + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + getRealPath() { + return this.baseFs.getRealPath(); + } + saveAndClose() { + var _a; + unwatchAllFiles(this); + if (this.mountInstances) { + for (const [path, { childFs }] of this.mountInstances.entries()) { + (_a = childFs.saveAndClose) == null ? void 0 : _a.call(childFs); + this.mountInstances.delete(path); + } + } + } + discardAndClose() { + var _a; + unwatchAllFiles(this); + if (this.mountInstances) { + for (const [path, { childFs }] of this.mountInstances.entries()) { + (_a = childFs.discardAndClose) == null ? void 0 : _a.call(childFs); + this.mountInstances.delete(path); + } + } + } + resolve(p) { + return this.baseFs.resolve(p); + } + remapFd(mountFs, fd) { + const remappedFd = this.nextFd++ | this.magic; + this.fdMap.set(remappedFd, [mountFs, fd]); + return remappedFd; + } + async openPromise(p, flags, mode) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.openPromise(p, flags, mode); + }, async (mountFs, { subPath }) => { + return this.remapFd(mountFs, await mountFs.openPromise(subPath, flags, mode)); + }); + } + openSync(p, flags, mode) { + return this.makeCallSync(p, () => { + return this.baseFs.openSync(p, flags, mode); + }, (mountFs, { subPath }) => { + return this.remapFd(mountFs, mountFs.openSync(subPath, flags, mode)); + }); + } + async opendirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.opendirPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.opendirPromise(subPath, opts); + }, { + requireSubpath: false + }); + } + opendirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.opendirSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.opendirSync(subPath, opts); + }, { + requireSubpath: false + }); + } + async readPromise(fd, buffer, offset, length, position) { + if ((fd & MOUNT_MASK) !== this.magic) + return await this.baseFs.readPromise(fd, buffer, offset, length, position); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + const [mountFs, realFd] = entry; + return await mountFs.readPromise(realFd, buffer, offset, length, position); + } + readSync(fd, buffer, offset, length, position) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.readSync(fd, buffer, offset, length, position); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`readSync`); + const [mountFs, realFd] = entry; + return mountFs.readSync(realFd, buffer, offset, length, position); + } + async writePromise(fd, buffer, offset, length, position) { + if ((fd & MOUNT_MASK) !== this.magic) { + if (typeof buffer === `string`) { + return await this.baseFs.writePromise(fd, buffer, offset); + } else { + return await this.baseFs.writePromise(fd, buffer, offset, length, position); + } + } + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`write`); + const [mountFs, realFd] = entry; + if (typeof buffer === `string`) { + return await mountFs.writePromise(realFd, buffer, offset); + } else { + return await mountFs.writePromise(realFd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + if ((fd & MOUNT_MASK) !== this.magic) { + if (typeof buffer === `string`) { + return this.baseFs.writeSync(fd, buffer, offset); + } else { + return this.baseFs.writeSync(fd, buffer, offset, length, position); + } + } + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`writeSync`); + const [mountFs, realFd] = entry; + if (typeof buffer === `string`) { + return mountFs.writeSync(realFd, buffer, offset); + } else { + return mountFs.writeSync(realFd, buffer, offset, length, position); + } + } + async closePromise(fd) { + if ((fd & MOUNT_MASK) !== this.magic) + return await this.baseFs.closePromise(fd); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`close`); + this.fdMap.delete(fd); + const [mountFs, realFd] = entry; + return await mountFs.closePromise(realFd); + } + closeSync(fd) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.closeSync(fd); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`closeSync`); + this.fdMap.delete(fd); + const [mountFs, realFd] = entry; + return mountFs.closeSync(realFd); + } + createReadStream(p, opts) { + if (p === null) + return this.baseFs.createReadStream(p, opts); + return this.makeCallSync(p, () => { + return this.baseFs.createReadStream(p, opts); + }, (mountFs, { archivePath, subPath }) => { + const stream = mountFs.createReadStream(subPath, opts); + stream.path = npath.fromPortablePath(this.pathUtils.join(archivePath, subPath)); + return stream; + }); + } + createWriteStream(p, opts) { + if (p === null) + return this.baseFs.createWriteStream(p, opts); + return this.makeCallSync(p, () => { + return this.baseFs.createWriteStream(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.createWriteStream(subPath, opts); + }); + } + async realpathPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.realpathPromise(p); + }, async (mountFs, { archivePath, subPath }) => { + let realArchivePath = this.realPaths.get(archivePath); + if (typeof realArchivePath === `undefined`) { + realArchivePath = await this.baseFs.realpathPromise(archivePath); + this.realPaths.set(archivePath, realArchivePath); + } + return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, await mountFs.realpathPromise(subPath))); + }); + } + realpathSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.realpathSync(p); + }, (mountFs, { archivePath, subPath }) => { + let realArchivePath = this.realPaths.get(archivePath); + if (typeof realArchivePath === `undefined`) { + realArchivePath = this.baseFs.realpathSync(archivePath); + this.realPaths.set(archivePath, realArchivePath); + } + return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, mountFs.realpathSync(subPath))); + }); + } + async existsPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.existsPromise(p); + }, async (mountFs, { subPath }) => { + return await mountFs.existsPromise(subPath); + }); + } + existsSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.existsSync(p); + }, (mountFs, { subPath }) => { + return mountFs.existsSync(subPath); + }); + } + async accessPromise(p, mode) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.accessPromise(p, mode); + }, async (mountFs, { subPath }) => { + return await mountFs.accessPromise(subPath, mode); + }); + } + accessSync(p, mode) { + return this.makeCallSync(p, () => { + return this.baseFs.accessSync(p, mode); + }, (mountFs, { subPath }) => { + return mountFs.accessSync(subPath, mode); + }); + } + async statPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.statPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.statPromise(subPath, opts); + }); + } + statSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.statSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.statSync(subPath, opts); + }); + } + async fstatPromise(fd, opts) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fstatPromise(fd, opts); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstat`); + const [mountFs, realFd] = entry; + return mountFs.fstatPromise(realFd, opts); + } + fstatSync(fd, opts) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fstatSync(fd, opts); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstatSync`); + const [mountFs, realFd] = entry; + return mountFs.fstatSync(realFd, opts); + } + async lstatPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.lstatPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.lstatPromise(subPath, opts); + }); + } + lstatSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.lstatSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.lstatSync(subPath, opts); + }); + } + async fchmodPromise(fd, mask) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fchmodPromise(fd, mask); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchmod`); + const [mountFs, realFd] = entry; + return mountFs.fchmodPromise(realFd, mask); + } + fchmodSync(fd, mask) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fchmodSync(fd, mask); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchmodSync`); + const [mountFs, realFd] = entry; + return mountFs.fchmodSync(realFd, mask); + } + async chmodPromise(p, mask) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.chmodPromise(p, mask); + }, async (mountFs, { subPath }) => { + return await mountFs.chmodPromise(subPath, mask); + }); + } + chmodSync(p, mask) { + return this.makeCallSync(p, () => { + return this.baseFs.chmodSync(p, mask); + }, (mountFs, { subPath }) => { + return mountFs.chmodSync(subPath, mask); + }); + } + async fchownPromise(fd, uid, gid) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fchownPromise(fd, uid, gid); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchown`); + const [zipFs, realFd] = entry; + return zipFs.fchownPromise(realFd, uid, gid); + } + fchownSync(fd, uid, gid) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.fchownSync(fd, uid, gid); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fchownSync`); + const [zipFs, realFd] = entry; + return zipFs.fchownSync(realFd, uid, gid); + } + async chownPromise(p, uid, gid) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.chownPromise(p, uid, gid); + }, async (mountFs, { subPath }) => { + return await mountFs.chownPromise(subPath, uid, gid); + }); + } + chownSync(p, uid, gid) { + return this.makeCallSync(p, () => { + return this.baseFs.chownSync(p, uid, gid); + }, (mountFs, { subPath }) => { + return mountFs.chownSync(subPath, uid, gid); + }); + } + async renamePromise(oldP, newP) { + return await this.makeCallPromise(oldP, async () => { + return await this.makeCallPromise(newP, async () => { + return await this.baseFs.renamePromise(oldP, newP); + }, async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }); + }, async (mountFsO, { subPath: subPathO }) => { + return await this.makeCallPromise(newP, async () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }, async (mountFsN, { subPath: subPathN }) => { + if (mountFsO !== mountFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + } else { + return await mountFsO.renamePromise(subPathO, subPathN); + } + }); + }); + } + renameSync(oldP, newP) { + return this.makeCallSync(oldP, () => { + return this.makeCallSync(newP, () => { + return this.baseFs.renameSync(oldP, newP); + }, () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }); + }, (mountFsO, { subPath: subPathO }) => { + return this.makeCallSync(newP, () => { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + }, (mountFsN, { subPath: subPathN }) => { + if (mountFsO !== mountFsN) { + throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` }); + } else { + return mountFsO.renameSync(subPathO, subPathN); + } + }); + }); + } + async copyFilePromise(sourceP, destP, flags = 0) { + const fallback = async (sourceFs, sourceP2, destFs, destP2) => { + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), { code: `EXDEV` }); + if (flags & fs.constants.COPYFILE_EXCL && await this.existsPromise(sourceP2)) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EEXIST` }); + let content; + try { + content = await sourceFs.readFilePromise(sourceP2); + } catch (error) { + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EINVAL` }); + } + await destFs.writeFilePromise(destP2, content); + }; + return await this.makeCallPromise(sourceP, async () => { + return await this.makeCallPromise(destP, async () => { + return await this.baseFs.copyFilePromise(sourceP, destP, flags); + }, async (mountFsD, { subPath: subPathD }) => { + return await fallback(this.baseFs, sourceP, mountFsD, subPathD); + }); + }, async (mountFsS, { subPath: subPathS }) => { + return await this.makeCallPromise(destP, async () => { + return await fallback(mountFsS, subPathS, this.baseFs, destP); + }, async (mountFsD, { subPath: subPathD }) => { + if (mountFsS !== mountFsD) { + return await fallback(mountFsS, subPathS, mountFsD, subPathD); + } else { + return await mountFsS.copyFilePromise(subPathS, subPathD, flags); + } + }); + }); + } + copyFileSync(sourceP, destP, flags = 0) { + const fallback = (sourceFs, sourceP2, destFs, destP2) => { + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), { code: `EXDEV` }); + if (flags & fs.constants.COPYFILE_EXCL && this.existsSync(sourceP2)) + throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EEXIST` }); + let content; + try { + content = sourceFs.readFileSync(sourceP2); + } catch (error) { + throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), { code: `EINVAL` }); + } + destFs.writeFileSync(destP2, content); + }; + return this.makeCallSync(sourceP, () => { + return this.makeCallSync(destP, () => { + return this.baseFs.copyFileSync(sourceP, destP, flags); + }, (mountFsD, { subPath: subPathD }) => { + return fallback(this.baseFs, sourceP, mountFsD, subPathD); + }); + }, (mountFsS, { subPath: subPathS }) => { + return this.makeCallSync(destP, () => { + return fallback(mountFsS, subPathS, this.baseFs, destP); + }, (mountFsD, { subPath: subPathD }) => { + if (mountFsS !== mountFsD) { + return fallback(mountFsS, subPathS, mountFsD, subPathD); + } else { + return mountFsS.copyFileSync(subPathS, subPathD, flags); + } + }); + }); + } + async appendFilePromise(p, content, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.appendFilePromise(p, content, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.appendFilePromise(subPath, content, opts); + }); + } + appendFileSync(p, content, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.appendFileSync(p, content, opts); + }, (mountFs, { subPath }) => { + return mountFs.appendFileSync(subPath, content, opts); + }); + } + async writeFilePromise(p, content, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.writeFilePromise(p, content, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.writeFilePromise(subPath, content, opts); + }); + } + writeFileSync(p, content, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.writeFileSync(p, content, opts); + }, (mountFs, { subPath }) => { + return mountFs.writeFileSync(subPath, content, opts); + }); + } + async unlinkPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.unlinkPromise(p); + }, async (mountFs, { subPath }) => { + return await mountFs.unlinkPromise(subPath); + }); + } + unlinkSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.unlinkSync(p); + }, (mountFs, { subPath }) => { + return mountFs.unlinkSync(subPath); + }); + } + async utimesPromise(p, atime, mtime) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.utimesPromise(p, atime, mtime); + }, async (mountFs, { subPath }) => { + return await mountFs.utimesPromise(subPath, atime, mtime); + }); + } + utimesSync(p, atime, mtime) { + return this.makeCallSync(p, () => { + return this.baseFs.utimesSync(p, atime, mtime); + }, (mountFs, { subPath }) => { + return mountFs.utimesSync(subPath, atime, mtime); + }); + } + async lutimesPromise(p, atime, mtime) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.lutimesPromise(p, atime, mtime); + }, async (mountFs, { subPath }) => { + return await mountFs.lutimesPromise(subPath, atime, mtime); + }); + } + lutimesSync(p, atime, mtime) { + return this.makeCallSync(p, () => { + return this.baseFs.lutimesSync(p, atime, mtime); + }, (mountFs, { subPath }) => { + return mountFs.lutimesSync(subPath, atime, mtime); + }); + } + async mkdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.mkdirPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.mkdirPromise(subPath, opts); + }); + } + mkdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.mkdirSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.mkdirSync(subPath, opts); + }); + } + async rmdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.rmdirPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.rmdirPromise(subPath, opts); + }); + } + rmdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.rmdirSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.rmdirSync(subPath, opts); + }); + } + async linkPromise(existingP, newP) { + return await this.makeCallPromise(newP, async () => { + return await this.baseFs.linkPromise(existingP, newP); + }, async (mountFs, { subPath }) => { + return await mountFs.linkPromise(existingP, subPath); + }); + } + linkSync(existingP, newP) { + return this.makeCallSync(newP, () => { + return this.baseFs.linkSync(existingP, newP); + }, (mountFs, { subPath }) => { + return mountFs.linkSync(existingP, subPath); + }); + } + async symlinkPromise(target, p, type) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.symlinkPromise(target, p, type); + }, async (mountFs, { subPath }) => { + return await mountFs.symlinkPromise(target, subPath); + }); + } + symlinkSync(target, p, type) { + return this.makeCallSync(p, () => { + return this.baseFs.symlinkSync(target, p, type); + }, (mountFs, { subPath }) => { + return mountFs.symlinkSync(target, subPath); + }); + } + async readFilePromise(p, encoding) { + return this.makeCallPromise(p, async () => { + return await this.baseFs.readFilePromise(p, encoding); + }, async (mountFs, { subPath }) => { + return await mountFs.readFilePromise(subPath, encoding); + }); + } + readFileSync(p, encoding) { + return this.makeCallSync(p, () => { + return this.baseFs.readFileSync(p, encoding); + }, (mountFs, { subPath }) => { + return mountFs.readFileSync(subPath, encoding); + }); + } + async readdirPromise(p, opts) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.readdirPromise(p, opts); + }, async (mountFs, { subPath }) => { + return await mountFs.readdirPromise(subPath, opts); + }, { + requireSubpath: false + }); + } + readdirSync(p, opts) { + return this.makeCallSync(p, () => { + return this.baseFs.readdirSync(p, opts); + }, (mountFs, { subPath }) => { + return mountFs.readdirSync(subPath, opts); + }, { + requireSubpath: false + }); + } + async readlinkPromise(p) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.readlinkPromise(p); + }, async (mountFs, { subPath }) => { + return await mountFs.readlinkPromise(subPath); + }); + } + readlinkSync(p) { + return this.makeCallSync(p, () => { + return this.baseFs.readlinkSync(p); + }, (mountFs, { subPath }) => { + return mountFs.readlinkSync(subPath); + }); + } + async truncatePromise(p, len) { + return await this.makeCallPromise(p, async () => { + return await this.baseFs.truncatePromise(p, len); + }, async (mountFs, { subPath }) => { + return await mountFs.truncatePromise(subPath, len); + }); + } + truncateSync(p, len) { + return this.makeCallSync(p, () => { + return this.baseFs.truncateSync(p, len); + }, (mountFs, { subPath }) => { + return mountFs.truncateSync(subPath, len); + }); + } + async ftruncatePromise(fd, len) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.ftruncatePromise(fd, len); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`ftruncate`); + const [mountFs, realFd] = entry; + return mountFs.ftruncatePromise(realFd, len); + } + ftruncateSync(fd, len) { + if ((fd & MOUNT_MASK) !== this.magic) + return this.baseFs.ftruncateSync(fd, len); + const entry = this.fdMap.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`ftruncateSync`); + const [mountFs, realFd] = entry; + return mountFs.ftruncateSync(realFd, len); + } + watch(p, a, b) { + return this.makeCallSync(p, () => { + return this.baseFs.watch( + p, + a, + b + ); + }, (mountFs, { subPath }) => { + return mountFs.watch( + subPath, + a, + b + ); + }); + } + watchFile(p, a, b) { + return this.makeCallSync(p, () => { + return this.baseFs.watchFile( + p, + a, + b + ); + }, () => { + return watchFile(this, p, a, b); + }); + } + unwatchFile(p, cb) { + return this.makeCallSync(p, () => { + return this.baseFs.unwatchFile(p, cb); + }, () => { + return unwatchFile(this, p, cb); + }); + } + async makeCallPromise(p, discard, accept, { requireSubpath = true } = {}) { + if (typeof p !== `string`) + return await discard(); + const normalizedP = this.resolve(p); + const mountInfo = this.findMount(normalizedP); + if (!mountInfo) + return await discard(); + if (requireSubpath && mountInfo.subPath === `/`) + return await discard(); + return await this.getMountPromise(mountInfo.archivePath, async (mountFs) => await accept(mountFs, mountInfo)); + } + makeCallSync(p, discard, accept, { requireSubpath = true } = {}) { + if (typeof p !== `string`) + return discard(); + const normalizedP = this.resolve(p); + const mountInfo = this.findMount(normalizedP); + if (!mountInfo) + return discard(); + if (requireSubpath && mountInfo.subPath === `/`) + return discard(); + return this.getMountSync(mountInfo.archivePath, (mountFs) => accept(mountFs, mountInfo)); + } + findMount(p) { + if (this.filter && !this.filter.test(p)) + return null; + let filePath = ``; + while (true) { + const pathPartWithArchive = p.substring(filePath.length); + const mountPoint = this.getMountPoint(pathPartWithArchive, filePath); + if (!mountPoint) + return null; + filePath = this.pathUtils.join(filePath, mountPoint); + if (!this.isMount.has(filePath)) { + if (this.notMount.has(filePath)) + continue; + try { + if (this.typeCheck !== null && (this.baseFs.lstatSync(filePath).mode & fs.constants.S_IFMT) !== this.typeCheck) { + this.notMount.add(filePath); + continue; + } + } catch { + return null; + } + this.isMount.add(filePath); + } + return { + archivePath: filePath, + subPath: this.pathUtils.join(PortablePath.root, p.substring(filePath.length)) + }; + } + } + limitOpenFiles(max) { + var _a, _b, _c; + if (this.mountInstances === null) + return; + const now = Date.now(); + let nextExpiresAt = now + this.maxAge; + let closeCount = max === null ? 0 : this.mountInstances.size - max; + for (const [path, { childFs, expiresAt, refCount }] of this.mountInstances.entries()) { + if (refCount !== 0 || ((_a = childFs.hasOpenFileHandles) == null ? void 0 : _a.call(childFs))) { + continue; + } else if (now >= expiresAt) { + (_b = childFs.saveAndClose) == null ? void 0 : _b.call(childFs); + this.mountInstances.delete(path); + closeCount -= 1; + continue; + } else if (max === null || closeCount <= 0) { + nextExpiresAt = expiresAt; + break; + } + (_c = childFs.saveAndClose) == null ? void 0 : _c.call(childFs); + this.mountInstances.delete(path); + closeCount -= 1; + } + if (this.limitOpenFilesTimeout === null && (max === null && this.mountInstances.size > 0 || max !== null) && isFinite(nextExpiresAt)) { + this.limitOpenFilesTimeout = setTimeout(() => { + this.limitOpenFilesTimeout = null; + this.limitOpenFiles(null); + }, nextExpiresAt - now).unref(); + } + } + async getMountPromise(p, accept) { + var _a; + if (this.mountInstances) { + let cachedMountFs = this.mountInstances.get(p); + if (!cachedMountFs) { + const createFsInstance = await this.factoryPromise(this.baseFs, p); + cachedMountFs = this.mountInstances.get(p); + if (!cachedMountFs) { + cachedMountFs = { + childFs: createFsInstance(), + expiresAt: 0, + refCount: 0 + }; + } + } + this.mountInstances.delete(p); + this.limitOpenFiles(this.maxOpenFiles - 1); + this.mountInstances.set(p, cachedMountFs); + cachedMountFs.expiresAt = Date.now() + this.maxAge; + cachedMountFs.refCount += 1; + try { + return await accept(cachedMountFs.childFs); + } finally { + cachedMountFs.refCount -= 1; + } + } else { + const mountFs = (await this.factoryPromise(this.baseFs, p))(); + try { + return await accept(mountFs); + } finally { + (_a = mountFs.saveAndClose) == null ? void 0 : _a.call(mountFs); + } + } + } + getMountSync(p, accept) { + var _a; + if (this.mountInstances) { + let cachedMountFs = this.mountInstances.get(p); + if (!cachedMountFs) { + cachedMountFs = { + childFs: this.factorySync(this.baseFs, p), + expiresAt: 0, + refCount: 0 + }; + } + this.mountInstances.delete(p); + this.limitOpenFiles(this.maxOpenFiles - 1); + this.mountInstances.set(p, cachedMountFs); + cachedMountFs.expiresAt = Date.now() + this.maxAge; + return accept(cachedMountFs.childFs); + } else { + const childFs = this.factorySync(this.baseFs, p); + try { + return accept(childFs); + } finally { + (_a = childFs.saveAndClose) == null ? void 0 : _a.call(childFs); + } + } + } +} + +class PosixFS extends ProxiedFS { + constructor(baseFs) { + super(npath); + this.baseFs = baseFs; + } + mapFromBase(path) { + return npath.fromPortablePath(path); + } + mapToBase(path) { + return npath.toPortablePath(path); + } +} + +const NUMBER_REGEXP = /^[0-9]+$/; +const VIRTUAL_REGEXP = /^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/; +const VALID_COMPONENT = /^([^/]+-)?[a-f0-9]+$/; +class VirtualFS extends ProxiedFS { + constructor({ baseFs = new NodeFS() } = {}) { + super(ppath); + this.baseFs = baseFs; + } + static makeVirtualPath(base, component, to) { + if (ppath.basename(base) !== `__virtual__`) + throw new Error(`Assertion failed: Virtual folders must be named "__virtual__"`); + if (!ppath.basename(component).match(VALID_COMPONENT)) + throw new Error(`Assertion failed: Virtual components must be ended by an hexadecimal hash`); + const target = ppath.relative(ppath.dirname(base), to); + const segments = target.split(`/`); + let depth = 0; + while (depth < segments.length && segments[depth] === `..`) + depth += 1; + const finalSegments = segments.slice(depth); + const fullVirtualPath = ppath.join(base, component, String(depth), ...finalSegments); + return fullVirtualPath; + } + static resolveVirtual(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match || !match[3] && match[5]) + return p; + const target = ppath.dirname(match[1]); + if (!match[3] || !match[4]) + return target; + const isnum = NUMBER_REGEXP.test(match[4]); + if (!isnum) + return p; + const depth = Number(match[4]); + const backstep = `../`.repeat(depth); + const subpath = match[5] || `.`; + return VirtualFS.resolveVirtual(ppath.join(target, backstep, subpath)); + } + getExtractHint(hints) { + return this.baseFs.getExtractHint(hints); + } + getRealPath() { + return this.baseFs.getRealPath(); + } + realpathSync(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match) + return this.baseFs.realpathSync(p); + if (!match[5]) + return p; + const realpath = this.baseFs.realpathSync(this.mapToBase(p)); + return VirtualFS.makeVirtualPath(match[1], match[3], realpath); + } + async realpathPromise(p) { + const match = p.match(VIRTUAL_REGEXP); + if (!match) + return await this.baseFs.realpathPromise(p); + if (!match[5]) + return p; + const realpath = await this.baseFs.realpathPromise(this.mapToBase(p)); + return VirtualFS.makeVirtualPath(match[1], match[3], realpath); + } + mapToBase(p) { + if (p === ``) + return p; + if (this.pathUtils.isAbsolute(p)) + return VirtualFS.resolveVirtual(p); + const resolvedRoot = VirtualFS.resolveVirtual(this.baseFs.resolve(PortablePath.dot)); + const resolvedP = VirtualFS.resolveVirtual(this.baseFs.resolve(p)); + return ppath.relative(resolvedRoot, resolvedP) || PortablePath.dot; + } + mapFromBase(p) { + return p; + } +} + +class NodePathFS extends ProxiedFS { + constructor(baseFs) { + super(npath); + this.baseFs = baseFs; + } + mapFromBase(path) { + return path; + } + mapToBase(path) { + if (typeof path === `string`) + return path; + if (path instanceof url.URL) + return url.fileURLToPath(path); + if (Buffer.isBuffer(path)) { + const str = path.toString(); + if (Buffer.byteLength(str) !== path.byteLength) + throw new Error(`Non-utf8 buffers are not supported at the moment. Please upvote the following issue if you encounter this error: https://github.com/yarnpkg/berry/issues/4942`); + return str; + } + throw new Error(`Unsupported path type: ${nodeUtils.inspect(path)}`); + } +} + +var _a, _b, _c, _d; +const kBaseFs = Symbol(`kBaseFs`); +const kFd = Symbol(`kFd`); +const kClosePromise = Symbol(`kClosePromise`); +const kCloseResolve = Symbol(`kCloseResolve`); +const kCloseReject = Symbol(`kCloseReject`); +const kRefs = Symbol(`kRefs`); +const kRef = Symbol(`kRef`); +const kUnref = Symbol(`kUnref`); +class FileHandle { + constructor(fd, baseFs) { + this[_a] = 1; + this[_b] = void 0; + this[_c] = void 0; + this[_d] = void 0; + this[kBaseFs] = baseFs; + this[kFd] = fd; + } + get fd() { + return this[kFd]; + } + async appendFile(data, options) { + try { + this[kRef](this.appendFile); + const encoding = (typeof options === `string` ? options : options == null ? void 0 : options.encoding) ?? void 0; + return await this[kBaseFs].appendFilePromise(this.fd, data, encoding ? { encoding } : void 0); + } finally { + this[kUnref](); + } + } + async chown(uid, gid) { + try { + this[kRef](this.chown); + return await this[kBaseFs].fchownPromise(this.fd, uid, gid); + } finally { + this[kUnref](); + } + } + async chmod(mode) { + try { + this[kRef](this.chmod); + return await this[kBaseFs].fchmodPromise(this.fd, mode); + } finally { + this[kUnref](); + } + } + createReadStream(options) { + return this[kBaseFs].createReadStream(null, { ...options, fd: this.fd }); + } + createWriteStream(options) { + return this[kBaseFs].createWriteStream(null, { ...options, fd: this.fd }); + } + datasync() { + throw new Error(`Method not implemented.`); + } + sync() { + throw new Error(`Method not implemented.`); + } + async read(bufferOrOptions, offset, length, position) { + try { + this[kRef](this.read); + let buffer; + if (!Buffer.isBuffer(bufferOrOptions)) { + bufferOrOptions ?? (bufferOrOptions = {}); + buffer = bufferOrOptions.buffer ?? Buffer.alloc(16384); + offset = bufferOrOptions.offset || 0; + length = bufferOrOptions.length ?? buffer.byteLength; + position = bufferOrOptions.position ?? null; + } else { + buffer = bufferOrOptions; + } + offset ?? (offset = 0); + length ?? (length = 0); + if (length === 0) { + return { + bytesRead: length, + buffer + }; + } + const bytesRead = await this[kBaseFs].readPromise(this.fd, buffer, offset, length, position); + return { + bytesRead, + buffer + }; + } finally { + this[kUnref](); + } + } + async readFile(options) { + try { + this[kRef](this.readFile); + const encoding = (typeof options === `string` ? options : options == null ? void 0 : options.encoding) ?? void 0; + return await this[kBaseFs].readFilePromise(this.fd, encoding); + } finally { + this[kUnref](); + } + } + readLines(options) { + return readline.createInterface({ + input: this.createReadStream(options), + crlfDelay: Infinity + }); + } + async stat(opts) { + try { + this[kRef](this.stat); + return await this[kBaseFs].fstatPromise(this.fd, opts); + } finally { + this[kUnref](); + } + } + async truncate(len) { + try { + this[kRef](this.truncate); + return await this[kBaseFs].ftruncatePromise(this.fd, len); + } finally { + this[kUnref](); + } + } + utimes(atime, mtime) { + throw new Error(`Method not implemented.`); + } + async writeFile(data, options) { + try { + this[kRef](this.writeFile); + const encoding = (typeof options === `string` ? options : options == null ? void 0 : options.encoding) ?? void 0; + await this[kBaseFs].writeFilePromise(this.fd, data, encoding); + } finally { + this[kUnref](); + } + } + async write(...args) { + try { + this[kRef](this.write); + if (ArrayBuffer.isView(args[0])) { + const [buffer, offset, length, position] = args; + const bytesWritten = await this[kBaseFs].writePromise(this.fd, buffer, offset ?? void 0, length ?? void 0, position ?? void 0); + return { bytesWritten, buffer }; + } else { + const [data, position, encoding] = args; + const bytesWritten = await this[kBaseFs].writePromise(this.fd, data, position, encoding); + return { bytesWritten, buffer: data }; + } + } finally { + this[kUnref](); + } + } + async writev(buffers, position) { + try { + this[kRef](this.writev); + let bytesWritten = 0; + if (typeof position !== `undefined`) { + for (const buffer of buffers) { + const writeResult = await this.write(buffer, void 0, void 0, position); + bytesWritten += writeResult.bytesWritten; + position += writeResult.bytesWritten; + } + } else { + for (const buffer of buffers) { + const writeResult = await this.write(buffer); + bytesWritten += writeResult.bytesWritten; + } + } + return { + buffers, + bytesWritten + }; + } finally { + this[kUnref](); + } + } + readv(buffers, position) { + throw new Error(`Method not implemented.`); + } + close() { + if (this[kFd] === -1) + return Promise.resolve(); + if (this[kClosePromise]) + return this[kClosePromise]; + this[kRefs]--; + if (this[kRefs] === 0) { + const fd = this[kFd]; + this[kFd] = -1; + this[kClosePromise] = this[kBaseFs].closePromise(fd).finally(() => { + this[kClosePromise] = void 0; + }); + } else { + this[kClosePromise] = new Promise((resolve, reject) => { + this[kCloseResolve] = resolve; + this[kCloseReject] = reject; + }).finally(() => { + this[kClosePromise] = void 0; + this[kCloseReject] = void 0; + this[kCloseResolve] = void 0; + }); + } + return this[kClosePromise]; + } + [(_a = kRefs, _b = kClosePromise, _c = kCloseResolve, _d = kCloseReject, kRef)](caller) { + if (this[kFd] === -1) { + const err = new Error(`file closed`); + err.code = `EBADF`; + err.syscall = caller.name; + throw err; + } + this[kRefs]++; + } + [kUnref]() { + this[kRefs]--; + if (this[kRefs] === 0) { + const fd = this[kFd]; + this[kFd] = -1; + this[kBaseFs].closePromise(fd).then(this[kCloseResolve], this[kCloseReject]); + } + } +} + +const SYNC_IMPLEMENTATIONS = /* @__PURE__ */ new Set([ + `accessSync`, + `appendFileSync`, + `createReadStream`, + `createWriteStream`, + `chmodSync`, + `fchmodSync`, + `chownSync`, + `fchownSync`, + `closeSync`, + `copyFileSync`, + `linkSync`, + `lstatSync`, + `fstatSync`, + `lutimesSync`, + `mkdirSync`, + `openSync`, + `opendirSync`, + `readlinkSync`, + `readFileSync`, + `readdirSync`, + `readlinkSync`, + `realpathSync`, + `renameSync`, + `rmdirSync`, + `statSync`, + `symlinkSync`, + `truncateSync`, + `ftruncateSync`, + `unlinkSync`, + `unwatchFile`, + `utimesSync`, + `watch`, + `watchFile`, + `writeFileSync`, + `writeSync` +]); +const ASYNC_IMPLEMENTATIONS = /* @__PURE__ */ new Set([ + `accessPromise`, + `appendFilePromise`, + `fchmodPromise`, + `chmodPromise`, + `fchownPromise`, + `chownPromise`, + `closePromise`, + `copyFilePromise`, + `linkPromise`, + `fstatPromise`, + `lstatPromise`, + `lutimesPromise`, + `mkdirPromise`, + `openPromise`, + `opendirPromise`, + `readdirPromise`, + `realpathPromise`, + `readFilePromise`, + `readdirPromise`, + `readlinkPromise`, + `renamePromise`, + `rmdirPromise`, + `statPromise`, + `symlinkPromise`, + `truncatePromise`, + `ftruncatePromise`, + `unlinkPromise`, + `utimesPromise`, + `writeFilePromise`, + `writeSync` +]); +function patchFs(patchedFs, fakeFs) { + fakeFs = new NodePathFS(fakeFs); + const setupFn = (target, name, replacement) => { + const orig = target[name]; + target[name] = replacement; + if (typeof (orig == null ? void 0 : orig[nodeUtils.promisify.custom]) !== `undefined`) { + replacement[nodeUtils.promisify.custom] = orig[nodeUtils.promisify.custom]; + } + }; + { + setupFn(patchedFs, `exists`, (p, ...args) => { + const hasCallback = typeof args[args.length - 1] === `function`; + const callback = hasCallback ? args.pop() : () => { + }; + process.nextTick(() => { + fakeFs.existsPromise(p).then((exists) => { + callback(exists); + }, () => { + callback(false); + }); + }); + }); + setupFn(patchedFs, `read`, (...args) => { + let [fd, buffer, offset, length, position, callback] = args; + if (args.length <= 3) { + let options = {}; + if (args.length < 3) { + callback = args[1]; + } else { + options = args[1]; + callback = args[2]; + } + ({ + buffer = Buffer.alloc(16384), + offset = 0, + length = buffer.byteLength, + position + } = options); + } + if (offset == null) + offset = 0; + length |= 0; + if (length === 0) { + process.nextTick(() => { + callback(null, 0, buffer); + }); + return; + } + if (position == null) + position = -1; + process.nextTick(() => { + fakeFs.readPromise(fd, buffer, offset, length, position).then((bytesRead) => { + callback(null, bytesRead, buffer); + }, (error) => { + callback(error, 0, buffer); + }); + }); + }); + for (const fnName of ASYNC_IMPLEMENTATIONS) { + const origName = fnName.replace(/Promise$/, ``); + if (typeof patchedFs[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + const wrapper = (...args) => { + const hasCallback = typeof args[args.length - 1] === `function`; + const callback = hasCallback ? args.pop() : () => { + }; + process.nextTick(() => { + fakeImpl.apply(fakeFs, args).then((result) => { + callback(null, result); + }, (error) => { + callback(error); + }); + }); + }; + setupFn(patchedFs, origName, wrapper); + } + patchedFs.realpath.native = patchedFs.realpath; + } + { + setupFn(patchedFs, `existsSync`, (p) => { + try { + return fakeFs.existsSync(p); + } catch (error) { + return false; + } + }); + setupFn(patchedFs, `readSync`, (...args) => { + let [fd, buffer, offset, length, position] = args; + if (args.length <= 3) { + const options = args[2] || {}; + ({ offset = 0, length = buffer.byteLength, position } = options); + } + if (offset == null) + offset = 0; + length |= 0; + if (length === 0) + return 0; + if (position == null) + position = -1; + return fakeFs.readSync(fd, buffer, offset, length, position); + }); + for (const fnName of SYNC_IMPLEMENTATIONS) { + const origName = fnName; + if (typeof patchedFs[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + setupFn(patchedFs, origName, fakeImpl.bind(fakeFs)); + } + patchedFs.realpathSync.native = patchedFs.realpathSync; + } + { + const patchedFsPromises = patchedFs.promises; + for (const fnName of ASYNC_IMPLEMENTATIONS) { + const origName = fnName.replace(/Promise$/, ``); + if (typeof patchedFsPromises[origName] === `undefined`) + continue; + const fakeImpl = fakeFs[fnName]; + if (typeof fakeImpl === `undefined`) + continue; + if (fnName === `open`) + continue; + setupFn(patchedFsPromises, origName, (pathLike, ...args) => { + if (pathLike instanceof FileHandle) { + return pathLike[origName].apply(pathLike, args); + } else { + return fakeImpl.call(fakeFs, pathLike, ...args); + } + }); + } + setupFn(patchedFsPromises, `open`, async (...args) => { + const fd = await fakeFs.openPromise(...args); + return new FileHandle(fd, fakeFs); + }); + } + { + patchedFs.read[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { + const res = fakeFs.readPromise(fd, buffer, ...args); + return { bytesRead: await res, buffer }; + }; + patchedFs.write[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { + const res = fakeFs.writePromise(fd, buffer, ...args); + return { bytesWritten: await res, buffer }; + }; + } +} + +let cachedInstance; +let registeredFactory = () => { + throw new Error(`Assertion failed: No libzip instance is available, and no factory was configured`); +}; +function setFactory(factory) { + registeredFactory = factory; +} +function getInstance() { + if (typeof cachedInstance === `undefined`) + cachedInstance = registeredFactory(); + return cachedInstance; +} + +var libzipSync = {exports: {}}; + +(function (module, exports) { +var frozenFs = Object.assign({}, fs__default.default); +var createModule = function() { + var _scriptDir = void 0; + if (typeof __filename !== "undefined") + _scriptDir = _scriptDir || __filename; + return function(createModule2) { + createModule2 = createModule2 || {}; + var Module = typeof createModule2 !== "undefined" ? createModule2 : {}; + var readyPromiseResolve, readyPromiseReject; + Module["ready"] = new Promise(function(resolve, reject) { + readyPromiseResolve = resolve; + readyPromiseReject = reject; + }); + var moduleOverrides = {}; + var key; + for (key in Module) { + if (Module.hasOwnProperty(key)) { + moduleOverrides[key] = Module[key]; + } + } + var scriptDirectory = ""; + function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; + } + var read_, readBinary; + var nodeFS; + var nodePath; + { + { + scriptDirectory = __dirname + "/"; + } + read_ = function shell_read(filename, binary) { + var ret = tryParseAsDataURI(filename); + if (ret) { + return binary ? ret : ret.toString(); + } + if (!nodeFS) + nodeFS = frozenFs; + if (!nodePath) + nodePath = path__default.default; + filename = nodePath["normalize"](filename); + return nodeFS["readFileSync"](filename, binary ? null : "utf8"); + }; + readBinary = function readBinary2(filename) { + var ret = read_(filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; + }; + if (process["argv"].length > 1) { + process["argv"][1].replace(/\\/g, "/"); + } + process["argv"].slice(2); + Module["inspect"] = function() { + return "[Emscripten Module object]"; + }; + } + Module["print"] || console.log.bind(console); + var err = Module["printErr"] || console.warn.bind(console); + for (key in moduleOverrides) { + if (moduleOverrides.hasOwnProperty(key)) { + Module[key] = moduleOverrides[key]; + } + } + moduleOverrides = null; + if (Module["arguments"]) + ; + if (Module["thisProgram"]) + ; + if (Module["quit"]) + ; + var wasmBinary; + if (Module["wasmBinary"]) + wasmBinary = Module["wasmBinary"]; + Module["noExitRuntime"] || true; + if (typeof WebAssembly !== "object") { + abort("no native wasm support detected"); + } + function getValue(ptr, type, noSafe) { + type = type || "i8"; + if (type.charAt(type.length - 1) === "*") + type = "i32"; + switch (type) { + case "i1": + return HEAP8[ptr >> 0]; + case "i8": + return HEAP8[ptr >> 0]; + case "i16": + return LE_HEAP_LOAD_I16((ptr >> 1) * 2); + case "i32": + return LE_HEAP_LOAD_I32((ptr >> 2) * 4); + case "i64": + return LE_HEAP_LOAD_I32((ptr >> 2) * 4); + case "float": + return LE_HEAP_LOAD_F32((ptr >> 2) * 4); + case "double": + return LE_HEAP_LOAD_F64((ptr >> 3) * 8); + default: + abort("invalid type for getValue: " + type); + } + return null; + } + var wasmMemory; + var ABORT = false; + function assert(condition, text) { + if (!condition) { + abort("Assertion failed: " + text); + } + } + function getCFunc(ident) { + var func = Module["_" + ident]; + assert( + func, + "Cannot call unknown function " + ident + ", make sure it is exported" + ); + return func; + } + function ccall(ident, returnType, argTypes, args, opts) { + var toC = { + string: function(str) { + var ret2 = 0; + if (str !== null && str !== void 0 && str !== 0) { + var len = (str.length << 2) + 1; + ret2 = stackAlloc(len); + stringToUTF8(str, ret2, len); + } + return ret2; + }, + array: function(arr) { + var ret2 = stackAlloc(arr.length); + writeArrayToMemory(arr, ret2); + return ret2; + } + }; + function convertReturnValue(ret2) { + if (returnType === "string") + return UTF8ToString(ret2); + if (returnType === "boolean") + return Boolean(ret2); + return ret2; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) + stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func.apply(null, cArgs); + ret = convertReturnValue(ret); + if (stack !== 0) + stackRestore(stack); + return ret; + } + function cwrap(ident, returnType, argTypes, opts) { + argTypes = argTypes || []; + var numericArgs = argTypes.every(function(type) { + return type === "number"; + }); + var numericRet = returnType !== "string"; + if (numericRet && numericArgs && !opts) { + return getCFunc(ident); + } + return function() { + return ccall(ident, returnType, argTypes, arguments); + }; + } + var UTF8Decoder = new TextDecoder("utf8"); + function UTF8ToString(ptr, maxBytesToRead) { + if (!ptr) + return ""; + var maxPtr = ptr + maxBytesToRead; + for (var end = ptr; !(end >= maxPtr) && HEAPU8[end]; ) + ++end; + return UTF8Decoder.decode(HEAPU8.subarray(ptr, end)); + } + function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + if (!(maxBytesToWrite > 0)) + return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = 65536 + ((u & 1023) << 10) | u1 & 1023; + } + if (u <= 127) { + if (outIdx >= endIdx) + break; + heap[outIdx++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) + break; + heap[outIdx++] = 192 | u >> 6; + heap[outIdx++] = 128 | u & 63; + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) + break; + heap[outIdx++] = 224 | u >> 12; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } else { + if (outIdx + 3 >= endIdx) + break; + heap[outIdx++] = 240 | u >> 18; + heap[outIdx++] = 128 | u >> 12 & 63; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63; + } + } + heap[outIdx] = 0; + return outIdx - startIdx; + } + function stringToUTF8(str, outPtr, maxBytesToWrite) { + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + } + function lengthBytesUTF8(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) + u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; + if (u <= 127) + ++len; + else if (u <= 2047) + len += 2; + else if (u <= 65535) + len += 3; + else + len += 4; + } + return len; + } + function allocateUTF8(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) + stringToUTF8Array(str, HEAP8, ret, size); + return ret; + } + function writeArrayToMemory(array, buffer2) { + HEAP8.set(array, buffer2); + } + function alignUp(x, multiple) { + if (x % multiple > 0) { + x += multiple - x % multiple; + } + return x; + } + var buffer, HEAP8, HEAPU8; + var HEAP_DATA_VIEW; + function updateGlobalBufferAndViews(buf) { + buffer = buf; + Module["HEAP_DATA_VIEW"] = HEAP_DATA_VIEW = new DataView(buf); + Module["HEAP8"] = HEAP8 = new Int8Array(buf); + Module["HEAP16"] = new Int16Array(buf); + Module["HEAP32"] = new Int32Array(buf); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf); + Module["HEAPU16"] = new Uint16Array(buf); + Module["HEAPU32"] = new Uint32Array(buf); + Module["HEAPF32"] = new Float32Array(buf); + Module["HEAPF64"] = new Float64Array(buf); + } + Module["INITIAL_MEMORY"] || 16777216; + var wasmTable; + var __ATPRERUN__ = []; + var __ATINIT__ = []; + var __ATPOSTRUN__ = []; + function preRun() { + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") + Module["preRun"] = [Module["preRun"]]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); + } + function initRuntime() { + callRuntimeCallbacks(__ATINIT__); + } + function postRun() { + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") + Module["postRun"] = [Module["postRun"]]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + callRuntimeCallbacks(__ATPOSTRUN__); + } + function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); + } + function addOnInit(cb) { + __ATINIT__.unshift(cb); + } + function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); + } + var runDependencies = 0; + var dependenciesFulfilled = null; + function addRunDependency(id) { + runDependencies++; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + } + function removeRunDependency(id) { + runDependencies--; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + if (runDependencies == 0) { + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } + } + Module["preloadedImages"] = {}; + Module["preloadedAudios"] = {}; + function abort(what) { + if (Module["onAbort"]) { + Module["onAbort"](what); + } + what += ""; + err(what); + ABORT = true; + what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; + var e = new WebAssembly.RuntimeError(what); + readyPromiseReject(e); + throw e; + } + var dataURIPrefix = "data:application/octet-stream;base64,"; + function isDataURI(filename) { + return filename.startsWith(dataURIPrefix); + } + var wasmBinaryFile = "data:application/octet-stream;base64,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AQsgAEEAOgAAQQAPCyAAKAIEIgNFBEBBAA8LIAAgAjcDECADIAGnaigAAAtVAgF+AX8gAARAAkAgACkDCFANAEIBIQEDQCAAKAIAIAJBBHRqEDogASAAKQMIWg0BIAGnIQIgAUIBfCEBDAALAAsgACgCABAGIAAoAigQECAAEAYLC2QBAn8CQAJAAkAgAEUEQCABpxAIIgNFDQJBGBAIIgJFDQEMAwsgACEDQRgQCCICDQJBAA8LIAMQBgtBAA8LIAJCADcDECACIAE3AwggAiADNgIEIAJBAToAACACIABFOgABIAILnQECAn4BfwJAAkAgAC0AAEUNACAAKQMQIgJCd1YNACACQgh8IgMgACkDCFgNAQsgAEEAOgAADwsgACgCBCIERQRADwsgACADNwMQIAQgAqdqIgAgAUI4iDwAByAAIAFCMIg8AAYgACABQiiIPAAFIAAgAUIgiDwABCAAIAFCGIg8AAMgACABQhCIPAACIAAgAUIIiDwAASAAIAE8AAAL8AICAn8BfgJAIAJFDQAgACACaiIDQQFrIAE6AAAgACABOgAAIAJBA0kNACADQQJrIAE6AAAgACABOgABIANBA2sgAToAACAAIAE6AAIgAkEHSQ0AIANBBGsgAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgA2AgAgAyACIARrQXxxIgJqIgFBBGsgADYCACACQQlJDQAgAyAANgIIIAMgADYCBCABQQhrIAA2AgAgAUEMayAANgIAIAJBGUkNACADIAA2AhggAyAANgIUIAMgADYCECADIAA2AgwgAUEQayAANgIAIAFBFGsgADYCACABQRhrIAA2AgAgAUEcayAANgIAIAIgA0EEcUEYciIBayICQSBJDQAgAK1CgYCAgBB+IQUgASADaiEBA0AgASAFNwMYIAEgBTcDECABIAU3AwggASAFNwMAIAFBIGohASACQSBrIgJBH0sNAAsLC28BA38gAEEMaiECAkACfyAAKAIgIgFFBEBBfyEBQRIMAQsgACABQQFrIgM2AiBBACEBIAMNASAAQQBCAEECEA4aIAAoAgAiAEUNASAAEBtBf0oNAUEUCyEAIAIEQCACQQA2AgQgAiAANgIACwsgAQufAQIBfwF+An8CQAJ+IAAoAgAiAygCJEEBRkEA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RQ0AIAQtAAxFDQFBFyEFIAcNAQtBACECIAMgAEEIaiADGyIABEAgAEEANgIEIAAgBTYCAAsLIAILbgEBfyMAQYACayIFJAACQCAEQYDABHENACACIANMDQAgBSABQf8BcSACIANrIgJBgAIgAkGAAkkiARsQGiABRQRAA0AgACAFQYACEC4gAkGAAmsiAkH/AUsNAAsLIAAgBSACEC4LIAVBgAJqJAALUgECf0H0mAEoAgAiASAAQQNqQXxxIgJqIQACQCACQQAgACABTRsNACAAPwBBEHRLBEAgABADRQ0BC0H0mAEgADYCACABDwtB+JsBQTA2AgBBfwuGBQEGfyAAKAIwIgNBhgJrIQYgACgCPCECIAMhAQNAIAAoAkQgAiAAKAJkIgRqayECIAEgBmogBE0EQCAAKAJIIgEgASADaiADEAkaAkAgAyAAKAJoIgFNBEAgACABIANrNgJoDAELIABCADcDaAsgACAAKAJkIANrIgE2AmQgACAAKAJUIANrNgJUIAEgACgCqC1JBEAgACABNgKoLQsgAEHQmAEoAgARBAAgAiADaiECCwJAIAAoAgAiASgCBCIERQ0AIAAoAjwhBSAAIAIgBCACIARJGyICBH8gACgCSCAAKAJkaiAFaiEFIAEgBCACazYCBAJAIAEoAhwoAhRBAkYEQCABIAUgAhBADAELIAUgASgCACACEAkhBCABKAIcKAIUQQFHDQAgASABKAIwIAQgAkHImAEoAgARAAA2AjALIAEgASgCACACajYCACABIAEoAgggAmo2AgggACgCPAUgBQsgAmoiAjYCPAJAIAAoAqgtIgEgAmpBA0kNACAAKAJkIAFrIgEEQCAAIAFBAWtBxJgBKAIAEQEAGiAAKAI8IQILIAAoAqgtIAJBAUZrIgRFDQAgACABIARBwJgBKAIAEQcAIAAgACgCqC0gBGs2AqgtIAAoAjwhAgsgAkGFAksNACAAKAIAKAIERQ0AIAAoAjAhAQwBCwsCQCAAKAJEIgIgACgCQCIDTQ0AIAACfyAAKAI8IAAoAmRqIgEgA0sEQCAAKAJIIAFqQQAgAiABayIDQYICIANBggJJGyIDEBogASADagwBCyABQYICaiIBIANNDQEgACgCSCADakEAIAIgA2siAiABIANrIgMgAiADSRsiAxAaIAAoAkAgA2oLNgJACws3ACAAQn83AxAgAEEANgIIIABCADcDACAAQQA2AjAgAEL/////DzcDKCAAQgA3AxggAEIANwMgC6UBAQF/QdgAEAgiAUUEQEEADwsCQCAABEAgASAAQdgAEAkaDAELIAFCADcDICABQQA2AhggAUL/////DzcDECABQQA7AQwgAUG/hig2AgggAUEBOgAGIAFBADoABCABQgA3A0ggAUGAgNiNeDYCRCABQgA3AyggAUIANwMwIAFCADcDOCABQUBrQQA7AQAgAUIANwNQCyABQQE6AAUgAUEANgIAIAELWAICfgF/AkACQCAALQAARQ0AIAApAxAiAyACrXwiBCADVA0AIAQgACkDCFgNAQsgAEEAOgAADwsgACgCBCIFRQRADwsgACAENwMQIAUgA6dqIAEgAhAJGguWAQECfwJAAkAgAkUEQCABpxAIIgVFDQFBGBAIIgQNAiAFEAYMAQsgAiEFQRgQCCIEDQELIAMEQCADQQA2AgQgA0EONgIAC0EADwsgBEIANwMQIAQgATcDCCAEIAU2AgQgBEEBOgAAIAQgAkU6AAEgACAFIAEgAxBpQQBIBH8gBC0AAQRAIAQoAgQQBgsgBBAGQQAFIAQLC5sCAQN/IAAtAABBIHFFBEACQCABIQMCQCACIAAiASgCECIABH8gAAUCfyABIAEtAEoiAEEBayAAcjoASiABKAIAIgBBCHEEQCABIABBIHI2AgBBfwwBCyABQgA3AgQgASABKAIsIgA2AhwgASAANgIUIAEgACABKAIwajYCEEEACw0BIAEoAhALIAEoAhQiBWtLBEAgASADIAIgASgCJBEAABoMAgsCfyABLABLQX9KBEAgAiEAA0AgAiAAIgRFDQIaIAMgBEEBayIAai0AAEEKRw0ACyABIAMgBCABKAIkEQAAIARJDQIgAyAEaiEDIAEoAhQhBSACIARrDAELIAILIQAgBSADIAAQCRogASABKAIUIABqNgIUCwsLCxAAIAAoAggQBiAAQQA2AggLWQIBfwF+AkACf0EAIABFDQAaIACtIAGtfiIDpyICIAAgAXJBgIAESQ0AGkF/IAIgA0IgiKcbCyICEAgiAEUNACAAQQRrLQAAQQNxRQ0AIABBACACEBoLIAAL8AEBAn9BfyEBAkAgAC0AKA0AIAAoAiRBA0YEQCAAQQxqBEAgAEEANgIQIABB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DwsCQAJAIAAgASACIAMQhwEiBEUNAEEYEAgiAkUEQCADBEAgA0EANgIEIANBDjYCAAsCQCAEKAIoIgBFBEAgBCkDGCEBDAELIABBADYCKCAEKAIoQgA3AyAgBCAEKQMYIgUgBCkDICIBIAEgBVQbIgE3AxgLIAQpAwggAVYEQANAIAQoAgAgAadBBHRqKAIAEAYgAUIBfCIBIAQpAwhUDQALCyAEKAIAEAYgBCgCBBAGIAQQBgwBCyACQQA2AhQgAiAENgIQIAJBABABNgIMIAJBADYCCCACQgA3AgACf0E4EAgiAEUEQCADBEAgA0EANgIEIANBDjYCAAtBAAwBCyAAQQA2AgggAEIANwMAIABCADcDICAAQoCAgIAQNwIsIABBADoAKCAAQQA2AhQgAEIANwIMIABBADsBNCAAIAI2AgggAEEjNgIEIABCPyACQQBCAEEOQSMRDAAiASABQgBTGzcDGCAACyIADQEgAigCECIDBEACQCADKAIoIgBFBEAgAykDGCEBDAELIABBADYCKCADKAIoQgA3AyAgAyADKQMYIgUgAykDICIBIAEgBVQbIgE3AxgLIAMpAwggAVYEQANAIAMoAgAgAadBBHRqKAIAEAYgAUIBfCIBIAMpAwhUDQALCyADKAIAEAYgAygCBBAGIAMQBgsgAhAGC0EAIQALIAALFAAgABBBIAAoAgAQICAAKAIEECALiwwBBn8gACABaiEFAkACQCAAKAIEIgJBAXENACACQQNxRQ0BIAAoAgAiAiABaiEBAkAgACACayIAQbycASgCAEcEQCACQf8BTQRAIAAoAggiBCACQQN2IgJBA3RB0JwBakYaIAAoAgwiAyAERw0CQaicAUGonAEoAgBBfiACd3E2AgAMAwsgACgCGCEGAkAgACAAKAIMIgNHBEAgACgCCCICQbicASgCAEkaIAIgAzYCDCADIAI2AggMAQsCQCAAQRRqIgIoAgAiBA0AIABBEGoiAigCACIEDQBBACEDDAELA0AgAiEHIAQiA0EUaiICKAIAIgQNACADQRBqIQIgAygCECIEDQALIAdBADYCAAsgBkUNAgJAIAAgACgCHCIEQQJ0QdieAWoiAigCAEYEQCACIAM2AgAgAw0BQaycAUGsnAEoAgBBfiAEd3E2AgAMBAsgBkEQQRQgBigCECAARhtqIAM2AgAg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ACIIQiCIpyEEIAinIQEMAwsgAUEHTQRAIAAgAmpBAWshByABIAJJBEAgA0EEaiEGA0AgByAAa0EBaiIEIAEgASAESxsiBUEITwRAA0AgACADKQAANwAAIANBCGohAyAAQQhqIQAMAAsACyAFQQRJBH8gAwUgACADKAAANgAAIAVBBGshBSAAQQRqIQAgBgshBCAFQQJPBEAgACAELwAAOwAAIAVBAmshBSAEQQJqIQQgAEECaiEACyAFQQFGBEAgACAELQAAOgAAIABBAWohAAsgAiABayICIAFLDQALIAJFDQULAkAgByAAa0EBaiIBIAIgASACSRsiAkEISQ0AIAJBCGsiBEEDdkEBakEHcSIBBEADQCAAIAMpAAA3AAAgAkEIayECIANBCGohAyAAQQhqIQAgAUEBayIBDQALCyAEQThJDQADQCAAIAMpAAA3AAAgACADKQAINwAIIAAgAykAEDcAECAAIAMpABg3ABggACADKQAgNwAgIAAgAykAKDcAKCAAIAMpADA3ADAgACADKQA4NwA4IANBQGshAyAAQUBrIQAgAkFAaiICQQdLDQALCyACQQRPBEAgACADKAAANgAAIAJBBGshAiADQQRqIQMgAEEEaiEACyACQQJPBEAgACADLwAAOwAAIAJBAmshAiADQQJqIQMgAEECaiEACyACQQFHDQQgACADLQAAOgAAIABBAWoPCyAAIAMpAAA3AAAgACACQQFrIgFBB3FBAWoiAmohACABQQhJDQMgAiADaiEDIAFBA3YiAkEBayEEIAJBB3EiAQRAA0AgACADKQAANwAAIAJBAWshAiADQQhqIQMgAEEIaiEAIAFBAWsiAQ0ACwsgBEEHSQ0DA0AgACADKQAANwAAIAAgAykACDcACCAAIAMpABA3ABAgACADKQAYNwAYIAAgAykAIDcAICAAIAMpACg3ACggACADKQAwNwAwIAAgAykAODcAOCADQUBrIQMgAEFAayEAIAJBCGsiAg0ACwwDCyADLQAAQYGChAhsCyIBIQQLIAJBB3EhBgJAIAJBeHEiAkUNACABrSAErUIghoQhCCACQQhrIgRBA3ZBAWpBB3EiAQRAA0AgACAINwAAIAJBCGshAiAAQQhqIQAgAUEBayIBDQALCyAEQThJDQADQCAAIAg3ADggACAINwAwIAAgCDcAKCAAIAg3ACAgACAINwAYIAAgCDcAECAAIAg3AAggACAINwAAIABBQGshACACQUBqIgINAAsLIAZFDQAgACADIAYQCSAGaiEACyAADwsgACADLQABOgABIAJBAkYEQCAAQQJqDwsgACADLQACOgACIAJBA0YEQCAAQQNqDwsgACADLQADOgADIAJBBEYEQCAAQQRqDwsgACADLQAEOgAEIAJBBUYEQCAAQQVqDwsgACADLQAFOgAFIAJBBkYEQCAAQQZqDwsgACADLQAGOgAGIABBB2oLAwABC2wBA38CQCABKAIAIgNBB0sNACADIAIoAgBPDQAgACADayEEA0AgACAEKQAANwAAIAIgAigCACABKAIAIgVrNgIAIAEgASgCAEEBdCIDNgIAIAAgBWohACADQQdLDQEgAyACKAIASQ0ACwsgAAu8AgEBfwJAIAMgAGtBAWoiAyACIAIgA0sbIgJBCEkNACACQQhrIgRBA3ZBAWpBB3EiAwRAA0AgACABKQAANwAAIAJBCGshAiABQQhqIQEgAEEIaiEAIANBAWsiAw0ACwsgBEE4SQ0AA0AgACABKQAANwAAIAAgASkACDcACCAAIAEpABA3ABAgACABKQAYNwAYIAAgASkAIDcAICAAIAEpACg3ACggACABKQAwNwAwIAAgASkAODcAOCABQUBrIQEgAEFAayEAIAJBQGoiAkEHSw0ACwsgAkEETwRAIAAgASgAADYAACACQQRrIQIgAUEEaiEBIABBBGohAAsgAkECTwRAIAAgAS8AADsAACACQQJrIQIgAUECaiEBIABBAmohAAsgAkEBRgR/IAAgAS0AADoAACAAQQFqBSAACwvnAQECfyAAIAEpAAA3AAAgACACQQFrIgJBB3FBAWoiA2ohAAJAIAJBCEkNACABIANqIQEgAkEDdiICQQFrIQQgAkEHcSIDBEADQCAAIAEpAAA3AAAgAkEBayECIAFBCGohASAAQQhqIQAgA0EBayIDDQALCyAEQQdJDQADQCAAIAEpAAA3AAAgACABKQAINwAIIAAgASkAEDcAECAAIAEpABg3ABggACABKQAgNwAgIAAgASkAKDcAKCAAIAEpADA3ADAgACABKQA4NwA4IAFBQGshASAAQUBrIQAgAkEIayICDQALCyAAC/wFAQR/IABB//8DcSEDIABBEHYhBEEBIQAgAkEB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ADYCBCACQQ42AgALDAELIANBARB0IAMgARBmEBIgAyAFIAQoAgwQLAJ/IAMtAABFBEAgAgRAIAJBADYCBCACQRQ2AgALQQAMAQsgACADLQAABH4gAykDEAVCAAunQf//A3EgAygCBBBICyEGIAMQBwsgBEEQaiQAIAYL4AECAn8BfkEwEAgiAkUEQCABBEAgAUEANgIEIAFBDjYCAAtBAA8LIAJCADcDCCACQQA2AgAgAkIANwMQIAJCADcDGCACQgA3AyAgAkIANwAlIABQBEAgAg8LAkAgAEL/////AFYNACAAp0EEdBAIIgNFDQAgAiADNgIAQQAhAUIBIQQDQCADIAFBBHRqIgFCADcCACABQgA3AAUgACAEUgRAIASnIQEgBEIBfCEEDAELCyACIAA3AwggAiAANwMQIAIPCyABBEAgAUEANgIEIAFBDjYCAAtBABAQIAIQBkEAC+4BAgN/AX4jAEEQayIEJAACQCAEQQxqQgQQGCIDRQRAQX8hAgwBCwJAIAEEQCACQYAGcSEFA0ACQCAFIAEoAgRxRQ0AAkAgAykDCEIAVARAIANBADoAAAwBCyADQgA3AxAgA0EBOgAACyADIAEvAQgQDSADIAEvAQoQDSADLQAARQRAIABBCGoiAARAIABBADYCBCAAQRQ2AgALQX8hAgwEC0F/IQIgACAEQQxqQgQQHEEASA0DIAEzAQoiBlANACAAIAEoAgwgBhAcQQBIDQMLIAEoAgAiAQ0ACwtBACECCyADEAcLIARBEGokACACCzwBAX8gAARAIAFBgAZxIQEDQCABIAAoAgRxBEAgAiAALwEKakEEaiECCyAAKAIAIgANAAsLIAJB//8DcQucAQEDfyAARQRAQQAPCyAAIQMDQAJ/AkACQCAALwEIIgFB9OABTQRAIAFBAUYNASABQfXGAUYNAQwCCyABQYGyAkYNACABQfXgAUcNAQsgACgCACEBIABBADYCACAAKAIMEAYgABAGIAEgAyAAIANGGyEDAkAgAkUEQEEAIQIMAQsgAiABNgIACyABDAELIAAiAigCAAsiAA0ACyADC7IEAgV/AX4CQAJAAkAgACABrRAYIgEEQCABLQAADQFBACEADAILIAQEQCAEQQA2AgQgBEEONgIAC0EADwtBACEAA0AgAS0AAAR+IAEpAwggASkDEH0FQgALQgRUDQEgARALIQcgASABEAsiBq0QEyIIRQRAQQAhAiAEBEAgBEEANgIEIARBFTYCAAsgARAHIABFDQMDQCAAKAIAIQEgACgCDBAGIAAQBiABIgANAAsMAwsCQAJAQRAQCCIFBEAgBSAGOwEKIAUgBzsBCCAFIAI2AgQgBUEANgIAIAZFDQEgBSAIIAYQZyIGNgIMIAYNAiAFEAYLQQAhAiAEBEAgBEEANgIEIARBDjYCAAsgARAHIABFDQQDQCAAKAIAIQEgACgCDBAGIAAQBiABIgANAAsMBAsgBUEANgIMCwJAIABFBEAgBSEADAELIAkgBTYCAAsgBSEJIAEtAAANAAsLAkAgAS0AAAR/IAEpAxAgASkDCFEFQQALDQAgASABLQAABH4gASkDCCABKQMQfQVCAAsiCkL/////D4MQEyECAkAgCqciBUEDSw0AIAJFDQAgAkHBFCAFEDxFDQELQQAhAiAEBEAgBEEANgIEIARBFTYCAAsgARAHIABFDQEDQCAAKAIAIQEgACgCDBAGIAAQBiABIgANAAsMAQsgARAHIAMEQCADIAA2AgBBAQ8LQQEhAiAARQ0AA0AgACgCACEBIAAoAgwQBiAAEAYgASIADQALCyACC74BAQV/IAAEfyAAIQIDQCACIgQoAgAiAg0ACyABBEADQCABIgMvAQghBiADKAIAIQEgACECAkACQANAAkAgAi8BCCAGRw0AIAIvAQoiBSADLwEKRw0AIAVFDQIgAigCDCADKAIMIAUQPEUNAgsgAigCACICDQALIANBADYCACAEIAM2AgAgAyEEDAELIAIgAigCBCADKAIEQYAGcXI2AgQgA0EANgIAIAMoAgwQBiADEAYLIAENAAsLIAAFIAELC1UCAn4BfwJAAkAgAC0AAEUNACAAKQMQIgJCAXwiAyACVA0AIAMgACkDCFgNAQsgAEEAOgAADwsgACgCBCIERQRADwsgACADNwMQIAQgAqdqIAE6AAALWgICfgF/An8CQAJAIAAtAABFDQAgACkDECIBQgF8IgIgAVQNACACIAApAwhYDQELIABBADoAAEEADAELQQAgACgCBCIDRQ0AGiAAIAI3AxAgAyABp2otAAALC94BAQN/IAEgACkDMFoEQCAAQQhqBEAgAEEANgIMIABBEjYCCAtBfw8LIABBCGohAiAALQAYQQJxBEAg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DAELIAFBGU4EQCAAIAAoAhAiAUEBajYCECABIAAoAgRqIAApA7gtIgI8AAAgACAAKAIQIgFBAWo2AhAgASAAKAIEaiACQgiIPAAAIAAgACgCECIBQQFqNgIQIAEgACgCBGogAkIQiDwAACAAIAAoAhAiAUEBajYCECABIAAoAgRqIAJCGIg8AAAgACAAQbwtajUCADcDuC0gACAAKALALUEgayIBNgLALQsgAUEJTgRAIAAgACgCECIBQQFqNgIQIAEgACgCBGogACkDuC0iAjwAACAAIAAoAhAiAUEBajYCECABIAAoAgRqIAJCCIg8AAAgACAAKQO4LUIQiDcDuC0gACAAKALALUEQayIBNgLALQsgAUEBSA0AIAAgACgCECIBQQFqNgIQIAEgACgCBGogACkDuC08AAALIABBADYCwC0gAEIANwO4LQvwBAEDfyAAQYgBaiECA0AgAiABQQJ0IgNqQQA7AQAgAiADQQRyakEAOwEAIAFBAmoiAUGeAkcNAAsgAEEAOwHwFCAAQQA7AfwSIABBuBVqQQA7AQAgAEG0FWpBADsBACAAQbAVakEAOwEAIABBrBVqQQA7AQAgAEGoFWpBADsBACAAQaQVakEAOwEAIABBoBVqQQA7AQAgAEGcFWpBADsBACAAQZgVakEAOwEAIABBlBVqQQA7AQAgAEGQFWpBADsBACAAQYwVakEAOwEAIABBiBVqQQA7AQAgAEGEFWpBADsBACAAQYAVakEAOwEAIABB/BRqQQA7AQAgAEH4FGpBADsBACAAQfQUakEAOwEAIABB8BNqQQA7AQAgAEHsE2pBADsBACAAQegTakEAOwEAIABB5BNqQQA7AQAgAEHgE2pBADsBACAAQdwTakEAOwEAIABB2BNqQQA7AQAgAEHUE2pBADsBACAAQdATakEAOwEAIABBzBNqQQA7AQAgAEHIE2pBADsBACAAQcQTakEAOwEAIABBwBNqQQA7AQAgAEG8E2pBADsBACAAQbgTakEAOwEAIABBtBNqQQA7AQAgAEGwE2pBADsBACAAQawTakEAOwEAIABBqBNqQQA7AQAgAEGkE2pBADsBACAAQaATakEAOwEAIABBnBNqQQA7AQAgAEGYE2pBADsBACAAQZQTakEAOwEAIABBkBNqQQA7AQAgAEGME2pBADsBACAAQYgTakEAOwEA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AAwFCyABLQAPDQQgASgCrEAgASgCqEAoAggRAgCsIQUMBAsgA0IIWgR+IAIgASgCADYCACACIAEoAgQ2AgRCCAVCfwshBQwDCyABRQ0CIAEoAqxAIAEoAqhAKAIEEQQAIAEQLyABEAYMAgsgB0F/NgIAQRAgBxAkQj+EIQUMAQsgAQRAIAFBADYCBCABQRQ2AgALQn8hBQsgB0EQaiQAIAULYwBByAAQCCIARQRAQfibASgCACEBIAIEQCACIAE2AgQgAkEBNgIACyAADwsgAEEAOgAMIABBADoABCAAIAI2AgAgAEEANgI4IABCADcDMCAAIAFBCSABQQFrQQlJGzYCCCAAC0gBAX8gAEIANwIEIAAgATYCAAJAIAFBAEgNAEGwEygCACABTA0AIAFBAnRBwBNqKAIAQQFHDQBB+JsBKAIAIQILIAAgAjYCBAvuhwECJH8BfiACKQMAIScgACABNgIcIAAgJ0L/////DyAnQv////8PVBs+AiAgAEEQaiEKAn8gAC0ABARAAn8gAC0ADEECdCENQX4hAQJAAkACQCAKRQ0AIAooAiBFDQAgCigCJEUNACAKKAIcIgNFDQAgAygCACAKRw0AAkACQCADKAIgIgVBOWsOOQECAgICAgICAgICAgECAgIBAgICAgICAgICAgICAgICAgIBAgICAgICAgICAgIBAgICAgICAgICAQALIAVBmgVGDQAgBUEqRw0BCyANQQVLDQACQAJAIAooAgxFDQAgCigCBCIEBEAgCigCAEUNAQsgBUGaBUcNASANQQRGDQELIApBkPEAKAIANgIYQX4MBAsgCigCEEUNASADKAIkIQEgAyANNgIkAkAgAygCEARAIAMQFAJAIAooAhAiBSADKAIQIgkgBSAJSRsiAUUNACAKKAIMIAMoAgggARAJGiAKIAooAgwgAWo2AgwgAyADKAIIIAFqNgIIIAogCigCFCABajYCFCAKIAooAhAgAWsiBTYCECADIAMoAhAgAWsiCTYCECAJDQAgAyADKAIENgIIQQAhCQsgBQRAIAMoAiAhBQwCCwwECyAEDQAgDUEBdEF3QQAgDUEESxtqIAFBAXRBd0EAIAFBBEobakoNACANQQRGDQAMAgsCQAJAAkACQAJAIAVBKkcEQCAFQZoFRw0BIAooAgRFDQMMBwsgAygCFEUEQCADQfEANgIgDAILIAMoAjRBDHRBgPABayEBAkAgAygCfEECTg0AIAMoAngiBEEBTA0AIARBBUwEQCABQcAAciEBDAELQYABQcABIARBBkYbIAFyIQELIAMgCUEBajYCECADKAIEIAlqIAFBIHIgASADKAJkGyIBQQh2OgAAIAMgAygCECIEQQFqNgIQIAQgAygCBGogAUEfcCABckEfczoAACADKAJkBEAgAyAKKAIwEF0LIApBATYCMCADQfEANgIgIAoQDCADKAIQDQcgAygCICEFCwJAAkACQAJAIAVBOUYEfyADKAIAQQA2AjAgAyADKAIQIgFBAWo2AhAgASADKAIEakEfOgAAIAMgAygCECIBQQFqNgIQIAEgAygCBGpBiwE6AAAgAyADKAIQIgFBAWo2AhAgASADKAIEakEIOgAAAkAgAygCHCIBRQRAIANBABA0IAMgAygCECIBQQFqNgIQIAEgAygCBGpBADoAAEECIQEgAygCeCIEQQlHBEBBBCAEQQJIQQJ0IAMoAnxBAUobIQELIAMgAygCECIEQQFqNgIQIAQgAygCBGogAToAACADIAMoAhAiAUEBajYCECABIAMoAgRqQQM6AAAgA0HxADYCICAKEAwgAygCEEUNAQwNCyABKAIkIQQgASgCHCEFIAEoAhAhByABKAIsIQkgASgCACELIAMgAygCECIIQQFqNgIQQQIhASAIIAMoAgRqIAlBAEdBAXQgC0EAR3IgB0EAR0ECdHIgBUEAR0EDdHIgBEEAR0EEdHI6AAAgAyADKAIcKAIEEDQgAygCeCIEQQlHBEBBBCAEQQJIQQJ0IAMoAnxBAUobIQELIAMgAygCECIEQQFqNgIQIAQgAygCBGogAToAACADKAIcKAIMIQEgAyADKAIQIgRBAWo2AhAgBCADKAIEaiABOgAAIAMoAhwiASgCEAR/IAEoAhQhASADIAMoAhAiBEEBajYCECAEIAMoAgRqIAE6AAAgAyADKAIQIgRBAWo2AhAgBCADKAIEaiABQQh2OgAAIAMoAhwFIAELKAIsBEAgCgJ/IAooAjAhASADKAIQIQRBACADKAIEIgVFDQAaIAEgBSAErUHMmAEoAgARAwALNgIwCyADQcUANgIgIANBADYCGAwCCyADKAIgBSAFC0HFAGsOIwAEBAQBBAQEBAQEBAQEBAQEBAQEBAQCBAQEBAQEBAQEBAQDBAsgAygCHCIEKAIQIgUEQCADKAIMIgkgAygCECIBIAQvARQgAygCGCIHayIEakkEQANAIAMoAgQgAWogBSAHaiAJIAFrIgkQCRogAyADKAIMIgU2AhACQCADKAIcKAIsRQ0AIAEgBU8NACAKAn8gCigCMCEHQQAgAygCBCABaiILRQ0AGiAHIAsgBSABa61BzJgBKAIAEQMACzYCMAsgAyADKAIYIAlqNgIYIAooAhwiARAUAkAgCigCECIFIAEoAhAiByAFIAdJGyIFRQ0AIAooAgwgASgCCCAFEAkaIAogCigCDCAFajYCDCABIAEoAgggBWo2AgggCiAKKAIUIAVqNgIUIAogCigCECAFazYCECABIAEoAhAgBWsiBTYCECAFDQAgASABKAIENgIICyADKAIQDQwgAygCGCEHIAMoAhwoAhAhBUEAIQEgBCAJayIEIAMoAgwiCUsNAAsLIAMoAgQgAWogBSAHaiAEEAkaIAMgAygCECAEaiIENgIQAkAgAygCHCgCLEUNACABIARPDQAgCgJ/IAooAjAhBUEAIAMoAgQgAWoiB0UNABogBSAHIAQgAWutQcyYASgCABEDAAs2AjALIANBADYCGAsgA0HJADYCIAsgAygCHCgCHARAIAMoAhAiASEEA0ACQCABIAMoAgxHDQACQCADKAIcKAIsRQ0AIAEgBE0NACAKAn8gCigCMCEFQQAgAygCBCAEaiIHRQ0AGiAFIAcgASAEa61BzJgBKAIAEQMACzYCMAsgCigCHCIBEBQCQCAKKAIQIgQgASgCECIFIAQgBUkbIgRFDQAgCigCDCABKAIIIAQQCRogCiAKKAIMIARqNgIMIAEgASgCCCAEajYCCCAKIAooAhQgBGo2AhQgCiAKKAIQIARrNgIQIAEgASgCECAEayIENgIQIAQNACABIAEoAgQ2AggLQQAhAUEAIQQgAygCEEUNAAwLCyADKAIcKAIcIQUgAyADKAIYIgdBAWo2AhggBSAHai0AACEFIAMgAUEBajYCECADKAIEIAFqIAU6AAAgBQRAIAMoAhAhAQwBCwsCQCADKAIcKAIsRQ0AIAMoAhAiASAETQ0AIAoCfyAKKAIwIQVBACADKAIEIARqIgdFDQAaIAUgByABIARrrUHMmAEoAgARAwALNgIwCyADQQA2AhgLIANB2wA2AiALAkAgAygCHCgCJEUNACADKAIQIgEhBANAAkAgASADKAIMRw0AAkAgAygCHCgCLEUNACABIARNDQAgCgJ/IAooAjAhBUEAIAMoAgQgBGoiB0UNABogBSAHIAEgBGutQcyYASgCABEDAAs2AjALIAooAhwiARAUAkAgCigCECIEIAEoAhAiBSAEIAVJGyIERQ0AIAooAgwgASgCCCAEEAkaIAogCigCDCAEajYCDCABIAEoAgggBGo2AgggCiAKKAIUIARqNgIUIAogCigCECAEazYCECABIAEoAhAgBGsiBDYCECAEDQAgASABKAIENgIIC0EAIQFBACEEIAMoAhBFDQAMCgsgAygCHCgCJCEFIAMgAygCGCIHQQFqNgIYIAUgB2otAAAhBSADIAFBAWo2AhAgAygCBCABaiAFOgAAIAUEQCADKAIQIQEMAQsLIAMoAhwoAixFDQAgAygCECIBIARNDQAgCgJ/IAooAjAhBUEAIAMoAgQgBGoiB0UNABogBSAHIAEgBGutQcyYASgCABEDAAs2AjALIANB5wA2AiALAkAgAygCHCgCLARAIAMoAgwgAygCECIBQQJqSQRAIAoQDCADKAIQDQJBACEBCyAKKAIwIQQgAyABQQFqNgIQIAMoAgQgAWogBDoAACADIAMoAhAiAUEBajYCECABIAMoAgRqIARBCHY6AAAgAygCAEEANgIwCyADQfEANgIgIAoQDCADKAIQRQ0BDAcLDAYLIAooAgQNAQsgAygCPA0AIA1FDQEgAygCIEGaBUYNAQsCfyADKAJ4IgFFBEAgAyANEFwMAQsCQAJAAkAgAygCfEECaw4CAAECCwJ/AkADQAJAIAMoAjwNACADECkgAygCPA0AIA0NAkEADAMLIAMoAkggAygCZGotAAAhASADIAMoApQtIgRBAWo2ApQtIAQgAygCkC1qQQA6AAAgAyADKAKULSIEQQFqNgKULSAEIAMoApAtakEAOgAAIAMgAygClC0iBEEBajYClC0gBCADKAKQLWogAToAACADIAFBAnRqIgEgAS8BiAFBAWo7AYgBIAMgAygCPEEBazYCPCADIAMoAmRBAWoiBDYCZCADKAKULSADKAKYLUcNACADIAMoAlQiAUEATgR/IAMoAkggAWoFQQALIAQgAWtBABAPIAMgAygCZDYCVCADKAIAIgEoAhwiBBAUAkAgASgCECIFIAQoAhAiByAFIAdJGyIFRQ0AIAEoAgwgBCgCCCAFEAkaIAEgASgCDCAFajYCDCAEIAQoAgggBWo2AgggASABKAIUIAVqNgIUIAEgASgCECAFazYCECAEIAQoAhAgBWsiATYCECABDQAgBCAEKAIENgIICyADKAIAKAIQDQALQQAMAQsgA0EANgKoLSANQQRGBEAgAyADKAJUIgFBAE4EfyADKAJIIAFqBUEACyADKAJkIAFrQQEQDyADIAMoAmQ2AlQgAygCACIBKAIcIgQQFAJAIAEoAhAiBSAEKAIQIgcgBSAHSRsiBUUNACABKAIMIAQoAgggBRAJGiABIAEoAgwgBWo2AgwgBCAEKAIIIAVqNgIIIAEgASgCFCAFajYCFCABIAEoAhAgBWs2AhAgBCAEKAIQIAVrIgE2AhAgAQ0AIAQgBCgCBDYCCAtBA0ECIAMoAgAoAhAbDAELAkAgAygClC1FDQAgAyADKAJUIgFBAE4EfyADKAJIIAFqBUEACyADKAJkIAFrQQAQDyADIAMoAmQ2AlQgAygCACIBKAIcIgQQFAJAIAEoAhAiBSAEKAIQIgcgBSAHSRsiBUUNACABKAIMIAQoAgggBRAJGiABIAEoAgwgBWo2AgwgBCAEKAIIIAVqNgIIIAEgASgCFCAFajYCFCABIAEoAhAgBWs2AhAgBCAEKAIQIAVrIgE2AhAgAQ0AIAQgBCgCBDYCCAsgAygCACgCEA0AQQAMAQtBAQsMAgsCfwJAA0ACQAJAAkACQCADKAI8IghBggJLDQAgAxApAkAgAygCPCIIQYICSw0AIA0NAEEADAcLIAhFDQUgCEECSw0AIAMoAmQhCwwBCyADKAJkIgtFBEBBACELDAELIAMoAkggC2oiDEEBayIBLQAAIgkgDC0AAEcNACAJIAEtAAJHDQAgCSABLQADRw0AIAxBggJqIQ5BfyEBAkACQAJAAkACQAJAA0AgASAMaiIFLQAEIAlGBEAgCSAFLQAFRw0CIAkgBS0ABkcNAyAJIAUtAAdHDQQgCSAMIAFBCGoiBGoiBy0AAEcNByAJIAUtAAlHDQUgCSAFLQAKRw0GIAkgBUELaiIHLQAARw0HIAFB9wFIIQUgBCEBIAUNAQwHCwsgBUEEaiEHDAULIAVBBWohBwwECyAFQQZqIQcMAwsgBUEHaiEHDAILIAVBCWohBwwBCyAFQQpqIQcLIAggByAOa0GCAmoiASABIAhLGyIBQQJLDQELIAMoAkggC2otAAAhASADIAMoApQtIgRBAWo2ApQtIAQgAygCkC1qQQA6AAAgAyADKAKULSIEQQFqNgKULSAEIAMoApAtakEAOgAAIAMgAygClC0iBEEBajYClC0gBCADKAKQLWogAToAACADIAFBAnRqIgEgAS8BiAFBAWo7AYgBIAMgAygCPEEBazYCPCADIAMoAmRBAWoiCzYCZAwBCyADIAMoApQtIgRBAWo2ApQtIAQgAygCkC1qQQE6AAAgAyADKAKULSIEQQFqNgKULSAEIAMoApAtakEAOgAAIAMgAygClC0iBEEBajYClC0gBCADKAKQLWogAUEDazoAACADIAMoAqQtQQFqNgKkLSABQc3pAGotAABBAnQgA2pBjAlqIgQgBC8BAEEBajsBACADQdDlAC0AAEECdGpB/BJqIgQgBC8BAEEBajsBACADIAMoAjwgAWs2AjwgAyADKAJkIAFqIgs2AmQLIAMoApQtIAMoApgtRw0AIAMgAygCVCIBQQBOBH8gAygCSCABagVBAAsgCyABa0EAEA8gAyADKAJkNgJUIAMoAgAiASgCHCIEEBQCQCABKAIQIgUgBCgCECIHIAUgB0kbIgVFDQAgASgCDCAEKAIIIAUQCRogASABKAIMIAVqNgIMIAQgBCgCCCAFajYCCCABIAEoAhQgBWo2AhQgASABKAIQIAVrNgIQIAQgBCgCECAFayIBNgIQIAENACAEIAQoAgQ2AggLIAMoAgAoAhANAAtBAAwBCyADQQA2AqgtIA1BBEYEQCADIAMoAlQiAUEATgR/IAMoAkggAWoFQQALIAMoAmQgAWtBARAPIAMgAygCZDYCVCADKAIAIgEoAhwiBBAUAkAgASgCECIFIAQoAhAiByAFIAdJGyIFRQ0AIAEoAgwgBCgCCCAFEAkaIAEgASgCDCAFajYCDCAEIAQoAgggBWo2AgggASABKAIUIAVqNgIUIAEgASgCECAFazYCECAEIAQoAhAgBWsiATYCECABDQAgBCAEKAIENgIIC0EDQQIgAygCACgCEBsMAQsCQCADKAKULUUNACADIAMoAlQiAUEATgR/IAMoAkggAWoFQQALIAMoAmQgAWtB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ASABKAIodCIFIAEoAtA3akEBIAMoAiARAAAiAzYCOCADRQ0CIAMgBWpBACABKALQNxAaCyABKAIsIgVFBEAgAUIANwIwIAFBASABKAIodCIFNgIsCyAWIA5rIgMgBU8EQCABKAI4IBEgBWsgBRAJGiABQQA2AjQgASABKAIsNgIwDAELIAEoAjQiDSABKAI4aiARIANrIAMgBSANayIFIAMgBUkbIgUQCRogAyAFayIDBEAgASgCOCARIANrIAMQCRogASADNgI0IAEgASgCLDYCMAwBCyABQQAgASgCNCAFaiIDIAMgASgCLCINRhs2AjQgASgCMCIDIA1PDQAgASADIAVqNgIwCyAKIB8gCigCBGsiBSAKKAIIajYCCCAKIBYgCigCEGsiASAKKAIUajYCFCAGIAYoAiAgAWo2AiACQCAGLQAMQQRxRQ0AIAFFDQAgBgJ/IAYoAhQEQAJ/IAYoAhwhA0EAIAooAgwgAWsiDUUNABogAyANIAGtQcyYASgCABEDAAsMAQsgBigCHCAKKAIMIAFrIAFByJgBKAIAEQAACyIDNgIcIAogAzYCMAsgCiAGKAJAIAYoAghBAEdBBnRqIAYoAgQiA0G//gBGQQd0akGAAiADQcL+AEZBCHQgA0HH/gBGG2o2AiwgBCAEQXsgBBsgASAFchshFwwCCyAGQdL+ADYCBAtBfCEXCyAUQRBqJAAgFwshASACIAIpAwAgADUCIH03AwACQAJAAkACQCABQQVqDgcBAgICAgMAAgtBAQ8LIAAoAhQNAEEDDwsgACgCACIABEAgACABNgIEIABBDTYCAAtBAiEBCyABCwkAIABBAToADAtEAAJAIAJC/////w9YBEAgACgCFEUNAQsgACgCACIABEAgAEEANgIEIABBEjYCAAtBAA8LIAAgATYCECAAIAI+AhRBAQu6AQEEfyAAQRBqIQECfyAALQAEBEAgARBeDAELQX4hAwJAIAFFDQAgASgCIEUNACABKAIkIgRFDQAgASgCHCICRQ0AIAIoAgAgAUcNACACKAIEQbT+AGtBH0sNACACKAI4IgMEQCABKAIoIAMgBBEGACABKAIkIQQgASgCHCECCyABKAIoIAIgBBEGAEEAIQMgAUEANgIcCyADCyIBBEAgACgCACIABEAgACABNgIEIABBDTYCAAsLIAFFC5gMAQZ/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IAEQBiAABEAgAEEANgIEIABBDjYCAAsLIABBADYCFAwUCyADQgA3AwAgACABNgIUIAFBQGtCADcDACABQgA3AzgMFAsCQAJAIAJQBEBByAAQCCIDRQ0UIANCADcDACADQgA3AzAgA0EANgIoIANCADcDICADQgA3AxggA0IANwMQIANCADcDCCADQgA3AzggA0EIEAgiATYCBCABDQEgAxAGIAAEQCAAQQA2AgQgAEEONgIACwwUCyACIAAoAhAiASkDMFYEQCAABEAgAEEANgIEIABBEjYCAAsMFAsgASgCKARAIAAEQCAAQQA2AgQgAEEdNgIACwwUCyABKAIEIQMCQCABKQMIIgZCAX0iB1ANAANAAkAgAiADIAcgBH1CAYggBHwiBadBA3RqKQMAVARAIAVCAX0hBwwBCyAFIAZRBEAgBiEFDAMLIAMgBUIBfCIEp0EDdGopAwAgAlYNAgsgBCEFIAQgB1QNAAsLAkAgAiADIAWnIgpBA3RqKQMAfSIEUEUEQCABKAIAIgMgCkEEdGopAwghBwwBCyABKAIAIgMgBUIBfSIFp0EEdGopAwgiByEECyACIAcgBH1UBEAgAARAIABBADYCBCAAQRw2AgALDBQLIAMgBUIBfCIFQQAgABCHASIDRQ0TIAMoAgAgAygCCCIKQQR0akEIayAENwMAIAMoAgQgCkEDdGogAjcDACADIAI3AzAgAyABKQMYIgYgAykDCCIEQgF9IgcgBiAHVBs3AxggASADNgIoIAMgATYCKCABIAQ3AyAgAyAFNwMgDAELIAFCADcDAAsgACADNgIUIAMgBDcDQCADIAI3AzhCACEEDBMLIAAoAhAiAQRAAkAgASgCKCIDRQRAIAEpAxghAgwBCyADQQA2AiggASgCKEIANwMgIAEgASkDGCICIAEpAyAiBSACIAVWGyICNwMYCyABKQMIIAJWBEADQCABKAIAIAKnQQR0aigCABAGIAJCAXwiAiABKQMIVA0ACwsgASgCABAGIAEoAgQQBiABEAYLIAAoAhQhASAAQQA2AhQgACABNgIQDBILIAJCCFoEfiABIAAoAgA2AgAgASAAKAIENgIEQggFQn8LIQQMEQsgACgCECIBBEACQCABKAIoIgNFBEAgASkDGCECDAELIANBADYCKCABKAIoQgA3AyAgASABKQMYIgIgASkDICIFIAIgBVYbIgI3AxgLIAEpAwggAlYEQANAIAEoAgAgAqdBBHRqKAIAEAYgAkIBfCICIAEpAwhUDQALCyABKAIAEAYgASgCBBAGIAEQBgsgACgCFCIBBEACQCABKAIoIgNFBEAgASkDGCECDAELIANBADYCKCABKAIoQgA3AyAgASABKQMYIgIgASkDICIFIAIgBVYbIgI3AxgLIAEpAwggAlYEQANAIAEoAgAgAqdBBHRqKAIAEAYgAkIBfCICIAEpAwhUDQALCyABKAIAEAYgASgCBBAGIAEQBgsgABAGDBALIAAoAhAiAEIANwM4IABBQGtCADcDAAwPCyACQn9XBEAgAARAIABBADYCBCAAQRI2AgALDA4LIAIgACgCECIDKQMwIAMpAzgiBn0iBSACIAVUGyIFUA0OIAEgAykDQCIHpyIAQQR0IgEgAygCAGoiCigCACAGIAMoAgQgAEEDdGopAwB9IgKnaiAFIAopAwggAn0iBiAFIAZUGyIEpxAJIQogByAEIAMoAgAiACABaikDCCACfVGtfCECIAUgBlYEQANAIAogBKdqIAAgAqdBBHQiAWoiACgCACAFIAR9IgYgACkDCCIHIAYgB1QbIganEAkaIAIgBiADKAIAIgAgAWopAwhRrXwhAiAFIAQgBnwiBFYNAAsLIAMgAjcDQCADIAMpAzggBHw3AzgMDgtCfyEEQcgAEAgiA0UNDSADQgA3AwAgA0IANwMwIANBADYCKCADQgA3AyAgA0IANwMYIANCADcDECADQgA3AwggA0IANwM4IANBCBAIIgE2AgQgAUUEQCADEAYgAARAIABBADYCBCAAQQ42AgALDA4LIAFCADcDACAAKAIQIgEEQAJAIAEoAigiCkUEQCABKQMYIQQMAQsgCkEANgIoIAEoAihCADcDICABIAEpAxgiAiABKQMgIgUgAiAFVhsiBDcDGAsgASkDCCAEVgRAA0AgASgCACAEp0EEdGooAgAQBiAEQgF8IgQgASkDCFQNAAsLIAEoAgAQBiABKAIEEAYgARAGCyAAIAM2AhBCACEEDA0LIAAoAhQiAQRAAkAgASgCKCIDRQRAIAEpAxghAgwBCyADQQA2AiggASgCKEIANwMgIAEgASkDGCICIAEpAyAiBSACIAVWGyICNwMYCyABKQMIIAJWBEADQCABKAIAIAKn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cm9yAFRlbGwgZXJyb3IASW50ZXJuYWwgZXJyb3IAU2VlayBlcnJvcgBXcml0ZSBlcnJvcgBmaWxlIGVycm9yAFJlYWQgZXJyb3IAWmxpYiBlcnJvcgBkYXRhIGVycm9yAENSQyBlcnJvcgBpbmNvbXBhdGlibGUgdmVyc2lvbgBpbnZhbGlkIGNvZGUgLS0gbWlzc2luZyBlbmQtb2YtYmxvY2sAaW5jb3JyZWN0IGhlYWRlciBjaGVjawBpbmNvcnJlY3QgbGVuZ3RoIGNoZWNrAGluY29ycmVjdCBkYXRhIGNoZWNrAGludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrAGhlYWRlciBjcmMgbWlzbWF0Y2gAMS4yLjExLnpsaWItbmcAaW52YWxpZCB3aW5kb3cgc2l6ZQBSZWFkLW9ubHkgYXJjaGl2ZQBOb3QgYSB6aXAgYXJjaGl2ZQBSZXNvdXJjZSBzdGlsbCBpbiB1c2UATWFsbG9jIGZhaWx1cmUAaW52YWxpZCBibG9jayB0eXBlAEZhaWx1cmUgdG8gY3JlYXRlIHRlbXBvcmFyeSBmaWxlAENhbid0IG9wZW4gZmlsZQBObyBzdWNoIGZpbGUAUHJlbWF0dXJlIGVuZCBvZiBmaWxlAENhbid0IHJlbW92ZSBmaWxlAGludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZQBpbnZhbGlkIGRpc3RhbmNlIGNvZGUAdW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QAc3RyZWFtIGVuZABDb21wcmVzc2VkIGRhdGEgaW52YWxpZABNdWx0aS1kaXNrIHppcCBhcmNoaXZlcyBub3Qgc3VwcG9ydGVkAE9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkAEVuY3J5cHRpb24gbWV0aG9kIG5vdCBzdXBwb3J0ZWQAQ29tcHJlc3Npb24gbWV0aG9kIG5vdCBzdXBwb3J0ZWQARW50cnkgaGFzIGJlZW4gZGVsZXRlZABDb250YWluaW5nIHppcCBhcmNoaXZlIHdhcyBjbG9zZWQAQ2xvc2luZyB6aXAgYXJjaGl2ZSBmYWlsZWQAUmVuYW1pbmcgdGVtcG9yYXJ5IGZpbGUgZmFpbGVkAEVudHJ5IGhhcyBiZWVuIGNoYW5nZWQATm8gcGFzc3dvcmQg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AQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQeDZAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdjaAAttBAAAAAQABAAIAAQABQAAAAQABAAIAAQABgAAAAQABgAgACAABgAAAAQABAAQABAABwAAAAgAEAAgACAABwAAAAgAEACAAIAABwAAAAgAIACAAAABCAAAACAAgAACAQAECAAAACAAAgECAQAQCABB0NsAC/cJDAAIAIwACABMAAgAzAAIACwACACsAAgAbAAIAOwACAAcAAgAnAAIAFwACADcAAgAPAAIALwACAB8AAgA/AAIAAIACACCAAgAQgAIAMIACAAiAAgAogAIAGIACADiAAgAEgAIAJIACABSAAgA0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJ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IGRvd24ASG9zdCBpcyB1bnJlYWNoYWJsZQBBZGRyZXNzIGluIHVzZQBCcm9rZW4gcGlwZQBJL08gZXJyb3IATm8gc3VjaCBkZXZpY2Ugb3IgYWRkcmVzcwBCbG9jayBkZXZpY2UgcmVxdWlyZWQATm8gc3VjaCBkZXZpY2UATm90IGEgZGlyZWN0b3J5AElzIGEgZGlyZWN0b3J5AFRleHQgZmlsZSBidXN5AEV4ZWMgZm9ybWF0IGVycm9yAEludmFsaWQgYXJndW1lbnQAQXJndW1lbnQgbGlzdCB0b28gbG9uZwBTeW1ib2xpYyBsaW5rIGxvb3AARmlsZW5hbWUgdG9vIGxvbmcAVG9vIG1hbnkgb3BlbiBmaWxlcyBpbiBzeXN0ZW0ATm8gZmlsZSBkZXNjcmlwdG9ycyBhdmFpbGFibGUAQmFkIGZpbGUgZGVzY3JpcHRvcgBObyBjaGlsZCBwcm9jZXNzAEJhZCBhZGRyZXNzAEZpbGUgdG9vIGxhcmdlAFRvbyBtYW55IGxpbmtzAE5vIGxvY2tzIGF2YWlsYWJsZQBSZXNvdXJjZSBkZWFkbG9jayB3b3VsZCBvY2N1cgBTdGF0ZSBub3QgcmVjb3ZlcmFibGUAUHJldmlvdXMgb3duZXIgZGllZABPcGVyYXRpb24gY2FuY2VsZWQARnVuY3Rpb24gbm90IGltcGxlbWVudGVkAE5vIG1lc3NhZ2Ugb2YgZGVzaXJlZCB0eXBlAElkZW50aWZpZXIgcmVtb3ZlZABEZXZpY2Ugbm90IGEgc3RyZWFtAE5vIGRhdGEgYXZhaWxhYmxlAERldmljZSB0aW1lb3V0AE91dCBvZiBzdHJlYW1zIHJlc291cmNlcwBMaW5rIGhhcyBiZWVuIHNldmVyZWQAUHJvdG9jb2wgZXJyb3IAQmFkIG1lc3NhZ2UARmlsZSBkZXNjcmlwdG9yIGluIGJhZCBzdGF0ZQBOb3QgYSBzb2NrZXQARGVzdGluYXRpb24gYWRkcmVzcyByZXF1aXJlZABNZXNzYWdlIHRvbyBsYXJnZQBQcm90b2NvbCB3cm9uZyB0eXBlIGZvciBzb2NrZXQAUHJvdG9jb2wgbm90IGF2YWlsYWJsZQBQcm90b2NvbCBub3Qgc3VwcG9ydGVkAFNvY2tldCB0eXBlIG5vdCBzdXBwb3J0ZWQATm90IHN1cHBvcnRlZABQcm90b2NvbCBmYW1pbHkgbm90IHN1cHBvcnRlZABBZGRyZXNzIGZhbWlseSBub3Qgc3VwcG9ydGVkIGJ5IHByb3RvY29sAEFkZHJlc3Mgbm90IGF2YWlsYWJsZQBOZXR3b3JrIGlzIGRvd24ATmV0d29yayB1bnJlYWNoYWJsZQBDb25uZWN0aW9uIHJlc2V0IGJ5IG5ldHdvcmsAQ29ubmVjdGlvbiBhYm9ydGVkAE5vIGJ1ZmZlciBzcGFjZSBhdmFpbGFibGUAU29ja2V0IGlzIGNvbm5lY3RlZABTb2NrZXQgbm90IGNvbm5lY3RlZABDYW5ub3Qgc2VuZCBhZnRlciBzb2NrZXQgc2h1dGRvd24AT3BlcmF0aW9uIGFscmVhZHkgaW4gcHJvZ3Jlc3MAT3BlcmF0aW9uIGluIHByb2dyZXNzAFN0YWxlIGZpbGUgaGFuZGxlAFJlbW90ZSBJL08gZXJyb3IAUXVvdGEgZXhjZWVkZWQATm8gbWVkaXVtIGZvdW5kAFdyb25nIG1lZGl1bSB0eXBlAE5vIGVycm9yIGluZm9ybWF0aW9uAEHAmAELdRYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAACIAAABwUFAAJgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQBB5JoBCwJQUABBoJsBCxD/////////////////////"; + if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); + } + function getBinary(file) { + try { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + var binary = tryParseAsDataURI(file); + if (binary) { + return binary; + } + if (readBinary) { + return readBinary(file); + } else { + throw "sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"; + } + } catch (err2) { + abort(err2); + } + } + function instantiateSync(file, info) { + var instance; + var module2; + var binary; + try { + binary = getBinary(file); + module2 = new WebAssembly.Module(binary); + instance = new WebAssembly.Instance(module2, info); + } catch (e) { + var str = e.toString(); + err("failed to compile wasm module: " + str); + if (str.includes("imported Memory") || str.includes("memory import")) { + err( + "Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)." + ); + } + throw e; + } + return [instance, module2]; + } + function createWasm() { + var info = { a: asmLibraryArg }; + function receiveInstance(instance, module2) { + var exports3 = instance.exports; + Module["asm"] = exports3; + wasmMemory = Module["asm"]["g"]; + updateGlobalBufferAndViews(wasmMemory.buffer); + wasmTable = Module["asm"]["$"]; + addOnInit(Module["asm"]["h"]); + removeRunDependency(); + } + addRunDependency(); + if (Module["instantiateWasm"]) { + try { + var exports2 = Module["instantiateWasm"](info, receiveInstance); + return exports2; + } catch (e) { + err("Module.instantiateWasm callback failed with error: " + e); + return false; + } + } + var result = instantiateSync(wasmBinaryFile, info); + receiveInstance(result[0]); + return Module["asm"]; + } + function LE_HEAP_LOAD_F32(byteOffset) { + return HEAP_DATA_VIEW.getFloat32(byteOffset, true); + } + function LE_HEAP_LOAD_F64(byteOffset) { + return HEAP_DATA_VIEW.getFloat64(byteOffset, true); + } + function LE_HEAP_LOAD_I16(byteOffset) { + return HEAP_DATA_VIEW.getInt16(byteOffset, true); + } + function LE_HEAP_LOAD_I32(byteOffset) { + return HEAP_DATA_VIEW.getInt32(byteOffset, true); + } + function LE_HEAP_STORE_I32(byteOffset, value) { + HEAP_DATA_VIEW.setInt32(byteOffset, value, true); + } + function callRuntimeCallbacks(callbacks) { + while (callbacks.length > 0) { + var callback = callbacks.shift(); + if (typeof callback == "function") { + callback(Module); + continue; + } + var func = callback.func; + if (typeof func === "number") { + if (callback.arg === void 0) { + wasmTable.get(func)(); + } else { + wasmTable.get(func)(callback.arg); + } + } else { + func(callback.arg === void 0 ? null : callback.arg); + } + } + } + function _gmtime_r(time, tmPtr) { + var date = new Date(LE_HEAP_LOAD_I32((time >> 2) * 4) * 1e3); + LE_HEAP_STORE_I32((tmPtr >> 2) * 4, date.getUTCSeconds()); + LE_HEAP_STORE_I32((tmPtr + 4 >> 2) * 4, date.getUTCMinutes()); + LE_HEAP_STORE_I32((tmPtr + 8 >> 2) * 4, date.getUTCHours()); + LE_HEAP_STORE_I32((tmPtr + 12 >> 2) * 4, date.getUTCDate()); + LE_HEAP_STORE_I32((tmPtr + 16 >> 2) * 4, date.getUTCMonth()); + LE_HEAP_STORE_I32((tmPtr + 20 >> 2) * 4, date.getUTCFullYear() - 1900); + LE_HEAP_STORE_I32((tmPtr + 24 >> 2) * 4, date.getUTCDay()); + LE_HEAP_STORE_I32((tmPtr + 36 >> 2) * 4, 0); + LE_HEAP_STORE_I32((tmPtr + 32 >> 2) * 4, 0); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; + LE_HEAP_STORE_I32((tmPtr + 28 >> 2) * 4, yday); + if (!_gmtime_r.GMTString) + _gmtime_r.GMTString = allocateUTF8("GMT"); + LE_HEAP_STORE_I32((tmPtr + 40 >> 2) * 4, _gmtime_r.GMTString); + return tmPtr; + } + function ___gmtime_r(a0, a1) { + return _gmtime_r(a0, a1); + } + function _emscripten_memcpy_big(dest, src, num) { + HEAPU8.copyWithin(dest, src, src + num); + } + function emscripten_realloc_buffer(size) { + try { + wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16); + updateGlobalBufferAndViews(wasmMemory.buffer); + return 1; + } catch (e) { + } + } + function _emscripten_resize_heap(requestedSize) { + var oldSize = HEAPU8.length; + requestedSize = requestedSize >>> 0; + var maxHeapSize = 2147483648; + if (requestedSize > maxHeapSize) { + return false; + } + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); + overGrownHeapSize = Math.min( + overGrownHeapSize, + requestedSize + 100663296 + ); + var newSize = Math.min( + maxHeapSize, + alignUp(Math.max(requestedSize, overGrownHeapSize), 65536) + ); + var replacement = emscripten_realloc_buffer(newSize); + if (replacement) { + return true; + } + } + return false; + } + function _setTempRet0(val) { + } + function _time(ptr) { + var ret = Date.now() / 1e3 | 0; + if (ptr) { + LE_HEAP_STORE_I32((ptr >> 2) * 4, ret); + } + return ret; + } + function _tzset() { + if (_tzset.called) + return; + _tzset.called = true; + var currentYear = new Date().getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + LE_HEAP_STORE_I32((__get_timezone() >> 2) * 4, stdTimezoneOffset * 60); + LE_HEAP_STORE_I32( + (__get_daylight() >> 2) * 4, + Number(winterOffset != summerOffset) + ); + function extractZone(date) { + var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); + return match ? match[1] : "GMT"; + } + var winterName = extractZone(winter); + var summerName = extractZone(summer); + var winterNamePtr = allocateUTF8(winterName); + var summerNamePtr = allocateUTF8(summerName); + if (summerOffset < winterOffset) { + LE_HEAP_STORE_I32((__get_tzname() >> 2) * 4, winterNamePtr); + LE_HEAP_STORE_I32((__get_tzname() + 4 >> 2) * 4, summerNamePtr); + } else { + LE_HEAP_STORE_I32((__get_tzname() >> 2) * 4, summerNamePtr); + LE_HEAP_STORE_I32((__get_tzname() + 4 >> 2) * 4, winterNamePtr); + } + } + function _timegm(tmPtr) { + _tzset(); + var time = Date.UTC( + LE_HEAP_LOAD_I32((tmPtr + 20 >> 2) * 4) + 1900, + LE_HEAP_LOAD_I32((tmPtr + 16 >> 2) * 4), + LE_HEAP_LOAD_I32((tmPtr + 12 >> 2) * 4), + LE_HEAP_LOAD_I32((tmPtr + 8 >> 2) * 4), + LE_HEAP_LOAD_I32((tmPtr + 4 >> 2) * 4), + LE_HEAP_LOAD_I32((tmPtr >> 2) * 4), + 0 + ); + var date = new Date(time); + LE_HEAP_STORE_I32((tmPtr + 24 >> 2) * 4, date.getUTCDay()); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; + LE_HEAP_STORE_I32((tmPtr + 28 >> 2) * 4, yday); + return date.getTime() / 1e3 | 0; + } + function intArrayFromBase64(s) { + { + var buf; + try { + buf = Buffer.from(s, "base64"); + } catch (_) { + buf = new Buffer(s, "base64"); + } + return new Uint8Array( + buf["buffer"], + buf["byteOffset"], + buf["byteLength"] + ); + } + } + function tryParseAsDataURI(filename) { + if (!isDataURI(filename)) { + return; + } + return intArrayFromBase64(filename.slice(dataURIPrefix.length)); + } + var asmLibraryArg = { + e: ___gmtime_r, + c: _emscripten_memcpy_big, + d: _emscripten_resize_heap, + a: _setTempRet0, + b: _time, + f: _timegm + }; + var asm = createWasm(); + Module["___wasm_call_ctors"] = asm["h"]; + Module["_zip_ext_count_symlinks"] = asm["i"]; + Module["_zip_file_get_external_attributes"] = asm["j"]; + Module["_zipstruct_stat"] = asm["k"]; + Module["_zipstruct_statS"] = asm["l"]; + Module["_zipstruct_stat_name"] = asm["m"]; + Module["_zipstruct_stat_index"] = asm["n"]; + Module["_zipstruct_stat_size"] = asm["o"]; + Module["_zipstruct_stat_mtime"] = asm["p"]; + Module["_zipstruct_stat_crc"] = asm["q"]; + Module["_zipstruct_error"] = asm["r"]; + Module["_zipstruct_errorS"] = asm["s"]; + Module["_zipstruct_error_code_zip"] = asm["t"]; + Module["_zipstruct_stat_comp_size"] = asm["u"]; + Module["_zipstruct_stat_comp_method"] = asm["v"]; + Module["_zip_close"] = asm["w"]; + Module["_zip_delete"] = asm["x"]; + Module["_zip_dir_add"] = asm["y"]; + Module["_zip_discard"] = asm["z"]; + Module["_zip_error_init_with_code"] = asm["A"]; + Module["_zip_get_error"] = asm["B"]; + Module["_zip_file_get_error"] = asm["C"]; + Module["_zip_error_strerror"] = asm["D"]; + Module["_zip_fclose"] = asm["E"]; + Module["_zip_file_add"] = asm["F"]; + Module["_free"] = asm["G"]; + var _malloc = Module["_malloc"] = asm["H"]; + Module["_zip_source_error"] = asm["I"]; + Module["_zip_source_seek"] = asm["J"]; + Module["_zip_file_set_external_attributes"] = asm["K"]; + Module["_zip_file_set_mtime"] = asm["L"]; + Module["_zip_fopen"] = asm["M"]; + Module["_zip_fopen_index"] = asm["N"]; + Module["_zip_fread"] = asm["O"]; + Module["_zip_get_name"] = asm["P"]; + Module["_zip_get_num_entries"] = asm["Q"]; + Module["_zip_source_read"] = asm["R"]; + Module["_zip_name_locate"] = asm["S"]; + Module["_zip_open_from_source"] = asm["T"]; + Module["_zip_set_file_compression"] = asm["U"]; + Module["_zip_source_buffer"] = asm["V"]; + Module["_zip_source_buffer_create"] = asm["W"]; + Module["_zip_source_close"] = asm["X"]; + Module["_zip_source_free"] = asm["Y"]; + Module["_zip_source_keep"] = asm["Z"]; + Module["_zip_source_open"] = asm["_"]; + Module["_zip_source_set_mtime"] = asm["aa"]; + Module["_zip_source_tell"] = asm["ba"]; + Module["_zip_stat"] = asm["ca"]; + Module["_zip_stat_index"] = asm["da"]; + var __get_tzname = Module["__get_tzname"] = asm["ea"]; + var __get_daylight = Module["__get_daylight"] = asm["fa"]; + var __get_timezone = Module["__get_timezone"] = asm["ga"]; + var stackSave = Module["stackSave"] = asm["ha"]; + var stackRestore = Module["stackRestore"] = asm["ia"]; + var stackAlloc = Module["stackAlloc"] = asm["ja"]; + Module["cwrap"] = cwrap; + Module["getValue"] = getValue; + var calledRun; + dependenciesFulfilled = function runCaller() { + if (!calledRun) + run(); + if (!calledRun) + dependenciesFulfilled = runCaller; + }; + function run(args) { + if (runDependencies > 0) { + return; + } + preRun(); + if (runDependencies > 0) { + return; + } + function doRun() { + if (calledRun) + return; + calledRun = true; + Module["calledRun"] = true; + if (ABORT) + return; + initRuntime(); + readyPromiseResolve(Module); + if (Module["onRuntimeInitialized"]) + Module["onRuntimeInitialized"](); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + setTimeout(function() { + setTimeout(function() { + Module["setStatus"](""); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + } + Module["run"] = run; + if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") + Module["preInit"] = [Module["preInit"]]; + while (Module["preInit"].length > 0) { + Module["preInit"].pop()(); + } + } + run(); + return createModule2; + }; +}(); +module.exports = createModule; +}(libzipSync)); + +const createModule = libzipSync.exports; + +const number64 = [ + `number`, + `number` +]; +var Errors = /* @__PURE__ */ ((Errors2) => { + Errors2[Errors2["ZIP_ER_OK"] = 0] = "ZIP_ER_OK"; + Errors2[Errors2["ZIP_ER_MULTIDISK"] = 1] = "ZIP_ER_MULTIDISK"; + Errors2[Errors2["ZIP_ER_RENAME"] = 2] = "ZIP_ER_RENAME"; + Errors2[Errors2["ZIP_ER_CLOSE"] = 3] = "ZIP_ER_CLOSE"; + Errors2[Errors2["ZIP_ER_SEEK"] = 4] = "ZIP_ER_SEEK"; + Errors2[Errors2["ZIP_ER_READ"] = 5] = "ZIP_ER_READ"; + Errors2[Errors2["ZIP_ER_WRITE"] = 6] = "ZIP_ER_WRITE"; + Errors2[Errors2["ZIP_ER_CRC"] = 7] = "ZIP_ER_CRC"; + Errors2[Errors2["ZIP_ER_ZIPCLOSED"] = 8] = "ZIP_ER_ZIPCLOSED"; + Errors2[Errors2["ZIP_ER_NOENT"] = 9] = "ZIP_ER_NOENT"; + Errors2[Errors2["ZIP_ER_EXISTS"] = 10] = "ZIP_ER_EXISTS"; + Errors2[Errors2["ZIP_ER_OPEN"] = 11] = "ZIP_ER_OPEN"; + Errors2[Errors2["ZIP_ER_TMPOPEN"] = 12] = "ZIP_ER_TMPOPEN"; + Errors2[Errors2["ZIP_ER_ZLIB"] = 13] = "ZIP_ER_ZLIB"; + Errors2[Errors2["ZIP_ER_MEMORY"] = 14] = "ZIP_ER_MEMORY"; + Errors2[Errors2["ZIP_ER_CHANGED"] = 15] = "ZIP_ER_CHANGED"; + Errors2[Errors2["ZIP_ER_COMPNOTSUPP"] = 16] = "ZIP_ER_COMPNOTSUPP"; + Errors2[Errors2["ZIP_ER_EOF"] = 17] = "ZIP_ER_EOF"; + Errors2[Errors2["ZIP_ER_INVAL"] = 18] = "ZIP_ER_INVAL"; + Errors2[Errors2["ZIP_ER_NOZIP"] = 19] = "ZIP_ER_NOZIP"; + Errors2[Errors2["ZIP_ER_INTERNAL"] = 20] = "ZIP_ER_INTERNAL"; + Errors2[Errors2["ZIP_ER_INCONS"] = 21] = "ZIP_ER_INCONS"; + Errors2[Errors2["ZIP_ER_REMOVE"] = 22] = "ZIP_ER_REMOVE"; + Errors2[Errors2["ZIP_ER_DELETED"] = 23] = "ZIP_ER_DELETED"; + Errors2[Errors2["ZIP_ER_ENCRNOTSUPP"] = 24] = "ZIP_ER_ENCRNOTSUPP"; + Errors2[Errors2["ZIP_ER_RDONLY"] = 25] = "ZIP_ER_RDONLY"; + Errors2[Errors2["ZIP_ER_NOPASSWD"] = 26] = "ZIP_ER_NOPASSWD"; + Errors2[Errors2["ZIP_ER_WRONGPASSWD"] = 27] = "ZIP_ER_WRONGPASSWD"; + Errors2[Errors2["ZIP_ER_OPNOTSUPP"] = 28] = "ZIP_ER_OPNOTSUPP"; + Errors2[Errors2["ZIP_ER_INUSE"] = 29] = "ZIP_ER_INUSE"; + Errors2[Errors2["ZIP_ER_TELL"] = 30] = "ZIP_ER_TELL"; + Errors2[Errors2["ZIP_ER_COMPRESSED_DATA"] = 31] = "ZIP_ER_COMPRESSED_DATA"; + return Errors2; +})(Errors || {}); +const makeInterface = (emZip) => ({ + get HEAP8() { + return emZip.HEAP8; + }, + get HEAPU8() { + return emZip.HEAPU8; + }, + errors: Errors, + SEEK_SET: 0, + SEEK_CUR: 1, + SEEK_END: 2, + ZIP_CHECKCONS: 4, + ZIP_EXCL: 2, + ZIP_RDONLY: 16, + ZIP_FL_OVERWRITE: 8192, + ZIP_FL_COMPRESSED: 4, + ZIP_OPSYS_DOS: 0, + ZIP_OPSYS_AMIGA: 1, + ZIP_OPSYS_OPENVMS: 2, + ZIP_OPSYS_UNIX: 3, + ZIP_OPSYS_VM_CMS: 4, + ZIP_OPSYS_ATARI_ST: 5, + ZIP_OPSYS_OS_2: 6, + ZIP_OPSYS_MACINTOSH: 7, + ZIP_OPSYS_Z_SYSTEM: 8, + ZIP_OPSYS_CPM: 9, + ZIP_OPSYS_WINDOWS_NTFS: 10, + ZIP_OPSYS_MVS: 11, + ZIP_OPSYS_VSE: 12, + ZIP_OPSYS_ACORN_RISC: 13, + ZIP_OPSYS_VFAT: 14, + ZIP_OPSYS_ALTERNATE_MVS: 15, + ZIP_OPSYS_BEOS: 16, + ZIP_OPSYS_TANDEM: 17, + ZIP_OPSYS_OS_400: 18, + ZIP_OPSYS_OS_X: 19, + ZIP_CM_DEFAULT: -1, + ZIP_CM_STORE: 0, + ZIP_CM_DEFLATE: 8, + uint08S: emZip._malloc(1), + uint16S: emZip._malloc(2), + uint32S: emZip._malloc(4), + uint64S: emZip._malloc(8), + malloc: emZip._malloc, + free: emZip._free, + getValue: emZip.getValue, + openFromSource: emZip.cwrap(`zip_open_from_source`, `number`, [`number`, `number`, `number`]), + close: emZip.cwrap(`zip_close`, `number`, [`number`]), + discard: emZip.cwrap(`zip_discard`, null, [`number`]), + getError: emZip.cwrap(`zip_get_error`, `number`, [`number`]), + getName: emZip.cwrap(`zip_get_name`, `string`, [`number`, `number`, `number`]), + getNumEntries: emZip.cwrap(`zip_get_num_entries`, `number`, [`number`, `number`]), + delete: emZip.cwrap(`zip_delete`, `number`, [`number`, `number`]), + stat: emZip.cwrap(`zip_stat`, `number`, [`number`, `string`, `number`, `number`]), + statIndex: emZip.cwrap(`zip_stat_index`, `number`, [`number`, ...number64, `number`, `number`]), + fopen: emZip.cwrap(`zip_fopen`, `number`, [`number`, `string`, `number`]), + fopenIndex: emZip.cwrap(`zip_fopen_index`, `number`, [`number`, ...number64, `number`]), + fread: emZip.cwrap(`zip_fread`, `number`, [`number`, `number`, `number`, `number`]), + fclose: emZip.cwrap(`zip_fclose`, `number`, [`number`]), + dir: { + add: emZip.cwrap(`zip_dir_add`, `number`, [`number`, `string`]) + }, + file: { + add: emZip.cwrap(`zip_file_add`, `number`, [`number`, `string`, `number`, `number`]), + getError: emZip.cwrap(`zip_file_get_error`, `number`, [`number`]), + getExternalAttributes: emZip.cwrap(`zip_file_get_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), + setExternalAttributes: emZip.cwrap(`zip_file_set_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), + setMtime: emZip.cwrap(`zip_file_set_mtime`, `number`, [`number`, ...number64, `number`, `number`]), + setCompression: emZip.cwrap(`zip_set_file_compression`, `number`, [`number`, ...number64, `number`, `number`]) + }, + ext: { + countSymlinks: emZip.cwrap(`zip_ext_count_symlinks`, `number`, [`number`]) + }, + error: { + initWithCode: emZip.cwrap(`zip_error_init_with_code`, null, [`number`, `number`]), + strerror: emZip.cwrap(`zip_error_strerror`, `string`, [`number`]) + }, + name: { + locate: emZip.cwrap(`zip_name_locate`, `number`, [`number`, `string`, `number`]) + }, + source: { + fromUnattachedBuffer: emZip.cwrap(`zip_source_buffer_create`, `number`, [`number`, ...number64, `number`, `number`]), + fromBuffer: emZip.cwrap(`zip_source_buffer`, `number`, [`number`, `number`, ...number64, `number`]), + free: emZip.cwrap(`zip_source_free`, null, [`number`]), + keep: emZip.cwrap(`zip_source_keep`, null, [`number`]), + open: emZip.cwrap(`zip_source_open`, `number`, [`number`]), + close: emZip.cwrap(`zip_source_close`, `number`, [`number`]), + seek: emZip.cwrap(`zip_source_seek`, `number`, [`number`, ...number64, `number`]), + tell: emZip.cwrap(`zip_source_tell`, `number`, [`number`]), + read: emZip.cwrap(`zip_source_read`, `number`, [`number`, `number`, `number`]), + error: emZip.cwrap(`zip_source_error`, `number`, [`number`]), + setMtime: emZip.cwrap(`zip_source_set_mtime`, `number`, [`number`, `number`]) + }, + struct: { + stat: emZip.cwrap(`zipstruct_stat`, `number`, []), + statS: emZip.cwrap(`zipstruct_statS`, `number`, []), + statName: emZip.cwrap(`zipstruct_stat_name`, `string`, [`number`]), + statIndex: emZip.cwrap(`zipstruct_stat_index`, `number`, [`number`]), + statSize: emZip.cwrap(`zipstruct_stat_size`, `number`, [`number`]), + statCompSize: emZip.cwrap(`zipstruct_stat_comp_size`, `number`, [`number`]), + statCompMethod: emZip.cwrap(`zipstruct_stat_comp_method`, `number`, [`number`]), + statMtime: emZip.cwrap(`zipstruct_stat_mtime`, `number`, [`number`]), + statCrc: emZip.cwrap(`zipstruct_stat_crc`, `number`, [`number`]), + error: emZip.cwrap(`zipstruct_error`, `number`, []), + errorS: emZip.cwrap(`zipstruct_errorS`, `number`, []), + errorCodeZip: emZip.cwrap(`zipstruct_error_code_zip`, `number`, [`number`]) + } +}); + +function getArchivePart(path, extension) { + let idx = path.indexOf(extension); + if (idx <= 0) + return null; + let nextCharIdx = idx; + while (idx >= 0) { + nextCharIdx = idx + extension.length; + if (path[nextCharIdx] === ppath.sep) + break; + if (path[idx - 1] === ppath.sep) + return null; + idx = path.indexOf(extension, nextCharIdx); + } + if (path.length > nextCharIdx && path[nextCharIdx] !== ppath.sep) + return null; + return path.slice(0, nextCharIdx); +} +class ZipOpenFS extends MountFS { + static async openPromise(fn, opts) { + const zipOpenFs = new ZipOpenFS(opts); + try { + return await fn(zipOpenFs); + } finally { + zipOpenFs.saveAndClose(); + } + } + constructor(opts = {}) { + const fileExtensions = opts.fileExtensions; + const readOnlyArchives = opts.readOnlyArchives; + const getMountPoint = typeof fileExtensions === `undefined` ? (path) => getArchivePart(path, `.zip`) : (path) => { + for (const extension of fileExtensions) { + const result = getArchivePart(path, extension); + if (result) { + return result; + } + } + return null; + }; + const factorySync = (baseFs, p) => { + return new ZipFS(p, { + baseFs, + readOnly: readOnlyArchives, + stats: baseFs.statSync(p) + }); + }; + const factoryPromise = async (baseFs, p) => { + const zipOptions = { + baseFs, + readOnly: readOnlyArchives, + stats: await baseFs.statPromise(p) + }; + return () => { + return new ZipFS(p, zipOptions); + }; + }; + super({ + ...opts, + factorySync, + factoryPromise, + getMountPoint + }); + } +} + +const DEFAULT_COMPRESSION_LEVEL = `mixed`; +function toUnixTimestamp(time) { + if (typeof time === `string` && String(+time) === time) + return +time; + if (typeof time === `number` && Number.isFinite(time)) { + if (time < 0) { + return Date.now() / 1e3; + } else { + return time; + } + } + if (nodeUtils.types.isDate(time)) + return time.getTime() / 1e3; + throw new Error(`Invalid time`); +} +function makeEmptyArchive() { + return Buffer.from([ + 80, + 75, + 5, + 6, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ]); +} +class LibzipError extends Error { + constructor(message, code) { + super(message); + this.name = `Libzip Error`; + this.code = code; + } +} +class ZipFS extends BasePortableFakeFS { + constructor(source, opts = {}) { + super(); + this.listings = /* @__PURE__ */ new Map(); + this.entries = /* @__PURE__ */ new Map(); + this.fileSources = /* @__PURE__ */ new Map(); + this.fds = /* @__PURE__ */ new Map(); + this.nextFd = 0; + this.ready = false; + this.readOnly = false; + const pathOptions = opts; + this.level = typeof pathOptions.level !== `undefined` ? pathOptions.level : DEFAULT_COMPRESSION_LEVEL; + source ?? (source = makeEmptyArchive()); + if (typeof source === `string`) { + const { baseFs = new NodeFS() } = pathOptions; + this.baseFs = baseFs; + this.path = source; + } else { + this.path = null; + this.baseFs = null; + } + if (opts.stats) { + this.stats = opts.stats; + } else { + if (typeof source === `string`) { + try { + this.stats = this.baseFs.statSync(source); + } catch (error) { + if (error.code === `ENOENT` && pathOptions.create) { + this.stats = makeDefaultStats(); + } else { + throw error; + } + } + } else { + this.stats = makeDefaultStats(); + } + } + this.libzip = getInstance(); + const errPtr = this.libzip.malloc(4); + try { + let flags = 0; + if (opts.readOnly) { + flags |= this.libzip.ZIP_RDONLY; + this.readOnly = true; + } + if (typeof source === `string`) + source = pathOptions.create ? makeEmptyArchive() : this.baseFs.readFileSync(source); + const lzSource = this.allocateUnattachedSource(source); + try { + this.zip = this.libzip.openFromSource(lzSource, flags, errPtr); + this.lzSource = lzSource; + } catch (error) { + this.libzip.source.free(lzSource); + throw error; + } + if (this.zip === 0) { + const error = this.libzip.struct.errorS(); + this.libzip.error.initWithCode(error, this.libzip.getValue(errPtr, `i32`)); + throw this.makeLibzipError(error); + } + } finally { + this.libzip.free(errPtr); + } + this.listings.set(PortablePath.root, /* @__PURE__ */ new Set()); + const entryCount = this.libzip.getNumEntries(this.zip, 0); + for (let t = 0; t < entryCount; ++t) { + const raw = this.libzip.getName(this.zip, t, 0); + if (ppath.isAbsolute(raw)) + continue; + const p = ppath.resolve(PortablePath.root, raw); + this.registerEntry(p, t); + if (raw.endsWith(`/`)) { + this.registerListing(p); + } + } + this.symlinkCount = this.libzip.ext.countSymlinks(this.zip); + if (this.symlinkCount === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.ready = true; + } + makeLibzipError(error) { + const errorCode = this.libzip.struct.errorCodeZip(error); + const strerror = this.libzip.error.strerror(error); + const libzipError = new LibzipError(strerror, this.libzip.errors[errorCode]); + if (errorCode === this.libzip.errors.ZIP_ER_CHANGED) + throw new Error(`Assertion failed: Unexpected libzip error: ${libzipError.message}`); + return libzipError; + } + getExtractHint(hints) { + for (const fileName of this.entries.keys()) { + const ext = this.pathUtils.extname(fileName); + if (hints.relevantExtensions.has(ext)) { + return true; + } + } + return false; + } + getAllFiles() { + return Array.from(this.entries.keys()); + } + getRealPath() { + if (!this.path) + throw new Error(`ZipFS don't have real paths when loaded from a buffer`); + return this.path; + } + prepareClose() { + if (!this.ready) + throw EBUSY(`archive closed, close`); + unwatchAllFiles(this); + } + getBufferAndClose() { + this.prepareClose(); + if (this.entries.size === 0) { + this.discardAndClose(); + return makeEmptyArchive(); + } + try { + this.libzip.source.keep(this.lzSource); + if (this.libzip.close(this.zip) === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + if (this.libzip.source.open(this.lzSource) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_END) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + const size = this.libzip.source.tell(this.lzSource); + if (size === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_SET) === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + const buffer = this.libzip.malloc(size); + if (!buffer) + throw new Error(`Couldn't allocate enough memory`); + try { + const rc = this.libzip.source.read(this.lzSource, buffer, size); + if (rc === -1) + throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); + else if (rc < size) + throw new Error(`Incomplete read`); + else if (rc > size) + throw new Error(`Overread`); + const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); + return Buffer.from(memory); + } finally { + this.libzip.free(buffer); + } + } finally { + this.libzip.source.close(this.lzSource); + this.libzip.source.free(this.lzSource); + this.ready = false; + } + } + discardAndClose() { + this.prepareClose(); + this.libzip.discard(this.zip); + this.ready = false; + } + saveAndClose() { + if (!this.path || !this.baseFs) + throw new Error(`ZipFS cannot be saved and must be discarded when loaded from a buffer`); + if (this.readOnly) { + this.discardAndClose(); + return; + } + const newMode = this.baseFs.existsSync(this.path) || this.stats.mode === DEFAULT_MODE ? void 0 : this.stats.mode; + this.baseFs.writeFileSync(this.path, this.getBufferAndClose(), { mode: newMode }); + this.ready = false; + } + resolve(p) { + return ppath.resolve(PortablePath.root, p); + } + async openPromise(p, flags, mode) { + return this.openSync(p, flags, mode); + } + openSync(p, flags, mode) { + const fd = this.nextFd++; + this.fds.set(fd, { cursor: 0, p }); + return fd; + } + hasOpenFileHandles() { + return !!this.fds.size; + } + async opendirPromise(p, opts) { + return this.opendirSync(p, opts); + } + opendirSync(p, opts = {}) { + const resolvedP = this.resolveFilename(`opendir '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`opendir '${p}'`); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`opendir '${p}'`); + const entries = [...directoryListing]; + const fd = this.openSync(resolvedP, `r`); + const onClose = () => { + this.closeSync(fd); + }; + return opendir(this, resolvedP, entries, { onClose }); + } + async readPromise(fd, buffer, offset, length, position) { + return this.readSync(fd, buffer, offset, length, position); + } + readSync(fd, buffer, offset = 0, length = buffer.byteLength, position = -1) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + const realPosition = position === -1 || position === null ? entry.cursor : position; + const source = this.readFileSync(entry.p); + source.copy(buffer, offset, realPosition, realPosition + length); + const bytesRead = Math.max(0, Math.min(source.length - realPosition, length)); + if (position === -1 || position === null) + entry.cursor += bytesRead; + return bytesRead; + } + async writePromise(fd, buffer, offset, length, position) { + if (typeof buffer === `string`) { + return this.writeSync(fd, buffer, position); + } else { + return this.writeSync(fd, buffer, offset, length, position); + } + } + writeSync(fd, buffer, offset, length, position) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + throw new Error(`Unimplemented`); + } + async closePromise(fd) { + return this.closeSync(fd); + } + closeSync(fd) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`read`); + this.fds.delete(fd); + } + createReadStream(p, { encoding } = {}) { + if (p === null) + throw new Error(`Unimplemented`); + const fd = this.openSync(p, `r`); + const stream$1 = Object.assign( + new stream.PassThrough({ + emitClose: true, + autoDestroy: true, + destroy: (error, callback) => { + clearImmediate(immediate); + this.closeSync(fd); + callback(error); + } + }), + { + close() { + stream$1.destroy(); + }, + bytesRead: 0, + path: p, + pending: false + } + ); + const immediate = setImmediate(async () => { + try { + const data = await this.readFilePromise(p, encoding); + stream$1.bytesRead = data.length; + stream$1.end(data); + } catch (error) { + stream$1.destroy(error); + } + }); + return stream$1; + } + createWriteStream(p, { encoding } = {}) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (p === null) + throw new Error(`Unimplemented`); + const chunks = []; + const fd = this.openSync(p, `w`); + const stream$1 = Object.assign( + new stream.PassThrough({ + autoDestroy: true, + emitClose: true, + destroy: (error, callback) => { + try { + if (error) { + callback(error); + } else { + this.writeFileSync(p, Buffer.concat(chunks), encoding); + callback(null); + } + } catch (err) { + callback(err); + } finally { + this.closeSync(fd); + } + } + }), + { + close() { + stream$1.destroy(); + }, + bytesWritten: 0, + path: p, + pending: false + } + ); + stream$1.on(`data`, (chunk) => { + const chunkBuffer = Buffer.from(chunk); + stream$1.bytesWritten += chunkBuffer.length; + chunks.push(chunkBuffer); + }); + return stream$1; + } + async realpathPromise(p) { + return this.realpathSync(p); + } + realpathSync(p) { + const resolvedP = this.resolveFilename(`lstat '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`lstat '${p}'`); + return resolvedP; + } + async existsPromise(p) { + return this.existsSync(p); + } + existsSync(p) { + if (!this.ready) + throw EBUSY(`archive closed, existsSync '${p}'`); + if (this.symlinkCount === 0) { + const resolvedP2 = ppath.resolve(PortablePath.root, p); + return this.entries.has(resolvedP2) || this.listings.has(resolvedP2); + } + let resolvedP; + try { + resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, false); + } catch (error) { + return false; + } + if (resolvedP === void 0) + return false; + return this.entries.has(resolvedP) || this.listings.has(resolvedP); + } + async accessPromise(p, mode) { + return this.accessSync(p, mode); + } + accessSync(p, mode = fs.constants.F_OK) { + const resolvedP = this.resolveFilename(`access '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`access '${p}'`); + if (this.readOnly && mode & fs.constants.W_OK) { + throw EROFS(`access '${p}'`); + } + } + async statPromise(p, opts = { bigint: false }) { + if (opts.bigint) + return this.statSync(p, { bigint: true }); + return this.statSync(p); + } + statSync(p, opts = { bigint: false, throwIfNoEntry: true }) { + const resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, opts.throwIfNoEntry); + if (resolvedP === void 0) + return void 0; + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { + if (opts.throwIfNoEntry === false) + return void 0; + throw ENOENT(`stat '${p}'`); + } + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`stat '${p}'`); + return this.statImpl(`stat '${p}'`, resolvedP, opts); + } + async fstatPromise(fd, opts) { + return this.fstatSync(fd, opts); + } + fstatSync(fd, opts) { + const entry = this.fds.get(fd); + if (typeof entry === `undefined`) + throw EBADF(`fstatSync`); + const { p } = entry; + const resolvedP = this.resolveFilename(`stat '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`stat '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`stat '${p}'`); + return this.statImpl(`fstat '${p}'`, resolvedP, opts); + } + async lstatPromise(p, opts = { bigint: false }) { + if (opts.bigint) + return this.lstatSync(p, { bigint: true }); + return this.lstatSync(p); + } + lstatSync(p, opts = { bigint: false, throwIfNoEntry: true }) { + const resolvedP = this.resolveFilename(`lstat '${p}'`, p, false, opts.throwIfNoEntry); + if (resolvedP === void 0) + return void 0; + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { + if (opts.throwIfNoEntry === false) + return void 0; + throw ENOENT(`lstat '${p}'`); + } + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`lstat '${p}'`); + return this.statImpl(`lstat '${p}'`, resolvedP, opts); + } + statImpl(reason, p, opts = {}) { + const entry = this.entries.get(p); + if (typeof entry !== `undefined`) { + const stat = this.libzip.struct.statS(); + const rc = this.libzip.statIndex(this.zip, entry, 0, 0, stat); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const uid = this.stats.uid; + const gid = this.stats.gid; + const size = this.libzip.struct.statSize(stat) >>> 0; + const blksize = 512; + const blocks = Math.ceil(size / blksize); + const mtimeMs = (this.libzip.struct.statMtime(stat) >>> 0) * 1e3; + const atimeMs = mtimeMs; + const birthtimeMs = mtimeMs; + const ctimeMs = mtimeMs; + const atime = new Date(atimeMs); + const birthtime = new Date(birthtimeMs); + const ctime = new Date(ctimeMs); + const mtime = new Date(mtimeMs); + const type = this.listings.has(p) ? fs.constants.S_IFDIR : this.isSymbolicLink(entry) ? fs.constants.S_IFLNK : fs.constants.S_IFREG; + const defaultMode = type === fs.constants.S_IFDIR ? 493 : 420; + const mode = type | this.getUnixMode(entry, defaultMode) & 511; + const crc = this.libzip.struct.statCrc(stat); + const statInstance = Object.assign(new StatEntry(), { uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc }); + return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; + } + if (this.listings.has(p)) { + const uid = this.stats.uid; + const gid = this.stats.gid; + const size = 0; + const blksize = 512; + const blocks = 0; + const atimeMs = this.stats.mtimeMs; + const birthtimeMs = this.stats.mtimeMs; + const ctimeMs = this.stats.mtimeMs; + const mtimeMs = this.stats.mtimeMs; + const atime = new Date(atimeMs); + const birthtime = new Date(birthtimeMs); + const ctime = new Date(ctimeMs); + const mtime = new Date(mtimeMs); + const mode = fs.constants.S_IFDIR | 493; + const crc = 0; + const statInstance = Object.assign(new StatEntry(), { uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc }); + return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; + } + throw new Error(`Unreachable`); + } + getUnixMode(index, defaultMode) { + const rc = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; + if (opsys !== this.libzip.ZIP_OPSYS_UNIX) + return defaultMode; + return this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; + } + registerListing(p) { + const existingListing = this.listings.get(p); + if (existingListing) + return existingListing; + const parentListing = this.registerListing(ppath.dirname(p)); + parentListing.add(ppath.basename(p)); + const newListing = /* @__PURE__ */ new Set(); + this.listings.set(p, newListing); + return newListing; + } + registerEntry(p, index) { + const parentListing = this.registerListing(ppath.dirname(p)); + parentListing.add(ppath.basename(p)); + this.entries.set(p, index); + } + unregisterListing(p) { + this.listings.delete(p); + const parentListing = this.listings.get(ppath.dirname(p)); + parentListing == null ? void 0 : parentListing.delete(ppath.basename(p)); + } + unregisterEntry(p) { + this.unregisterListing(p); + const entry = this.entries.get(p); + this.entries.delete(p); + if (typeof entry === `undefined`) + return; + this.fileSources.delete(entry); + if (this.isSymbolicLink(entry)) { + this.symlinkCount--; + } + } + deleteEntry(p, index) { + this.unregisterEntry(p); + const rc = this.libzip.delete(this.zip, index); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + resolveFilename(reason, p, resolveLastComponent = true, throwIfNoEntry = true) { + if (!this.ready) + throw EBUSY(`archive closed, ${reason}`); + let resolvedP = ppath.resolve(PortablePath.root, p); + if (resolvedP === `/`) + return PortablePath.root; + const fileIndex = this.entries.get(resolvedP); + if (resolveLastComponent && fileIndex !== void 0) { + if (this.symlinkCount !== 0 && this.isSymbolicLink(fileIndex)) { + const target = this.getFileSource(fileIndex).toString(); + return this.resolveFilename(reason, ppath.resolve(ppath.dirname(resolvedP), target), true, throwIfNoEntry); + } else { + return resolvedP; + } + } + while (true) { + const parentP = this.resolveFilename(reason, ppath.dirname(resolvedP), true, throwIfNoEntry); + if (parentP === void 0) + return parentP; + const isDir = this.listings.has(parentP); + const doesExist = this.entries.has(parentP); + if (!isDir && !doesExist) { + if (throwIfNoEntry === false) + return void 0; + throw ENOENT(reason); + } + if (!isDir) + throw ENOTDIR(reason); + resolvedP = ppath.resolve(parentP, ppath.basename(resolvedP)); + if (!resolveLastComponent || this.symlinkCount === 0) + break; + const index = this.libzip.name.locate(this.zip, resolvedP.slice(1), 0); + if (index === -1) + break; + if (this.isSymbolicLink(index)) { + const target = this.getFileSource(index).toString(); + resolvedP = ppath.resolve(ppath.dirname(resolvedP), target); + } else { + break; + } + } + return resolvedP; + } + allocateBuffer(content) { + if (!Buffer.isBuffer(content)) + content = Buffer.from(content); + const buffer = this.libzip.malloc(content.byteLength); + if (!buffer) + throw new Error(`Couldn't allocate enough memory`); + const heap = new Uint8Array(this.libzip.HEAPU8.buffer, buffer, content.byteLength); + heap.set(content); + return { buffer, byteLength: content.byteLength }; + } + allocateUnattachedSource(content) { + const error = this.libzip.struct.errorS(); + const { buffer, byteLength } = this.allocateBuffer(content); + const source = this.libzip.source.fromUnattachedBuffer(buffer, byteLength, 0, 1, error); + if (source === 0) { + this.libzip.free(error); + throw this.makeLibzipError(error); + } + return source; + } + allocateSource(content) { + const { buffer, byteLength } = this.allocateBuffer(content); + const source = this.libzip.source.fromBuffer(this.zip, buffer, byteLength, 0, 1); + if (source === 0) { + this.libzip.free(buffer); + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + return source; + } + setFileSource(p, content) { + const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content); + const target = ppath.relative(PortablePath.root, p); + const lzSource = this.allocateSource(content); + try { + const newIndex = this.libzip.file.add(this.zip, target, lzSource, this.libzip.ZIP_FL_OVERWRITE); + if (newIndex === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + if (this.level !== `mixed`) { + const method = this.level === 0 ? this.libzip.ZIP_CM_STORE : this.libzip.ZIP_CM_DEFLATE; + const rc = this.libzip.file.setCompression(this.zip, newIndex, 0, method, this.level); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + this.fileSources.set(newIndex, buffer); + return newIndex; + } catch (error) { + this.libzip.source.free(lzSource); + throw error; + } + } + isSymbolicLink(index) { + if (this.symlinkCount === 0) + return false; + const attrs = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); + if (attrs === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; + if (opsys !== this.libzip.ZIP_OPSYS_UNIX) + return false; + const attributes = this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; + return (attributes & fs.constants.S_IFMT) === fs.constants.S_IFLNK; + } + getFileSource(index, opts = { asyncDecompress: false }) { + const cachedFileSource = this.fileSources.get(index); + if (typeof cachedFileSource !== `undefined`) + return cachedFileSource; + const stat = this.libzip.struct.statS(); + const rc = this.libzip.statIndex(this.zip, index, 0, 0, stat); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + const size = this.libzip.struct.statCompSize(stat); + const compressionMethod = this.libzip.struct.statCompMethod(stat); + const buffer = this.libzip.malloc(size); + try { + const file = this.libzip.fopenIndex(this.zip, index, 0, this.libzip.ZIP_FL_COMPRESSED); + if (file === 0) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + try { + const rc2 = this.libzip.fread(file, buffer, size, 0); + if (rc2 === -1) + throw this.makeLibzipError(this.libzip.file.getError(file)); + else if (rc2 < size) + throw new Error(`Incomplete read`); + else if (rc2 > size) + throw new Error(`Overread`); + const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); + const data = Buffer.from(memory); + if (compressionMethod === 0) { + this.fileSources.set(index, data); + return data; + } else if (opts.asyncDecompress) { + return new Promise((resolve, reject) => { + zlib__default.default.inflateRaw(data, (error, result) => { + if (error) { + reject(error); + } else { + this.fileSources.set(index, result); + resolve(result); + } + }); + }); + } else { + const decompressedData = zlib__default.default.inflateRawSync(data); + this.fileSources.set(index, decompressedData); + return decompressedData; + } + } finally { + this.libzip.fclose(file); + } + } finally { + this.libzip.free(buffer); + } + } + async fchmodPromise(fd, mask) { + return this.chmodPromise(this.fdToPath(fd, `fchmod`), mask); + } + fchmodSync(fd, mask) { + return this.chmodSync(this.fdToPath(fd, `fchmodSync`), mask); + } + async chmodPromise(p, mask) { + return this.chmodSync(p, mask); + } + chmodSync(p, mask) { + if (this.readOnly) + throw EROFS(`chmod '${p}'`); + mask &= 493; + const resolvedP = this.resolveFilename(`chmod '${p}'`, p, false); + const entry = this.entries.get(resolvedP); + if (typeof entry === `undefined`) + throw new Error(`Assertion failed: The entry should have been registered (${resolvedP})`); + const oldMod = this.getUnixMode(entry, fs.constants.S_IFREG | 0); + const newMod = oldMod & ~511 | mask; + const rc = this.libzip.file.setExternalAttributes(this.zip, entry, 0, 0, this.libzip.ZIP_OPSYS_UNIX, newMod << 16); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + async fchownPromise(fd, uid, gid) { + return this.chownPromise(this.fdToPath(fd, `fchown`), uid, gid); + } + fchownSync(fd, uid, gid) { + return this.chownSync(this.fdToPath(fd, `fchownSync`), uid, gid); + } + async chownPromise(p, uid, gid) { + return this.chownSync(p, uid, gid); + } + chownSync(p, uid, gid) { + throw new Error(`Unimplemented`); + } + async renamePromise(oldP, newP) { + return this.renameSync(oldP, newP); + } + renameSync(oldP, newP) { + throw new Error(`Unimplemented`); + } + async copyFilePromise(sourceP, destP, flags) { + const { indexSource, indexDest, resolvedDestP } = this.prepareCopyFile(sourceP, destP, flags); + const source = await this.getFileSource(indexSource, { asyncDecompress: true }); + const newIndex = this.setFileSource(resolvedDestP, source); + if (newIndex !== indexDest) { + this.registerEntry(resolvedDestP, newIndex); + } + } + copyFileSync(sourceP, destP, flags = 0) { + const { indexSource, indexDest, resolvedDestP } = this.prepareCopyFile(sourceP, destP, flags); + const source = this.getFileSource(indexSource); + const newIndex = this.setFileSource(resolvedDestP, source); + if (newIndex !== indexDest) { + this.registerEntry(resolvedDestP, newIndex); + } + } + prepareCopyFile(sourceP, destP, flags = 0) { + if (this.readOnly) + throw EROFS(`copyfile '${sourceP} -> '${destP}'`); + if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) + throw ENOSYS(`unsupported clone operation`, `copyfile '${sourceP}' -> ${destP}'`); + const resolvedSourceP = this.resolveFilename(`copyfile '${sourceP} -> ${destP}'`, sourceP); + const indexSource = this.entries.get(resolvedSourceP); + if (typeof indexSource === `undefined`) + throw EINVAL(`copyfile '${sourceP}' -> '${destP}'`); + const resolvedDestP = this.resolveFilename(`copyfile '${sourceP}' -> ${destP}'`, destP); + const indexDest = this.entries.get(resolvedDestP); + if ((flags & (fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE_FORCE)) !== 0 && typeof indexDest !== `undefined`) + throw EEXIST(`copyfile '${sourceP}' -> '${destP}'`); + return { + indexSource, + resolvedDestP, + indexDest + }; + } + async appendFilePromise(p, content, opts) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (typeof opts === `undefined`) + opts = { flag: `a` }; + else if (typeof opts === `string`) + opts = { flag: `a`, encoding: opts }; + else if (typeof opts.flag === `undefined`) + opts = { flag: `a`, ...opts }; + return this.writeFilePromise(p, content, opts); + } + appendFileSync(p, content, opts = {}) { + if (this.readOnly) + throw EROFS(`open '${p}'`); + if (typeof opts === `undefined`) + opts = { flag: `a` }; + else if (typeof opts === `string`) + opts = { flag: `a`, encoding: opts }; + else if (typeof opts.flag === `undefined`) + opts = { flag: `a`, ...opts }; + return this.writeFileSync(p, content, opts); + } + fdToPath(fd, reason) { + var _a; + const path = (_a = this.fds.get(fd)) == null ? void 0 : _a.p; + if (typeof path === `undefined`) + throw EBADF(reason); + return path; + } + async writeFilePromise(p, content, opts) { + const { encoding, mode, index, resolvedP } = this.prepareWriteFile(p, opts); + if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) + content = Buffer.concat([await this.getFileSource(index, { asyncDecompress: true }), Buffer.from(content)]); + if (encoding !== null) + content = content.toString(encoding); + const newIndex = this.setFileSource(resolvedP, content); + if (newIndex !== index) + this.registerEntry(resolvedP, newIndex); + if (mode !== null) { + await this.chmodPromise(resolvedP, mode); + } + } + writeFileSync(p, content, opts) { + const { encoding, mode, index, resolvedP } = this.prepareWriteFile(p, opts); + if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) + content = Buffer.concat([this.getFileSource(index), Buffer.from(content)]); + if (encoding !== null) + content = content.toString(encoding); + const newIndex = this.setFileSource(resolvedP, content); + if (newIndex !== index) + this.registerEntry(resolvedP, newIndex); + if (mode !== null) { + this.chmodSync(resolvedP, mode); + } + } + prepareWriteFile(p, opts) { + if (typeof p === `number`) + p = this.fdToPath(p, `read`); + if (this.readOnly) + throw EROFS(`open '${p}'`); + const resolvedP = this.resolveFilename(`open '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`open '${p}'`); + let encoding = null, mode = null; + if (typeof opts === `string`) { + encoding = opts; + } else if (typeof opts === `object`) { + ({ + encoding = null, + mode = null + } = opts); + } + const index = this.entries.get(resolvedP); + return { + encoding, + mode, + resolvedP, + index + }; + } + async unlinkPromise(p) { + return this.unlinkSync(p); + } + unlinkSync(p) { + if (this.readOnly) + throw EROFS(`unlink '${p}'`); + const resolvedP = this.resolveFilename(`unlink '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`unlink '${p}'`); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`unlink '${p}'`); + this.deleteEntry(resolvedP, index); + } + async utimesPromise(p, atime, mtime) { + return this.utimesSync(p, atime, mtime); + } + utimesSync(p, atime, mtime) { + if (this.readOnly) + throw EROFS(`utimes '${p}'`); + const resolvedP = this.resolveFilename(`utimes '${p}'`, p); + this.utimesImpl(resolvedP, mtime); + } + async lutimesPromise(p, atime, mtime) { + return this.lutimesSync(p, atime, mtime); + } + lutimesSync(p, atime, mtime) { + if (this.readOnly) + throw EROFS(`lutimes '${p}'`); + const resolvedP = this.resolveFilename(`utimes '${p}'`, p, false); + this.utimesImpl(resolvedP, mtime); + } + utimesImpl(resolvedP, mtime) { + if (this.listings.has(resolvedP)) { + if (!this.entries.has(resolvedP)) + this.hydrateDirectory(resolvedP); + } + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + const rc = this.libzip.file.setMtime(this.zip, entry, 0, toUnixTimestamp(mtime), 0); + if (rc === -1) { + throw this.makeLibzipError(this.libzip.getError(this.zip)); + } + } + async mkdirPromise(p, opts) { + return this.mkdirSync(p, opts); + } + mkdirSync(p, { mode = 493, recursive = false } = {}) { + if (recursive) + return this.mkdirpSync(p, { chmod: mode }); + if (this.readOnly) + throw EROFS(`mkdir '${p}'`); + const resolvedP = this.resolveFilename(`mkdir '${p}'`, p); + if (this.entries.has(resolvedP) || this.listings.has(resolvedP)) + throw EEXIST(`mkdir '${p}'`); + this.hydrateDirectory(resolvedP); + this.chmodSync(resolvedP, mode); + return void 0; + } + async rmdirPromise(p, opts) { + return this.rmdirSync(p, opts); + } + rmdirSync(p, { recursive = false } = {}) { + if (this.readOnly) + throw EROFS(`rmdir '${p}'`); + if (recursive) { + this.removeSync(p); + return; + } + const resolvedP = this.resolveFilename(`rmdir '${p}'`, p); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`rmdir '${p}'`); + if (directoryListing.size > 0) + throw ENOTEMPTY(`rmdir '${p}'`); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`rmdir '${p}'`); + this.deleteEntry(p, index); + } + hydrateDirectory(resolvedP) { + const index = this.libzip.dir.add(this.zip, ppath.relative(PortablePath.root, resolvedP)); + if (index === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.registerListing(resolvedP); + this.registerEntry(resolvedP, index); + return index; + } + async linkPromise(existingP, newP) { + return this.linkSync(existingP, newP); + } + linkSync(existingP, newP) { + throw EOPNOTSUPP(`link '${existingP}' -> '${newP}'`); + } + async symlinkPromise(target, p) { + return this.symlinkSync(target, p); + } + symlinkSync(target, p) { + if (this.readOnly) + throw EROFS(`symlink '${target}' -> '${p}'`); + const resolvedP = this.resolveFilename(`symlink '${target}' -> '${p}'`, p); + if (this.listings.has(resolvedP)) + throw EISDIR(`symlink '${target}' -> '${p}'`); + if (this.entries.has(resolvedP)) + throw EEXIST(`symlink '${target}' -> '${p}'`); + const index = this.setFileSource(resolvedP, target); + this.registerEntry(resolvedP, index); + const rc = this.libzip.file.setExternalAttributes(this.zip, index, 0, 0, this.libzip.ZIP_OPSYS_UNIX, (fs.constants.S_IFLNK | 511) << 16); + if (rc === -1) + throw this.makeLibzipError(this.libzip.getError(this.zip)); + this.symlinkCount += 1; + } + async readFilePromise(p, encoding) { + if (typeof encoding === `object`) + encoding = encoding ? encoding.encoding : void 0; + const data = await this.readFileBuffer(p, { asyncDecompress: true }); + return encoding ? data.toString(encoding) : data; + } + readFileSync(p, encoding) { + if (typeof encoding === `object`) + encoding = encoding ? encoding.encoding : void 0; + const data = this.readFileBuffer(p); + return encoding ? data.toString(encoding) : data; + } + readFileBuffer(p, opts = { asyncDecompress: false }) { + if (typeof p === `number`) + p = this.fdToPath(p, `read`); + const resolvedP = this.resolveFilename(`open '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`open '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`open '${p}'`); + if (this.listings.has(resolvedP)) + throw EISDIR(`read`); + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + return this.getFileSource(entry, opts); + } + async readdirPromise(p, opts) { + return this.readdirSync(p, opts); + } + readdirSync(p, opts) { + const resolvedP = this.resolveFilename(`scandir '${p}'`, p); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`scandir '${p}'`); + const directoryListing = this.listings.get(resolvedP); + if (!directoryListing) + throw ENOTDIR(`scandir '${p}'`); + const entries = [...directoryListing]; + if (!(opts == null ? void 0 : opts.withFileTypes)) + return entries; + return entries.map((name) => { + return Object.assign(this.statImpl(`lstat`, ppath.join(p, name)), { + name + }); + }); + } + async readlinkPromise(p) { + const entry = this.prepareReadlink(p); + return (await this.getFileSource(entry, { asyncDecompress: true })).toString(); + } + readlinkSync(p) { + const entry = this.prepareReadlink(p); + return this.getFileSource(entry).toString(); + } + prepareReadlink(p) { + const resolvedP = this.resolveFilename(`readlink '${p}'`, p, false); + if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) + throw ENOENT(`readlink '${p}'`); + if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) + throw ENOTDIR(`open '${p}'`); + if (this.listings.has(resolvedP)) + throw EINVAL(`readlink '${p}'`); + const entry = this.entries.get(resolvedP); + if (entry === void 0) + throw new Error(`Unreachable`); + if (!this.isSymbolicLink(entry)) + throw EINVAL(`readlink '${p}'`); + return entry; + } + async truncatePromise(p, len = 0) { + const resolvedP = this.resolveFilename(`open '${p}'`, p); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`open '${p}'`); + const source = await this.getFileSource(index, { asyncDecompress: true }); + const truncated = Buffer.alloc(len, 0); + source.copy(truncated); + return await this.writeFilePromise(p, truncated); + } + truncateSync(p, len = 0) { + const resolvedP = this.resolveFilename(`open '${p}'`, p); + const index = this.entries.get(resolvedP); + if (typeof index === `undefined`) + throw EINVAL(`open '${p}'`); + const source = this.getFileSource(index); + const truncated = Buffer.alloc(len, 0); + source.copy(truncated); + return this.writeFileSync(p, truncated); + } + async ftruncatePromise(fd, len) { + return this.truncatePromise(this.fdToPath(fd, `ftruncate`), len); + } + ftruncateSync(fd, len) { + return this.truncateSync(this.fdToPath(fd, `ftruncateSync`), len); + } + watch(p, a, b) { + let persistent; + switch (typeof a) { + case `function`: + case `string`: + case `undefined`: + { + persistent = true; + } + break; + default: + { + ({ persistent = true } = a); + } + break; + } + if (!persistent) + return { on: () => { + }, close: () => { + } }; + const interval = setInterval(() => { + }, 24 * 60 * 60 * 1e3); + return { on: () => { + }, close: () => { + clearInterval(interval); + } }; + } + watchFile(p, a, b) { + const resolvedP = ppath.resolve(PortablePath.root, p); + return watchFile(this, resolvedP, a, b); + } + unwatchFile(p, cb) { + const resolvedP = ppath.resolve(PortablePath.root, p); + return unwatchFile(this, resolvedP, cb); + } +} + +setFactory(() => { + const emZip = createModule(); + return makeInterface(emZip); +}); + +var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => { + ErrorCode2["API_ERROR"] = `API_ERROR`; + ErrorCode2["BUILTIN_NODE_RESOLUTION_FAILED"] = `BUILTIN_NODE_RESOLUTION_FAILED`; + ErrorCode2["EXPORTS_RESOLUTION_FAILED"] = `EXPORTS_RESOLUTION_FAILED`; + ErrorCode2["MISSING_DEPENDENCY"] = `MISSING_DEPENDENCY`; + ErrorCode2["MISSING_PEER_DEPENDENCY"] = `MISSING_PEER_DEPENDENCY`; + ErrorCode2["QUALIFIED_PATH_RESOLUTION_FAILED"] = `QUALIFIED_PATH_RESOLUTION_FAILED`; + ErrorCode2["INTERNAL"] = `INTERNAL`; + ErrorCode2["UNDECLARED_DEPENDENCY"] = `UNDECLARED_DEPENDENCY`; + ErrorCode2["UNSUPPORTED"] = `UNSUPPORTED`; + return ErrorCode2; +})(ErrorCode || {}); +const MODULE_NOT_FOUND_ERRORS = /* @__PURE__ */ new Set([ + "BUILTIN_NODE_RESOLUTION_FAILED" /* BUILTIN_NODE_RESOLUTION_FAILED */, + "MISSING_DEPENDENCY" /* MISSING_DEPENDENCY */, + "MISSING_PEER_DEPENDENCY" /* MISSING_PEER_DEPENDENCY */, + "QUALIFIED_PATH_RESOLUTION_FAILED" /* QUALIFIED_PATH_RESOLUTION_FAILED */, + "UNDECLARED_DEPENDENCY" /* UNDECLARED_DEPENDENCY */ +]); +function makeError(pnpCode, message, data = {}, code) { + code ?? (code = MODULE_NOT_FOUND_ERRORS.has(pnpCode) ? `MODULE_NOT_FOUND` : pnpCode); + const propertySpec = { + configurable: true, + writable: true, + enumerable: false + }; + return Object.defineProperties(new Error(message), { + code: { + ...propertySpec, + value: code + }, + pnpCode: { + ...propertySpec, + value: pnpCode + }, + data: { + ...propertySpec, + value: data + } + }); +} +function getIssuerModule(parent) { + let issuer = parent; + while (issuer && (issuer.id === `[eval]` || issuer.id === `` || !issuer.filename)) + issuer = issuer.parent; + return issuer || null; +} +function getPathForDisplay(p) { + return npath.normalize(npath.fromPortablePath(p)); +} + +const [major, minor] = process.versions.node.split(`.`).map((value) => parseInt(value, 10)); +const WATCH_MODE_MESSAGE_USES_ARRAYS = major > 19 || major === 19 && minor >= 2 || major === 18 && minor >= 13; + +const builtinModules = new Set(require$$0.Module.builtinModules || Object.keys(process.binding(`natives`))); +const isBuiltinModule = (request) => request.startsWith(`node:`) || builtinModules.has(request); +function readPackageScope(checkPath) { + const rootSeparatorIndex = checkPath.indexOf(npath.sep); + let separatorIndex; + do { + separatorIndex = checkPath.lastIndexOf(npath.sep); + checkPath = checkPath.slice(0, separatorIndex); + if (checkPath.endsWith(`${npath.sep}node_modules`)) + return false; + const pjson = readPackage(checkPath + npath.sep); + if (pjson) { + return { + data: pjson, + path: checkPath + }; + } + } while (separatorIndex > rootSeparatorIndex); + return false; +} +function readPackage(requestPath) { + const jsonPath = npath.resolve(requestPath, `package.json`); + if (!fs__default.default.existsSync(jsonPath)) + return null; + return JSON.parse(fs__default.default.readFileSync(jsonPath, `utf8`)); +} +function ERR_REQUIRE_ESM(filename, parentPath = null) { + const basename = parentPath && path__default.default.basename(filename) === path__default.default.basename(parentPath) ? filename : path__default.default.basename(filename); + const msg = `require() of ES Module ${filename}${parentPath ? ` from ${parentPath}` : ``} not supported. +Instead change the require of ${basename} in ${parentPath} to a dynamic import() which is available in all CommonJS modules.`; + const err = new Error(msg); + err.code = `ERR_REQUIRE_ESM`; + return err; +} +function reportRequiredFilesToWatchMode(files) { + if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) { + files = files.map((filename) => npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename)))); + if (WATCH_MODE_MESSAGE_USES_ARRAYS) { + process.send({ "watch:require": files }); + } else { + for (const filename of files) { + process.send({ "watch:require": filename }); + } + } + } +} + +function applyPatch(pnpapi, opts) { + const defaultCache = {}; + let enableNativeHooks = true; + process.versions.pnp = String(pnpapi.VERSIONS.std); + const moduleExports = require$$0__default.default; + moduleExports.findPnpApi = (lookupSource) => { + const lookupPath = lookupSource instanceof url.URL ? url.fileURLToPath(lookupSource) : lookupSource; + const apiPath = opts.manager.findApiPathFor(lookupPath); + if (apiPath === null) + return null; + const apiEntry = opts.manager.getApiEntry(apiPath, true); + return apiEntry.instance.findPackageLocator(lookupPath) ? apiEntry.instance : null; + }; + function getRequireStack(parent) { + const requireStack = []; + for (let cursor = parent; cursor; cursor = cursor.parent) + requireStack.push(cursor.filename || cursor.id); + return requireStack; + } + const originalModuleLoad = require$$0.Module._load; + require$$0.Module._load = function(request, parent, isMain) { + if (!enableNativeHooks) + return originalModuleLoad.call(require$$0.Module, request, parent, isMain); + if (isBuiltinModule(request)) { + try { + enableNativeHooks = false; + return originalModuleLoad.call(require$$0.Module, request, parent, isMain); + } finally { + enableNativeHooks = true; + } + } + const parentApiPath = opts.manager.getApiPathFromParent(parent); + const parentApi = parentApiPath !== null ? opts.manager.getApiEntry(parentApiPath, true).instance : null; + if (parentApi === null) + return originalModuleLoad(request, parent, isMain); + if (request === `pnpapi`) + return parentApi; + const modulePath = require$$0.Module._resolveFilename(request, parent, isMain); + const isOwnedByRuntime = parentApi !== null ? parentApi.findPackageLocator(modulePath) !== null : false; + const moduleApiPath = isOwnedByRuntime ? parentApiPath : opts.manager.findApiPathFor(npath.dirname(modulePath)); + const entry = moduleApiPath !== null ? opts.manager.getApiEntry(moduleApiPath) : { instance: null, cache: defaultCache }; + const cacheEntry = entry.cache[modulePath]; + if (cacheEntry) { + if (cacheEntry.loaded === false && cacheEntry.isLoading !== true) { + try { + cacheEntry.isLoading = true; + if (isMain) { + process.mainModule = cacheEntry; + cacheEntry.id = `.`; + } + cacheEntry.load(modulePath); + } finally { + cacheEntry.isLoading = false; + } + } + return cacheEntry.exports; + } + const module = new require$$0.Module(modulePath, parent ?? void 0); + module.pnpApiPath = moduleApiPath; + reportRequiredFilesToWatchMode([modulePath]); + entry.cache[modulePath] = module; + if (isMain) { + process.mainModule = module; + module.id = `.`; + } + let hasThrown = true; + try { + module.isLoading = true; + module.load(modulePath); + hasThrown = false; + } finally { + module.isLoading = false; + if (hasThrown) { + delete require$$0.Module._cache[modulePath]; + } + } + return module.exports; + }; + function getIssuerSpecsFromPaths(paths) { + return paths.map((path) => ({ + apiPath: opts.manager.findApiPathFor(path), + path, + module: null + })); + } + function getIssuerSpecsFromModule(module) { + if (module && module.id !== `` && module.id !== `internal/preload` && !module.parent && !module.filename && module.paths.length > 0) { + return [{ + apiPath: opts.manager.findApiPathFor(module.paths[0]), + path: module.paths[0], + module + }]; + } + const issuer = getIssuerModule(module); + if (issuer !== null) { + const path = npath.dirname(issuer.filename); + const apiPath = opts.manager.getApiPathFromParent(issuer); + return [{ apiPath, path, module }]; + } else { + const path = process.cwd(); + const apiPath = opts.manager.findApiPathFor(npath.join(path, `[file]`)) ?? opts.manager.getApiPathFromParent(null); + return [{ apiPath, path, module }]; + } + } + function makeFakeParent(path) { + const fakeParent = new require$$0.Module(``); + const fakeFilePath = npath.join(path, `[file]`); + fakeParent.paths = require$$0.Module._nodeModulePaths(fakeFilePath); + return fakeParent; + } + const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/; + const originalModuleResolveFilename = require$$0.Module._resolveFilename; + require$$0.Module._resolveFilename = function(request, parent, isMain, options) { + if (isBuiltinModule(request)) + return request; + if (!enableNativeHooks) + return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, options); + if (options && options.plugnplay === false) { + const { plugnplay, ...rest } = options; + const forwardedOptions = Object.keys(rest).length > 0 ? rest : void 0; + try { + enableNativeHooks = false; + return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, forwardedOptions); + } finally { + enableNativeHooks = true; + } + } + if (options) { + const optionNames = new Set(Object.keys(options)); + optionNames.delete(`paths`); + optionNames.delete(`plugnplay`); + if (optionNames.size > 0) { + throw makeError( + ErrorCode.UNSUPPORTED, + `Some options passed to require() aren't supported by PnP yet (${Array.from(optionNames).join(`, `)})` + ); + } + } + const issuerSpecs = options && options.paths ? getIssuerSpecsFromPaths(options.paths) : getIssuerSpecsFromModule(parent); + if (request.match(pathRegExp) === null) { + const parentDirectory = (parent == null ? void 0 : parent.filename) != null ? npath.dirname(parent.filename) : null; + const absoluteRequest = npath.isAbsolute(request) ? request : parentDirectory !== null ? npath.resolve(parentDirectory, request) : null; + if (absoluteRequest !== null) { + const apiPath = parentDirectory === npath.dirname(absoluteRequest) && (parent == null ? void 0 : parent.pnpApiPath) ? parent.pnpApiPath : opts.manager.findApiPathFor(absoluteRequest); + if (apiPath !== null) { + issuerSpecs.unshift({ + apiPath, + path: parentDirectory, + module: null + }); + } + } + } + let firstError; + for (const { apiPath, path, module } of issuerSpecs) { + let resolution; + const issuerApi = apiPath !== null ? opts.manager.getApiEntry(apiPath, true).instance : null; + try { + if (issuerApi !== null) { + resolution = issuerApi.resolveRequest(request, path !== null ? `${path}/` : null); + } else { + if (path === null) + throw new Error(`Assertion failed: Expected the path to be set`); + resolution = originalModuleResolveFilename.call(require$$0.Module, request, module || makeFakeParent(path), isMain); + } + } catch (error) { + firstError = firstError || error; + continue; + } + if (resolution !== null) { + return resolution; + } + } + const requireStack = getRequireStack(parent); + Object.defineProperty(firstError, `requireStack`, { + configurable: true, + writable: true, + enumerable: false, + value: requireStack + }); + if (requireStack.length > 0) + firstError.message += ` +Require stack: +- ${requireStack.join(` +- `)}`; + if (typeof firstError.pnpCode === `string`) + Error.captureStackTrace(firstError); + throw firstError; + }; + const originalFindPath = require$$0.Module._findPath; + require$$0.Module._findPath = function(request, paths, isMain) { + if (request === `pnpapi`) + return false; + if (!enableNativeHooks) + return originalFindPath.call(require$$0.Module, request, paths, isMain); + const isAbsolute = npath.isAbsolute(request); + if (isAbsolute) + paths = [``]; + else if (!paths || paths.length === 0) + return false; + for (const path of paths) { + let resolution; + try { + const pnpApiPath = opts.manager.findApiPathFor(isAbsolute ? request : path); + if (pnpApiPath !== null) { + const api = opts.manager.getApiEntry(pnpApiPath, true).instance; + resolution = api.resolveRequest(request, path) || false; + } else { + resolution = originalFindPath.call(require$$0.Module, request, [path], isMain); + } + } catch (error) { + continue; + } + if (resolution) { + return resolution; + } + } + return false; + }; + const originalExtensionJSFunction = require$$0.Module._extensions[`.js`]; + require$$0.Module._extensions[`.js`] = function(module, filename) { + var _a, _b; + if (filename.endsWith(`.js`)) { + const pkg = readPackageScope(filename); + if (pkg && ((_a = pkg.data) == null ? void 0 : _a.type) === `module`) { + const err = ERR_REQUIRE_ESM(filename, (_b = module.parent) == null ? void 0 : _b.filename); + Error.captureStackTrace(err); + throw err; + } + } + originalExtensionJSFunction.call(this, module, filename); + }; + const originalDlopen = process.dlopen; + process.dlopen = function(...args) { + const [module, filename, ...rest] = args; + return originalDlopen.call( + this, + module, + npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename))), + ...rest + ); + }; + const originalEmit = process.emit; + process.emit = function(name, data, ...args) { + if (name === `warning` && typeof data === `object` && data.name === `ExperimentalWarning` && (data.message.includes(`--experimental-loader`) || data.message.includes(`Custom ESM Loaders is an experimental feature`))) + return false; + return originalEmit.apply(process, arguments); + }; + patchFs(fs__default.default, new PosixFS(opts.fakeFs)); +} + +function hydrateRuntimeState(data, { basePath }) { + const portablePath = npath.toPortablePath(basePath); + const absolutePortablePath = ppath.resolve(portablePath); + const ignorePattern = data.ignorePatternData !== null ? new RegExp(data.ignorePatternData) : null; + const packageLocatorsByLocations = /* @__PURE__ */ new Map(); + const packageRegistry = new Map(data.packageRegistryData.map(([packageName, packageStoreData]) => { + return [packageName, new Map(packageStoreData.map(([packageReference, packageInformationData]) => { + if (packageName === null !== (packageReference === null)) + throw new Error(`Assertion failed: The name and reference should be null, or neither should`); + const discardFromLookup = packageInformationData.discardFromLookup ?? false; + const packageLocator = { name: packageName, reference: packageReference }; + const entry = packageLocatorsByLocations.get(packageInformationData.packageLocation); + if (!entry) { + packageLocatorsByLocations.set(packageInformationData.packageLocation, { locator: packageLocator, discardFromLookup }); + } else { + entry.discardFromLookup = entry.discardFromLookup && discardFromLookup; + if (!discardFromLookup) { + entry.locator = packageLocator; + } + } + let resolvedPackageLocation = null; + return [packageReference, { + packageDependencies: new Map(packageInformationData.packageDependencies), + packagePeers: new Set(packageInformationData.packagePeers), + linkType: packageInformationData.linkType, + discardFromLookup, + get packageLocation() { + return resolvedPackageLocation || (resolvedPackageLocation = ppath.join(absolutePortablePath, packageInformationData.packageLocation)); + } + }]; + }))]; + })); + const fallbackExclusionList = new Map(data.fallbackExclusionList.map(([packageName, packageReferences]) => { + return [packageName, new Set(packageReferences)]; + })); + const fallbackPool = new Map(data.fallbackPool); + const dependencyTreeRoots = data.dependencyTreeRoots; + const enableTopLevelFallback = data.enableTopLevelFallback; + return { + basePath: portablePath, + dependencyTreeRoots, + enableTopLevelFallback, + fallbackExclusionList, + fallbackPool, + ignorePattern, + packageLocatorsByLocations, + packageRegistry + }; +} + +/** + * @param {object} exports + * @param {Set} keys + */ +function loop(exports, keys) { + if (typeof exports === 'string') { + return exports; + } + + if (exports) { + let idx, tmp; + if (Array.isArray(exports)) { + for (idx=0; idx < exports.length; idx++) { + if (tmp = loop(exports[idx], keys)) return tmp; + } + } else { + for (idx in exports) { + if (keys.has(idx)) { + return loop(exports[idx], keys); + } + } + } + } +} + +/** + * @param {string} name The package name + * @param {string} entry The target entry, eg "." + * @param {number} [condition] Unmatched condition? + */ +function bail(name, entry, condition) { + throw new Error( + condition + ? `No known conditions for "${entry}" entry in "${name}" package` + : `Missing "${entry}" export in "${name}" package` + ); +} + +/** + * @param {string} name the package name + * @param {string} entry the target path/import + */ +function toName(name, entry) { + return entry === name ? '.' + : entry[0] === '.' ? entry + : entry.replace(new RegExp('^' + name + '\/'), './'); +} + +/** + * @param {object} pkg package.json contents + * @param {string} [entry] entry name or import path + * @param {object} [options] + * @param {boolean} [options.browser] + * @param {boolean} [options.require] + * @param {string[]} [options.conditions] + * @param {boolean} [options.unsafe] + */ +function resolve(pkg, entry='.', options={}) { + let { name, exports } = pkg; + + if (exports) { + let { browser, require, unsafe, conditions=[] } = options; + + let target = toName(name, entry); + if (target[0] !== '.') target = './' + target; + + if (typeof exports === 'string') { + return target === '.' ? exports : bail(name, target); + } + + let allows = new Set(['default', ...conditions]); + unsafe || allows.add(require ? 'require' : 'import'); + unsafe || allows.add(browser ? 'browser' : 'node'); + + let key, tmp, isSingle=false; + + for (key in exports) { + isSingle = key[0] !== '.'; + break; + } + + if (isSingle) { + return target === '.' + ? loop(exports, allows) || bail(name, target, 1) + : bail(name, target); + } + + if (tmp = exports[target]) { + return loop(tmp, allows) || bail(name, target, 1); + } + + for (key in exports) { + tmp = key[key.length - 1]; + if (tmp === '/' && target.startsWith(key)) { + return (tmp = loop(exports[key], allows)) + ? (tmp + target.substring(key.length)) + : bail(name, target, 1); + } + if (tmp === '*' && target.startsWith(key.slice(0, -1))) { + // do not trigger if no *content* to inject + if (target.substring(key.length - 1).length > 0) { + return (tmp = loop(exports[key], allows)) + ? tmp.replace('*', target.substring(key.length - 1)) + : bail(name, target, 1); + } + } + } + + return bail(name, target); + } +} + +const ArrayIsArray = Array.isArray; +const JSONStringify = JSON.stringify; +const ObjectGetOwnPropertyNames = Object.getOwnPropertyNames; +const ObjectPrototypeHasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); +const RegExpPrototypeExec = (obj, string) => RegExp.prototype.exec.call(obj, string); +const RegExpPrototypeSymbolReplace = (obj, ...rest) => RegExp.prototype[Symbol.replace].apply(obj, rest); +const StringPrototypeEndsWith = (str, ...rest) => String.prototype.endsWith.apply(str, rest); +const StringPrototypeIncludes = (str, ...rest) => String.prototype.includes.apply(str, rest); +const StringPrototypeLastIndexOf = (str, ...rest) => String.prototype.lastIndexOf.apply(str, rest); +const StringPrototypeIndexOf = (str, ...rest) => String.prototype.indexOf.apply(str, rest); +const StringPrototypeReplace = (str, ...rest) => String.prototype.replace.apply(str, rest); +const StringPrototypeSlice = (str, ...rest) => String.prototype.slice.apply(str, rest); +const StringPrototypeStartsWith = (str, ...rest) => String.prototype.startsWith.apply(str, rest); +const SafeMap = Map; +const JSONParse = JSON.parse; + +function createErrorType(code, messageCreator, errorType) { + return class extends errorType { + constructor(...args) { + super(messageCreator(...args)); + this.code = code; + this.name = `${errorType.name} [${code}]`; + } + }; +} +const ERR_PACKAGE_IMPORT_NOT_DEFINED = createErrorType( + `ERR_PACKAGE_IMPORT_NOT_DEFINED`, + (specifier, packagePath, base) => { + return `Package import specifier "${specifier}" is not defined${packagePath ? ` in package ${packagePath}package.json` : ``} imported from ${base}`; + }, + TypeError +); +const ERR_INVALID_MODULE_SPECIFIER = createErrorType( + `ERR_INVALID_MODULE_SPECIFIER`, + (request, reason, base = void 0) => { + return `Invalid module "${request}" ${reason}${base ? ` imported from ${base}` : ``}`; + }, + TypeError +); +const ERR_INVALID_PACKAGE_TARGET = createErrorType( + `ERR_INVALID_PACKAGE_TARGET`, + (pkgPath, key, target, isImport = false, base = void 0) => { + const relError = typeof target === `string` && !isImport && target.length && !StringPrototypeStartsWith(target, `./`); + if (key === `.`) { + assert__default.default(isImport === false); + return `Invalid "exports" main target ${JSONStringify(target)} defined in the package config ${pkgPath}package.json${base ? ` imported from ${base}` : ``}${relError ? `; targets must start with "./"` : ``}`; + } + return `Invalid "${isImport ? `imports` : `exports`}" target ${JSONStringify( + target + )} defined for '${key}' in the package config ${pkgPath}package.json${base ? ` imported from ${base}` : ``}${relError ? `; targets must start with "./"` : ``}`; + }, + Error +); +const ERR_INVALID_PACKAGE_CONFIG = createErrorType( + `ERR_INVALID_PACKAGE_CONFIG`, + (path, base, message) => { + return `Invalid package config ${path}${base ? ` while importing ${base}` : ``}${message ? `. ${message}` : ``}`; + }, + Error +); + +function filterOwnProperties(source, keys) { + const filtered = /* @__PURE__ */ Object.create(null); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (ObjectPrototypeHasOwnProperty(source, key)) { + filtered[key] = source[key]; + } + } + return filtered; +} + +const packageJSONCache = new SafeMap(); +function getPackageConfig(path, specifier, base, readFileSyncFn) { + const existing = packageJSONCache.get(path); + if (existing !== void 0) { + return existing; + } + const source = readFileSyncFn(path); + if (source === void 0) { + const packageConfig2 = { + pjsonPath: path, + exists: false, + main: void 0, + name: void 0, + type: "none", + exports: void 0, + imports: void 0 + }; + packageJSONCache.set(path, packageConfig2); + return packageConfig2; + } + let packageJSON; + try { + packageJSON = JSONParse(source); + } catch (error) { + throw new ERR_INVALID_PACKAGE_CONFIG( + path, + (base ? `"${specifier}" from ` : "") + url.fileURLToPath(base || specifier), + error.message + ); + } + let { imports, main, name, type } = filterOwnProperties(packageJSON, [ + "imports", + "main", + "name", + "type" + ]); + const exports = ObjectPrototypeHasOwnProperty(packageJSON, "exports") ? packageJSON.exports : void 0; + if (typeof imports !== "object" || imports === null) { + imports = void 0; + } + if (typeof main !== "string") { + main = void 0; + } + if (typeof name !== "string") { + name = void 0; + } + if (type !== "module" && type !== "commonjs") { + type = "none"; + } + const packageConfig = { + pjsonPath: path, + exists: true, + main, + name, + type, + exports, + imports + }; + packageJSONCache.set(path, packageConfig); + return packageConfig; +} +function getPackageScopeConfig(resolved, readFileSyncFn) { + let packageJSONUrl = new URL("./package.json", resolved); + while (true) { + const packageJSONPath2 = packageJSONUrl.pathname; + if (StringPrototypeEndsWith(packageJSONPath2, "node_modules/package.json")) { + break; + } + const packageConfig2 = getPackageConfig( + url.fileURLToPath(packageJSONUrl), + resolved, + void 0, + readFileSyncFn + ); + if (packageConfig2.exists) { + return packageConfig2; + } + const lastPackageJSONUrl = packageJSONUrl; + packageJSONUrl = new URL("../package.json", packageJSONUrl); + if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) { + break; + } + } + const packageJSONPath = url.fileURLToPath(packageJSONUrl); + const packageConfig = { + pjsonPath: packageJSONPath, + exists: false, + main: void 0, + name: void 0, + type: "none", + exports: void 0, + imports: void 0 + }; + packageJSONCache.set(packageJSONPath, packageConfig); + return packageConfig; +} + +/** + @license + Copyright Node.js contributors. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +function throwImportNotDefined(specifier, packageJSONUrl, base) { + throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( + specifier, + packageJSONUrl && url.fileURLToPath(new URL(".", packageJSONUrl)), + url.fileURLToPath(base) + ); +} +function throwInvalidSubpath(subpath, packageJSONUrl, internal, base) { + const reason = `request is not a valid subpath for the "${internal ? "imports" : "exports"}" resolution of ${url.fileURLToPath(packageJSONUrl)}`; + throw new ERR_INVALID_MODULE_SPECIFIER( + subpath, + reason, + base && url.fileURLToPath(base) + ); +} +function throwInvalidPackageTarget(subpath, target, packageJSONUrl, internal, base) { + if (typeof target === "object" && target !== null) { + target = JSONStringify(target, null, ""); + } else { + target = `${target}`; + } + throw new ERR_INVALID_PACKAGE_TARGET( + url.fileURLToPath(new URL(".", packageJSONUrl)), + subpath, + target, + internal, + base && url.fileURLToPath(base) + ); +} +const invalidSegmentRegEx = /(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i; +const patternRegEx = /\*/g; +function resolvePackageTargetString(target, subpath, match, packageJSONUrl, base, pattern, internal, conditions) { + if (subpath !== "" && !pattern && target[target.length - 1] !== "/") + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + if (!StringPrototypeStartsWith(target, "./")) { + if (internal && !StringPrototypeStartsWith(target, "../") && !StringPrototypeStartsWith(target, "/")) { + let isURL = false; + try { + new URL(target); + isURL = true; + } catch { + } + if (!isURL) { + const exportTarget = pattern ? RegExpPrototypeSymbolReplace(patternRegEx, target, () => subpath) : target + subpath; + return exportTarget; + } + } + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + } + if (RegExpPrototypeExec( + invalidSegmentRegEx, + StringPrototypeSlice(target, 2) + ) !== null) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + const resolved = new URL(target, packageJSONUrl); + const resolvedPath = resolved.pathname; + const packagePath = new URL(".", packageJSONUrl).pathname; + if (!StringPrototypeStartsWith(resolvedPath, packagePath)) + throwInvalidPackageTarget(match, target, packageJSONUrl, internal, base); + if (subpath === "") + return resolved; + if (RegExpPrototypeExec(invalidSegmentRegEx, subpath) !== null) { + const request = pattern ? StringPrototypeReplace(match, "*", () => subpath) : match + subpath; + throwInvalidSubpath(request, packageJSONUrl, internal, base); + } + if (pattern) { + return new URL( + RegExpPrototypeSymbolReplace(patternRegEx, resolved.href, () => subpath) + ); + } + return new URL(subpath, resolved); +} +function isArrayIndex(key) { + const keyNum = +key; + if (`${keyNum}` !== key) + return false; + return keyNum >= 0 && keyNum < 4294967295; +} +function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, base, pattern, internal, conditions) { + if (typeof target === "string") { + return resolvePackageTargetString( + target, + subpath, + packageSubpath, + packageJSONUrl, + base, + pattern, + internal); + } else if (ArrayIsArray(target)) { + if (target.length === 0) { + return null; + } + let lastException; + for (let i = 0; i < target.length; i++) { + const targetItem = target[i]; + let resolveResult; + try { + resolveResult = resolvePackageTarget( + packageJSONUrl, + targetItem, + subpath, + packageSubpath, + base, + pattern, + internal, + conditions + ); + } catch (e) { + lastException = e; + if (e.code === "ERR_INVALID_PACKAGE_TARGET") { + continue; + } + throw e; + } + if (resolveResult === void 0) { + continue; + } + if (resolveResult === null) { + lastException = null; + continue; + } + return resolveResult; + } + if (lastException === void 0 || lastException === null) + return lastException; + throw lastException; + } else if (typeof target === "object" && target !== null) { + const keys = ObjectGetOwnPropertyNames(target); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (isArrayIndex(key)) { + throw new ERR_INVALID_PACKAGE_CONFIG( + url.fileURLToPath(packageJSONUrl), + base, + '"exports" cannot contain numeric property keys.' + ); + } + } + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key === "default" || conditions.has(key)) { + const conditionalTarget = target[key]; + const resolveResult = resolvePackageTarget( + packageJSONUrl, + conditionalTarget, + subpath, + packageSubpath, + base, + pattern, + internal, + conditions + ); + if (resolveResult === void 0) + continue; + return resolveResult; + } + } + return void 0; + } else if (target === null) { + return null; + } + throwInvalidPackageTarget( + packageSubpath, + target, + packageJSONUrl, + internal, + base + ); +} +function patternKeyCompare(a, b) { + const aPatternIndex = StringPrototypeIndexOf(a, "*"); + const bPatternIndex = StringPrototypeIndexOf(b, "*"); + const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; + const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; + if (baseLenA > baseLenB) + return -1; + if (baseLenB > baseLenA) + return 1; + if (aPatternIndex === -1) + return 1; + if (bPatternIndex === -1) + return -1; + if (a.length > b.length) + return -1; + if (b.length > a.length) + return 1; + return 0; +} +function packageImportsResolve({ + name, + base, + conditions, + readFileSyncFn +}) { + if (name === "#" || StringPrototypeStartsWith(name, "#/") || StringPrototypeEndsWith(name, "/")) { + const reason = "is not a valid internal imports specifier name"; + throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, url.fileURLToPath(base)); + } + let packageJSONUrl; + const packageConfig = getPackageScopeConfig(base, readFileSyncFn); + if (packageConfig.exists) { + packageJSONUrl = url.pathToFileURL(packageConfig.pjsonPath); + const imports = packageConfig.imports; + if (imports) { + if (ObjectPrototypeHasOwnProperty(imports, name) && !StringPrototypeIncludes(name, "*")) { + const resolveResult = resolvePackageTarget( + packageJSONUrl, + imports[name], + "", + name, + base, + false, + true, + conditions + ); + if (resolveResult != null) { + return resolveResult; + } + } else { + let bestMatch = ""; + let bestMatchSubpath; + const keys = ObjectGetOwnPropertyNames(imports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const patternIndex = StringPrototypeIndexOf(key, "*"); + if (patternIndex !== -1 && StringPrototypeStartsWith( + name, + StringPrototypeSlice(key, 0, patternIndex) + )) { + const patternTrailer = StringPrototypeSlice(key, patternIndex + 1); + if (name.length >= key.length && StringPrototypeEndsWith(name, patternTrailer) && patternKeyCompare(bestMatch, key) === 1 && StringPrototypeLastIndexOf(key, "*") === patternIndex) { + bestMatch = key; + bestMatchSubpath = StringPrototypeSlice( + name, + patternIndex, + name.length - patternTrailer.length + ); + } + } + } + if (bestMatch) { + const target = imports[bestMatch]; + const resolveResult = resolvePackageTarget( + packageJSONUrl, + target, + bestMatchSubpath, + bestMatch, + base, + true, + true, + conditions + ); + if (resolveResult != null) { + return resolveResult; + } + } + } + } + } + throwImportNotDefined(name, packageJSONUrl, base); +} + +const flagSymbol = Symbol('arg flag'); + +class ArgError extends Error { + constructor(msg, code) { + super(msg); + this.name = 'ArgError'; + this.code = code; + + Object.setPrototypeOf(this, ArgError.prototype); + } +} + +function arg( + opts, + { + argv = process.argv.slice(2), + permissive = false, + stopAtPositional = false + } = {} +) { + if (!opts) { + throw new ArgError( + 'argument specification object is required', + 'ARG_CONFIG_NO_SPEC' + ); + } + + const result = { _: [] }; + + const aliases = {}; + const handlers = {}; + + for (const key of Object.keys(opts)) { + if (!key) { + throw new ArgError( + 'argument key cannot be an empty string', + 'ARG_CONFIG_EMPTY_KEY' + ); + } + + if (key[0] !== '-') { + throw new ArgError( + `argument key must start with '-' but found: '${key}'`, + 'ARG_CONFIG_NONOPT_KEY' + ); + } + + if (key.length === 1) { + throw new ArgError( + `argument key must have a name; singular '-' keys are not allowed: ${key}`, + 'ARG_CONFIG_NONAME_KEY' + ); + } + + if (typeof opts[key] === 'string') { + aliases[key] = opts[key]; + continue; + } + + let type = opts[key]; + let isFlag = false; + + if ( + Array.isArray(type) && + type.length === 1 && + typeof type[0] === 'function' + ) { + const [fn] = type; + type = (value, name, prev = []) => { + prev.push(fn(value, name, prev[prev.length - 1])); + return prev; + }; + isFlag = fn === Boolean || fn[flagSymbol] === true; + } else if (typeof type === 'function') { + isFlag = type === Boolean || type[flagSymbol] === true; + } else { + throw new ArgError( + `type missing or not a function or valid array type: ${key}`, + 'ARG_CONFIG_VAD_TYPE' + ); + } + + if (key[1] !== '-' && key.length > 2) { + throw new ArgError( + `short argument keys (with a single hyphen) must have only one character: ${key}`, + 'ARG_CONFIG_SHORTOPT_TOOLONG' + ); + } + + handlers[key] = [type, isFlag]; + } + + for (let i = 0, len = argv.length; i < len; i++) { + const wholeArg = argv[i]; + + if (stopAtPositional && result._.length > 0) { + result._ = result._.concat(argv.slice(i)); + break; + } + + if (wholeArg === '--') { + result._ = result._.concat(argv.slice(i + 1)); + break; + } + + if (wholeArg.length > 1 && wholeArg[0] === '-') { + /* eslint-disable operator-linebreak */ + const separatedArguments = + wholeArg[1] === '-' || wholeArg.length === 2 + ? [wholeArg] + : wholeArg + .slice(1) + .split('') + .map((a) => `-${a}`); + /* eslint-enable operator-linebreak */ + + for (let j = 0; j < separatedArguments.length; j++) { + const arg = separatedArguments[j]; + const [originalArgName, argStr] = + arg[1] === '-' ? arg.split(/=(.*)/, 2) : [arg, undefined]; + + let argName = originalArgName; + while (argName in aliases) { + argName = aliases[argName]; + } + + if (!(argName in handlers)) { + if (permissive) { + result._.push(arg); + continue; + } else { + throw new ArgError( + `unknown or unexpected option: ${originalArgName}`, + 'ARG_UNKNOWN_OPTION' + ); + } + } + + const [type, isFlag] = handlers[argName]; + + if (!isFlag && j + 1 < separatedArguments.length) { + throw new ArgError( + `option requires argument (but was followed by another short argument): ${originalArgName}`, + 'ARG_MISSING_REQUIRED_SHORTARG' + ); + } + + if (isFlag) { + result[argName] = type(true, argName, result[argName]); + } else if (argStr === undefined) { + if ( + argv.length < i + 2 || + (argv[i + 1].length > 1 && + argv[i + 1][0] === '-' && + !( + argv[i + 1].match(/^-?\d*(\.(?=\d))?\d*$/) && + (type === Number || + // eslint-disable-next-line no-undef + (typeof BigInt !== 'undefined' && type === BigInt)) + )) + ) { + const extended = + originalArgName === argName ? '' : ` (alias for ${argName})`; + throw new ArgError( + `option requires argument: ${originalArgName}${extended}`, + 'ARG_MISSING_REQUIRED_LONGARG' + ); + } + + result[argName] = type(argv[i + 1], argName, result[argName]); + ++i; + } else { + result[argName] = type(argStr, argName, result[argName]); + } + } + } else { + result._.push(wholeArg); + } + } + + return result; +} + +arg.flag = (fn) => { + fn[flagSymbol] = true; + return fn; +}; + +// Utility types +arg.COUNT = arg.flag((v, name, existingCount) => (existingCount || 0) + 1); + +// Expose error class +arg.ArgError = ArgError; + +var arg_1 = arg; + +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +function getOptionValue(opt) { + parseOptions(); + return options[opt]; +} +let options; +function parseOptions() { + if (!options) { + options = { + "--conditions": [], + ...parseArgv(getNodeOptionsEnvArgv()), + ...parseArgv(process.execArgv) + }; + } +} +function parseArgv(argv) { + return arg_1( + { + "--conditions": [String], + "-C": "--conditions" + }, + { + argv, + permissive: true + } + ); +} +function getNodeOptionsEnvArgv() { + const errors = []; + const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || "", errors); + if (errors.length !== 0) ; + return envArgv; +} +function ParseNodeOptionsEnvVar(node_options, errors) { + const env_argv = []; + let is_in_string = false; + let will_start_new_arg = true; + for (let index = 0; index < node_options.length; ++index) { + let c = node_options[index]; + if (c === "\\" && is_in_string) { + if (index + 1 === node_options.length) { + errors.push("invalid value for NODE_OPTIONS (invalid escape)\n"); + return env_argv; + } else { + c = node_options[++index]; + } + } else if (c === " " && !is_in_string) { + will_start_new_arg = true; + continue; + } else if (c === '"') { + is_in_string = !is_in_string; + continue; + } + if (will_start_new_arg) { + env_argv.push(c); + will_start_new_arg = false; + } else { + env_argv[env_argv.length - 1] += c; + } + } + if (is_in_string) { + errors.push("invalid value for NODE_OPTIONS (unterminated string)\n"); + } + return env_argv; +} + +function makeApi(runtimeState, opts) { + const alwaysWarnOnFallback = Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK) > 0; + const debugLevel = Number(process.env.PNP_DEBUG_LEVEL); + const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/; + const isStrictRegExp = /^(\/|\.{1,2}(\/|$))/; + const isDirRegExp = /\/$/; + const isRelativeRegexp = /^\.{0,2}\//; + const topLevelLocator = { name: null, reference: null }; + const fallbackLocators = []; + const emittedWarnings = /* @__PURE__ */ new Set(); + if (runtimeState.enableTopLevelFallback === true) + fallbackLocators.push(topLevelLocator); + if (opts.compatibilityMode !== false) { + for (const name of [`react-scripts`, `gatsby`]) { + const packageStore = runtimeState.packageRegistry.get(name); + if (packageStore) { + for (const reference of packageStore.keys()) { + if (reference === null) { + throw new Error(`Assertion failed: This reference shouldn't be null`); + } else { + fallbackLocators.push({ name, reference }); + } + } + } + } + } + const { + ignorePattern, + packageRegistry, + packageLocatorsByLocations + } = runtimeState; + function makeLogEntry(name, args) { + return { + fn: name, + args, + error: null, + result: null + }; + } + function trace(entry) { + var _a, _b, _c, _d; + const colors = ((_b = (_a = process.stderr) == null ? void 0 : _a.hasColors) == null ? void 0 : _b.call(_a)) ?? process.stdout.isTTY; + const c = (n, str) => `\x1B[${n}m${str}\x1B[0m`; + const error = entry.error; + if (error) + console.error(c(`31;1`, `\u2716 ${(_c = entry.error) == null ? void 0 : _c.message.replace(/\n.*/s, ``)}`)); + else + console.error(c(`33;1`, `\u203C Resolution`)); + if (entry.args.length > 0) + console.error(); + for (const arg of entry.args) + console.error(` ${c(`37;1`, `In \u2190`)} ${nodeUtils.inspect(arg, { colors, compact: true })}`); + if (entry.result) { + console.error(); + console.error(` ${c(`37;1`, `Out \u2192`)} ${nodeUtils.inspect(entry.result, { colors, compact: true })}`); + } + const stack = ((_d = new Error().stack.match(/(?<=^ +)at.*/gm)) == null ? void 0 : _d.slice(2)) ?? []; + if (stack.length > 0) { + console.error(); + for (const line of stack) { + console.error(` ${c(`38;5;244`, line)}`); + } + } + console.error(); + } + function maybeLog(name, fn) { + if (opts.allowDebug === false) + return fn; + if (Number.isFinite(debugLevel)) { + if (debugLevel >= 2) { + return (...args) => { + const logEntry = makeLogEntry(name, args); + try { + return logEntry.result = fn(...args); + } catch (error) { + throw logEntry.error = error; + } finally { + trace(logEntry); + } + }; + } else if (debugLevel >= 1) { + return (...args) => { + try { + return fn(...args); + } catch (error) { + const logEntry = makeLogEntry(name, args); + logEntry.error = error; + trace(logEntry); + throw error; + } + }; + } + } + return fn; + } + function getPackageInformationSafe(packageLocator) { + const packageInformation = getPackageInformation(packageLocator); + if (!packageInformation) { + throw makeError( + ErrorCode.INTERNAL, + `Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)` + ); + } + return packageInformation; + } + function isDependencyTreeRoot(packageLocator) { + if (packageLocator.name === null) + return true; + for (const dependencyTreeRoot of runtimeState.dependencyTreeRoots) + if (dependencyTreeRoot.name === packageLocator.name && dependencyTreeRoot.reference === packageLocator.reference) + return true; + return false; + } + const defaultExportsConditions = /* @__PURE__ */ new Set([ + `default`, + `node`, + `require`, + ...getOptionValue(`--conditions`) + ]); + function applyNodeExportsResolution(unqualifiedPath, conditions = defaultExportsConditions) { + const locator = findPackageLocator(ppath.join(unqualifiedPath, `internal.js`), { + resolveIgnored: true, + includeDiscardFromLookup: true + }); + if (locator === null) { + throw makeError( + ErrorCode.INTERNAL, + `The locator that owns the "${unqualifiedPath}" path can't be found inside the dependency tree (this is probably an internal error)` + ); + } + const { packageLocation } = getPackageInformationSafe(locator); + const manifestPath = ppath.join(packageLocation, Filename.manifest); + if (!opts.fakeFs.existsSync(manifestPath)) + return null; + const pkgJson = JSON.parse(opts.fakeFs.readFileSync(manifestPath, `utf8`)); + let subpath = ppath.contains(packageLocation, unqualifiedPath); + if (subpath === null) { + throw makeError( + ErrorCode.INTERNAL, + `unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)` + ); + } + if (!isRelativeRegexp.test(subpath)) + subpath = `./${subpath}`; + let resolvedExport; + try { + resolvedExport = resolve(pkgJson, ppath.normalize(subpath), { + conditions, + unsafe: true + }); + } catch (error) { + throw makeError( + ErrorCode.EXPORTS_RESOLUTION_FAILED, + error.message, + { unqualifiedPath: getPathForDisplay(unqualifiedPath), locator, pkgJson, subpath: getPathForDisplay(subpath), conditions }, + `ERR_PACKAGE_PATH_NOT_EXPORTED` + ); + } + if (typeof resolvedExport === `string`) + return ppath.join(packageLocation, resolvedExport); + return null; + } + function applyNodeExtensionResolution(unqualifiedPath, candidates, { extensions }) { + let stat; + try { + candidates.push(unqualifiedPath); + stat = opts.fakeFs.statSync(unqualifiedPath); + } catch (error) { + } + if (stat && !stat.isDirectory()) + return opts.fakeFs.realpathSync(unqualifiedPath); + if (stat && stat.isDirectory()) { + let pkgJson; + try { + pkgJson = JSON.parse(opts.fakeFs.readFileSync(ppath.join(unqualifiedPath, Filename.manifest), `utf8`)); + } catch (error) { + } + let nextUnqualifiedPath; + if (pkgJson && pkgJson.main) + nextUnqualifiedPath = ppath.resolve(unqualifiedPath, pkgJson.main); + if (nextUnqualifiedPath && nextUnqualifiedPath !== unqualifiedPath) { + const resolution = applyNodeExtensionResolution(nextUnqualifiedPath, candidates, { extensions }); + if (resolution !== null) { + return resolution; + } + } + } + for (let i = 0, length = extensions.length; i < length; i++) { + const candidateFile = `${unqualifiedPath}${extensions[i]}`; + candidates.push(candidateFile); + if (opts.fakeFs.existsSync(candidateFile)) { + return candidateFile; + } + } + if (stat && stat.isDirectory()) { + for (let i = 0, length = extensions.length; i < length; i++) { + const candidateFile = ppath.format({ dir: unqualifiedPath, name: `index`, ext: extensions[i] }); + candidates.push(candidateFile); + if (opts.fakeFs.existsSync(candidateFile)) { + return candidateFile; + } + } + } + return null; + } + function makeFakeModule(path) { + const fakeModule = new require$$0.Module(path, null); + fakeModule.filename = path; + fakeModule.paths = require$$0.Module._nodeModulePaths(path); + return fakeModule; + } + function callNativeResolution(request, issuer) { + if (issuer.endsWith(`/`)) + issuer = ppath.join(issuer, `internal.js`); + return require$$0.Module._resolveFilename(npath.fromPortablePath(request), makeFakeModule(npath.fromPortablePath(issuer)), false, { plugnplay: false }); + } + function isPathIgnored(path) { + if (ignorePattern === null) + return false; + const subPath = ppath.contains(runtimeState.basePath, path); + if (subPath === null) + return false; + if (ignorePattern.test(subPath.replace(/\/$/, ``))) { + return true; + } else { + return false; + } + } + const VERSIONS = { std: 3, resolveVirtual: 1, getAllLocators: 1 }; + const topLevel = topLevelLocator; + function getPackageInformation({ name, reference }) { + const packageInformationStore = packageRegistry.get(name); + if (!packageInformationStore) + return null; + const packageInformation = packageInformationStore.get(reference); + if (!packageInformation) + return null; + return packageInformation; + } + function findPackageDependents({ name, reference }) { + const dependents = []; + for (const [dependentName, packageInformationStore] of packageRegistry) { + if (dependentName === null) + continue; + for (const [dependentReference, packageInformation] of packageInformationStore) { + if (dependentReference === null) + continue; + const dependencyReference = packageInformation.packageDependencies.get(name); + if (dependencyReference !== reference) + continue; + if (dependentName === name && dependentReference === reference) + continue; + dependents.push({ + name: dependentName, + reference: dependentReference + }); + } + } + return dependents; + } + function findBrokenPeerDependencies(dependency, initialPackage) { + const brokenPackages = /* @__PURE__ */ new Map(); + const alreadyVisited = /* @__PURE__ */ new Set(); + const traversal = (currentPackage) => { + const identifier = JSON.stringify(currentPackage.name); + if (alreadyVisited.has(identifier)) + return; + alreadyVisited.add(identifier); + const dependents = findPackageDependents(currentPackage); + for (const dependent of dependents) { + const dependentInformation = getPackageInformationSafe(dependent); + if (dependentInformation.packagePeers.has(dependency)) { + traversal(dependent); + } else { + let brokenSet = brokenPackages.get(dependent.name); + if (typeof brokenSet === `undefined`) + brokenPackages.set(dependent.name, brokenSet = /* @__PURE__ */ new Set()); + brokenSet.add(dependent.reference); + } + } + }; + traversal(initialPackage); + const brokenList = []; + for (const name of [...brokenPackages.keys()].sort()) + for (const reference of [...brokenPackages.get(name)].sort()) + brokenList.push({ name, reference }); + return brokenList; + } + function findPackageLocator(location, { resolveIgnored = false, includeDiscardFromLookup = false } = {}) { + if (isPathIgnored(location) && !resolveIgnored) + return null; + let relativeLocation = ppath.relative(runtimeState.basePath, location); + if (!relativeLocation.match(isStrictRegExp)) + relativeLocation = `./${relativeLocation}`; + if (!relativeLocation.endsWith(`/`)) + relativeLocation = `${relativeLocation}/`; + do { + const entry = packageLocatorsByLocations.get(relativeLocation); + if (typeof entry === `undefined` || entry.discardFromLookup && !includeDiscardFromLookup) { + relativeLocation = relativeLocation.substring(0, relativeLocation.lastIndexOf(`/`, relativeLocation.length - 2) + 1); + continue; + } + return entry.locator; + } while (relativeLocation !== ``); + return null; + } + function tryReadFile(filePath) { + try { + return opts.fakeFs.readFileSync(npath.toPortablePath(filePath), `utf8`); + } catch (err) { + if (err.code === `ENOENT`) + return void 0; + throw err; + } + } + function resolveToUnqualified(request, issuer, { considerBuiltins = true } = {}) { + if (request.startsWith(`#`)) + throw new Error(`resolveToUnqualified can not handle private import mappings`); + if (request === `pnpapi`) + return npath.toPortablePath(opts.pnpapiResolution); + if (considerBuiltins && isBuiltinModule(request)) + return null; + const requestForDisplay = getPathForDisplay(request); + const issuerForDisplay = issuer && getPathForDisplay(issuer); + if (issuer && isPathIgnored(issuer)) { + if (!ppath.isAbsolute(request) || findPackageLocator(request) === null) { + const result = callNativeResolution(request, issuer); + if (result === false) { + throw makeError( + ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED, + `The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${requestForDisplay}" +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + return npath.toPortablePath(result); + } + } + let unqualifiedPath; + const dependencyNameMatch = request.match(pathRegExp); + if (!dependencyNameMatch) { + if (ppath.isAbsolute(request)) { + unqualifiedPath = ppath.normalize(request); + } else { + if (!issuer) { + throw makeError( + ErrorCode.API_ERROR, + `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + const absoluteIssuer = ppath.resolve(issuer); + if (issuer.match(isDirRegExp)) { + unqualifiedPath = ppath.normalize(ppath.join(absoluteIssuer, request)); + } else { + unqualifiedPath = ppath.normalize(ppath.join(ppath.dirname(absoluteIssuer), request)); + } + } + } else { + if (!issuer) { + throw makeError( + ErrorCode.API_ERROR, + `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + const [, dependencyName, subPath] = dependencyNameMatch; + const issuerLocator = findPackageLocator(issuer); + if (!issuerLocator) { + const result = callNativeResolution(request, issuer); + if (result === false) { + throw makeError( + ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED, + `The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${requestForDisplay}" +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay } + ); + } + return npath.toPortablePath(result); + } + const issuerInformation = getPackageInformationSafe(issuerLocator); + let dependencyReference = issuerInformation.packageDependencies.get(dependencyName); + let fallbackReference = null; + if (dependencyReference == null) { + if (issuerLocator.name !== null) { + const exclusionEntry = runtimeState.fallbackExclusionList.get(issuerLocator.name); + const canUseFallbacks = !exclusionEntry || !exclusionEntry.has(issuerLocator.reference); + if (canUseFallbacks) { + for (let t = 0, T = fallbackLocators.length; t < T; ++t) { + const fallbackInformation = getPackageInformationSafe(fallbackLocators[t]); + const reference = fallbackInformation.packageDependencies.get(dependencyName); + if (reference == null) + continue; + if (alwaysWarnOnFallback) + fallbackReference = reference; + else + dependencyReference = reference; + break; + } + if (runtimeState.enableTopLevelFallback) { + if (dependencyReference == null && fallbackReference === null) { + const reference = runtimeState.fallbackPool.get(dependencyName); + if (reference != null) { + fallbackReference = reference; + } + } + } + } + } + } + let error = null; + if (dependencyReference === null) { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `Your application tried to access ${dependencyName} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + const brokenAncestors = findBrokenPeerDependencies(dependencyName, issuerLocator); + if (brokenAncestors.every((ancestor) => isDependencyTreeRoot(ancestor))) { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} +`).join(``)} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors } + ); + } else { + error = makeError( + ErrorCode.MISSING_PEER_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) + +${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} +`).join(``)} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors } + ); + } + } + } else if (dependencyReference === void 0) { + if (!considerBuiltins && isBuiltinModule(request)) { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `Your application tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in ${issuerLocator.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName } + ); + } + } else { + if (isDependencyTreeRoot(issuerLocator)) { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `Your application tried to access ${dependencyName}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerForDisplay} +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyName } + ); + } else { + error = makeError( + ErrorCode.UNDECLARED_DEPENDENCY, + `${issuerLocator.name} tried to access ${dependencyName}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +`, + { request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName } + ); + } + } + } + if (dependencyReference == null) { + if (fallbackReference === null || error === null) + throw error || new Error(`Assertion failed: Expected an error to have been set`); + dependencyReference = fallbackReference; + const message = error.message.replace(/\n.*/g, ``); + error.message = message; + if (!emittedWarnings.has(message) && debugLevel !== 0) { + emittedWarnings.add(message); + process.emitWarning(error); + } + } + const dependencyLocator = Array.isArray(dependencyReference) ? { name: dependencyReference[0], reference: dependencyReference[1] } : { name: dependencyName, reference: dependencyReference }; + const dependencyInformation = getPackageInformationSafe(dependencyLocator); + if (!dependencyInformation.packageLocation) { + throw makeError( + ErrorCode.MISSING_DEPENDENCY, + `A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${dependencyLocator.name}@${dependencyLocator.reference}${dependencyLocator.name !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} +Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) +`, + { request: requestForDisplay, issuer: issuerForDisplay, dependencyLocator: Object.assign({}, dependencyLocator) } + ); + } + const dependencyLocation = dependencyInformation.packageLocation; + if (subPath) { + unqualifiedPath = ppath.join(dependencyLocation, subPath); + } else { + unqualifiedPath = dependencyLocation; + } + } + return ppath.normalize(unqualifiedPath); + } + function resolveUnqualifiedExport(request, unqualifiedPath, conditions = defaultExportsConditions) { + if (isStrictRegExp.test(request)) + return unqualifiedPath; + const unqualifiedExportPath = applyNodeExportsResolution(unqualifiedPath, conditions); + if (unqualifiedExportPath) { + return ppath.normalize(unqualifiedExportPath); + } else { + return unqualifiedPath; + } + } + function resolveUnqualified(unqualifiedPath, { extensions = Object.keys(require$$0.Module._extensions) } = {}) { + const candidates = []; + const qualifiedPath = applyNodeExtensionResolution(unqualifiedPath, candidates, { extensions }); + if (qualifiedPath) { + return ppath.normalize(qualifiedPath); + } else { + reportRequiredFilesToWatchMode(candidates.map((candidate) => npath.fromPortablePath(candidate))); + const unqualifiedPathForDisplay = getPathForDisplay(unqualifiedPath); + const containingPackage = findPackageLocator(unqualifiedPath); + if (containingPackage) { + const { packageLocation } = getPackageInformationSafe(containingPackage); + let exists = true; + try { + opts.fakeFs.accessSync(packageLocation); + } catch (err) { + if ((err == null ? void 0 : err.code) === `ENOENT`) { + exists = false; + } else { + const readableError = ((err == null ? void 0 : err.message) ?? err ?? `empty exception thrown`).replace(/^[A-Z]/, ($0) => $0.toLowerCase()); + throw makeError(ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, `Required package exists but could not be accessed (${readableError}). + +Missing package: ${containingPackage.name}@${containingPackage.reference} +Expected package location: ${getPathForDisplay(packageLocation)} +`, { unqualifiedPath: unqualifiedPathForDisplay, extensions }); + } + } + if (!exists) { + const errorMessage = packageLocation.includes(`/unplugged/`) ? `Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).` : `Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.`; + throw makeError( + ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, + `${errorMessage} + +Missing package: ${containingPackage.name}@${containingPackage.reference} +Expected package location: ${getPathForDisplay(packageLocation)} +`, + { unqualifiedPath: unqualifiedPathForDisplay, extensions } + ); + } + } + throw makeError( + ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, + `Qualified path resolution failed: we looked for the following paths, but none could be accessed. + +Source path: ${unqualifiedPathForDisplay} +${candidates.map((candidate) => `Not found: ${getPathForDisplay(candidate)} +`).join(``)}`, + { unqualifiedPath: unqualifiedPathForDisplay, extensions } + ); + } + } + function resolvePrivateRequest(request, issuer, opts2) { + if (!issuer) + throw new Error(`Assertion failed: An issuer is required to resolve private import mappings`); + const resolved = packageImportsResolve({ + name: request, + base: url.pathToFileURL(npath.fromPortablePath(issuer)), + conditions: opts2.conditions ?? defaultExportsConditions, + readFileSyncFn: tryReadFile + }); + if (resolved instanceof URL) { + return resolveUnqualified(npath.toPortablePath(url.fileURLToPath(resolved)), { extensions: opts2.extensions }); + } else { + if (resolved.startsWith(`#`)) + throw new Error(`Mapping from one private import to another isn't allowed`); + return resolveRequest(resolved, issuer, opts2); + } + } + function resolveRequest(request, issuer, opts2 = {}) { + try { + if (request.startsWith(`#`)) + return resolvePrivateRequest(request, issuer, opts2); + const { considerBuiltins, extensions, conditions } = opts2; + const unqualifiedPath = resolveToUnqualified(request, issuer, { considerBuiltins }); + if (request === `pnpapi`) + return unqualifiedPath; + if (unqualifiedPath === null) + return null; + const isIssuerIgnored = () => issuer !== null ? isPathIgnored(issuer) : false; + const remappedPath = (!considerBuiltins || !isBuiltinModule(request)) && !isIssuerIgnored() ? resolveUnqualifiedExport(request, unqualifiedPath, conditions) : unqualifiedPath; + return resolveUnqualified(remappedPath, { extensions }); + } catch (error) { + if (Object.prototype.hasOwnProperty.call(error, `pnpCode`)) + Object.assign(error.data, { request: getPathForDisplay(request), issuer: issuer && getPathForDisplay(issuer) }); + throw error; + } + } + function resolveVirtual(request) { + const normalized = ppath.normalize(request); + const resolved = VirtualFS.resolveVirtual(normalized); + return resolved !== normalized ? resolved : null; + } + return { + VERSIONS, + topLevel, + getLocator: (name, referencish) => { + if (Array.isArray(referencish)) { + return { name: referencish[0], reference: referencish[1] }; + } else { + return { name, reference: referencish }; + } + }, + getDependencyTreeRoots: () => { + return [...runtimeState.dependencyTreeRoots]; + }, + getAllLocators() { + const locators = []; + for (const [name, entry] of packageRegistry) + for (const reference of entry.keys()) + if (name !== null && reference !== null) + locators.push({ name, reference }); + return locators; + }, + getPackageInformation: (locator) => { + const info = getPackageInformation(locator); + if (info === null) + return null; + const packageLocation = npath.fromPortablePath(info.packageLocation); + const nativeInfo = { ...info, packageLocation }; + return nativeInfo; + }, + findPackageLocator: (path) => { + return findPackageLocator(npath.toPortablePath(path)); + }, + resolveToUnqualified: maybeLog(`resolveToUnqualified`, (request, issuer, opts2) => { + const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; + const resolution = resolveToUnqualified(npath.toPortablePath(request), portableIssuer, opts2); + if (resolution === null) + return null; + return npath.fromPortablePath(resolution); + }), + resolveUnqualified: maybeLog(`resolveUnqualified`, (unqualifiedPath, opts2) => { + return npath.fromPortablePath(resolveUnqualified(npath.toPortablePath(unqualifiedPath), opts2)); + }), + resolveRequest: maybeLog(`resolveRequest`, (request, issuer, opts2) => { + const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; + const resolution = resolveRequest(npath.toPortablePath(request), portableIssuer, opts2); + if (resolution === null) + return null; + return npath.fromPortablePath(resolution); + }), + resolveVirtual: maybeLog(`resolveVirtual`, (path) => { + const result = resolveVirtual(npath.toPortablePath(path)); + if (result !== null) { + return npath.fromPortablePath(result); + } else { + return null; + } + }) + }; +} + +function makeManager(pnpapi, opts) { + const initialApiPath = npath.toPortablePath(pnpapi.resolveToUnqualified(`pnpapi`, null)); + const initialApiStats = opts.fakeFs.statSync(npath.toPortablePath(initialApiPath)); + const apiMetadata = /* @__PURE__ */ new Map([ + [initialApiPath, { + cache: require$$0.Module._cache, + instance: pnpapi, + stats: initialApiStats, + lastRefreshCheck: Date.now() + }] + ]); + function loadApiInstance(pnpApiPath) { + const nativePath = npath.fromPortablePath(pnpApiPath); + const module = new require$$0.Module(nativePath, null); + module.load(nativePath); + return module.exports; + } + function refreshApiEntry(pnpApiPath, apiEntry) { + const timeNow = Date.now(); + if (timeNow - apiEntry.lastRefreshCheck < 500) + return; + apiEntry.lastRefreshCheck = timeNow; + const stats = opts.fakeFs.statSync(pnpApiPath); + if (stats.mtime > apiEntry.stats.mtime) { + process.emitWarning(`[Warning] The runtime detected new information in a PnP file; reloading the API instance (${npath.fromPortablePath(pnpApiPath)})`); + apiEntry.stats = stats; + apiEntry.instance = loadApiInstance(pnpApiPath); + } + } + function getApiEntry(pnpApiPath, refresh = false) { + let apiEntry = apiMetadata.get(pnpApiPath); + if (typeof apiEntry !== `undefined`) { + if (refresh) { + refreshApiEntry(pnpApiPath, apiEntry); + } + } else { + apiMetadata.set(pnpApiPath, apiEntry = { + cache: {}, + instance: loadApiInstance(pnpApiPath), + stats: opts.fakeFs.statSync(pnpApiPath), + lastRefreshCheck: Date.now() + }); + } + return apiEntry; + } + const findApiPathCache = /* @__PURE__ */ new Map(); + function addToCacheAndReturn(start, end, target) { + if (target !== null) + target = VirtualFS.resolveVirtual(target); + let curr; + let next = start; + do { + curr = next; + findApiPathCache.set(curr, target); + next = ppath.dirname(curr); + } while (curr !== end); + return target; + } + function findApiPathFor(modulePath) { + let bestCandidate = null; + for (const [apiPath, apiEntry] of apiMetadata) { + const locator = apiEntry.instance.findPackageLocator(modulePath); + if (!locator) + continue; + if (apiMetadata.size === 1) + return apiPath; + const packageInformation = apiEntry.instance.getPackageInformation(locator); + if (!packageInformation) + throw new Error(`Assertion failed: Couldn't get package information for '${modulePath}'`); + if (!bestCandidate) + bestCandidate = { packageLocation: packageInformation.packageLocation, apiPaths: [] }; + if (packageInformation.packageLocation === bestCandidate.packageLocation) { + bestCandidate.apiPaths.push(apiPath); + } else if (packageInformation.packageLocation.length > bestCandidate.packageLocation.length) { + bestCandidate = { packageLocation: packageInformation.packageLocation, apiPaths: [apiPath] }; + } + } + if (bestCandidate) { + if (bestCandidate.apiPaths.length === 1) + return bestCandidate.apiPaths[0]; + const controlSegment = bestCandidate.apiPaths.map((apiPath) => ` ${npath.fromPortablePath(apiPath)}`).join(` +`); + throw new Error(`Unable to locate pnpapi, the module '${modulePath}' is controlled by multiple pnpapi instances. +This is usually caused by using the global cache (enableGlobalCache: true) + +Controlled by: +${controlSegment} +`); + } + const start = ppath.resolve(npath.toPortablePath(modulePath)); + let curr; + let next = start; + do { + curr = next; + const cached = findApiPathCache.get(curr); + if (cached !== void 0) + return addToCacheAndReturn(start, curr, cached); + const cjsCandidate = ppath.join(curr, Filename.pnpCjs); + if (opts.fakeFs.existsSync(cjsCandidate) && opts.fakeFs.statSync(cjsCandidate).isFile()) + return addToCacheAndReturn(start, curr, cjsCandidate); + const legacyCjsCandidate = ppath.join(curr, Filename.pnpJs); + if (opts.fakeFs.existsSync(legacyCjsCandidate) && opts.fakeFs.statSync(legacyCjsCandidate).isFile()) + return addToCacheAndReturn(start, curr, legacyCjsCandidate); + next = ppath.dirname(curr); + } while (curr !== PortablePath.root); + return addToCacheAndReturn(start, curr, null); + } + function getApiPathFromParent(parent) { + if (parent == null) + return initialApiPath; + if (typeof parent.pnpApiPath === `undefined`) { + if (parent.filename !== null) { + return parent.pnpApiPath = findApiPathFor(parent.filename); + } else { + return initialApiPath; + } + } + if (parent.pnpApiPath !== null) + return parent.pnpApiPath; + return null; + } + return { + getApiPathFromParent, + findApiPathFor, + getApiEntry + }; +} + +const localFs = { ...fs__default.default }; +const nodeFs = new NodeFS(localFs); +const defaultRuntimeState = $$SETUP_STATE(hydrateRuntimeState); +const defaultPnpapiResolution = __filename; +const defaultFsLayer = new VirtualFS({ + baseFs: new ZipOpenFS({ + baseFs: nodeFs, + maxOpenFiles: 80, + readOnlyArchives: true + }) +}); +class DynamicFS extends ProxiedFS { + constructor() { + super(ppath); + this.baseFs = defaultFsLayer; + } + mapToBase(p) { + return p; + } + mapFromBase(p) { + return p; + } +} +const dynamicFsLayer = new DynamicFS(); +let manager; +const defaultApi = Object.assign(makeApi(defaultRuntimeState, { + fakeFs: dynamicFsLayer, + pnpapiResolution: defaultPnpapiResolution +}), { + makeApi: ({ + basePath = void 0, + fakeFs = dynamicFsLayer, + pnpapiResolution = defaultPnpapiResolution, + ...rest + }) => { + const apiRuntimeState = typeof basePath !== `undefined` ? $$SETUP_STATE(hydrateRuntimeState, basePath) : defaultRuntimeState; + return makeApi(apiRuntimeState, { + fakeFs, + pnpapiResolution, + ...rest + }); + }, + setup: (api) => { + applyPatch(api || defaultApi, { + fakeFs: defaultFsLayer, + manager + }); + dynamicFsLayer.baseFs = new NodeFS(fs__default.default); + } +}); +manager = makeManager(defaultApi, { + fakeFs: dynamicFsLayer +}); +if (module.parent && module.parent.id === `internal/preload`) { + defaultApi.setup(); + if (module.filename) { + delete require$$0__default.default._cache[module.filename]; + } +} +if (process.mainModule === module) { + const reportError = (code, message, data) => { + process.stdout.write(`${JSON.stringify([{ code, message, data }, null])} +`); + }; + const reportSuccess = (resolution) => { + process.stdout.write(`${JSON.stringify([null, resolution])} +`); + }; + const processResolution = (request, issuer) => { + try { + reportSuccess(defaultApi.resolveRequest(request, issuer)); + } catch (error) { + reportError(error.code, error.message, error.data); + } + }; + const processRequest = (data) => { + try { + const [request, issuer] = JSON.parse(data); + processResolution(request, issuer); + } catch (error) { + reportError(`INVALID_JSON`, error.message, error.data); + } + }; + if (process.argv.length > 2) { + if (process.argv.length !== 4) { + process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} +`); + process.exitCode = 64; + } else { + processResolution(process.argv[2], process.argv[3]); + } + } else { + let buffer = ``; + const decoder = new StringDecoder__default.default.StringDecoder(); + process.stdin.on(`data`, (chunk) => { + buffer += decoder.write(chunk); + do { + const index = buffer.indexOf(` +`); + if (index === -1) + break; + const line = buffer.slice(0, index); + buffer = buffer.slice(index + 1); + processRequest(line); + } while (true); + }); + } +} + +module.exports = defaultApi; diff --git a/testdata/fixtures/pnp/test-expectations.json b/testdata/fixtures/pnp/test-expectations.json new file mode 100644 index 00000000000..b6ce0ded330 --- /dev/null +++ b/testdata/fixtures/pnp/test-expectations.json @@ -0,0 +1,378 @@ +[{ + "manifest": { + "__info": [], + "dependencyTreeRoots": [{ + "name": "root", + "reference": "workspace:." + }], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + [null, [ + [null, { + "packageLocation": "./", + "packageDependencies": [["test", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["root", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [["test", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["workspace-alias-dependency", [ + ["workspace:workspace-alias-dependency", { + "packageLocation": "./workspace-alias-dependency/", + "packageDependencies": [["alias", ["test", "npm:1.0.0"]]], + "linkType": "SOFT" + }] + ]], + ["workspace-self-dependency", [ + ["workspace:workspace-self-dependency", { + "packageLocation": "./workspace-self-dependency/", + "packageDependencies": [["workspace-self-dependency", "workspace:workspace-self-dependency"]], + "linkType": "SOFT" + }] + ]], + ["workspace-unfulfilled-peer-dependency", [ + ["workspace:workspace-unfulfilled-peer-dependency", { + "packageLocation": "./workspace-unfulfilled-peer-dependency/", + "packageDependencies": [["test", null]], + "linkType": "SOFT" + }] + ]], + ["longer", [ + ["workspace:longer", { + "packageLocation": "./longer/", + "packageDependencies": [["test", "npm:2.0.0"]], + "linkType": "SOFT" + }] + ]], + ["long", [ + ["workspace:long", { + "packageLocation": "./long/", + "packageDependencies": [["test", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["longerer", [ + ["workspace:longerer", { + "packageLocation": "./longerer/", + "packageDependencies": [["test", "npm:3.0.0"]], + "linkType": "SOFT" + }] + ]], + ["test", [ + ["npm:1.0.0", { + "packageLocation": "./test-1.0.0/", + "packageDependencies": [], + "linkType": "HARD" + }], + ["npm:2.0.0", { + "packageLocation": "./test-2.0.0/", + "packageDependencies": [], + "linkType": "HARD" + }], + ["npm:3.0.0", { + "packageLocation": "./test-3.0.0/", + "packageDependencies": [], + "linkType": "HARD" + }] + ]] + ] + }, + "tests": [{ + "it": "should allow a package to import one of its dependencies", + "imported": "test", + "importer": "/path/to/project/", + "expected": "/path/to/project/test-1.0.0/" + }, { + "it": "should allow a package to import itself, if specified in its own dependencies", + "imported": "workspace-self-dependency", + "importer": "/path/to/project/workspace-self-dependency/", + "expected": "/path/to/project/workspace-self-dependency/" + }, { + "it": "should allow a package to import an aliased dependency", + "imported": "alias", + "importer": "/path/to/project/workspace-alias-dependency/", + "expected": "/path/to/project/test-1.0.0/" + }, { + "it": "shouldn't allow a package to import something that isn't one of its dependencies", + "imported": "missing-dependency", + "importer": "/path/to/project/", + "expected": "error!" + }, { + "it": "shouldn't accidentally discard the trailing slash from the package locations", + "imported": "test", + "importer": "/path/to/project/long/", + "expected": "/path/to/project/test-1.0.0/" + }, { + "it": "should throw an exception when trying to access an unfulfilled peer dependency", + "imported": "test", + "importer": "/path/to/project/workspace-unfulfilled-peer-dependency/", + "expected": "error!" + }] +}, { + "manifest": { + "__info": [], + "dependencyTreeRoots": [{ + "name": "root", + "reference": "workspace:." + }], + "ignorePatternData": null, + "enableTopLevelFallback": true, + "fallbackPool": [ + ["test-2", "npm:1.0.0"], + ["alias", ["test-1", "npm:1.0.0"]] + ], + "fallbackExclusionList": [[ + "workspace-no-fallbacks", + ["workspace:workspace-no-fallbacks"] + ]], + "packageRegistryData": [ + [null, [ + [null, { + "packageLocation": "./", + "packageDependencies": [["test-1", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["root", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [["test-1", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["workspace-no-fallbacks", [ + ["workspace:workspace-no-fallbacks", { + "packageLocation": "./workspace-no-fallbacks/", + "packageDependencies": [], + "linkType": "SOFT" + }] + ]], + ["workspace-with-fallbacks", [ + ["workspace:workspace-with-fallbacks", { + "packageLocation": "./workspace-with-fallbacks/", + "packageDependencies": [], + "linkType": "SOFT" + }] + ]], + ["workspace-unfulfilled-peer-dependency", [ + ["workspace:workspace-unfulfilled-peer-dependency", { + "packageLocation": "./workspace-unfulfilled-peer-dependency/", + "packageDependencies": [ + ["test-1", null], + ["test-2", null] + ], + "linkType": "SOFT" + }] + ]], + ["test-1", [ + ["npm:1.0.0", { + "packageLocation": "./test-1/", + "packageDependencies": [], + "linkType": "HARD" + }] + ]], + ["test-2", [ + ["npm:1.0.0", { + "packageLocation": "./test-2/", + "packageDependencies": [], + "linkType": "HARD" + }] + ]] + ] + }, + "tests": [{ + "it": "should allow resolution coming from the fallback pool if enableTopLevelFallback is set to true", + "imported": "test-1", + "importer": "/path/to/project/", + "expected": "/path/to/project/test-1/" + }, { + "it": "should allow the fallback pool to contain aliases", + "imported": "alias", + "importer": "/path/to/project/", + "expected": "/path/to/project/test-1/" + }, { + "it": "shouldn't use the fallback pool when the importer package is listed in fallbackExclusionList", + "imported": "test-1", + "importer": "/path/to/project/workspace-no-fallbacks/", + "expected": "error!" + }, { + "it": "should implicitly use the top-level package dependencies as part of the fallback pool", + "imported": "test-2", + "importer": "/path/to/project/workspace-with-fallbacks/", + "expected": "/path/to/project/test-2/" + }, { + "it": "should throw an error if a resolution isn't in in the package dependencies, nor inside the fallback pool", + "imported": "test-3", + "importer": "/path/to/project/workspace-with-fallbacks/", + "expected": "error!" + }, { + "it": "should use the top-level fallback if a dependency is missing because of an unfulfilled peer dependency", + "imported": "test-1", + "importer": "/path/to/project/workspace-unfulfilled-peer-dependency/", + "expected": "/path/to/project/test-1/" + }, { + "it": "should use the fallback pool if a dependency is missing because of an unfulfilled peer dependency", + "imported": "test-2", + "importer": "/path/to/project/workspace-unfulfilled-peer-dependency/", + "expected": "/path/to/project/test-2/" + }] +}, { + "manifest": { + "__info": [], + "dependencyTreeRoots": [{ + "name": "root", + "reference": "workspace:." + }], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [ + ["test", "npm:1.0.0"] + ], + "fallbackExclusionList": [], + "packageRegistryData": [ + [null, [ + [null, { + "packageLocation": "./", + "packageDependencies": [], + "linkType": "SOFT" + }] + ]], + ["root", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [], + "linkType": "SOFT" + }] + ]], + ["test", [ + ["npm:1.0.0", { + "packageLocation": "./test-1/", + "packageDependencies": [], + "linkType": "HARD" + }] + ]] + ] + }, + "tests": [{ + "it": "should ignore the fallback pool if enableTopLevelFallback is set to false", + "imported": "test", + "importer": "/path/to/project/", + "expected": "error!" + }] +}, { + "manifest": { + "__info": [], + "dependencyTreeRoots": [{ + "name": "root", + "reference": "workspace:." + }], + "ignorePatternData": "^not-a-workspace(/|$)", + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + [null, [ + [null, { + "packageLocation": "./", + "packageDependencies": [], + "linkType": "SOFT" + }] + ]], + ["root", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [["test", "npm:1.0.0"]], + "linkType": "SOFT" + }] + ]], + ["test", [ + ["npm:1.0.0", { + "packageLocation": "./test/", + "packageDependencies": [], + "linkType": "HARD" + }] + ]] + ] + }, + "tests": [{ + "it": "shouldn't go through PnP when trying to resolve dependencies from packages covered by ignorePatternData", + "imported": "test", + "importer": "/path/to/project/not-a-workspace/", + "expected": "test" + }] +}, { + "manifest": { + "__info": [ + "This file is automatically generated. Do not touch it, or risk", + "your modifications being lost." + ], + "dependencyTreeRoots": [{ + "name": "root", + "reference": "workspace:." + }], + "enableTopLevelFallback": true, + "ignorePatternData": null, + "fallbackExclusionList": [], + "fallbackPool": [], + "packageRegistryData": [ + [null, [ + [null, { + "packageLocation": "./", + "packageDependencies": [ + ["root", "workspace:."], + ["pad-left", "npm:2.1.0"] + ], + "linkType": "SOFT" + }] + ]], + ["my-project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["root", "workspace:."], + ["pad-left", "npm:2.1.0"] + ], + "linkType": "SOFT" + }] + ]], + ["pad-left", [ + ["npm:2.1.0", { + "packageLocation": "../yarn/global/cache/pad-left-npm-2.1.0-ffe13d2d40-10c0.zip/node_modules/pad-left/", + "packageDependencies": [ + ["pad-left", "npm:2.1.0"], + ["repeat-string", "npm:1.6.1"] + ], + "linkType": "HARD" + }] + ]], + ["repeat-string", [ + ["npm:1.6.1", { + "packageLocation": "../yarn/global/cache/repeat-string-npm-1.6.1-bc8e388655-10c0.zip/node_modules/repeat-string/", + "packageDependencies": [ + ["repeat-string", "npm:1.6.1"] + ], + "linkType": "HARD" + }] + ]] + ] + }, + "tests": [{ + "it": "should resolve global packages", + "imported": "pad-left", + "importer": "/path/to/project/", + "expected": "/path/to/yarn/global/cache/pad-left-npm-2.1.0-ffe13d2d40-10c0.zip/node_modules/pad-left/" + }, { + "it": "should resolve global packages from third-party dependencies", + "imported": "repeat-string", + "importer": "/path/to/yarn/global/cache/pad-left-npm-2.1.0-ffe13d2d40-10c0.zip/node_modules/pad-left/", + "expected": "/path/to/yarn/global/cache/repeat-string-npm-1.6.1-bc8e388655-10c0.zip/node_modules/repeat-string/" + }] +}] From b382639adefa711e6dfd433c63d4fda0ee36c01a Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 3 Nov 2025 13:38:49 +0100 Subject: [PATCH 08/32] Apply lint on last pnp changes --- internal/module/resolver.go | 4 ++-- internal/vfs/pnpvfs/pnpvfs.go | 2 +- internal/vfs/pnpvfs/pnpvfs_test.go | 19 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/internal/module/resolver.go b/internal/module/resolver.go index f8c4f95a03f..17797a62f8a 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -2055,9 +2055,9 @@ func GetAutomaticTypeDirectiveNames(options *core.CompilerOptions, host Resoluti } var result []string - typeRoots, fromConfig := options.GetEffectiveTypeRoots(host.GetCurrentDirectory()) + typeRoots, _ := options.GetEffectiveTypeRoots(host.GetCurrentDirectory()) if pnpApi := host.PnpApi(); pnpApi != nil { - typeRoots, fromConfig = pnpApi.AppendPnpTypeRoots(typeRoots, host.GetCurrentDirectory(), options, fromConfig) + typeRoots, _ = pnpApi.AppendPnpTypeRoots(typeRoots, host.GetCurrentDirectory(), options, false) } for _, root := range typeRoots { if host.FS().DirectoryExists(root) { diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index 06e21d7972b..b405c404f1a 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -21,7 +21,7 @@ type pnpFS struct { var _ vfs.FS = (*pnpFS)(nil) -func From(fs vfs.FS) *pnpFS { +func From(fs vfs.FS) vfs.FS { pnpFS := &pnpFS{ fs: fs, cachedZipReadersMap: make(map[string]*zip.ReadCloser), diff --git a/internal/vfs/pnpvfs/pnpvfs_test.go b/internal/vfs/pnpvfs/pnpvfs_test.go index 78249ef3ca7..352e9bf0915 100644 --- a/internal/vfs/pnpvfs/pnpvfs_test.go +++ b/internal/vfs/pnpvfs/pnpvfs_test.go @@ -1,4 +1,4 @@ -package pnpvfs_test +package pnpvfs import ( "archive/zip" @@ -10,7 +10,6 @@ import ( "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/osvfs" - "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" "gotest.tools/v3/assert" ) @@ -35,10 +34,10 @@ func createTestZip(t *testing.T, files map[string]string) (string, vfs.FS) { assert.NilError(t, err) } - fs := pnpvfs.From(osvfs.FS()) + fs := From(osvfs.FS()) t.Cleanup(func() { - errClear := fs.ClearCache() + errClear := fs.(*pnpFS).ClearCache() assert.NilError(t, errClear) }) @@ -53,7 +52,7 @@ func TestPnpVfs_BasicFileOperations(t *testing.T) { "/project/package.json": `{"name": "test"}`, }, true) - fs := pnpvfs.From(underlyingFS) + fs := From(underlyingFS) assert.Assert(t, fs.FileExists("/project/src/index.ts")) assert.Assert(t, !fs.FileExists("/project/nonexistent.ts")) @@ -106,7 +105,7 @@ func TestPnpVfs_ZipFileDetection(t *testing.T) { func TestPnpVfs_ErrorHandling(t *testing.T) { t.Parallel() - fs := pnpvfs.From(osvfs.FS()) + fs := From(osvfs.FS()) t.Run("NonexistentZipFile", func(t *testing.T) { t.Parallel() @@ -147,9 +146,9 @@ func TestPnpVfs_ErrorHandling(t *testing.T) { func TestPnpVfs_CaseSensitivity(t *testing.T) { t.Parallel() - sensitiveFS := pnpvfs.From(vfstest.FromMap(map[string]string{}, true)) + sensitiveFS := From(vfstest.FromMap(map[string]string{}, true)) assert.Assert(t, sensitiveFS.UseCaseSensitiveFileNames()) - insensitiveFS := pnpvfs.From(vfstest.FromMap(map[string]string{}, false)) + insensitiveFS := From(vfstest.FromMap(map[string]string{}, false)) // pnpvfs is always case sensitive assert.Assert(t, insensitiveFS.UseCaseSensitiveFileNames()) } @@ -162,7 +161,7 @@ func TestPnpVfs_FallbackToRegularFiles(t *testing.T) { err := os.WriteFile(regularFile, []byte("regular content"), 0o644) assert.NilError(t, err) - fs := pnpvfs.From(osvfs.FS()) + fs := From(osvfs.FS()) assert.Assert(t, fs.FileExists(regularFile)) @@ -206,7 +205,7 @@ func TestPnpVfs_VirtualPathHandling(t *testing.T) { "/project/packages/packageB/package.json": `{"name": "packageB"}`, }, true) - fs := pnpvfs.From(underlyingFS) + fs := From(underlyingFS) assert.Assert(t, fs.FileExists("/project/packages/__virtual__/packageA-virtual-123456/0/packageA/package.json")) assert.Assert(t, fs.FileExists("/project/packages/subfolder/__virtual__/packageA-virtual-123456/1/packageA/package.json")) From f8dd02fd0cbe72d28cea6f6745a83ab776ae5abf Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 5 Nov 2025 12:11:19 +0100 Subject: [PATCH 09/32] Add pnp import completion --- .../tests/pnpAutoImportCompletion_test.go | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 internal/fourslash/tests/pnpAutoImportCompletion_test.go diff --git a/internal/fourslash/tests/pnpAutoImportCompletion_test.go b/internal/fourslash/tests/pnpAutoImportCompletion_test.go new file mode 100644 index 00000000000..d9cd9513c2d --- /dev/null +++ b/internal/fourslash/tests/pnpAutoImportCompletion_test.go @@ -0,0 +1,191 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/fourslash" + . "github.com/microsoft/typescript-go/internal/fourslash/tests/util" + "github.com/microsoft/typescript-go/internal/ls" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestPnpAutoImportCompletion1(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = ` +// @filename: /.pnp.cjs +module.exports = {}; + +// @filename: /.pnp.data.json +{ + "dependencyTreeRoots": [ + { + "name": "project", + "reference": "workspace:." + } + ], + "ignorePatternData": null, + "enableTopLevelFallback": false, + "fallbackPool": [], + "fallbackExclusionList": [], + "packageRegistryData": [ + ["project", [ + ["workspace:.", { + "packageLocation": "./", + "packageDependencies": [ + ["package-a", "npm:1.0.0"], + ["workspace-lib", "workspace:libs/workspace-lib"] + ] + }] + ]], + ["package-a", [ + ["npm:1.0.0", { + "packageLocation": "./.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/", + "packageDependencies": [] + }] + ]], + ["package-b", [ + ["npm:1.0.0", { + "packageLocation": "./.yarn/cache/package-b-npm-1.0.0-efgh5678/node_modules/package-b/", + "packageDependencies": [] + }] + ]], + ["workspace-lib", [ + ["workspace:libs/workspace-lib", { + "packageLocation": "./libs/workspace-lib/", + "packageDependencies": [] + }] + ]] + ] +} + +// @filename: package.json +{ + "name": "project", + "workspaces": [ + "libs/*" + ], + "dependencies": { + "package-a": "npm:1.0.0", + "workspace-lib": "workspace:*" + } +} + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/package.json +{ + "name": "package-a", + "version": "1.0.0", + "exports": { + ".": {"types": "./index.d.ts", "default": "./index.js"}, + "./subpath": {"types": "./helper.d.ts", "default": "./helper.js"} + }, + "types": "./index.d.ts", + "main": "./index.js" +} + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.js +export const aValue = "Some Var"; + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts +export declare const aValue: string; + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/helper.js +export function helperA(value) { + return "Helper A: " + value; +}; + +// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/helper.d.ts +export declare function helperA(value: string): string; + +// @filename: /libs/workspace-lib/package.json +{ + "name": "workspace-lib", + "version": "1.0.0", + "exports": { + ".": {"types": "./index.d.ts", "default": "./index.js"} + }, + "types": "./index.d.ts", + "main": "./index.js" +} + +// @filename: /libs/workspace-lib/index.js +export const workspaceValue = "Workspace Value"; +export function workspaceHelper() { + return "Helper from workspace"; +}; + +// @filename: /libs/workspace-lib/index.d.ts +export declare const workspaceValue: string; +export declare function workspaceHelper(): string; + +// @filename: /.yarn/cache/package-b-npm-1.0.0-efgh5678/node_modules/package-b/package.json +{ + "name": "package-b", + "version": "1.0.0", + "exports": { + ".": {"types": "./index.d.ts", "default": "./index.js"} + } +} + +// @filename: /.yarn/cache/package-b-npm-1.0.0-efgh5678/node_modules/package-b/index.js +export const bValue = "B Value"; +export function helperB(value) { + return "Helper B: " + value; +}; + +// @filename: /.yarn/cache/package-b-npm-1.0.0-efgh5678/node_modules/package-b/index.d.ts +export declare const bValue: string; +export declare function helperB(value: string): string; + +// @filename: /src/index.ts +import { bValue } from 'package-b'; // Should be erroring because package-b is not in project's dependencies +import { aValue } from 'package-a'; +aValue; +/**/ +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ + UserPreferences: &lsutil.UserPreferences{ + IncludeCompletionsForModuleExports: core.TSTrue, + IncludeCompletionsForImportStatements: core.TSTrue, + }, + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Includes: []fourslash.CompletionsExpectedItem{ + // Verify that helperA completion creates an import from 'package-a/subpath' + &lsproto.CompletionItem{ + Label: "helperA", + Data: PtrTo(any(&ls.CompletionItemData{ + AutoImport: &ls.AutoImportData{ + ModuleSpecifier: "package-a/subpath", + }, + })), + Kind: PtrTo(lsproto.CompletionItemKindFunction), + AdditionalTextEdits: fourslash.AnyTextEdits, + SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), + }, + // Verify that workspaceHelper completion creates an import from 'workspace-lib' + &lsproto.CompletionItem{ + Label: "workspaceHelper", + Data: PtrTo(any(&ls.CompletionItemData{ + AutoImport: &ls.AutoImportData{ + ModuleSpecifier: "workspace-lib", + }, + })), + Kind: PtrTo(lsproto.CompletionItemKindFunction), + AdditionalTextEdits: fourslash.AnyTextEdits, + SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), + }, + }, + // `bValue` can appear in the completion list since it's mentioned in a unresolved import, but `helperB` should not + Excludes: []string{"helperB"}, + }, + }) +} From 2f177444eb87ba2d961478f4f697f154b253a652 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 6 Nov 2025 10:06:12 +0100 Subject: [PATCH 10/32] Apply new lint fixes --- internal/pnp/manifestparser.go | 46 +++++++++++++++++----------------- internal/pnp/pnpapi.go | 7 ++---- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/internal/pnp/manifestparser.go b/internal/pnp/manifestparser.go index 23a7975cd25..cff5f81057d 100644 --- a/internal/pnp/manifestparser.go +++ b/internal/pnp/manifestparser.go @@ -119,7 +119,7 @@ func extractPnpDataStringFromPath(fs vfs.FS, path string) (string, error) { } func parseManifestFromData(pnpDataString string, manifestDir string) (*PnpManifestData, error) { - var rawData map[string]interface{} + var rawData map[string]any if err := json.Unmarshal([]byte(pnpDataString), &rawData); err != nil { return nil, fmt.Errorf("failed to parse JSON PnP data: %w", err) } @@ -133,12 +133,12 @@ func parseManifestFromData(pnpDataString string, manifestDir string) (*PnpManife } // TODO add error handling for corrupted data -func parsePnpManifest(rawData map[string]interface{}, manifestDir string) (*PnpManifestData, error) { +func parsePnpManifest(rawData map[string]any, manifestDir string) (*PnpManifestData, error) { data := &PnpManifestData{dirPath: manifestDir} - if roots, ok := rawData["dependencyTreeRoots"].([]interface{}); ok { + if roots, ok := rawData["dependencyTreeRoots"].([]any); ok { for _, root := range roots { - if rootMap, ok := root.(map[string]interface{}); ok { + if rootMap, ok := root.(map[string]any); ok { data.dependencyTreeRoots = append(data.dependencyTreeRoots, Locator{ Name: getField(rootMap, "name", parseString), Reference: getField(rootMap, "reference", parseString), @@ -163,9 +163,9 @@ func parsePnpManifest(rawData map[string]interface{}, manifestDir string) (*PnpM data.fallbackExclusionMap = make(map[string]*FallbackExclusion) - if exclusions, ok := rawData["fallbackExclusionList"].([]interface{}); ok { + if exclusions, ok := rawData["fallbackExclusionList"].([]any); ok { for _, exclusion := range exclusions { - if exclusionArr, ok := exclusion.([]interface{}); ok && len(exclusionArr) == 2 { + if exclusionArr, ok := exclusion.([]any); ok && len(exclusionArr) == 2 { name := parseString(exclusionArr[0]) entries := parseStringArray(exclusionArr[1]) exclusionEntry := &FallbackExclusion{ @@ -179,21 +179,21 @@ func parsePnpManifest(rawData map[string]interface{}, manifestDir string) (*PnpM data.packageRegistryMap = make(map[string]map[string]*PackageInfo) - if registryData, ok := rawData["packageRegistryData"].([]interface{}); ok { + if registryData, ok := rawData["packageRegistryData"].([]any); ok { for _, entry := range registryData { - if entryArr, ok := entry.([]interface{}); ok && len(entryArr) == 2 { + if entryArr, ok := entry.([]any); ok && len(entryArr) == 2 { ident := parseString(entryArr[0]) if data.packageRegistryMap[ident] == nil { data.packageRegistryMap[ident] = make(map[string]*PackageInfo) } - if versions, ok := entryArr[1].([]interface{}); ok { + if versions, ok := entryArr[1].([]any); ok { for _, version := range versions { - if versionArr, ok := version.([]interface{}); ok && len(versionArr) == 2 { + if versionArr, ok := version.([]any); ok && len(versionArr) == 2 { reference := parseString(versionArr[0]) - if infoMap, ok := versionArr[1].(map[string]interface{}); ok { + if infoMap, ok := versionArr[1].(map[string]any); ok { packageInfo := &PackageInfo{ PackageLocation: getField(infoMap, "packageLocation", parseString), PackageDependencies: getField(infoMap, "packageDependencies", parsePackageDependencies), @@ -251,22 +251,22 @@ func (data *PnpManifestData) addPackageToTrie(ident string, reference string, pa } // Helper functions for parsing JSON values - following patterns from tsoptions.parseString, etc. -func parseString(value interface{}) string { +func parseString(value any) string { if str, ok := value.(string); ok { return str } return "" } -func parseBool(value interface{}) bool { +func parseBool(value any) bool { if val, ok := value.(bool); ok { return val } return false } -func parseStringArray(value interface{}) []string { - if arr, ok := value.([]interface{}); ok { +func parseStringArray(value any) []string { + if arr, ok := value.([]any); ok { if arr == nil { return nil } @@ -281,11 +281,11 @@ func parseStringArray(value interface{}) []string { return nil } -func parseStringPairs(value interface{}) [][2]string { +func parseStringPairs(value any) [][2]string { var result [][2]string - if arr, ok := value.([]interface{}); ok { + if arr, ok := value.([]any); ok { for _, item := range arr { - if pair, ok := item.([]interface{}); ok && len(pair) == 2 { + if pair, ok := item.([]any); ok && len(pair) == 2 { result = append(result, [2]string{ parseString(pair[0]), parseString(pair[1]), @@ -296,11 +296,11 @@ func parseStringPairs(value interface{}) [][2]string { return result } -func parsePackageDependencies(value interface{}) []PackageDependency { +func parsePackageDependencies(value any) []PackageDependency { var result []PackageDependency - if arr, ok := value.([]interface{}); ok { + if arr, ok := value.([]any); ok { for _, item := range arr { - if pair, ok := item.([]interface{}); ok && len(pair) == 2 { + if pair, ok := item.([]any); ok && len(pair) == 2 { ident := parseString(pair[0]) // Check if second element is string (simple reference) or array (alias) @@ -310,7 +310,7 @@ func parsePackageDependencies(value interface{}) []PackageDependency { Reference: str, AliasName: "", }) - } else if aliasPair, ok := pair[1].([]interface{}); ok && len(aliasPair) == 2 { + } else if aliasPair, ok := pair[1].([]any); ok && len(aliasPair) == 2 { result = append(result, PackageDependency{ Ident: ident, Reference: parseString(aliasPair[1]), @@ -323,7 +323,7 @@ func parsePackageDependencies(value interface{}) []PackageDependency { return result } -func getField[T any](m map[string]interface{}, key string, parser func(interface{}) T) T { +func getField[T any](m map[string]any, key string, parser func(any) T) T { if val, exists := m[key]; exists { return parser(val) } diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 2950ae84db9..927ea7d1eeb 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -96,11 +96,8 @@ func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (stri if p.manifest.enableTopLevelFallback { excluded := false if exclusion, ok := p.manifest.fallbackExclusionMap[parentLocator.Name]; ok { - for _, entry := range exclusion.Entries { - if entry == parentLocator.Reference { - excluded = true - break - } + if slices.Contains(exclusion.Entries, parentLocator.Reference) { + excluded = true } } if !excluded { From 993103be7ec8a8cca001d7ce08ae3b10b0aec08d Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 6 Nov 2025 11:27:04 +0100 Subject: [PATCH 11/32] Mark any external pnp dependency as isExternalLibraryImport=true --- internal/module/resolver.go | 24 +++++++++++++++++++++--- internal/pnp/pnpapi.go | 2 +- internal/tspath/path.go | 11 ----------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/internal/module/resolver.go b/internal/module/resolver.go index 17797a62f8a..d162250882d 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -475,9 +475,10 @@ func (r *resolutionState) resolveNodeLikeWorker() *ResolvedModule { } else { candidate := normalizePathForCJSResolution(r.containingDirectory, r.name) resolved := r.nodeLoadModuleByRelativeName(r.extensions, candidate, false, true) + return r.createResolvedModule( resolved, - resolved != nil && (tspath.IsExternalLibraryImport(resolved.path)), + r.isExternalLibraryImport(resolved), ) } return r.createResolvedModule(nil, false) @@ -1089,7 +1090,8 @@ func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectoryImpl(ext ext } func (r *resolutionState) createResolvedModuleHandlingSymlink(resolved *resolved) *ResolvedModule { - isExternalLibraryImport := resolved != nil && (tspath.IsExternalLibraryImport(resolved.path)) + isExternalLibraryImport := r.isExternalLibraryImport(resolved) + if r.compilerOptions.PreserveSymlinks != core.TSTrue && isExternalLibraryImport && resolved.originalPath == "" && @@ -1137,7 +1139,8 @@ func (r *resolutionState) createResolvedTypeReferenceDirective(resolved *resolve resolvedTypeReferenceDirective.ResolvedFileName = resolved.path resolvedTypeReferenceDirective.Primary = primary resolvedTypeReferenceDirective.PackageId = resolved.packageId - resolvedTypeReferenceDirective.IsExternalLibraryImport = tspath.IsExternalLibraryImport(resolved.path) + + resolvedTypeReferenceDirective.IsExternalLibraryImport = r.isExternalLibraryImport(resolved) if r.compilerOptions.PreserveSymlinks != core.TSTrue { originalPath, resolvedFileName := r.getOriginalAndResolvedFileName(resolved.path) @@ -1885,6 +1888,21 @@ func (r *resolutionState) conditionMatches(condition string) bool { return false } +func (r *resolutionState) isExternalLibraryImport(resolved *resolved) bool { + if resolved == nil { + return false + } + + isExternalLibraryImport := strings.Contains(resolved.path, "/node_modules/") + + pnpApi := r.resolver.host.PnpApi() + if pnpApi != nil && !isExternalLibraryImport { + isExternalLibraryImport = pnpApi.IsInPnpModule(resolved.path, r.containingDirectory) + } + + return isExternalLibraryImport +} + func (r *resolutionState) getTraceFunc() func(string) { if r.tracer != nil { return r.tracer.write diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 927ea7d1eeb..5f0c9eb8184 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -346,10 +346,10 @@ func (p *PnpApi) GetPackageLocationAbsolutePath(packageInfo *PackageInfo) string return tspath.ResolvePath(p.manifest.dirPath, packageLocation) } +// Checks if fromFileName and toFileName are in different pnp modules func (p *PnpApi) IsInPnpModule(fromFileName string, toFileName string) bool { fromLocator, _ := p.FindLocator(fromFileName) toLocator, _ := p.FindLocator(toFileName) - // The targeted filename is in a pnp module different from the requesting filename return fromLocator != nil && toLocator != nil && fromLocator.Name != toLocator.Name } diff --git a/internal/tspath/path.go b/internal/tspath/path.go index c7dfb642b5b..d30955021b8 100644 --- a/internal/tspath/path.go +++ b/internal/tspath/path.go @@ -869,17 +869,6 @@ func IsExternalModuleNameRelative(moduleName string) bool { return PathIsRelative(moduleName) || IsRootedDiskPath(moduleName) } -func IsExternalLibraryImport(path string) bool { - // When PnP is enabled, some internal libraries can be resolved as virtual packages, which should be treated as external libraries - // Since these virtual pnp packages don't have a `/node_modules/` folder, we need to check for the presence of `/__virtual__/` in the path - // See https://yarnpkg.com/advanced/lexicon#virtual-package for more details - return strings.Contains(path, "/node_modules/") || isPnpVirtualPath(path) -} - -func isPnpVirtualPath(path string) bool { - return strings.Contains(path, "/__virtual__/") -} - type ComparePathsOptions struct { UseCaseSensitiveFileNames bool CurrentDirectory string From 0665cd8aaa1a12354279b294cf4bd74570787d73 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 12 Nov 2025 13:01:12 +0100 Subject: [PATCH 12/32] Handle empty strings for FindLocator --- internal/pnp/pnpapi.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 5f0c9eb8184..f17a3885644 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -177,6 +177,10 @@ func (p *PnpApi) GetPackage(locator *Locator) *PackageInfo { } func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { + if parentPath == "" { + return nil, nil + } + relativePath := tspath.GetRelativePathFromDirectory(p.manifest.dirPath, parentPath, tspath.ComparePathsOptions{UseCaseSensitiveFileNames: true}) From 781b5de13568fdbfca24a540f1c77be4aa3e5f1b Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 20 Nov 2025 14:57:32 +0100 Subject: [PATCH 13/32] Use strings.Cut instead of string.Index for pnp --- internal/pnp/pnpapi.go | 6 +++--- internal/vfs/pnpvfs/pnpvfs.go | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index f17a3885644..ee043524ccf 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -272,12 +272,12 @@ func (p *PnpApi) ParseBareIdentifier(specifier string) (ident string, modulePath ident = specifier[:firstSlash+1+secondSlash] } } else { - firstSlash := strings.Index(specifier, "/") + beforeFirstSlash, _, found := strings.Cut(specifier, "/") - if firstSlash == -1 { + if !found { ident = specifier } else { - ident = specifier[:firstSlash] + ident = beforeFirstSlash } } diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index b405c404f1a..1f7f60a86f4 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -178,13 +178,11 @@ func getMatchingFS(pnpFS *pnpFS, path string) (vfs.FS, string, string) { // Virtual paths are used to make different paths resolve to the same real file or folder, which is necessary in some cases when PnP is enabled // See https://yarnpkg.com/advanced/lexicon#virtual-package and https://yarnpkg.com/advanced/pnpapi#resolvevirtual for more details func resolveVirtual(path string) (realPath string, hash string, basePath string) { - idx := strings.Index(path, "/__virtual__/") - if idx == -1 { + base, rest, found := strings.Cut(path, "/__virtual__/") + if !found { return path, "", "" } - base := path[:idx] - rest := path[idx+len("/__virtual__/"):] parts := strings.SplitN(rest, "/", 3) if len(parts) < 3 { // Not enough parts to match the pattern, return as is @@ -198,7 +196,7 @@ func resolveVirtual(path string) (realPath string, hash string, basePath string) return path, "", "" } - basePath = path[:idx] + "/__virtual__" + basePath = base + "/__virtual__" // Apply dirname n times to base for range depth { From 68db04ab820c75c89c20073e2451d2cdfdf2f754 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 20 Nov 2025 18:24:01 +0100 Subject: [PATCH 14/32] Fix completion issue for pnp packages --- internal/pnp/pnpapi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index ee043524ccf..c9436a53259 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -347,7 +347,7 @@ func (p *PnpApi) GetPackageLocationAbsolutePath(packageInfo *PackageInfo) string } packageLocation := packageInfo.PackageLocation - return tspath.ResolvePath(p.manifest.dirPath, packageLocation) + return tspath.RemoveTrailingDirectorySeparators(tspath.ResolvePath(p.manifest.dirPath, packageLocation)) } // Checks if fromFileName and toFileName are in different pnp modules From 151d26b43bcb739418c056325691850800d778cf Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Fri, 5 Dec 2025 14:45:22 +0100 Subject: [PATCH 15/32] Use updated diagnostic messages in pnpapi + fix autocomplete tests --- internal/diagnostics/diagnostics_generated.go | 16 ++++----- .../diagnostics/extraDiagnosticMessages.json | 10 ++---- .../tests/pnpAutoImportCompletion_test.go | 15 ++++---- internal/module/resolver.go | 7 ++-- internal/pnp/pnpapi.go | 34 ++++++++++--------- 5 files changed, 39 insertions(+), 43 deletions(-) diff --git a/internal/diagnostics/diagnostics_generated.go b/internal/diagnostics/diagnostics_generated.go index 0d51dd729d7..794e6fad559 100644 --- a/internal/diagnostics/diagnostics_generated.go +++ b/internal/diagnostics/diagnostics_generated.go @@ -4280,13 +4280,11 @@ var Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_t var X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2 = &Message{code: 110005, category: CategoryError, key: "_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application__110005", text: "{0} tried to access '{1}' (a peer dependency) but it isn't provided by its ancestors/your application; this makes the require call ambiguous and unsound.\n\nRequired package: {1}\nRequired by: {2}"} -var X_no_PnP_manifest_found = &Message{code: 110006, category: CategoryError, key: "no_PnP_manifest_found_110006", text: "no PnP manifest found"} +var X_no_package_found_for_path_0 = &Message{code: 110006, category: CategoryError, key: "no_package_found_for_path_0_110006", text: "no package found for path '{0}'"} -var X_no_package_found_for_path_0 = &Message{code: 110007, category: CategoryError, key: "no_package_found_for_path_0_110007", text: "no package found for path '{0}'"} +var Empty_specifier_Colon_0 = &Message{code: 110007, category: CategoryError, key: "Empty_specifier_Colon_0_110007", text: "Empty specifier: '{0}'"} -var Empty_specifier_Colon_0 = &Message{code: 110008, category: CategoryError, key: "Empty_specifier_Colon_0_110008", text: "Empty specifier: '{0}'"} - -var Invalid_specifier_Colon_0 = &Message{code: 110009, category: CategoryError, key: "Invalid_specifier_Colon_0_110009", text: "Invalid specifier: '{0}'"} +var Invalid_specifier_Colon_0 = &Message{code: 110008, category: CategoryError, key: "Invalid_specifier_Colon_0_110008", text: "Invalid specifier: '{0}'"} func keyToMessage(key Key) *Message { switch key { @@ -8568,13 +8566,11 @@ func keyToMessage(key Key) *Message { return Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_satisfy_the_requirement_Use_a_devDependency_if_needed_Required_package_Colon_0_Required_by_Colon_1 case "_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application__110005": return X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2 - case "no_PnP_manifest_found_110006": - return X_no_PnP_manifest_found - case "no_package_found_for_path_0_110007": + case "no_package_found_for_path_0_110006": return X_no_package_found_for_path_0 - case "Empty_specifier_Colon_0_110008": + case "Empty_specifier_Colon_0_110007": return Empty_specifier_Colon_0 - case "Invalid_specifier_Colon_0_110009": + case "Invalid_specifier_Colon_0_110008": return Invalid_specifier_Colon_0 default: return nil diff --git a/internal/diagnostics/extraDiagnosticMessages.json b/internal/diagnostics/extraDiagnosticMessages.json index 543964fb92e..d3c29e8aeec 100644 --- a/internal/diagnostics/extraDiagnosticMessages.json +++ b/internal/diagnostics/extraDiagnosticMessages.json @@ -55,21 +55,17 @@ "category": "Error", "code": 110005 }, - "no PnP manifest found": { - "category": "Error", - "code": 110006 - }, "no package found for path '{0}'": { "category": "Error", - "code": 110007 + "code": 110006 }, "Empty specifier: '{0}'": { "category": "Error", - "code": 110008 + "code": 110007 }, "Invalid specifier: '{0}'": { "category": "Error", - "code": 110009 + "code": 110008 }, "Non-relative paths are not allowed. Did you forget a leading './'?": { "category": "Error", diff --git a/internal/fourslash/tests/pnpAutoImportCompletion_test.go b/internal/fourslash/tests/pnpAutoImportCompletion_test.go index d9cd9513c2d..074ea2d76df 100644 --- a/internal/fourslash/tests/pnpAutoImportCompletion_test.go +++ b/internal/fourslash/tests/pnpAutoImportCompletion_test.go @@ -146,7 +146,8 @@ import { aValue } from 'package-a'; aValue; /**/ ` - f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ UserPreferences: &lsutil.UserPreferences{ IncludeCompletionsForModuleExports: core.TSTrue, @@ -162,11 +163,11 @@ aValue; // Verify that helperA completion creates an import from 'package-a/subpath' &lsproto.CompletionItem{ Label: "helperA", - Data: PtrTo(any(&ls.CompletionItemData{ - AutoImport: &ls.AutoImportData{ + Data: &lsproto.CompletionItemData{ + AutoImport: &lsproto.AutoImportData{ ModuleSpecifier: "package-a/subpath", }, - })), + }, Kind: PtrTo(lsproto.CompletionItemKindFunction), AdditionalTextEdits: fourslash.AnyTextEdits, SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), @@ -174,11 +175,11 @@ aValue; // Verify that workspaceHelper completion creates an import from 'workspace-lib' &lsproto.CompletionItem{ Label: "workspaceHelper", - Data: PtrTo(any(&ls.CompletionItemData{ - AutoImport: &ls.AutoImportData{ + Data: &lsproto.CompletionItemData{ + AutoImport: &lsproto.AutoImportData{ ModuleSpecifier: "workspace-lib", }, - })), + }, Kind: PtrTo(lsproto.CompletionItemKindFunction), AdditionalTextEdits: fourslash.AnyTextEdits, SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), diff --git a/internal/module/resolver.go b/internal/module/resolver.go index 19b10044754..0275fd3ea31 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -11,6 +11,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/diagnostics" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/semver" "github.com/microsoft/typescript-go/internal/tspath" ) @@ -994,7 +995,7 @@ func (r *resolutionState) loadModuleFromPnpResolution(ext extensions, moduleName packageDirectory, err := pnpApi.ResolveToUnqualified(packageName, issuer) if err != nil { if r.tracer != nil { - r.tracer.write(err.Error()) + r.tracer.write(err.Message, err.Args...) } return nil } @@ -1815,11 +1816,11 @@ func (r *resolutionState) readPackageJsonPeerDependencies(packageJsonInfo *packa var peerDependencyPath string if pnpApi != nil { - var err error + var err *pnp.PnpError peerDependencyPath, err = pnpApi.ResolveToUnqualified(name, packageDirectory) if err != nil { if r.tracer != nil { - r.tracer.write(err.Error()) + r.tracer.write(err.Message, err.Args...) } continue } diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index c9436a53259..5daf7ef30cd 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -64,7 +64,12 @@ func (p *PnpApi) RefreshManifest() error { return nil } -func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (string, error) { +type PnpError struct { + Message *diagnostics.Message + Args []any +} + +func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (string, *PnpError) { if p.manifest == nil { panic("ResolveToUnqualified called with no PnP manifest available") } @@ -112,13 +117,13 @@ func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (stri if referenceOrAlias == nil { if isNodeJSBuiltin(specifier) { if isDependencyTreeRoot(p.manifest, parentLocator) { - return "", errors.New(diagnostics.Your_application_tried_to_access_0_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_0_isn_t_otherwise_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2.Format(ident, ident, viaSuffix(specifier, ident), parentPath)) + return "", &PnpError{Message: diagnostics.Your_application_tried_to_access_0_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_0_isn_t_otherwise_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2, Args: []any{ident, ident, viaSuffix(specifier, ident), parentPath}} } - return "", errors.New(diagnostics.X_0_tried_to_access_1_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_1_isn_t_otherwise_declared_in_0_s_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_2_Required_by_Colon_3.Format(parentLocator.Name, ident, ident, parentLocator.Name, ident, viaSuffix(specifier, ident), parentPath)) + return "", &PnpError{Message: diagnostics.X_0_tried_to_access_1_While_this_module_is_usually_interpreted_as_a_Node_builtin_your_resolver_is_running_inside_a_non_Node_resolution_context_where_such_builtins_are_ignored_Since_1_isn_t_otherwise_declared_in_0_s_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_2_Required_by_Colon_3, Args: []any{parentLocator.Name, ident, ident, parentLocator.Name, ident, viaSuffix(specifier, ident), parentPath}} } if isDependencyTreeRoot(p.manifest, parentLocator) { - return "", errors.New(diagnostics.Your_application_tried_to_access_0_but_it_isn_t_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2.Format(ident, ident, viaSuffix(specifier, ident), parentPath)) + return "", &PnpError{Message: diagnostics.Your_application_tried_to_access_0_but_it_isn_t_declared_in_your_dependencies_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_0_1_Required_by_Colon_2, Args: []any{ident, ident, viaSuffix(specifier, ident), parentPath}} } brokenAncestors := findBrokenPeerDependencies(specifier, parentLocator) @@ -133,9 +138,9 @@ func (p *PnpApi) ResolveToUnqualified(specifier string, parentPath string) (stri } if len(brokenAncestors) > 0 && allBrokenAreRoots { - return "", errors.New(diagnostics.Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_satisfy_the_requirement_Use_a_devDependency_if_needed_Required_package_Colon_0_Required_by_Colon_1.Format(ident, ident, parentPath)) + return "", &PnpError{Message: diagnostics.Your_application_tried_to_access_0_a_peer_dependency_this_isn_t_allowed_as_there_is_no_ancestor_to_satisfy_the_requirement_Use_a_devDependency_if_needed_Required_package_Colon_0_Required_by_Colon_1, Args: []any{ident, ident, parentPath}} } else { - return "", errors.New(diagnostics.X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2.Format(parentLocator.Name, ident, ident, parentPath)) + return "", &PnpError{Message: diagnostics.X_0_tried_to_access_1_a_peer_dependency_but_it_isn_t_provided_by_its_ancestors_Slashyour_application_this_makes_the_require_call_ambiguous_and_unsound_Required_package_Colon_1_Required_by_Colon_2, Args: []any{parentLocator.Name, ident, ident, parentPath}} } } @@ -159,7 +164,7 @@ func (p *PnpApi) findClosestPnpManifest() (*PnpManifestData, error) { } if tspath.IsDiskPathRoot(directoryPath) { - return nil, errors.New(diagnostics.X_no_PnP_manifest_found.Format()) + return nil, errors.New("no PnP manifest found") } directoryPath = tspath.GetDirectoryPath(directoryPath) @@ -176,7 +181,7 @@ func (p *PnpApi) GetPackage(locator *Locator) *PackageInfo { return packageInfo } -func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { +func (p *PnpApi) FindLocator(parentPath string) (*Locator, *PnpError) { if parentPath == "" { return nil, nil } @@ -186,11 +191,8 @@ func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { if p.manifest.ignorePatternData != nil { match, err := p.manifest.ignorePatternData.MatchString(relativePath) - if err != nil { - return nil, err - } - if match { + if err == nil && match { return nil, nil } } @@ -222,7 +224,7 @@ func (p *PnpApi) FindLocator(parentPath string) (*Locator, error) { } if bestLocator == nil { - return nil, errors.New(diagnostics.X_no_package_found_for_path_0.Format(relativePath)) + return nil, &PnpError{Message: diagnostics.X_no_package_found_for_path_0, Args: []any{relativePath}} } return bestLocator, nil @@ -252,16 +254,16 @@ func (p *PnpApi) ResolveViaFallback(name string) *PackageDependency { return nil } -func (p *PnpApi) ParseBareIdentifier(specifier string) (ident string, modulePath string, err error) { +func (p *PnpApi) ParseBareIdentifier(specifier string) (ident string, modulePath string, err *PnpError) { if len(specifier) == 0 { - return "", "", errors.New(diagnostics.Empty_specifier_Colon_0.Format(specifier)) + return "", "", &PnpError{Message: diagnostics.Empty_specifier_Colon_0, Args: []any{specifier}} } firstSlash := strings.Index(specifier, "/") if specifier[0] == '@' { if firstSlash == -1 { - return "", "", errors.New(diagnostics.Invalid_specifier_Colon_0.Format(specifier)) + return "", "", &PnpError{Message: diagnostics.Invalid_specifier_Colon_0, Args: []any{specifier}} } secondSlash := strings.Index(specifier[firstSlash+1:], "/") From 9d4c5446cdf4ad3fd6e2c1438ba87e7d5ab011b8 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Fri, 5 Dec 2025 15:41:18 +0100 Subject: [PATCH 16/32] Fix tests after main merge --- internal/modulespecifiers/specifiers_test.go | 5 + .../reference/compiler/pnpSimpleTest.js | 14 +-- .../reference/compiler/pnpSimpleTest.symbols | 20 ++-- .../reference/compiler/pnpSimpleTest.types | 20 ++-- .../pnpTransitiveDependencies.errors.txt | 100 ++++++++++-------- .../compiler/pnpTransitiveDependencies.js | 38 +++++-- .../compiler/pnpTypeRootsResolution.js | 6 ++ .../compiler/pnpTypeRootsResolution.symbols | 54 +++++----- .../compiler/pnpTypeRootsResolution.types | 44 ++++---- .../tests/cases/compiler/pnpSimpleTest.ts | 20 ++-- .../compiler/pnpTransitiveDependencies.ts | 10 ++ .../cases/compiler/pnpTypeRootsResolution.ts | 10 ++ 12 files changed, 198 insertions(+), 143 deletions(-) diff --git a/internal/modulespecifiers/specifiers_test.go b/internal/modulespecifiers/specifiers_test.go index 96f98252fd8..b71e8a524fa 100644 --- a/internal/modulespecifiers/specifiers_test.go +++ b/internal/modulespecifiers/specifiers_test.go @@ -7,6 +7,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/symlinks" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" @@ -23,6 +24,10 @@ func (h *mockModuleSpecifierGenerationHost) GetCurrentDirectory() string { return h.currentDir } +func (h *mockModuleSpecifierGenerationHost) PnpApi() *pnp.PnpApi { + return nil +} + func (h *mockModuleSpecifierGenerationHost) UseCaseSensitiveFileNames() bool { return h.useCaseSensitiveFileNames } diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.js b/testdata/baselines/reference/compiler/pnpSimpleTest.js index 4f17149ae57..5f225d0667d 100644 --- a/testdata/baselines/reference/compiler/pnpSimpleTest.js +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.js @@ -59,11 +59,6 @@ module.exports = {}; "types": "index.d.ts" } -//// [index.js] -exports.helperA = function(value) { - return "Helper A: " + value; -}; - //// [index.d.ts] export declare function helperA(value: string): string; @@ -77,11 +72,6 @@ export declare function helperA(value: string): string; "types": "index.d.ts" } -//// [index.js] -exports.helperB = function(value) { - return "Helper B: " + value; -}; - //// [index.d.ts] export declare function helperB(value: number): string; @@ -108,3 +98,7 @@ function processData(text, num) { const resultB = (0, package_b_1.helperB)(num); return `${resultA} | ${resultB}`; } + + +//// [index.d.ts] +export declare function processData(text: string, num: number): string; diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.symbols b/testdata/baselines/reference/compiler/pnpSimpleTest.symbols index c2e6e68b830..057a2c39631 100644 --- a/testdata/baselines/reference/compiler/pnpSimpleTest.symbols +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.symbols @@ -1,15 +1,5 @@ //// [tests/cases/compiler/pnpSimpleTest.ts] //// -=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === -export declare function helperA(value: string): string; ->helperA : Symbol(helperA, Decl(index.d.ts, 0, 0)) ->value : Symbol(value, Decl(index.d.ts, 0, 32)) - -=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === -export declare function helperB(value: number): string; ->helperB : Symbol(helperB, Decl(index.d.ts, 0, 0)) ->value : Symbol(value, Decl(index.d.ts, 0, 32)) - === /src/index.ts === // Workspace package that imports both third-party dependencies import { helperA } from 'package-a'; @@ -37,3 +27,13 @@ export function processData(text: string, num: number): string { >resultA : Symbol(resultA, Decl(index.ts, 5, 7)) >resultB : Symbol(resultB, Decl(index.ts, 6, 7)) } +=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === +export declare function helperA(value: string): string; +>helperA : Symbol(helperA, Decl(index.d.ts, 0, 0)) +>value : Symbol(value, Decl(index.d.ts, 0, 32)) + +=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === +export declare function helperB(value: number): string; +>helperB : Symbol(helperB, Decl(index.d.ts, 0, 0)) +>value : Symbol(value, Decl(index.d.ts, 0, 32)) + diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.types b/testdata/baselines/reference/compiler/pnpSimpleTest.types index 90ce12017ba..9600e20f144 100644 --- a/testdata/baselines/reference/compiler/pnpSimpleTest.types +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.types @@ -1,15 +1,5 @@ //// [tests/cases/compiler/pnpSimpleTest.ts] //// -=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === -export declare function helperA(value: string): string; ->helperA : (value: string) => string ->value : string - -=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === -export declare function helperB(value: number): string; ->helperB : (value: number) => string ->value : number - === /src/index.ts === // Workspace package that imports both third-party dependencies import { helperA } from 'package-a'; @@ -40,3 +30,13 @@ export function processData(text: string, num: number): string { >resultA : string >resultB : string } +=== /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts === +export declare function helperA(value: string): string; +>helperA : (value: string) => string +>value : string + +=== /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts === +export declare function helperB(value: number): string; +>helperB : (value: number) => string +>value : number + diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt index a3063b90480..19eb9040301 100644 --- a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt @@ -1,6 +1,61 @@ /src/index.ts(5,36): error TS2307: Cannot find module 'package-b' or its corresponding type declarations. +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "exclude": [".pnp.cjs"], + "rootDir": ".", + "declaration": true, + "outDir": "./dist" + } + } + +==== /packages/package-a/index.ts (0 errors) ==== + import type { ConfigOptions } from 'package-b'; + + export interface HelperResult { + message: string; + config: ConfigOptions; + } + + export function helperA(value: string, config: ConfigOptions): HelperResult { + return { + message: "Helper A: " + value, + config: config + }; + } + +==== /packages/package-b/index.ts (0 errors) ==== + export interface ConfigOptions { + enabled: boolean; + timeout: number; + } + + export function helperB(value: number): string { + return "Helper B: " + value; + } + +==== /src/index.ts (1 errors) ==== + // Test that the project can import package-a directly + // package-a's types depend on package-b's types (ConfigOptions) + import { helperA } from 'package-a'; + import type { HelperResult } from 'package-a'; + import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'package-b' or its corresponding type declarations. + + export function useDirectDependency(text: string): HelperResult { + const config: ConfigOptions = { enabled: true, timeout: 5000 }; + return helperA(text, config); + } + + // Test that the project CANNOT import package-b directly even though package-a uses it + // This should cause an error since package-b is not in project's dependencies + export function attemptDirectImport(): ConfigOptions { + return { enabled: false, timeout: 1000 }; + } + ==== /.pnp.cjs (0 errors) ==== module.exports = {}; @@ -65,21 +120,6 @@ } } -==== /packages/package-a/index.ts (0 errors) ==== - import type { ConfigOptions } from 'package-b'; - - export interface HelperResult { - message: string; - config: ConfigOptions; - } - - export function helperA(value: string, config: ConfigOptions): HelperResult { - return { - message: "Helper A: " + value, - config: config - }; - } - ==== /packages/package-b/package.json (0 errors) ==== { "name": "package-b", @@ -88,34 +128,4 @@ ".": "./index.ts" } } - -==== /packages/package-b/index.ts (0 errors) ==== - export interface ConfigOptions { - enabled: boolean; - timeout: number; - } - - export function helperB(value: number): string { - return "Helper B: " + value; - } - -==== /src/index.ts (1 errors) ==== - // Test that the project can import package-a directly - // package-a's types depend on package-b's types (ConfigOptions) - import { helperA } from 'package-a'; - import type { HelperResult } from 'package-a'; - import type { ConfigOptions } from 'package-b'; // This should error - package-b is not a direct dependency - ~~~~~~~~~~~ -!!! error TS2307: Cannot find module 'package-b' or its corresponding type declarations. - - export function useDirectDependency(text: string): HelperResult { - const config: ConfigOptions = { enabled: true, timeout: 5000 }; - return helperA(text, config); - } - - // Test that the project CANNOT import package-b directly even though package-a uses it - // This should cause an error since package-b is not in project's dependencies - export function attemptDirectImport(): ConfigOptions { - return { enabled: false, timeout: 1000 }; - } \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js index b55c6702266..2b95d329dc2 100644 --- a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js @@ -64,6 +64,15 @@ module.exports = {}; } } +//// [package.json] +{ + "name": "package-b", + "version": "2.0.0", + "exports": { + ".": "./index.ts" + } +} + //// [index.ts] import type { ConfigOptions } from 'package-b'; @@ -79,15 +88,6 @@ export function helperA(value: string, config: ConfigOptions): HelperResult { }; } -//// [package.json] -{ - "name": "package-b", - "version": "2.0.0", - "exports": { - ".": "./index.ts" - } -} - //// [index.ts] export interface ConfigOptions { enabled: boolean; @@ -151,3 +151,23 @@ function useDirectDependency(text) { function attemptDirectImport() { return { enabled: false, timeout: 1000 }; } + + +//// [index.d.ts] +export interface ConfigOptions { + enabled: boolean; + timeout: number; +} +export declare function helperB(value: number): string; +//// [index.d.ts] +import type { ConfigOptions } from 'package-b'; +export interface HelperResult { + message: string; + config: ConfigOptions; +} +export declare function helperA(value: string, config: ConfigOptions): HelperResult; +//// [index.d.ts] +import type { HelperResult } from 'package-a'; +import type { ConfigOptions } from 'package-b'; +export declare function useDirectDependency(text: string): HelperResult; +export declare function attemptDirectImport(): ConfigOptions; diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js index c1e90142710..9759e4f2e0c 100644 --- a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js @@ -101,3 +101,9 @@ function handleRequest(req, res) { res.json({ data: 'Hello, world!' }); } exports.server = (0, server_lib_1.createServer)(); + + +//// [index.d.ts] +import type { Request, Response } from 'server-lib'; +export declare function handleRequest(req: Request, res: Response): void; +export declare const server: Record; diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols index 739cb2367e0..e7e802d9ed7 100644 --- a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.symbols @@ -1,5 +1,32 @@ //// [tests/cases/compiler/pnpTypeRootsResolution.ts] //// +=== /src/index.ts === +// Test that TypeScript can resolve @types packages through PnP +import type { Request, Response } from 'server-lib'; +>Request : Symbol(Request, Decl(index.ts, 1, 13)) +>Response : Symbol(Response, Decl(index.ts, 1, 22)) + +import { createServer } from 'server-lib'; +>createServer : Symbol(createServer, Decl(index.ts, 2, 8)) + +export function handleRequest(req: Request, res: Response): void { +>handleRequest : Symbol(handleRequest, Decl(index.ts, 2, 42)) +>req : Symbol(req, Decl(index.ts, 4, 30)) +>Request : Symbol(Request, Decl(index.ts, 1, 13)) +>res : Symbol(res, Decl(index.ts, 4, 43)) +>Response : Symbol(Response, Decl(index.ts, 1, 22)) + + res.json({ data: 'Hello, world!' }); +>res.json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) +>res : Symbol(res, Decl(index.ts, 4, 43)) +>json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) +>data : Symbol(data, Decl(index.ts, 5, 12)) +} + +export const server = createServer(); +>server : Symbol(server, Decl(index.ts, 8, 12)) +>createServer : Symbol(createServer, Decl(index.ts, 2, 8)) + === /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts === export interface Request { >Request : Symbol(Request, Decl(index.d.ts, 0, 0)) @@ -31,30 +58,3 @@ export declare function createServer(): Record; >createServer : Symbol(createServer, Decl(index.d.ts, 8, 1)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) -=== /src/index.ts === -// Test that TypeScript can resolve @types packages through PnP -import type { Request, Response } from 'server-lib'; ->Request : Symbol(Request, Decl(index.ts, 1, 13)) ->Response : Symbol(Response, Decl(index.ts, 1, 22)) - -import { createServer } from 'server-lib'; ->createServer : Symbol(createServer, Decl(index.ts, 2, 8)) - -export function handleRequest(req: Request, res: Response): void { ->handleRequest : Symbol(handleRequest, Decl(index.ts, 2, 42)) ->req : Symbol(req, Decl(index.ts, 4, 30)) ->Request : Symbol(Request, Decl(index.ts, 1, 13)) ->res : Symbol(res, Decl(index.ts, 4, 43)) ->Response : Symbol(Response, Decl(index.ts, 1, 22)) - - res.json({ data: 'Hello, world!' }); ->res.json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) ->res : Symbol(res, Decl(index.ts, 4, 43)) ->json : Symbol(Response.json, Decl(index.d.ts, 6, 44)) ->data : Symbol(data, Decl(index.ts, 5, 12)) -} - -export const server = createServer(); ->server : Symbol(server, Decl(index.ts, 8, 12)) ->createServer : Symbol(createServer, Decl(index.ts, 2, 8)) - diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types index 963f0b9c689..f78d3049cfd 100644 --- a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.types @@ -1,27 +1,5 @@ //// [tests/cases/compiler/pnpTypeRootsResolution.ts] //// -=== /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts === -export interface Request { - params: Record; ->params : Record - - query: Record; ->query : Record -} - -export interface Response { - send(body: Record): void; ->send : (body: Record) => void ->body : Record - - json(body: Record): void; ->json : (body: Record) => void ->body : Record -} - -export declare function createServer(): Record; ->createServer : () => Record - === /src/index.ts === // Test that TypeScript can resolve @types packages through PnP import type { Request, Response } from 'server-lib'; @@ -51,3 +29,25 @@ export const server = createServer(); >createServer() : Record >createServer : () => Record +=== /.yarn/cache/@types-server-lib-npm-2.0.0-mnop3456/node_modules/@types/server-lib/index.d.ts === +export interface Request { + params: Record; +>params : Record + + query: Record; +>query : Record +} + +export interface Response { + send(body: Record): void; +>send : (body: Record) => void +>body : Record + + json(body: Record): void; +>json : (body: Record) => void +>body : Record +} + +export declare function createServer(): Record; +>createServer : () => Record + diff --git a/testdata/tests/cases/compiler/pnpSimpleTest.ts b/testdata/tests/cases/compiler/pnpSimpleTest.ts index 7c4b2603ee5..2cae99f2ef8 100644 --- a/testdata/tests/cases/compiler/pnpSimpleTest.ts +++ b/testdata/tests/cases/compiler/pnpSimpleTest.ts @@ -59,11 +59,6 @@ module.exports = {}; "types": "index.d.ts" } -// @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.js -exports.helperA = function(value) { - return "Helper A: " + value; -}; - // @filename: /.yarn/cache/package-a-npm-1.0.0-abcd1234/node_modules/package-a/index.d.ts export declare function helperA(value: string): string; @@ -77,14 +72,19 @@ export declare function helperA(value: string): string; "types": "index.d.ts" } -// @filename: /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.js -exports.helperB = function(value) { - return "Helper B: " + value; -}; - // @filename: /.yarn/cache/package-b-npm-2.0.0-efgh5678/node_modules/package-b/index.d.ts export declare function helperB(value: number): string; +// @filename: /tsconfig.json +{ + "compilerOptions": { + "exclude": [".pnp.cjs"], + "rootDir": ".", + "declaration": true, + "outDir": "./dist" + } +} + // @filename: /src/index.ts // Workspace package that imports both third-party dependencies import { helperA } from 'package-a'; diff --git a/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts index 41fdc6d77e7..05aea085ae3 100644 --- a/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts +++ b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts @@ -52,6 +52,16 @@ module.exports = {}; } } +// @filename: /tsconfig.json +{ + "compilerOptions": { + "exclude": [".pnp.cjs"], + "rootDir": ".", + "declaration": true, + "outDir": "./dist" + } +} + // @filename: /packages/package-a/package.json { "name": "package-a", diff --git a/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts index 85153441532..3a4a5813b3b 100644 --- a/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts +++ b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts @@ -53,6 +53,16 @@ module.exports = {}; } } +// @filename: /tsconfig.json +{ + "compilerOptions": { + "exclude": [".pnp.cjs"], + "rootDir": ".", + "declaration": true, + "outDir": "./dist" + } +} + // @filename: /.yarn/cache/server-lib-npm-2.0.0-ijkl9012/node_modules/server-lib/package.json { "name": "server-lib", From f46e24d8547db720c3cf600446c51cc11da89799 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Fri, 16 Jan 2026 15:52:44 +0100 Subject: [PATCH 17/32] Fix autocomplete for pnp to support autoimport new infra --- .../tests/pnpAutoImportCompletion_test.go | 4 ++-- internal/ls/autoimport/aliasresolver.go | 6 ++++++ internal/ls/autoimport/registry.go | 17 ++++++++++++++--- internal/ls/autoimport/util.go | 7 +++++++ internal/modulespecifiers/specifiers.go | 2 +- internal/pnp/pnpapi_test.go | 6 +++--- internal/project/autoimport.go | 14 ++++++++++++++ 7 files changed, 47 insertions(+), 9 deletions(-) diff --git a/internal/fourslash/tests/pnpAutoImportCompletion_test.go b/internal/fourslash/tests/pnpAutoImportCompletion_test.go index 074ea2d76df..39aa61f5548 100644 --- a/internal/fourslash/tests/pnpAutoImportCompletion_test.go +++ b/internal/fourslash/tests/pnpAutoImportCompletion_test.go @@ -164,7 +164,7 @@ aValue; &lsproto.CompletionItem{ Label: "helperA", Data: &lsproto.CompletionItemData{ - AutoImport: &lsproto.AutoImportData{ + AutoImport: &lsproto.AutoImportFix{ ModuleSpecifier: "package-a/subpath", }, }, @@ -176,7 +176,7 @@ aValue; &lsproto.CompletionItem{ Label: "workspaceHelper", Data: &lsproto.CompletionItemData{ - AutoImport: &lsproto.AutoImportData{ + AutoImport: &lsproto.AutoImportFix{ ModuleSpecifier: "workspace-lib", }, }, diff --git a/internal/ls/autoimport/aliasresolver.go b/internal/ls/autoimport/aliasresolver.go index 6aa6b475f24..b1ca7cea499 100644 --- a/internal/ls/autoimport/aliasresolver.go +++ b/internal/ls/autoimport/aliasresolver.go @@ -8,6 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/symlinks" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" @@ -225,4 +226,9 @@ func (r *aliasResolver) SourceFileMayBeEmitted(sourceFile *ast.SourceFile, force panic("unimplemented") } +// PnpApi implements checker.Program. +func (r *aliasResolver) PnpApi() *pnp.PnpApi { + panic("unimplemented") +} + var _ checker.Program = (*aliasResolver)(nil) diff --git a/internal/ls/autoimport/registry.go b/internal/ls/autoimport/registry.go index ac5ff391fa8..d2bf22eec6d 100644 --- a/internal/ls/autoimport/registry.go +++ b/internal/ls/autoimport/registry.go @@ -22,6 +22,7 @@ import ( "github.com/microsoft/typescript-go/internal/lsp/lsproto" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/project/dirty" "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/symlinks" @@ -362,6 +363,7 @@ type RegistryChange struct { type RegistryCloneHost interface { module.ResolutionHost FS() vfs.FS + PnpApi() *pnp.PnpApi GetDefaultProject(path tspath.Path) (tspath.Path, *compiler.Program) GetProgramForProject(projectPath tspath.Path) *compiler.Program GetPackageJson(fileName string) *packagejson.InfoCacheEntry @@ -915,9 +917,18 @@ outer: continue outer } } - // Skip all node_modules files - they are always handled by node_modules buckets. - // This simplifies the logic and ensures exports are indexed consistently. - if strings.Contains(file.FileName(), "/node_modules/") { + + // If pnp is available, node_modules buckets won't be built as all packages are located in `.yarn/cache` + // This is why we need to handle all files, except the ones that are not importable in the project + pnpApi := b.host.PnpApi() + if pnpApi != nil { + if !pnpApi.IsImportable(string(projectPath), file.FileName()) { + continue + } + + // Skip all node_modules files - they are always handled by node_modules buckets. + // This simplifies the logic and ensures exports are indexed consistently. + } else if strings.Contains(file.FileName(), "/node_modules/") { continue } // Skip files that are realpaths of symlinks in node_modules. diff --git a/internal/ls/autoimport/util.go b/internal/ls/autoimport/util.go index dde0409dc4f..8817b3a0519 100644 --- a/internal/ls/autoimport/util.go +++ b/internal/ls/autoimport/util.go @@ -16,6 +16,7 @@ import ( "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/modulespecifiers" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/wrapvfs" @@ -252,6 +253,7 @@ func getPackageRealpathFuncs(fs vfs.FS, packageDir string) (toRealpath, toSymlin type resolutionHost struct { fs vfs.FS currentDirectory string + pnpApi *pnp.PnpApi } var _ module.ResolutionHost = (*resolutionHost)(nil) @@ -264,10 +266,15 @@ func (rh *resolutionHost) FS() vfs.FS { return rh.fs } +func (rh *resolutionHost) PnpApi() *pnp.PnpApi { + return rh.pnpApi +} + func getModuleResolver(host RegistryCloneHost, realpath func(string) string) *module.Resolver { rh := &resolutionHost{ fs: wrapvfs.Wrap(host.FS(), wrapvfs.Replacements{Realpath: realpath}), currentDirectory: host.GetCurrentDirectory(), + pnpApi: host.PnpApi(), } return module.NewResolver(rh, core.EmptyCompilerOptions, "", "") } diff --git a/internal/modulespecifiers/specifiers.go b/internal/modulespecifiers/specifiers.go index fc88410f20c..aa550ffd941 100644 --- a/internal/modulespecifiers/specifiers.go +++ b/internal/modulespecifiers/specifiers.go @@ -850,7 +850,7 @@ func tryGetModuleNameAsPnpPackage( nodeModulesDirectoryName = pnpPackageName + moduleSpecifier[parts.PackageRootIndex:] } - return GetPackageNameFromTypesPackageName(nodeModulesDirectoryName) + return module.GetPackageNameFromTypesPackageName(nodeModulesDirectoryName) } func tryGetModuleNameAsNodeModule( diff --git a/internal/pnp/pnpapi_test.go b/internal/pnp/pnpapi_test.go index 22839517f1d..2752c3b1026 100644 --- a/internal/pnp/pnpapi_test.go +++ b/internal/pnp/pnpapi_test.go @@ -31,8 +31,8 @@ func TestLoadPnPManifest(t *testing.T) { path string msg string }{ - {"pnp-yarn-v3.cjs", filepath.Join(repo.TestDataPath, "fixtures", "pnp", "pnp-yarn-v3.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 3"}, - {"pnp-yarn-v4.cjs", filepath.Join(repo.TestDataPath, "fixtures", "pnp", "pnp-yarn-v4.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 4"}, + {"pnp-yarn-v3.cjs", filepath.Join(repo.TestDataPath(), "fixtures", "pnp", "pnp-yarn-v3.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 3"}, + {"pnp-yarn-v4.cjs", filepath.Join(repo.TestDataPath(), "fixtures", "pnp", "pnp-yarn-v4.cjs"), "Expected to load the .pnp.cjs file generated by Yarn 4"}, } for _, tc := range cases { @@ -54,7 +54,7 @@ func TestLoadPnPManifest(t *testing.T) { func TestResolveUnqualified(t *testing.T) { t.Parallel() - expectationsPath := filepath.Join(repo.TestDataPath, "fixtures", "pnp", "test-expectations.json") + expectationsPath := filepath.Join(repo.TestDataPath(), "fixtures", "pnp", "test-expectations.json") content, err := os.ReadFile(expectationsPath) if err != nil { diff --git a/internal/project/autoimport.go b/internal/project/autoimport.go index 1f8d1e3a7c9..35e745f634b 100644 --- a/internal/project/autoimport.go +++ b/internal/project/autoimport.go @@ -9,8 +9,10 @@ import ( "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/ls/autoimport" "github.com/microsoft/typescript-go/internal/packagejson" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) type autoImportBuilderFS struct { @@ -61,6 +63,7 @@ type autoImportRegistryCloneHost struct { parseCache *ParseCache fs *sourceFS currentDirectory string + pnpApi *pnp.PnpApi filesMu sync.Mutex files []ParseCacheKey @@ -75,10 +78,16 @@ func newAutoImportRegistryCloneHost( currentDirectory string, toPath func(fileName string) tspath.Path, ) *autoImportRegistryCloneHost { + pnpApi := pnp.InitPnpApi(snapshotFSBuilder.fs, currentDirectory) + if pnpApi != nil { + snapshotFSBuilder.fs = pnpvfs.From(snapshotFSBuilder.fs) + } + return &autoImportRegistryCloneHost{ projectCollection: projectCollection, parseCache: parseCache, fs: newSourceFS(false, &autoImportBuilderFS{snapshotFSBuilder: snapshotFSBuilder}, toPath), + pnpApi: pnpApi, } } @@ -92,6 +101,11 @@ func (a *autoImportRegistryCloneHost) GetCurrentDirectory() string { return a.currentDirectory } +// PnpApi implements autoimport.RegistryCloneHost. +func (a *autoImportRegistryCloneHost) PnpApi() *pnp.PnpApi { + return a.pnpApi +} + // GetDefaultProject implements autoimport.RegistryCloneHost. func (a *autoImportRegistryCloneHost) GetDefaultProject(path tspath.Path) (tspath.Path, *compiler.Program) { project := a.projectCollection.GetDefaultProject(path) From 44c1f3019ef5382ba0baf6c4d9740b24b94e6d3c Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Tue, 17 Feb 2026 18:14:14 +0100 Subject: [PATCH 18/32] Fix yarn patch implementation by returning resolved paths on transitive dependencies --- internal/modulespecifiers/specifiers.go | 46 ++++++++++--------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/internal/modulespecifiers/specifiers.go b/internal/modulespecifiers/specifiers.go index 638c19a3d3c..3eef08d47a8 100644 --- a/internal/modulespecifiers/specifiers.go +++ b/internal/modulespecifiers/specifiers.go @@ -752,50 +752,40 @@ func tryGetModuleNameAsPnpPackage( pnpPackageName := "" fromLocator, _ := pnpApi.FindLocator(importingSourceFile.FileName()) toLocator, _ := pnpApi.FindLocator(pathObj.FileName) - - // Don't use the package name when the imported file is inside - // the source directory (prefer a relative path instead) - if fromLocator == toLocator { - return "" - } + parts := GetNodeModulePathParts(pathObj.FileName) if fromLocator != nil && toLocator != nil { - fromInfo := pnpApi.GetPackage(fromLocator) + // Don't use the package name when the imported file is inside + // the source directory (prefer a relative path instead) + if *fromLocator == *toLocator { + return "" + } - useToLocator := false + fromInfo := pnpApi.GetPackage(fromLocator) for i := range fromInfo.PackageDependencies { isAlias := fromInfo.PackageDependencies[i].IsAlias() if isAlias && fromInfo.PackageDependencies[i].AliasName == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { - useToLocator = true + pnpPackageName = toLocator.Name break } else if fromInfo.PackageDependencies[i].Ident == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { - useToLocator = true + pnpPackageName = toLocator.Name break } } - if useToLocator { - pnpPackageName = toLocator.Name - } - } - - var parts *NodeModulePathParts - if toLocator != nil { - toInfo := pnpApi.GetPackage(toLocator) - packageRootAbsolutePath := pnpApi.GetPackageLocationAbsolutePath(toInfo) - parts = &NodeModulePathParts{ - TopLevelNodeModulesIndex: -1, - TopLevelPackageNameIndex: -1, - PackageRootIndex: len(packageRootAbsolutePath), - FileNameIndex: strings.LastIndex(pathObj.FileName, "/"), + if parts == nil { + toInfo := pnpApi.GetPackage(toLocator) + packageRootAbsolutePath := pnpApi.GetPackageLocationAbsolutePath(toInfo) + parts = &NodeModulePathParts{ + TopLevelNodeModulesIndex: -1, + TopLevelPackageNameIndex: -1, + PackageRootIndex: len(packageRootAbsolutePath), + FileNameIndex: strings.LastIndex(pathObj.FileName, "/"), + } } } - if parts == nil { - return "" - } - // Simplify the full file path to something that can be resolved by Node. preferences := getModuleSpecifierPreferences(userPreferences, host, options, importingSourceFile, "") allowedEndings := preferences.getAllowedEndingsInPreferredOrder(core.ResolutionModeNone) From b10a0dc9da67e169a129a943de39f1997b0e8f25 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Wed, 18 Feb 2026 17:04:46 +0100 Subject: [PATCH 19/32] Make IsInPnpModule stricter by only matching valid dependencies --- internal/modulespecifiers/specifiers.go | 11 ++++++----- internal/pnp/pnpapi.go | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/internal/modulespecifiers/specifiers.go b/internal/modulespecifiers/specifiers.go index 3eef08d47a8..9a189176af6 100644 --- a/internal/modulespecifiers/specifiers.go +++ b/internal/modulespecifiers/specifiers.go @@ -287,7 +287,7 @@ func GetEachFileNameOfModule( if !(shouldFilterIgnoredPaths && containsIgnoredPath(p)) { IsInNodeModules := ContainsNodeModules(p) if pnpApi := host.PnpApi(); pnpApi != nil { - IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(importingFileName, p) + IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(p, importingFileName) } results = append(results, ModulePath{ @@ -350,7 +350,7 @@ func GetEachFileNameOfModule( if !(shouldFilterIgnoredPaths && containsIgnoredPath(p)) { IsInNodeModules := ContainsNodeModules(p) if pnpApi := host.PnpApi(); pnpApi != nil { - IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(importingFileName, p) + IsInNodeModules = IsInNodeModules || pnpApi.IsInPnpModule(p, importingFileName) } results = append(results, ModulePath{ @@ -764,11 +764,12 @@ func tryGetModuleNameAsPnpPackage( fromInfo := pnpApi.GetPackage(fromLocator) for i := range fromInfo.PackageDependencies { - isAlias := fromInfo.PackageDependencies[i].IsAlias() - if isAlias && fromInfo.PackageDependencies[i].AliasName == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { + dep := fromInfo.PackageDependencies[i] + isAlias := dep.IsAlias() + if isAlias && dep.AliasName == toLocator.Name && dep.Reference == toLocator.Reference { pnpPackageName = toLocator.Name break - } else if fromInfo.PackageDependencies[i].Ident == toLocator.Name && fromInfo.PackageDependencies[i].Reference == toLocator.Reference { + } else if dep.Ident == toLocator.Name && dep.Reference == toLocator.Reference { pnpPackageName = toLocator.Name break } diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 5daf7ef30cd..2215fc42f8b 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -352,11 +352,24 @@ func (p *PnpApi) GetPackageLocationAbsolutePath(packageInfo *PackageInfo) string return tspath.RemoveTrailingDirectorySeparators(tspath.ResolvePath(p.manifest.dirPath, packageLocation)) } -// Checks if fromFileName and toFileName are in different pnp modules -func (p *PnpApi) IsInPnpModule(fromFileName string, toFileName string) bool { +// Checks if toFileName is in a module defined in the dependencies of fromFileName +func (p *PnpApi) IsInPnpModule(toFileName string, fromFileName string) bool { fromLocator, _ := p.FindLocator(fromFileName) toLocator, _ := p.FindLocator(toFileName) - return fromLocator != nil && toLocator != nil && fromLocator.Name != toLocator.Name + + if fromLocator != nil && toLocator != nil && fromLocator.Name != toLocator.Name { + fromInfo := p.GetPackage(fromLocator) + for _, dep := range fromInfo.PackageDependencies { + if dep.Ident == toLocator.Name { + return true + } + + if dep.IsAlias() && dep.AliasName == toLocator.Name { + return true + } + } + } + return false } func (p *PnpApi) AppendPnpTypeRoots(nmTypes []string, currentDirectory string, compilerOptions *core.CompilerOptions, nmFromConfig bool) ([]string, bool) { From 5cb7feb3a1855f7d2e816403f2509ef2af8db551 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 19 Feb 2026 10:36:39 +0100 Subject: [PATCH 20/32] Fix tests and lint after main merge + revert submodule hash diff --- _submodules/TypeScript | 2 +- .../tests/pnpAutoImportCompletion_test.go | 8 +++---- internal/pnp/manifestparser.go | 2 +- internal/pnp/pnpapi_test.go | 7 +++--- .../compiler/pnpDeclarationEmitWorkspace.js | 12 ++++------ .../reference/compiler/pnpSimpleTest.js | 13 +++++------ .../compiler/pnpTransitiveDependencies.js | 22 +++++-------------- .../compiler/pnpTransitiveDependencies.types | 4 ++-- .../compiler/pnpTypeRootsResolution.js | 10 +++------ 9 files changed, 29 insertions(+), 51 deletions(-) diff --git a/_submodules/TypeScript b/_submodules/TypeScript index 9e8eaa1746b..1dcae83560d 160000 --- a/_submodules/TypeScript +++ b/_submodules/TypeScript @@ -1 +1 @@ -Subproject commit 9e8eaa1746b0d09c3cd29048126ef9cf24f29c03 +Subproject commit 1dcae83560d6f1bf293fc91da39b040cbc0d4207 diff --git a/internal/fourslash/tests/pnpAutoImportCompletion_test.go b/internal/fourslash/tests/pnpAutoImportCompletion_test.go index 39aa61f5548..38f1bcd1f7f 100644 --- a/internal/fourslash/tests/pnpAutoImportCompletion_test.go +++ b/internal/fourslash/tests/pnpAutoImportCompletion_test.go @@ -168,9 +168,9 @@ aValue; ModuleSpecifier: "package-a/subpath", }, }, - Kind: PtrTo(lsproto.CompletionItemKindFunction), + Kind: new(lsproto.CompletionItemKindFunction), AdditionalTextEdits: fourslash.AnyTextEdits, - SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), + SortText: new(string(ls.SortTextAutoImportSuggestions)), }, // Verify that workspaceHelper completion creates an import from 'workspace-lib' &lsproto.CompletionItem{ @@ -180,9 +180,9 @@ aValue; ModuleSpecifier: "workspace-lib", }, }, - Kind: PtrTo(lsproto.CompletionItemKindFunction), + Kind: new(lsproto.CompletionItemKindFunction), AdditionalTextEdits: fourslash.AnyTextEdits, - SortText: PtrTo(string(ls.SortTextAutoImportSuggestions)), + SortText: new(string(ls.SortTextAutoImportSuggestions)), }, }, // `bValue` can appear in the completion list since it's mentioned in a unresolved import, but `helperB` should not diff --git a/internal/pnp/manifestparser.go b/internal/pnp/manifestparser.go index cff5f81057d..892fcec1e88 100644 --- a/internal/pnp/manifestparser.go +++ b/internal/pnp/manifestparser.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/go-json-experiment/json" + "github.com/microsoft/typescript-go/internal/json" "github.com/dlclark/regexp2" "github.com/microsoft/typescript-go/internal/tspath" diff --git a/internal/pnp/pnpapi_test.go b/internal/pnp/pnpapi_test.go index 2752c3b1026..2dfb189fb78 100644 --- a/internal/pnp/pnpapi_test.go +++ b/internal/pnp/pnpapi_test.go @@ -5,16 +5,15 @@ import ( "path/filepath" "testing" - "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" + "github.com/microsoft/typescript-go/internal/json" "github.com/microsoft/typescript-go/internal/repo" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs/osvfs" ) type TestSuite struct { - Manifest jsontext.Value `json:"manifest"` - Tests []TestCase `json:"tests"` + Manifest json.Value `json:"manifest"` + Tests []TestCase `json:"tests"` } type TestCase struct { diff --git a/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js index a949a85d468..9db753db03a 100644 --- a/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js +++ b/testdata/baselines/reference/compiler/pnpDeclarationEmitWorkspace.js @@ -99,15 +99,11 @@ export interface AppConfig { //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.factory = void 0; -exports.initializeService = initializeService; -const other_subpath_1 = require("package-a/other-subpath"); -function initializeService(url) { - return (0, other_subpath_1.createServiceConfig)(url); +import { createServiceConfig } from 'package-a/other-subpath'; +export function initializeService(url) { + return createServiceConfig(url); } -exports.factory = other_subpath_1.createServiceConfig; +export const factory = createServiceConfig; //// [index.d.ts] diff --git a/testdata/baselines/reference/compiler/pnpSimpleTest.js b/testdata/baselines/reference/compiler/pnpSimpleTest.js index 5f225d0667d..7ad3d4ec880 100644 --- a/testdata/baselines/reference/compiler/pnpSimpleTest.js +++ b/testdata/baselines/reference/compiler/pnpSimpleTest.js @@ -87,15 +87,12 @@ export function processData(text: string, num: number): string { } //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.processData = processData; // Workspace package that imports both third-party dependencies -const package_a_1 = require("package-a"); -const package_b_1 = require("package-b"); -function processData(text, num) { - const resultA = (0, package_a_1.helperA)(text); - const resultB = (0, package_b_1.helperB)(num); +import { helperA } from 'package-a'; +import { helperB } from 'package-b'; +export function processData(text, num) { + const resultA = helperA(text); + const resultB = helperB(num); return `${resultA} | ${resultB}`; } diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js index 2b95d329dc2..6d8af25a2cb 100644 --- a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.js @@ -118,37 +118,27 @@ export function attemptDirectImport(): ConfigOptions { //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.helperB = helperB; -function helperB(value) { +export function helperB(value) { return "Helper B: " + value; } //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.helperA = helperA; -function helperA(value, config) { +export function helperA(value, config) { return { message: "Helper A: " + value, config: config }; } //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.useDirectDependency = useDirectDependency; -exports.attemptDirectImport = attemptDirectImport; // Test that the project can import package-a directly // package-a's types depend on package-b's types (ConfigOptions) -const package_a_1 = require("package-a"); -function useDirectDependency(text) { +import { helperA } from 'package-a'; +export function useDirectDependency(text) { const config = { enabled: true, timeout: 5000 }; - return (0, package_a_1.helperA)(text, config); + return helperA(text, config); } // Test that the project CANNOT import package-b directly even though package-a uses it // This should cause an error since package-b is not in project's dependencies -function attemptDirectImport() { +export function attemptDirectImport() { return { enabled: false, timeout: 1000 }; } diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types index 67a56d6ef3d..0b04965c4b3 100644 --- a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.types @@ -56,7 +56,7 @@ export function helperB(value: number): string { // Test that the project can import package-a directly // package-a's types depend on package-b's types (ConfigOptions) import { helperA } from 'package-a'; ->helperA : (value: string, config: import("/packages/package-b/index").ConfigOptions) => HelperResult +>helperA : (value: string, config: import("../packages/package-b").ConfigOptions) => HelperResult import type { HelperResult } from 'package-a'; >HelperResult : HelperResult @@ -78,7 +78,7 @@ export function useDirectDependency(text: string): HelperResult { return helperA(text, config); >helperA(text, config) : HelperResult ->helperA : (value: string, config: import("/packages/package-b/index").ConfigOptions) => HelperResult +>helperA : (value: string, config: import("../packages/package-b").ConfigOptions) => HelperResult >text : string >config : ConfigOptions } diff --git a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js index 9759e4f2e0c..d1f7cb19551 100644 --- a/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js +++ b/testdata/baselines/reference/compiler/pnpTypeRootsResolution.js @@ -92,15 +92,11 @@ export const server = createServer(); //// [index.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.server = void 0; -exports.handleRequest = handleRequest; -const server_lib_1 = require("server-lib"); -function handleRequest(req, res) { +import { createServer } from 'server-lib'; +export function handleRequest(req, res) { res.json({ data: 'Hello, world!' }); } -exports.server = (0, server_lib_1.createServer)(); +export const server = createServer(); //// [index.d.ts] From f4c7635d66d1524f29b2a207fbbc70585c229054 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 30 Mar 2026 17:01:55 +0200 Subject: [PATCH 21/32] Remove usages of regexp2 in yarn pnp --- internal/pnp/manifestparser.go | 22 +++++++++++----------- internal/pnp/pnpapi.go | 4 ++-- testdata/fixtures/pnp/pnp-yarn-v3.cjs | 2 +- testdata/fixtures/pnp/pnp-yarn-v4.cjs | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/internal/pnp/manifestparser.go b/internal/pnp/manifestparser.go index 892fcec1e88..283da74ee61 100644 --- a/internal/pnp/manifestparser.go +++ b/internal/pnp/manifestparser.go @@ -3,15 +3,17 @@ package pnp import ( "errors" "fmt" + "regexp" "strings" "github.com/microsoft/typescript-go/internal/json" - "github.com/dlclark/regexp2" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" ) +var manifestRegex = regexp.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`) + type LinkType string const ( @@ -62,7 +64,7 @@ type PackageRegistryTrie struct { type PnpManifestData struct { dirPath string - ignorePatternData *regexp2.Regexp + ignorePatternData *regexp.Regexp enableTopLevelFallback bool fallbackPool [][2]string @@ -97,13 +99,12 @@ func extractPnpDataStringFromPath(fs vfs.FS, path string) (string, error) { if !ok { return "", errors.New("failed to read file: " + path) } - manifestRegex := regexp2.MustCompile(`(const[ \r\n]+RAW_RUNTIME_STATE[ \r\n]*=[ \r\n]*|hydrateRuntimeState\(JSON\.parse\()'`, regexp2.None) - matches, err := manifestRegex.FindStringMatch(pnpScriptString) - if err != nil || matches == nil { + loc := manifestRegex.FindStringIndex(pnpScriptString) + if loc == nil { return "", errors.New("we failed to locate the PnP data payload inside its manifest file. Did you manually edit the file?") } - start := matches.Index + matches.Length + start := loc[1] var b strings.Builder b.Grow(len(pnpScriptString)) for i := start; i < len(pnpScriptString); i++ { @@ -149,12 +150,11 @@ func parsePnpManifest(rawData map[string]any, manifestDir string) (*PnpManifestD ignorePatternData := getField(rawData, "ignorePatternData", parseString) if ignorePatternData != "" { - ignorePatternDataRegexp, err := regexp2.Compile(ignorePatternData, regexp2.None) - if err != nil { - return nil, fmt.Errorf("failed to compile ignore pattern data: %w", err) + ignorePatternDataRegexp, err := regexp.Compile(ignorePatternData) + // Skipping ignorePatternData if the regex is invalid, which can happen if the regex is not go-compatible + if err == nil { + data.ignorePatternData = ignorePatternDataRegexp } - - data.ignorePatternData = ignorePatternDataRegexp } data.enableTopLevelFallback = getField(rawData, "enableTopLevelFallback", parseBool) diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 2215fc42f8b..0fb2efe3031 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -190,9 +190,9 @@ func (p *PnpApi) FindLocator(parentPath string) (*Locator, *PnpError) { tspath.ComparePathsOptions{UseCaseSensitiveFileNames: true}) if p.manifest.ignorePatternData != nil { - match, err := p.manifest.ignorePatternData.MatchString(relativePath) + match := p.manifest.ignorePatternData.MatchString(relativePath) - if err == nil && match { + if match { return nil, nil } } diff --git a/testdata/fixtures/pnp/pnp-yarn-v3.cjs b/testdata/fixtures/pnp/pnp-yarn-v3.cjs index 0e6fd459fb1..39d88fe8f72 100644 --- a/testdata/fixtures/pnp/pnp-yarn-v3.cjs +++ b/testdata/fixtures/pnp/pnp-yarn-v3.cjs @@ -17,7 +17,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }\ ],\ "enableTopLevelFallback": true,\ - "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ + "ignorePatternData": "^.yarn/sdks(/.*)?$",\ "fallbackExclusionList": [\ ["tmp.trDEa5gPrG", ["workspace:."]]\ ],\ diff --git a/testdata/fixtures/pnp/pnp-yarn-v4.cjs b/testdata/fixtures/pnp/pnp-yarn-v4.cjs index 53539201e46..d13ce36071e 100644 --- a/testdata/fixtures/pnp/pnp-yarn-v4.cjs +++ b/testdata/fixtures/pnp/pnp-yarn-v4.cjs @@ -15,7 +15,7 @@ const RAW_RUNTIME_STATE = }\ ],\ "enableTopLevelFallback": true,\ - "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ + "ignorePatternData": "^.yarn/sdks(/.*)?$",\ "fallbackExclusionList": [\ ["tmp.trDEa5gPrG", ["workspace:."]]\ ],\ From 4acc00f75366696fb5cd722e0d3b84e37298a19b Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 30 Mar 2026 17:34:42 +0200 Subject: [PATCH 22/32] Fix tests for pnp --- internal/vfs/pnpvfs/pnpvfs.go | 18 +++--------------- internal/vfs/pnpvfs/pnpvfs_test.go | 12 ++++++------ 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index c1c43265824..82ae1cbf23a 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -54,22 +54,10 @@ func (pnpFS *pnpFS) FileExists(path string) bool { } func (pnpFS *pnpFS) GetAccessibleEntries(path string) vfs.Entries { - path, hash, basePath := resolveVirtual(path) - - fs, formattedPath, zipPath := getMatchingFS(pnpFS, path) - entries := fs.GetAccessibleEntries(formattedPath) - - for i, dir := range entries.Directories { - fullPath := tspath.CombinePaths(zipPath+formattedPath, dir) - entries.Directories[i] = makeVirtualPath(basePath, hash, fullPath) - } - - for i, file := range entries.Files { - fullPath := tspath.CombinePaths(zipPath+formattedPath, file) - entries.Files[i] = makeVirtualPath(basePath, hash, fullPath) - } + path, _, _ = resolveVirtual(path) - return entries + fs, formattedPath, _ := getMatchingFS(pnpFS, path) + return fs.GetAccessibleEntries(formattedPath) } func (pnpFS *pnpFS) ReadFile(path string) (contents string, ok bool) { diff --git a/internal/vfs/pnpvfs/pnpvfs_test.go b/internal/vfs/pnpvfs/pnpvfs_test.go index 66ba1478b53..be1275a8089 100644 --- a/internal/vfs/pnpvfs/pnpvfs_test.go +++ b/internal/vfs/pnpvfs/pnpvfs_test.go @@ -218,8 +218,8 @@ func TestPnpVfs_VirtualPathHandling(t *testing.T) { entries := fs.GetAccessibleEntries("/project/packages/__virtual__/packageB-virtual-123456/0/packageB") assert.DeepEqual(t, entries.Files, []string{ - "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/indexB.ts", - "/project/packages/__virtual__/packageB-virtual-123456/0/packageB/package.json", + "indexB.ts", + "package.json", }) assert.DeepEqual(t, entries.Directories, []string(nil)) @@ -266,12 +266,12 @@ func TestPnpVfs_RealZipIntegration(t *testing.T) { assert.Equal(t, content, zipFiles["package.json"]) entries := fs.GetAccessibleEntries(zipPath) - assert.DeepEqual(t, entries.Files, []string{zipPath + "/package.json", zipPath + "/tsconfig.json"}) - assert.DeepEqual(t, entries.Directories, []string{zipPath + "/src"}) + assert.DeepEqual(t, entries.Files, []string{"package.json", "tsconfig.json"}) + assert.DeepEqual(t, entries.Directories, []string{"src"}) entries = fs.GetAccessibleEntries(zipPath + "/src") - assert.DeepEqual(t, entries.Files, []string{zipPath + "/src/index.ts"}) - assert.DeepEqual(t, entries.Directories, []string{zipPath + "/src/utils"}) + assert.DeepEqual(t, entries.Files, []string{"index.ts"}) + assert.DeepEqual(t, entries.Directories, []string{"utils"}) assert.Equal(t, fs.Realpath(indexPath), indexPath) From 66f802dcd74e8b95b12b3177f0e8043919b0e1ae Mon Sep 17 00:00:00 2001 From: Chris Hegre Date: Mon, 13 Apr 2026 11:17:57 +0200 Subject: [PATCH 23/32] Fix yarn-pnp initialization ordering --- internal/api/server.go | 3 ++- internal/lsp/server.go | 3 ++- internal/project/session.go | 2 ++ internal/project/snapshot.go | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/api/server.go b/internal/api/server.go index a35cef82913..2c89d723609 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -85,7 +85,8 @@ func (s *StdioServer) Run(ctx context.Context) error { projectSession := project.NewSession(&project.SessionInit{ BackgroundCtx: ctx, Logger: nil, // TODO: Add logging support - FS: fs, + FS: fs, + PnpApi: pnpApi, Options: &project.SessionOptions{ CurrentDirectory: s.options.Cwd, DefaultLibraryPath: s.options.DefaultLibraryPath, diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 10d1b306d14..75eb194f29c 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -1140,7 +1140,8 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali PushDiagnosticsEnabled: !disablePushDiagnostics, Locale: s.locale, }, - FS: fs, + FS: fs, + PnpApi: pnpApi, Logger: s.logger, Client: s, NpmExecutor: s, diff --git a/internal/project/session.go b/internal/project/session.go index 25020532398..77de0ded90e 100644 --- a/internal/project/session.go +++ b/internal/project/session.go @@ -69,6 +69,7 @@ type SessionInit struct { Logger logging.Logger NpmExecutor ata.NpmExecutor ParseCache *ParseCache + PnpApi *pnp.PnpApi } // Session manages the state of an LSP session. It receives textDocument @@ -211,6 +212,7 @@ func NewSession(init *SessionInit) *Session { }, ), toPath, + init.PnpApi, ), initialUserPreferences: lsutil.NewDefaultUserPreferences(), workspaceUserPreferences: lsutil.NewDefaultUserPreferences(), diff --git a/internal/project/snapshot.go b/internal/project/snapshot.go index 8ba2ebf90d7..965dd999aa0 100644 --- a/internal/project/snapshot.go +++ b/internal/project/snapshot.go @@ -63,8 +63,8 @@ func NewSnapshot( autoImports *autoimport.Registry, autoImportsWatch *WatchedFiles[map[tspath.Path]string], toPath func(fileName string) tspath.Path, + pnpApi *pnp.PnpApi, ) *Snapshot { - pnpApi := pnp.InitPnpApi(fs.fs, sessionOptions.CurrentDirectory) if pnpApi != nil { fs.fs = pnpvfs.From(fs.fs) } @@ -464,6 +464,7 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma autoImports, autoImportsWatch, s.toPath, + s.pnpApi, ) newSnapshot.parentId = s.id newSnapshot.ProjectCollection = projectCollection From 5e25a5e24fa532e5fbf978cb9bff62b5baea6741 Mon Sep 17 00:00:00 2001 From: Chris Hegre Date: Wed, 15 Apr 2026 12:47:27 +0200 Subject: [PATCH 24/32] Yarn-pnp: Attach to session and hoist filesystem overrides --- internal/project/autoimport.go | 7 +------ internal/project/compilerhost.go | 8 +------- internal/project/projectcollectionbuilder.go | 4 +++- internal/project/session.go | 4 +++- internal/project/snapshot.go | 13 ++++--------- 5 files changed, 12 insertions(+), 24 deletions(-) diff --git a/internal/project/autoimport.go b/internal/project/autoimport.go index 17abfcd4305..90dead3cc42 100644 --- a/internal/project/autoimport.go +++ b/internal/project/autoimport.go @@ -11,7 +11,6 @@ import ( "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" - "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) type autoImportBuilderFS struct { @@ -83,14 +82,10 @@ func newAutoImportRegistryCloneHost( projectCollection *ProjectCollection, parseCache *ParseCache, snapshotFSBuilder *snapshotFSBuilder, + pnpApi *pnp.PnpApi, currentDirectory string, toPath func(fileName string) tspath.Path, ) *autoImportRegistryCloneHost { - pnpApi := pnp.InitPnpApi(snapshotFSBuilder.fs, currentDirectory) - if pnpApi != nil { - snapshotFSBuilder.fs = pnpvfs.From(snapshotFSBuilder.fs) - } - return &autoImportRegistryCloneHost{ projectCollection: projectCollection, parseCache: parseCache, diff --git a/internal/project/compilerhost.go b/internal/project/compilerhost.go index 87364ebcbc8..69c43a88597 100644 --- a/internal/project/compilerhost.go +++ b/internal/project/compilerhost.go @@ -9,7 +9,6 @@ import ( "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" - "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" ) var _ compiler.CompilerHost = (*compilerHost)(nil) @@ -34,17 +33,12 @@ func newCompilerHost( builder *ProjectCollectionBuilder, logger *logging.LogTree, ) *compilerHost { - pnpApi := pnp.InitPnpApi(builder.fs.fs, currentDirectory) - if pnpApi != nil { - builder.fs.fs = pnpvfs.From(builder.fs.fs) - } - return &compilerHost{ configFilePath: project.configFilePath, currentDirectory: currentDirectory, sessionOptions: builder.sessionOptions, - pnpApi: pnpApi, + pnpApi: builder.pnpApi, sourceFS: newSourceFS(true, builder.fs, builder.toPath), project: project, diff --git a/internal/project/projectcollectionbuilder.go b/internal/project/projectcollectionbuilder.go index b4563a8b420..80ba9474fc7 100644 --- a/internal/project/projectcollectionbuilder.go +++ b/internal/project/projectcollectionbuilder.go @@ -35,6 +35,7 @@ type ProjectCollectionBuilder struct { ctx context.Context fs *snapshotFSBuilder + pnpApi *pnp.PnpApi base *ProjectCollection compilerOptionsForInferredProjects *core.CompilerOptions configFileRegistryBuilder *configFileRegistryBuilder @@ -56,12 +57,12 @@ func newProjectCollectionBuilder( ctx context.Context, newSnapshotID uint64, fs *snapshotFSBuilder, + pnpApi *pnp.PnpApi, oldProjectCollection *ProjectCollection, oldConfigFileRegistry *ConfigFileRegistry, oldAPIOpenedProjects map[tspath.Path]struct{}, compilerOptionsForInferredProjects *core.CompilerOptions, sessionOptions *SessionOptions, - pnpApi *pnp.PnpApi, customConfigFileName string, parseCache *ParseCache, extendedConfigCache *ExtendedConfigCache, @@ -70,6 +71,7 @@ func newProjectCollectionBuilder( return &ProjectCollectionBuilder{ ctx: ctx, fs: fs, + pnpApi: pnpApi, toPath: fs.toPath, compilerOptionsForInferredProjects: compilerOptionsForInferredProjects, sessionOptions: sessionOptions, diff --git a/internal/project/session.go b/internal/project/session.go index 32d9d77831b..c4fc91100a1 100644 --- a/internal/project/session.go +++ b/internal/project/session.go @@ -87,6 +87,7 @@ type Session struct { logger logging.Logger npmExecutor ata.NpmExecutor fs *overlayFS + pnpApi *pnp.PnpApi // parseCache is the ref-counted cache of source files used when // creating programs during snapshot cloning. @@ -181,6 +182,7 @@ func NewSession(init *SessionInit) *Session { logger: init.Logger, npmExecutor: init.NpmExecutor, fs: overlayFS, + pnpApi: init.PnpApi, parseCache: parseCache, extendedConfigCache: extendedConfigCache, programCounter: &programCounter{}, @@ -243,7 +245,7 @@ func (s *Session) GetCurrentDirectory() string { // PnpApi implements module.ResolutionHost func (s *Session) PnpApi() *pnp.PnpApi { - return s.snapshot.PnpApi() + return s.pnpApi } // Gets copy of current configuration diff --git a/internal/project/snapshot.go b/internal/project/snapshot.go index 09b762918a6..051744e3a8f 100644 --- a/internal/project/snapshot.go +++ b/internal/project/snapshot.go @@ -21,7 +21,6 @@ import ( "github.com/microsoft/typescript-go/internal/project/logging" "github.com/microsoft/typescript-go/internal/sourcemap" "github.com/microsoft/typescript-go/internal/tspath" - "github.com/microsoft/typescript-go/internal/vfs/pnpvfs" "github.com/microsoft/typescript-go/internal/vfs/vfsmatch" ) @@ -65,10 +64,6 @@ func NewSnapshot( toPath func(fileName string) tspath.Path, pnpApi *pnp.PnpApi, ) *Snapshot { - if pnpApi != nil { - fs.fs = pnpvfs.From(fs.fs) - } - s := &Snapshot{ id: id, @@ -80,11 +75,10 @@ func NewSnapshot( ProjectCollection: &ProjectCollection{toPath: toPath}, compilerOptionsForInferredProjects: compilerOptionsForInferredProjects, - pnpApi: pnpApi, - userPreferences: userPreferences, AutoImports: autoImports, autoImportsWatch: autoImportsWatch, + pnpApi: pnpApi, } s.refCount.Store(1) s.converters = lsconv.NewConverters(s.sessionOptions.PositionEncoding, s.LSPLineMap) @@ -339,12 +333,12 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma ctx, newSnapshotID, fs, + session.pnpApi, s.ProjectCollection, s.ConfigFileRegistry, s.ProjectCollection.apiOpenedProjects, compilerOptionsForInferredProjects, s.sessionOptions, - s.pnpApi, customConfigFileName, session.parseCache, session.extendedConfigCache, @@ -429,6 +423,7 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma projectCollection, session.parseCache, fs, + session.pnpApi, s.sessionOptions.CurrentDirectory, s.toPath, ) @@ -469,7 +464,7 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma autoImports, autoImportsWatch, s.toPath, - s.pnpApi, + session.pnpApi, ) newSnapshot.parentId = s.id newSnapshot.ProjectCollection = projectCollection From 0ed2b6f45407ef0cfe0b188607ff46cd99204aca Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 18 May 2026 11:59:38 +0200 Subject: [PATCH 25/32] Always return a case sensitive iovfs when pnpfs is active --- internal/vfs/pnpvfs/pnpvfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index a303a281ae0..87c8614105b 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -171,7 +171,7 @@ func getMatchingFS(pnpFS *pnpFS, path string) (vfs.FS, string, string) { pnpFS.cachedZipReadersMap[zipPath] = usedReader } - return iovfs.From(usedReader, pnpFS.fs.UseCaseSensitiveFileNames()), internalPath, zipPath + return iovfs.From(usedReader /*useCaseSensitiveFileNames, always true for pnpfs*/, true), internalPath, zipPath } // Virtual paths are used to make different paths resolve to the same real file or folder, which is necessary in some cases when PnP is enabled From 3261a7b329b40b929b7686481d73c2f5537dd085 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 18 May 2026 12:02:24 +0200 Subject: [PATCH 26/32] Assess expected and unexpected errors in pnpapi tests --- internal/pnp/pnpapi_test.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/internal/pnp/pnpapi_test.go b/internal/pnp/pnpapi_test.go index 2dfb189fb78..f04e0951f6f 100644 --- a/internal/pnp/pnpapi_test.go +++ b/internal/pnp/pnpapi_test.go @@ -72,24 +72,31 @@ func TestResolveUnqualified(t *testing.T) { testSuite := &suites[si] rawManifest := &testSuite.Manifest - manifest, err := parseManifestFromData(rawManifest.String(), "/path/to/project/.pnp.cjs") + manifest, err := parseManifestFromData(rawManifest.String(), "/path/to/project") if err != nil { t.Fatalf("failed to init pnp manifest: %v", err) } for _, tc := range testSuite.Tests { - parent := filepath.Join(tc.Importer, "fooo") + parent := tspath.CombinePaths(tc.Importer, "fooo") pnpApi := &PnpApi{fs: osvfs.FS(), url: "/path/to/project/.pnp.cjs", manifest: manifest} t.Run(tc.It, func(t *testing.T) { t.Parallel() res, unqualifiedErr := pnpApi.ResolveToUnqualified(tc.Imported, parent) - switch { - case unqualifiedErr == nil && res != "": - if res != tc.Expected { - t.Fatalf("'%s': expected resolved path %q, got %q", tc.It, tc.Expected, res) + if tc.Expected == "error!" { + if unqualifiedErr == nil { + t.Fatalf("'%s': expected resolution to fail, got %q", tc.It, res) } + return + } + + if unqualifiedErr != nil { + t.Fatalf("'%s': expected resolved path %q, got error: %v", tc.It, tc.Expected, unqualifiedErr.Message) + } + if res != tc.Expected { + t.Fatalf("'%s': expected resolved path %q, got %q", tc.It, tc.Expected, res) } }) } From e3641b332a8e3b6655dccad757a191fc8270df14 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 18 May 2026 12:02:56 +0200 Subject: [PATCH 27/32] Set missing pnpapi in NewVFSParseConfigHost --- internal/tsoptions/tsoptionstest/vfsparseconfighost.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/tsoptions/tsoptionstest/vfsparseconfighost.go b/internal/tsoptions/tsoptionstest/vfsparseconfighost.go index 2f8e746380d..c94d82850d2 100644 --- a/internal/tsoptions/tsoptionstest/vfsparseconfighost.go +++ b/internal/tsoptions/tsoptionstest/vfsparseconfighost.go @@ -42,7 +42,7 @@ func (h *VfsParseConfigHost) PnpApi() *pnp.PnpApi { func NewVFSParseConfigHost(files map[string]string, currentDirectory string, useCaseSensitiveFileNames bool) *VfsParseConfigHost { var fs vfs.FS = vfstest.FromMap(files, useCaseSensitiveFileNames) - pnpApi := pnp.InitPnpApi(fs, tspath.NormalizePath(currentDirectory)) + pnpApi := pnp.InitPnpApi(fs, currentDirectory) if pnpApi != nil { fs = pnpvfs.From(fs) } @@ -50,6 +50,6 @@ func NewVFSParseConfigHost(files map[string]string, currentDirectory string, use return &VfsParseConfigHost{ Vfs: fs, CurrentDirectory: currentDirectory, - pnpApi: nil, + pnpApi: pnpApi, } } From 3041395d651f213a39740816d8803a5eb5ba6e2d Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Mon, 18 May 2026 12:05:26 +0200 Subject: [PATCH 28/32] Plug pnpvfs cache clearing to cachedvfs --- internal/vfs/cachedvfs/cachedvfs.go | 9 +++++++++ internal/vfs/pnpvfs/pnpvfs.go | 2 ++ 2 files changed, 11 insertions(+) diff --git a/internal/vfs/cachedvfs/cachedvfs.go b/internal/vfs/cachedvfs/cachedvfs.go index 7c3d5eb06cd..e4ad79bce93 100644 --- a/internal/vfs/cachedvfs/cachedvfs.go +++ b/internal/vfs/cachedvfs/cachedvfs.go @@ -37,12 +37,21 @@ func (fsys *FS) Enable() { fsys.enabled.Store(true) } +// Some filesystems maintain their own caches that need to be cleared (e.g. pnpvfs's zip reader cache). +type clearableFS interface { + ClearCache() error +} + func (fsys *FS) ClearCache() { fsys.directoryExistsCache.Clear() fsys.fileExistsCache.Clear() fsys.getAccessibleEntriesCache.Clear() fsys.realpathCache.Clear() fsys.statCache.Clear() + + if c, ok := fsys.fs.(clearableFS); ok { + _ = c.ClearCache() + } } func (fsys *FS) DirectoryExists(path string) bool { diff --git a/internal/vfs/pnpvfs/pnpvfs.go b/internal/vfs/pnpvfs/pnpvfs.go index 87c8614105b..e1aafd4c067 100644 --- a/internal/vfs/pnpvfs/pnpvfs.go +++ b/internal/vfs/pnpvfs/pnpvfs.go @@ -231,6 +231,8 @@ func makeVirtualPath(basePath string, hash string, targetPath string) string { return path.Join(basePath, hash, strconv.Itoa(depth), subPath) } +// TODO: improve the cache clearing system, as somehow the GC is not able to collect all zip readers +// even when they are all closed and cleared from the map func (pnpFS *pnpFS) ClearCache() error { pnpFS.cacheReaderMutex.Lock() defer pnpFS.cacheReaderMutex.Unlock() From 24a3ef8446c94d6e985851d8c2579cb669331b32 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Tue, 9 Jun 2026 11:32:37 +0200 Subject: [PATCH 29/32] Fix tests after merge --- internal/compiler/program_test.go | 2 +- internal/execute/tsc/extendedconfigcache_test.go | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/compiler/program_test.go b/internal/compiler/program_test.go index 57846f4f050..7156680fe9a 100644 --- a/internal/compiler/program_test.go +++ b/internal/compiler/program_test.go @@ -291,7 +291,7 @@ func TestIncludeProcessorDiagnosticsWithMissingFileCasing(t *testing.T) { CompilerOptions: &opts, }, }, - Host: compiler.NewCompilerHost("/", fs, bundled.LibPath(), nil, nil), + Host: compiler.NewCompilerHost("/", fs, bundled.LibPath(), nil, nil, nil), }) // GetProgramDiagnostics triggers getDiagnostics which processes all diff --git a/internal/execute/tsc/extendedconfigcache_test.go b/internal/execute/tsc/extendedconfigcache_test.go index c0d4e1ed26e..6e8a30e74d7 100644 --- a/internal/execute/tsc/extendedconfigcache_test.go +++ b/internal/execute/tsc/extendedconfigcache_test.go @@ -4,19 +4,21 @@ import ( "testing" "github.com/microsoft/typescript-go/internal/execute/tsc" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" ) type testParseConfigHost struct { - fs vfs.FS - cwd string + fs vfs.FS + cwd string + pnpApi *pnp.PnpApi } func (h *testParseConfigHost) FS() vfs.FS { return h.fs } func (h *testParseConfigHost) GetCurrentDirectory() string { return h.cwd } - +func (h *testParseConfigHost) PnpApi() *pnp.PnpApi { return h.pnpApi } func TestExtendedConfigCacheExtendsCircularity(t *testing.T) { t.Parallel() From 74e9deee65eb36dd809e23ccd98f3e27fa70df6c Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Fri, 19 Jun 2026 10:44:38 +0200 Subject: [PATCH 30/32] Fix missing pnpapi method in aliasresolver test --- internal/ls/autoimport/aliasresolver_crash_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/ls/autoimport/aliasresolver_crash_test.go b/internal/ls/autoimport/aliasresolver_crash_test.go index 897261c15d2..c257c5c9b8c 100644 --- a/internal/ls/autoimport/aliasresolver_crash_test.go +++ b/internal/ls/autoimport/aliasresolver_crash_test.go @@ -12,6 +12,7 @@ import ( "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/packagejson" "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/pnp" "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" @@ -26,6 +27,7 @@ func (h *fakeCloneHost) GetCurrentDirectory() string { return "/" } func (h *fakeCloneHost) GetDefaultProject(path tspath.Path) (tspath.Path, *compiler.Program) { return "", nil } +func (h *fakeCloneHost) PnpApi() *pnp.PnpApi { return nil } func (h *fakeCloneHost) GetProgramForProject(projectPath tspath.Path) *compiler.Program { return nil } From f3fa6ef2f688be1864262b615e335e6697a0ea71 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 2 Jul 2026 13:16:43 +0200 Subject: [PATCH 31/32] Fix test fixtures for pnp --- .../reference/compiler/pnpTransitiveDependencies.errors.txt | 2 +- testdata/tests/cases/compiler/pnpSimpleTest.ts | 2 +- testdata/tests/cases/compiler/pnpTransitiveDependencies.ts | 2 +- testdata/tests/cases/compiler/pnpTypeRootsResolution.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt index 19eb9040301..2fd03a2f02a 100644 --- a/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt +++ b/testdata/baselines/reference/compiler/pnpTransitiveDependencies.errors.txt @@ -3,8 +3,8 @@ ==== /tsconfig.json (0 errors) ==== { + "exclude": [".pnp.cjs"], "compilerOptions": { - "exclude": [".pnp.cjs"], "rootDir": ".", "declaration": true, "outDir": "./dist" diff --git a/testdata/tests/cases/compiler/pnpSimpleTest.ts b/testdata/tests/cases/compiler/pnpSimpleTest.ts index 2cae99f2ef8..26b9a06c6f2 100644 --- a/testdata/tests/cases/compiler/pnpSimpleTest.ts +++ b/testdata/tests/cases/compiler/pnpSimpleTest.ts @@ -77,8 +77,8 @@ export declare function helperB(value: number): string; // @filename: /tsconfig.json { + "exclude": [".pnp.cjs"], "compilerOptions": { - "exclude": [".pnp.cjs"], "rootDir": ".", "declaration": true, "outDir": "./dist" diff --git a/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts index 05aea085ae3..755e4abfebd 100644 --- a/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts +++ b/testdata/tests/cases/compiler/pnpTransitiveDependencies.ts @@ -54,8 +54,8 @@ module.exports = {}; // @filename: /tsconfig.json { + "exclude": [".pnp.cjs"], "compilerOptions": { - "exclude": [".pnp.cjs"], "rootDir": ".", "declaration": true, "outDir": "./dist" diff --git a/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts index 3a4a5813b3b..07ca379225f 100644 --- a/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts +++ b/testdata/tests/cases/compiler/pnpTypeRootsResolution.ts @@ -55,8 +55,8 @@ module.exports = {}; // @filename: /tsconfig.json { + "exclude": [".pnp.cjs"], "compilerOptions": { - "exclude": [".pnp.cjs"], "rootDir": ".", "declaration": true, "outDir": "./dist" From ff6ade71d287299f2d25fa70881549f69c692bb6 Mon Sep 17 00:00:00 2001 From: Guyllian Gomez Date: Thu, 2 Jul 2026 15:10:33 +0200 Subject: [PATCH 32/32] Invalidate all projects if .pnp.cjs changes --- internal/pnp/pnpapi.go | 7 +++++++ internal/project/filechange.go | 1 + internal/project/overlayfs.go | 2 ++ internal/project/project.go | 10 ++++++++++ internal/project/projectcollectionbuilder.go | 8 ++++++++ internal/project/session.go | 17 +++++++++++++++-- internal/project/snapshot.go | 6 ++++++ 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/internal/pnp/pnpapi.go b/internal/pnp/pnpapi.go index 0fb2efe3031..a149a3fa1ec 100644 --- a/internal/pnp/pnpapi.go +++ b/internal/pnp/pnpapi.go @@ -46,6 +46,13 @@ func findBrokenPeerDependencies(specifier string, parent *Locator) []Locator { return []Locator{} } +func (p *PnpApi) GetManifestPath() string { + if p.manifest == nil { + return "" + } + return tspath.CombinePaths(p.manifest.dirPath, ".pnp.cjs") +} + func (p *PnpApi) RefreshManifest() error { var newData *PnpManifestData var err error diff --git a/internal/project/filechange.go b/internal/project/filechange.go index edc209b397b..8b7da6646d1 100644 --- a/internal/project/filechange.go +++ b/internal/project/filechange.go @@ -17,6 +17,7 @@ const ( FileChangeKindWatchCreate FileChangeKindWatchChange FileChangeKindWatchDelete + FileChangeKindPnpInstall ) func (k FileChangeKind) IsWatchKind() bool { diff --git a/internal/project/overlayfs.go b/internal/project/overlayfs.go index 1b300a01312..0e6d4882b83 100644 --- a/internal/project/overlayfs.go +++ b/internal/project/overlayfs.go @@ -291,6 +291,8 @@ func (fs *overlayFS) processChanges(changes []FileChange) (FileChangeSummary, ma } else { events.deleted = true } + case FileChangeKindPnpInstall: + result.InvalidateAll = true } } diff --git a/internal/project/project.go b/internal/project/project.go index 39c77aa78df..277c9c12349 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -77,6 +77,7 @@ type Project struct { programFilesWatch *WatchedFiles[*collections.SyncSet[tspath.Path]] typingsWatch *WatchedFiles[PatternsAndIgnored] + pnpManifestWatch *WatchedFiles[PatternsAndIgnored] checkerPool *checkerPool @@ -164,6 +165,14 @@ func NewProject( core.Identity, ) } + if builder.pnpApi != nil { + project.pnpManifestWatch = NewWatchedFiles( + "pnp manifest files for "+configFileName, + lsproto.WatchKindChange, + lsproto.GetClientCapabilities(builder.ctx).Workspace.DidChangeWatchedFiles.RelativePatternSupport, + core.Identity, + ) + } return project } @@ -259,6 +268,7 @@ func (p *Project) Clone() *Project { programFilesWatch: p.programFilesWatch, typingsWatch: p.typingsWatch, + pnpManifestWatch: p.pnpManifestWatch, checkerPool: p.checkerPool, diff --git a/internal/project/projectcollectionbuilder.go b/internal/project/projectcollectionbuilder.go index 4844586d848..b588002050c 100644 --- a/internal/project/projectcollectionbuilder.go +++ b/internal/project/projectcollectionbuilder.go @@ -1148,6 +1148,14 @@ func (b *ProjectCollectionBuilder) updateProgram(entry dirty.Value[*Project], lo if result.UpdateKind == ProgramUpdateKindNewFiles { filesChanged = true project.programFilesWatch = project.CloneWatchers() + if project.pnpManifestWatch != nil && b.pnpApi != nil { + pnpManifestPath := b.pnpApi.GetManifestPath() + if pnpManifestPath != "" { + project.pnpManifestWatch = project.pnpManifestWatch.Clone(PatternsAndIgnored{ + patternsInsideWorkspace: []string{pnpManifestPath}, + }) + } + } } project.dirty = false project.dirtyFilePath = "" diff --git a/internal/project/session.go b/internal/project/session.go index b87c78055e0..cfb9b95c4b2 100644 --- a/internal/project/session.go +++ b/internal/project/session.go @@ -75,7 +75,7 @@ type SessionInit struct { Logger logging.Logger NpmExecutor ata.NpmExecutor ParseCache *ParseCache - PnpApi *pnp.PnpApi + PnpApi *pnp.PnpApi } // Session manages the state of an LSP session. It receives textDocument @@ -371,7 +371,11 @@ func (s *Session) DidChangeWatchedFiles(ctx context.Context, changes []*lsproto. case lsproto.FileChangeTypeCreated: kind = FileChangeKindWatchCreate case lsproto.FileChangeTypeChanged: - kind = FileChangeKindWatchChange + if s.pnpApi != nil && strings.HasSuffix(change.Uri.FileName(), ".pnp.cjs") { + kind = FileChangeKindPnpInstall + } else { + kind = FileChangeKindWatchChange + } case lsproto.FileChangeTypeDeleted: kind = FileChangeKindWatchDelete default: @@ -1377,10 +1381,12 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er func(_ tspath.Path, addedProject *Project) { errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.programFilesWatch)...) errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.typingsWatch)...) + errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.pnpManifestWatch)...) }, func(_ tspath.Path, removedProject *Project) { errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.programFilesWatch, nil)...) errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.typingsWatch, nil)...) + errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.pnpManifestWatch, nil)...) }, func(_ tspath.Path, oldProject, newProject *Project) { if oldProject.programFilesWatch.ID() != newProject.programFilesWatch.ID() { @@ -1397,6 +1403,13 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er errors = append(errors, updateWatch(ctx, s, s.logger, nil, newProject.typingsWatch)...) } } + if oldProject.pnpManifestWatch.ID() != newProject.pnpManifestWatch.ID() { + errors = append(errors, updateWatch(ctx, s, s.logger, oldProject.pnpManifestWatch, newProject.pnpManifestWatch)...) + } else { + if s.watches.IsPending(newProject.pnpManifestWatch.ID()) { + errors = append(errors, updateWatch(ctx, s, s.logger, nil, newProject.pnpManifestWatch)...) + } + } }, ) diff --git a/internal/project/snapshot.go b/internal/project/snapshot.go index c3dd2f081d0..90ec8b18589 100644 --- a/internal/project/snapshot.go +++ b/internal/project/snapshot.go @@ -320,6 +320,12 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma change.fileChanges = fs.convertOpenAndCloseToChanges(change.fileChanges) } + if session.pnpApi != nil && change.fileChanges.InvalidateAll { + if err := session.pnpApi.RefreshManifest(); err != nil { + logger.Logf("Failed to refresh PnP manifest: %v", err) + } + } + compilerOptionsForInferredProjects := s.compilerOptionsForInferredProjects if change.compilerOptionsForInferredProjects != nil { // !!! mark inferred projects as dirty?