typescript-virtual-container 1.4.7 → 1.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/benchmark-results.txt +21 -21
- package/builds/self-standalone.js +979 -168
- package/builds/standalone-wo-sftp.js +982 -173
- package/builds/standalone.cjs +989 -179
- package/builds/web-full-api.min.js +0 -1
- package/builds/web.min.js +0 -1
- package/dist/Honeypot/index.d.ts +6 -0
- package/dist/Honeypot/index.d.ts.map +1 -1
- package/dist/Honeypot/index.js +20 -0
- package/dist/Honeypot/index.js.map +1 -1
- package/dist/SSHMimic/index.d.ts +6 -5
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +8 -5
- package/dist/SSHMimic/index.js.map +1 -1
- package/dist/SSHMimic/sftp.d.ts +1 -0
- package/dist/SSHMimic/sftp.d.ts.map +1 -1
- package/dist/SSHMimic/sftp.js.map +1 -1
- package/dist/VirtualFileSystem/binaryPack.d.ts.map +1 -1
- package/dist/VirtualFileSystem/binaryPack.js +21 -9
- package/dist/VirtualFileSystem/binaryPack.js.map +1 -1
- package/dist/VirtualFileSystem/index.d.ts +25 -0
- package/dist/VirtualFileSystem/index.d.ts.map +1 -1
- package/dist/VirtualFileSystem/index.js +152 -47
- package/dist/VirtualFileSystem/index.js.map +1 -1
- package/dist/VirtualFileSystem/internalTypes.d.ts +23 -4
- package/dist/VirtualFileSystem/internalTypes.d.ts.map +1 -1
- package/dist/VirtualFileSystem/journal.d.ts +1 -0
- package/dist/VirtualFileSystem/journal.d.ts.map +1 -1
- package/dist/VirtualFileSystem/journal.js.map +1 -1
- package/dist/VirtualFileSystem/path.js +1 -1
- package/dist/VirtualFileSystem/path.js.map +1 -1
- package/dist/VirtualShell/idleManager.d.ts +69 -0
- package/dist/VirtualShell/idleManager.d.ts.map +1 -0
- package/dist/VirtualShell/idleManager.js +110 -0
- package/dist/VirtualShell/idleManager.js.map +1 -0
- package/dist/VirtualShell/index.d.ts +41 -1
- package/dist/VirtualShell/index.d.ts.map +1 -1
- package/dist/VirtualShell/index.js +54 -1
- package/dist/VirtualShell/index.js.map +1 -1
- package/dist/VirtualUserManager/index.d.ts +4 -2
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/VirtualUserManager/index.js +0 -1
- package/dist/VirtualUserManager/index.js.map +1 -1
- package/dist/commands/command-helpers.d.ts +5 -2
- package/dist/commands/command-helpers.d.ts.map +1 -1
- package/dist/commands/command-helpers.js.map +1 -1
- package/dist/commands/man.d.ts.map +1 -1
- package/dist/commands/man.js +5 -28
- package/dist/commands/man.js.map +1 -1
- package/dist/commands/manuals-bundle.d.ts +11 -0
- package/dist/commands/manuals-bundle.d.ts.map +1 -0
- package/dist/commands/manuals-bundle.js +898 -0
- package/dist/commands/manuals-bundle.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/linuxRootfs.d.ts +8 -1
- package/dist/modules/linuxRootfs.d.ts.map +1 -1
- package/dist/modules/linuxRootfs.js +47 -14
- package/dist/modules/linuxRootfs.js.map +1 -1
- package/dist/self-standalone.js +15 -0
- package/dist/self-standalone.js.map +1 -1
- package/dist/standalone.js +22 -0
- package/dist/standalone.js.map +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/HoneyPot.html +9 -9
- package/docs/classes/IdleManager.html +162 -0
- package/docs/classes/SshClient.html +18 -18
- package/docs/classes/VirtualFileSystem.html +50 -33
- package/docs/classes/VirtualPackageManager.html +13 -13
- package/docs/classes/VirtualSftpServer.html +3 -3
- package/docs/classes/VirtualShell.html +47 -28
- package/docs/classes/VirtualSshServer.html +12 -7
- package/docs/classes/VirtualUserManager.html +30 -30
- package/docs/functions/assertDiff.html +2 -2
- package/docs/functions/diffSnapshots.html +2 -2
- package/docs/functions/formatDiff.html +2 -2
- package/docs/functions/getArg.html +3 -3
- package/docs/functions/getFlag.html +2 -2
- package/docs/functions/ifFlag.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +4 -5
- package/docs/interfaces/AuditLogEntry.html +3 -3
- package/docs/interfaces/CommandContext.html +13 -13
- package/docs/interfaces/CommandResult.html +13 -13
- package/docs/interfaces/ExecStream.html +6 -6
- package/docs/interfaces/HoneyPotStats.html +5 -3
- package/docs/interfaces/IdleManagerOptions.html +7 -0
- package/docs/interfaces/InstalledPackage.html +11 -11
- package/docs/interfaces/NanoEditorSession.html +5 -5
- package/docs/interfaces/PackageDefinition.html +14 -14
- package/docs/interfaces/PackageFile.html +5 -5
- package/docs/interfaces/PasswordChallenge.html +16 -0
- package/docs/interfaces/RemoveOptions.html +3 -3
- package/docs/interfaces/ShellEnv.html +4 -4
- package/docs/interfaces/ShellModule.html +8 -8
- package/docs/interfaces/ShellProperties.html +5 -5
- package/docs/interfaces/ShellStream.html +7 -7
- package/docs/interfaces/SudoChallenge.html +9 -9
- package/docs/interfaces/VfsBaseNode.html +7 -7
- package/docs/interfaces/VfsDiff.html +6 -6
- package/docs/interfaces/VfsDiffEntry.html +4 -4
- package/docs/interfaces/VfsDiffModified.html +6 -6
- package/docs/interfaces/VfsDirectoryNode.html +8 -8
- package/docs/interfaces/VfsFileNode.html +9 -9
- package/docs/interfaces/VfsOptions.html +18 -4
- package/docs/interfaces/VfsSnapshot.html +3 -3
- package/docs/interfaces/VfsSnapshotBaseNode.html +4 -4
- package/docs/interfaces/VfsSnapshotDirectoryNode.html +5 -5
- package/docs/interfaces/VfsSnapshotFileNode.html +6 -6
- package/docs/interfaces/VirtualActiveSession.html +12 -0
- package/docs/interfaces/VirtualSftpServerOptions.html +7 -0
- package/docs/interfaces/VirtualShellVfsLike.html +15 -0
- package/docs/interfaces/VirtualShellVfsOptions.html +3 -0
- package/docs/interfaces/WriteFileOptions.html +4 -4
- package/docs/modules.html +1 -1
- package/docs/types/ArgParseOptions.html +4 -0
- package/docs/types/CommandMode.html +2 -2
- package/docs/types/CommandOutcome.html +2 -2
- package/docs/types/IdleState.html +1 -0
- package/docs/types/VfsNodeStats.html +2 -2
- package/docs/types/VfsNodeType.html +2 -2
- package/docs/types/VfsPersistenceMode.html +2 -2
- package/docs/types/VfsSnapshotNode.html +2 -2
- package/examples/web.min.js +0 -1
- package/package.json +13 -12
- package/scripts/generate-manuals-bundle.mjs +49 -0
- package/scripts/publish-package.sh +1 -1
- package/src/Honeypot/index.ts +24 -0
- package/src/SSHMimic/index.ts +9 -5
- package/src/SSHMimic/sftp.ts +6 -0
- package/src/VirtualFileSystem/binaryPack.ts +21 -9
- package/src/VirtualFileSystem/index.ts +151 -53
- package/src/VirtualFileSystem/internalTypes.ts +24 -4
- package/src/VirtualFileSystem/journal.ts +1 -0
- package/src/VirtualFileSystem/path.ts +1 -1
- package/src/VirtualShell/idleManager.ts +137 -0
- package/src/VirtualShell/index.ts +64 -1
- package/src/VirtualUserManager/index.ts +4 -2
- package/src/commands/command-helpers.ts +5 -1
- package/src/commands/man.ts +5 -37
- package/src/commands/manuals-bundle.ts +898 -0
- package/src/index.ts +7 -1
- package/src/modules/linuxRootfs.ts +58 -14
- package/src/self-standalone.ts +13 -0
- package/src/standalone.ts +23 -0
- package/typedoc.json +45 -0
- package/builds/self-standalone.js.map +0 -7
- package/builds/standalone-wo-sftp.js.map +0 -7
- package/builds/standalone.cjs.map +0 -7
- package/builds/web-full-api.min.js.map +0 -7
- package/builds/web.min.js.map +0 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>IdleState | typescript-virtual-container - v1.4.9</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container - v1.4.9</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">IdleState</a></li></ul><h1>Type Alias IdleState</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">IdleState</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"active"</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">"frozen"</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/0d803b637251950a3a6075168d6d3d1127271694/src/VirtualShell/idleManager.ts#L40">src/VirtualShell/idleManager.ts:40</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">typescript-virtual-container - v1.4.9</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsNodeStats | typescript-virtual-container</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsNodeStats</a></li></ul><h1>Type Alias VfsNodeStats</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsNodeStats</span><span class="tsd-signature-symbol">:</span> <a href="../interfaces/VfsFileNode.html" class="tsd-signature-type tsd-kind-interface">VfsFileNode</a> <span class="tsd-signature-symbol">|</span> <a href="../interfaces/VfsDirectoryNode.html" class="tsd-signature-type tsd-kind-interface">VfsDirectoryNode</a></div><div class="tsd-comment tsd-typography"><p>Union of file and directory stat responses.</p>
|
|
2
|
-
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsNodeStats | typescript-virtual-container - v1.4.9</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container - v1.4.9</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsNodeStats</a></li></ul><h1>Type Alias VfsNodeStats</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsNodeStats</span><span class="tsd-signature-symbol">:</span> <a href="../interfaces/VfsFileNode.html" class="tsd-signature-type tsd-kind-interface">VfsFileNode</a> <span class="tsd-signature-symbol">|</span> <a href="../interfaces/VfsDirectoryNode.html" class="tsd-signature-type tsd-kind-interface">VfsDirectoryNode</a></div><div class="tsd-comment tsd-typography"><p>Union of file and directory stat responses.</p>
|
|
2
|
+
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/0d803b637251950a3a6075168d6d3d1127271694/src/types/vfs.ts#L35">src/types/vfs.ts:35</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">typescript-virtual-container - v1.4.9</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsNodeType | typescript-virtual-container</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsNodeType</a></li></ul><h1>Type Alias VfsNodeType</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsNodeType</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"file"</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">"directory"</span></div><div class="tsd-comment tsd-typography"><p>Supported virtual node kinds.</p>
|
|
2
|
-
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsNodeType | typescript-virtual-container - v1.4.9</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container - v1.4.9</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsNodeType</a></li></ul><h1>Type Alias VfsNodeType</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsNodeType</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"file"</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">"directory"</span></div><div class="tsd-comment tsd-typography"><p>Supported virtual node kinds.</p>
|
|
2
|
+
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/0d803b637251950a3a6075168d6d3d1127271694/src/types/vfs.ts#L2">src/types/vfs.ts:2</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">typescript-virtual-container - v1.4.9</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsPersistenceMode | typescript-virtual-container</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsPersistenceMode</a></li></ul><h1>Type Alias VfsPersistenceMode</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsPersistenceMode</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"memory"</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">"fs"</span></div><div class="tsd-comment tsd-typography"><p>"memory" — pure in-memory, no disk I/O (default).</p>
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsPersistenceMode | typescript-virtual-container - v1.4.9</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container - v1.4.9</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsPersistenceMode</a></li></ul><h1>Type Alias VfsPersistenceMode</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsPersistenceMode</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"memory"</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">"fs"</span></div><div class="tsd-comment tsd-typography"><p>"memory" — pure in-memory, no disk I/O (default).</p>
|
|
2
2
|
<p>"fs" — mirrors the VFS tree to a directory on the host filesystem.
|
|
3
3
|
<code>snapshotPath</code> must be set to the directory where the binary
|
|
4
4
|
snapshot file will be read/written (<code>vfs-snapshot.vfsb</code>).</p>
|
|
5
|
-
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/
|
|
5
|
+
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/0d803b637251950a3a6075168d6d3d1127271694/src/VirtualFileSystem/index.ts#L36">src/VirtualFileSystem/index.ts:36</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">typescript-virtual-container - v1.4.9</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsSnapshotNode | typescript-virtual-container</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsSnapshotNode</a></li></ul><h1>Type Alias VfsSnapshotNode</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsSnapshotNode</span><span class="tsd-signature-symbol">:</span> <a href="../interfaces/VfsSnapshotFileNode.html" class="tsd-signature-type tsd-kind-interface">VfsSnapshotFileNode</a> <span class="tsd-signature-symbol">|</span> <a href="../interfaces/VfsSnapshotDirectoryNode.html" class="tsd-signature-type tsd-kind-interface">VfsSnapshotDirectoryNode</a></div><div class="tsd-comment tsd-typography"><p>Union of serialized snapshot node variants.</p>
|
|
2
|
-
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>VfsSnapshotNode | typescript-virtual-container - v1.4.9</title><meta name="description" content="Documentation for typescript-virtual-container"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">typescript-virtual-container - v1.4.9</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">VfsSnapshotNode</a></li></ul><h1>Type Alias VfsSnapshotNode</h1></div><div class="tsd-signature"><span class="tsd-kind-type-alias">VfsSnapshotNode</span><span class="tsd-signature-symbol">:</span> <a href="../interfaces/VfsSnapshotFileNode.html" class="tsd-signature-type tsd-kind-interface">VfsSnapshotFileNode</a> <span class="tsd-signature-symbol">|</span> <a href="../interfaces/VfsSnapshotDirectoryNode.html" class="tsd-signature-type tsd-kind-interface">VfsSnapshotDirectoryNode</a></div><div class="tsd-comment tsd-typography"><p>Union of serialized snapshot node variants.</p>
|
|
2
|
+
</div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/itsrealfortune/typescript-virtual-container/blob/0d803b637251950a3a6075168d6d3d1127271694/src/types/vfs.ts#L76">src/types/vfs.ts:76</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">typescript-virtual-container - v1.4.9</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
package/examples/web.min.js
CHANGED
|
@@ -10,4 +10,3 @@ var R=Object.defineProperty;var F=(o,e,t)=>e in o?R(o,e,{enumerable:!0,configura
|
|
|
10
10
|
`),this.vfs.exists("/etc/hosts")||this.vfs.writeFile("/etc/hosts",`127.0.0.1 localhost
|
|
11
11
|
::1 localhost
|
|
12
12
|
`),this.initialized=!0)}getCurrentWorkingDirectory(){return this.cwd}async executeCommandLine(e,t=!0){await this.ensureInitialized();let r=e.trim();if(!r)return{exitCode:0};let n=await E(r,this.env.vars,this.env.lastExitCode,a=>this.executeCommandLine(a,!1).then(c=>c.stdout??"")),s=$(n),i=await this.executeStatements(s.statements);return this.env.lastExitCode=i.exitCode??0,t&&await this.vfs.flushMirror(),i}async executeStatements(e){let t={exitCode:0},r=0;for(;r<e.length;){let n=e[r];if(t=await this.executePipeline(n.pipeline.commands),this.env.lastExitCode=t.exitCode??0,t.closeSession||t.switchUser)return t;let s=n.op;if(!(!s||s===";")){if(s==="&&"){if((t.exitCode??0)!==0)for(;r<e.length&&e[r]?.op==="&&";)r+=1}else if(s==="||"&&(t.exitCode??0)===0)for(;r<e.length&&e[r]?.op==="||";)r+=1}r+=1}return t}async executePipeline(e){return e.length===0?{exitCode:0}:e.length===1?this.executeSingleCommandWithRedirections(e[0]):this.executePipelineChain(e)}async executeSingleCommandWithRedirections(e){let t;if(e.inputFile){let n=u(e.inputFile,this.cwd);try{t=this.vfs.readFile(n)}catch{return{stderr:`${e.inputFile}: No such file or directory`,exitCode:1}}}let r=await this.executeCommand(e.name,e.args,t);if(e.outputFile){let n=u(e.outputFile,this.cwd),s=r.stdout??"";if(e.appendOutput&&this.vfs.exists(n)){let i=this.vfs.readFile(n);this.vfs.writeFile(n,`${i}${s}`)}else this.vfs.writeFile(n,s);return{...r,stdout:""}}return r}async executePipelineChain(e){let t="",r=0;for(let n=0;n<e.length;n+=1){let s=e[n];if(n===0&&s.inputFile){let a=u(s.inputFile,this.cwd);try{t=this.vfs.readFile(a)}catch{return{stderr:`${s.inputFile}: No such file or directory`,exitCode:1}}}let i=await this.executeCommand(s.name,s.args,t);t=i.stdout??"",r=i.exitCode??0}return{stdout:t,exitCode:r}}async executeCommand(e,t,r){let n=this.resolveCommand(e);if(!n)return{stderr:`${e}: command not found`,exitCode:127};let i={args:t.map(a=>w(a,this.env.vars,this.env.lastExitCode,this.env.vars.HOME)),stdin:r,cwd:this.cwd,env:this.env,rawInput:`${e} ${t.join(" ")}`.trim(),shell:this};try{let a=await n.run(i);return a.nextCwd&&(this.cwd=a.nextCwd,this.env.vars.PWD=a.nextCwd),a}catch(a){return{stderr:a instanceof Error?a.message:String(a),exitCode:1}}}};function ie(o="typescript-vm",e={}){return new W(o,e)}export{N as IndexedDbMirrorVfs,W as WebShell,ie as createWebShell};
|
|
13
|
-
//# sourceMappingURL=web.min.js.map
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "1.4.
|
|
7
|
+
"version": "1.4.9",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -28,19 +28,20 @@
|
|
|
28
28
|
"test-battery": "bun test tests/",
|
|
29
29
|
"test-salve": "for f in tests/*.test.ts; do echo \"\\n🧪 Testing $f...\"; bun test \"$f\" --timeout 10000; sleep 0.25; done",
|
|
30
30
|
"build": "tsc --project tsconfig.json",
|
|
31
|
-
"deploy:npm": "
|
|
31
|
+
"deploy:npm": "bun publish --access public",
|
|
32
32
|
"bench": "rm -rf .benchmark-shells/ && bun benchmark-virtualshell.ts",
|
|
33
|
-
"standalone-build:wo-sftp": "bunx esbuild src/standalone-wo-sftp.ts --bundle --platform=node --target=node18 --outfile=builds/standalone-wo-sftp.js --tree-shaking=true --minify
|
|
34
|
-
"web-build": "bunx esbuild src/web.ts --bundle --platform=browser --format=esm --target=es2020 --outfile=builds/web.min.js --tree-shaking=true --minify
|
|
35
|
-
"web-build-iife": "bunx esbuild src/web.ts --bundle --platform=browser --format=iife --target=es2020 --outfile=builds/web-iife.min.js --tree-shaking=true --minify --
|
|
33
|
+
"standalone-build:wo-sftp": "bunx esbuild src/standalone-wo-sftp.ts --bundle --platform=node --target=node18 --outfile=builds/standalone-wo-sftp.js --tree-shaking=true --minify --banner:js='#!/usr/bin/env node'",
|
|
34
|
+
"web-build": "bunx esbuild src/web.ts --bundle --platform=browser --format=esm --target=es2020 --outfile=builds/web.min.js --tree-shaking=true --minify",
|
|
35
|
+
"web-build-iife": "bunx esbuild src/web.ts --bundle --platform=browser --format=iife --target=es2020 --outfile=builds/web-iife.min.js --tree-shaking=true --minify --global-name=WebShellLib",
|
|
36
36
|
"example-build": "bun run web-build && cp builds/web.min.js examples/web.min.js",
|
|
37
|
-
"example-serve": "cd examples &&
|
|
38
|
-
"web-full-build": "bunx esbuild src/web-api.ts --bundle --platform=browser --format=esm --target=es2020 --outfile=builds/web-full-api.min.js --tree-shaking=true --minify --
|
|
37
|
+
"example-serve": "cd examples && bun server.js",
|
|
38
|
+
"web-full-build": "bunx esbuild src/web-api.ts --bundle --platform=browser --format=esm --target=es2020 --outfile=builds/web-full-api.min.js --tree-shaking=true --minify --alias:node:events=./polyfills/node_events/index.js --alias:node:path=./polyfills/node_path/index.js --alias:node:os=./polyfills/node_os/index.js --alias:node:fs=./polyfills/node_fs/index.js --alias:node:fs/promises=./polyfills/node_fs/promises.js --alias:node:crypto=./polyfills/node_crypto/index.js --alias:node:child_process=./polyfills/node_child_process/index.js --alias:node:zlib=./polyfills/node_zlib/index.js --alias:node:vm=./polyfills/node_vm/index.js",
|
|
39
39
|
"publish-package": "bash ./scripts/publish-package.sh",
|
|
40
|
-
"self-standalone-build": "bunx esbuild src/self-standalone.ts --bundle --platform=node --format=esm --target=node18 --outfile=builds/self-standalone.js --tree-shaking=true --minify --
|
|
41
|
-
"standalone-build": "bunx esbuild src/standalone.ts --bundle --platform=node --target=node18 --outfile=builds/standalone.cjs --tree-shaking=true --minify
|
|
42
|
-
"build-all": "bun run self-standalone-build && bun run standalone-build && bun run standalone-build:wo-sftp && bun run web-build && bun run web-full-build && bun run example-build",
|
|
43
|
-
"publish-doc": "bunx typedoc && bunx gh-pages -d docs"
|
|
40
|
+
"self-standalone-build": "bunx esbuild src/self-standalone.ts --bundle --platform=node --format=esm --target=node18 --outfile=builds/self-standalone.js --tree-shaking=true --minify --banner:js='#!/usr/bin/env node'",
|
|
41
|
+
"standalone-build": "bunx esbuild src/standalone.ts --bundle --platform=node --target=node18 --outfile=builds/standalone.cjs --tree-shaking=true --minify --banner:js='#!/usr/bin/env node'",
|
|
42
|
+
"build-all": "bun run generate-manuals && bun run self-standalone-build && bun run standalone-build && bun run standalone-build:wo-sftp && bun run web-build && bun run web-full-build && bun run example-build",
|
|
43
|
+
"publish-doc": "bunx typedoc && bunx gh-pages -d docs",
|
|
44
|
+
"generate-manuals": "bun scripts/generate-manuals-bundle.mjs"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@biomejs/biome": "^2.4.15",
|
|
@@ -56,4 +57,4 @@
|
|
|
56
57
|
"dependencies": {
|
|
57
58
|
"ssh2": "^1.17.0"
|
|
58
59
|
}
|
|
59
|
-
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* scripts/generate-manuals-bundle.mjs
|
|
4
|
+
*
|
|
5
|
+
* Reads all .txt files from src/commands/manuals/ and generates
|
|
6
|
+
* src/commands/manuals-bundle.ts — a static Record<string, string>
|
|
7
|
+
* that is tree-shaken into standalone/web builds.
|
|
8
|
+
*
|
|
9
|
+
* Run: node scripts/generate-manuals-bundle.mjs
|
|
10
|
+
* Called automatically by the "prebuild" step in package.json.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { join, basename } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
18
|
+
const manualsDir = join(__dirname, "../src/commands/manuals");
|
|
19
|
+
const outFile = join(__dirname, "../src/commands/manuals-bundle.ts");
|
|
20
|
+
|
|
21
|
+
const files = readdirSync(manualsDir)
|
|
22
|
+
.filter((f) => f.endsWith(".txt"))
|
|
23
|
+
.sort();
|
|
24
|
+
|
|
25
|
+
const entries = files.map((file) => {
|
|
26
|
+
const key = basename(file, ".txt");
|
|
27
|
+
const content = readFileSync(join(manualsDir, file), "utf8").replace(/\n$/, "");
|
|
28
|
+
// Escape backticks and template literal syntax
|
|
29
|
+
const escaped = content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
30
|
+
return `\t"${key}": \`${escaped}\``;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const output = `/**
|
|
34
|
+
* Auto-generated by scripts/generate-manuals-bundle.mjs
|
|
35
|
+
* DO NOT EDIT — run \`node scripts/generate-manuals-bundle.mjs\` to regenerate.
|
|
36
|
+
*
|
|
37
|
+
* Inlines all src/commands/manuals/*.txt files so that standalone and web
|
|
38
|
+
* builds have access to man pages without needing filesystem access.
|
|
39
|
+
*/
|
|
40
|
+
/** biome-ignore-all lint/style/useNamingConvention: generated keys match command names (e.g. lsb_release) */
|
|
41
|
+
|
|
42
|
+
/** Static map of command name → man page content. */
|
|
43
|
+
export const MANUALS: Readonly<Record<string, string>> = {
|
|
44
|
+
${entries.join(",\n")},
|
|
45
|
+
} as const;
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
writeFileSync(outFile, output, "utf8");
|
|
49
|
+
console.log(`✓ Generated manuals-bundle.ts (${files.length} manuals)`);
|
package/src/Honeypot/index.ts
CHANGED
|
@@ -43,6 +43,8 @@ export interface HoneyPotStats {
|
|
|
43
43
|
userDeleted: number;
|
|
44
44
|
clientConnects: number;
|
|
45
45
|
clientDisconnects: number;
|
|
46
|
+
shellFreezes: number;
|
|
47
|
+
shellThaws: number;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const perf: PerfLogger = createPerfLogger("HoneyPot");
|
|
@@ -68,9 +70,13 @@ export class HoneyPot {
|
|
|
68
70
|
userDeleted: 0,
|
|
69
71
|
clientConnects: 0,
|
|
70
72
|
clientDisconnects: 0,
|
|
73
|
+
shellFreezes: 0,
|
|
74
|
+
shellThaws: 0,
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
private maxLogSize: number;
|
|
78
|
+
/** Reference kept so VFS events can ping the shell's idle manager. */
|
|
79
|
+
private _shell: VirtualShell | null = null;
|
|
74
80
|
|
|
75
81
|
/**
|
|
76
82
|
* Creates a new HoneyPot instance.
|
|
@@ -99,6 +105,7 @@ export class HoneyPot {
|
|
|
99
105
|
sftp?: SftpMimic,
|
|
100
106
|
): void {
|
|
101
107
|
perf.mark("attach");
|
|
108
|
+
this._shell = shell;
|
|
102
109
|
this.attachVirtualShell(shell);
|
|
103
110
|
this.attachVirtualFileSystem(vfs);
|
|
104
111
|
this.attachVirtualUserManager(users);
|
|
@@ -130,23 +137,38 @@ export class HoneyPot {
|
|
|
130
137
|
this.log("VirtualShell", "session:start", data);
|
|
131
138
|
},
|
|
132
139
|
);
|
|
140
|
+
|
|
141
|
+
(shell as EventEmitter).on("shell:freeze", () => {
|
|
142
|
+
this.stats.shellFreezes++;
|
|
143
|
+
this.log("VirtualShell", "shell:freeze", {});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
(shell as EventEmitter).on("shell:thaw", () => {
|
|
147
|
+
this.stats.shellThaws++;
|
|
148
|
+
this.log("VirtualShell", "shell:thaw", {});
|
|
149
|
+
});
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
/**
|
|
136
153
|
* Attaches to VirtualFileSystem events.
|
|
154
|
+
* Also pings the shell's idle manager so SFTP/direct VFS activity
|
|
155
|
+
* counts as activity and prevents spurious freezes.
|
|
137
156
|
*/
|
|
138
157
|
private attachVirtualFileSystem(vfs: VirtualFileSystem): void {
|
|
139
158
|
(vfs as EventEmitter).on("file:read", (data: Record<string, unknown>) => {
|
|
140
159
|
this.stats.fileReads++;
|
|
160
|
+
this._shell?.pingIdle();
|
|
141
161
|
this.log("VirtualFileSystem", "file:read", data);
|
|
142
162
|
});
|
|
143
163
|
|
|
144
164
|
(vfs as EventEmitter).on("file:write", (data: Record<string, unknown>) => {
|
|
145
165
|
this.stats.fileWrites++;
|
|
166
|
+
this._shell?.pingIdle();
|
|
146
167
|
this.log("VirtualFileSystem", "file:write", data);
|
|
147
168
|
});
|
|
148
169
|
|
|
149
170
|
(vfs as EventEmitter).on("dir:create", (data: Record<string, unknown>) => {
|
|
171
|
+
this._shell?.pingIdle();
|
|
150
172
|
this.log("VirtualFileSystem", "dir:create", data);
|
|
151
173
|
});
|
|
152
174
|
|
|
@@ -354,6 +376,8 @@ export class HoneyPot {
|
|
|
354
376
|
userDeleted: 0,
|
|
355
377
|
clientConnects: 0,
|
|
356
378
|
clientDisconnects: 0,
|
|
379
|
+
shellFreezes: 0,
|
|
380
|
+
shellThaws: 0,
|
|
357
381
|
};
|
|
358
382
|
}
|
|
359
383
|
|
package/src/SSHMimic/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ const DEV = !!process.env.DEV_MODE;
|
|
|
26
26
|
const devLog = DEV ? console.log.bind(console) : () => {};
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
/** @internal */
|
|
29
30
|
interface RateLimitEntry {
|
|
30
31
|
attempts: number;
|
|
31
32
|
lockedUntil: number;
|
|
@@ -45,11 +46,12 @@ class SshMimic extends EventEmitter {
|
|
|
45
46
|
/**
|
|
46
47
|
* Creates a new SSH mimic server instance.
|
|
47
48
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
50
|
-
* @param
|
|
51
|
-
* @param
|
|
52
|
-
* @param
|
|
49
|
+
* @param options - Configuration object for the SSH server.
|
|
50
|
+
* @param options.port - TCP port to bind on localhost.
|
|
51
|
+
* @param options.hostname - Virtual hostname used for the SSH ident and default shell label.
|
|
52
|
+
* @param options.shell - Optional preconfigured virtual shell instance to reuse.
|
|
53
|
+
* @param options.maxAuthAttempts - Max failed attempts per IP before lockout (default: 5).
|
|
54
|
+
* @param options.lockoutDurationMs - Lockout window in ms after exceeding attempts (default: 60 000).
|
|
53
55
|
*/
|
|
54
56
|
constructor({
|
|
55
57
|
port,
|
|
@@ -311,6 +313,8 @@ class SshMimic extends EventEmitter {
|
|
|
311
313
|
*/
|
|
312
314
|
public stop(): void {
|
|
313
315
|
perf.mark("stop");
|
|
316
|
+
// Flush pending WAL journal before closing
|
|
317
|
+
void this.shell.vfs.stopAutoFlush();
|
|
314
318
|
if (this.server) {
|
|
315
319
|
this.server.close(() => {
|
|
316
320
|
devLog("SSH Mimic stopped");
|
package/src/SSHMimic/sftp.ts
CHANGED
|
@@ -41,6 +41,7 @@ const OPEN_MODE = {
|
|
|
41
41
|
|
|
42
42
|
const perf: PerfLogger = createPerfLogger("SftpMimic");
|
|
43
43
|
|
|
44
|
+
/** @internal */
|
|
44
45
|
interface SftpFileHandle {
|
|
45
46
|
type: "file";
|
|
46
47
|
path: string;
|
|
@@ -48,6 +49,7 @@ interface SftpFileHandle {
|
|
|
48
49
|
buffer: Buffer;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
/** @internal */
|
|
51
53
|
interface SftpDirHandle {
|
|
52
54
|
type: "dir";
|
|
53
55
|
path: string;
|
|
@@ -55,8 +57,10 @@ interface SftpDirHandle {
|
|
|
55
57
|
index: number;
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
/** @internal */
|
|
58
61
|
type SftpHandle = SftpFileHandle | SftpDirHandle;
|
|
59
62
|
|
|
63
|
+
/** @internal */
|
|
60
64
|
interface SftpAttributes {
|
|
61
65
|
mode: number;
|
|
62
66
|
uid: number;
|
|
@@ -66,6 +70,7 @@ interface SftpAttributes {
|
|
|
66
70
|
mtime: number | Date;
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
/** @internal */
|
|
69
74
|
interface SftpServerStream {
|
|
70
75
|
on(
|
|
71
76
|
event: "OPEN",
|
|
@@ -139,6 +144,7 @@ interface SftpServerStream {
|
|
|
139
144
|
): void;
|
|
140
145
|
}
|
|
141
146
|
|
|
147
|
+
/** Options for {@link SftpMimic} constructor. */
|
|
142
148
|
export interface SftpMimicOptions {
|
|
143
149
|
port: number;
|
|
144
150
|
hostname?: string;
|
|
@@ -35,6 +35,7 @@ import type {
|
|
|
35
35
|
InternalDirectoryNode,
|
|
36
36
|
InternalFileNode,
|
|
37
37
|
InternalNode,
|
|
38
|
+
InternalStubNode,
|
|
38
39
|
} from "./internalTypes";
|
|
39
40
|
|
|
40
41
|
const MAGIC = Buffer.from([0x56, 0x46, 0x53, 0x21]); // "VFS!"
|
|
@@ -97,18 +98,28 @@ function encodeNode(enc: Encoder, node: InternalNode): void {
|
|
|
97
98
|
enc.writeUint8(TYPE_FILE);
|
|
98
99
|
enc.writeString(f.name);
|
|
99
100
|
enc.writeUint32(f.mode);
|
|
100
|
-
enc.writeFloat64(f.createdAt
|
|
101
|
-
enc.writeFloat64(f.updatedAt
|
|
101
|
+
enc.writeFloat64(f.createdAt);
|
|
102
|
+
enc.writeFloat64(f.updatedAt);
|
|
102
103
|
enc.writeUint8(f.compressed ? 0x01 : 0x00);
|
|
103
104
|
enc.writeBytes(f.content);
|
|
105
|
+
} else if (node.type === "stub") {
|
|
106
|
+
// Encode stub as a regular uncompressed file node
|
|
107
|
+
const s = node as InternalStubNode;
|
|
108
|
+
enc.writeUint8(TYPE_FILE);
|
|
109
|
+
enc.writeString(s.name);
|
|
110
|
+
enc.writeUint32(s.mode);
|
|
111
|
+
enc.writeFloat64(s.createdAt);
|
|
112
|
+
enc.writeFloat64(s.updatedAt);
|
|
113
|
+
enc.writeUint8(0x00); // not compressed
|
|
114
|
+
enc.writeBytes(Buffer.from(s.stubContent, "utf8"));
|
|
104
115
|
} else {
|
|
105
116
|
const d = node as InternalDirectoryNode;
|
|
106
117
|
enc.writeUint8(TYPE_DIR);
|
|
107
118
|
enc.writeString(d.name);
|
|
108
119
|
enc.writeUint32(d.mode);
|
|
109
|
-
enc.writeFloat64(d.createdAt
|
|
110
|
-
enc.writeFloat64(d.updatedAt
|
|
111
|
-
const children =
|
|
120
|
+
enc.writeFloat64(d.createdAt);
|
|
121
|
+
enc.writeFloat64(d.updatedAt);
|
|
122
|
+
const children = Object.values(d.children);
|
|
112
123
|
enc.writeUint32(children.length);
|
|
113
124
|
for (const child of children) encodeNode(enc, child);
|
|
114
125
|
}
|
|
@@ -177,8 +188,8 @@ function decodeNode(dec: Decoder): InternalNode {
|
|
|
177
188
|
const type = dec.readUint8();
|
|
178
189
|
const name = dec.readString();
|
|
179
190
|
const mode = dec.readUint32();
|
|
180
|
-
const createdAt =
|
|
181
|
-
const updatedAt =
|
|
191
|
+
const createdAt = dec.readFloat64();
|
|
192
|
+
const updatedAt = dec.readFloat64();
|
|
182
193
|
|
|
183
194
|
if (type === TYPE_FILE) {
|
|
184
195
|
const compressed = dec.readUint8() === 0x01;
|
|
@@ -196,10 +207,10 @@ function decodeNode(dec: Decoder): InternalNode {
|
|
|
196
207
|
|
|
197
208
|
if (type === TYPE_DIR) {
|
|
198
209
|
const count = dec.readUint32();
|
|
199
|
-
const children =
|
|
210
|
+
const children = Object.create(null) as Record<string, InternalNode>;
|
|
200
211
|
for (let i = 0; i < count; i++) {
|
|
201
212
|
const child = decodeNode(dec);
|
|
202
|
-
children
|
|
213
|
+
children[child.name] = child;
|
|
203
214
|
}
|
|
204
215
|
return {
|
|
205
216
|
type: "directory",
|
|
@@ -208,6 +219,7 @@ function decodeNode(dec: Decoder): InternalNode {
|
|
|
208
219
|
createdAt,
|
|
209
220
|
updatedAt,
|
|
210
221
|
children,
|
|
222
|
+
_childCount: count,
|
|
211
223
|
} satisfies InternalDirectoryNode;
|
|
212
224
|
}
|
|
213
225
|
|