{"_id":"@acastellon/vcs","_rev":"5-9990ab9064b9800ad0ec37a1afe80197","name":"@acastellon/vcs","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"@acastellon/vcs","version":"1.0.0","keywords":["hash","files","crypt"],"author":{"name":"Antonio Castellon"},"license":"MIT","_id":"@acastellon/vcs@1.0.0","maintainers":[{"name":"acastellon","email":"antonio@castellon.ch"}],"homepage":"https://github.com/antonio-castellon/vcs#readme","bugs":{"url":"https://github.com/antonio-castellon/vcs/issues"},"dist":{"shasum":"39059a55ac5fa1b57f1b9d4abc74007115c6fe28","tarball":"https://registry.npmjs.org/@acastellon/vcs/-/vcs-1.0.0.tgz","fileCount":5,"integrity":"sha512-4mPi9nUJwCyvroedZZKcRpf8brC2H6V9aM3fQObTuEBRgDn3OqNcNOzA1F6CGp0k0CUtT6qOjXYtwtqhc5i+ag==","signatures":[{"sig":"MEUCIFB1E2qSgPGiXNlQn3yN+cFu3FZY/bQO+5sNCcuyGfyEAiEAyragQJ09b6gvoWdxxMpCKmNPHcy9jrWNWD/ptAzLZNY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":2563,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdkx4eCRA9TVsSAnZWagAAofYP/0KW/oeWna90RfrW4iz+\n1pBqfYvYS8tTufG0zA/1j5YVR5TwadITMJndRNY3gTXPDk9/WAbudk6ej83X\nHylghi2FGBwauoDr0fvtdQM0DMSltC2B+sdf5o6WJKFo/+dxUZ31B18pQf6H\n1s2SNn6v9zEvS5JmsTl7CUehGHxHxKC0k5xndqdyw0BHetFQ0kAl12L3JuN7\nA3wevQTItXoDxCDH6LLv6uHyuju5kPBdi36tT99EpTvUSQ74b8u9+Gt/uFzJ\nr0igo0XzNhIcL+8drr3jbdcgxitVtS+M4KHT503qiwHsexDW9pZ8OYJJcvhB\nyodjMAzWL6yB+kbLBqfhjMA+62gBOGDb7UOZfEIDQZPUEFhNKOqG7OOcC0Nh\npsNAxBiKXI4T9mj7W7fpMADpTnmgxfnHtE+PkUSHVgipSNqO9hUZ//3t8Cgz\nL1oiNQirmVcU5WKXeBq8Lt3Gy/rMQncx4ttcaoe68HPVMmtJ+8C1rsR2tKEP\nhU8L1t8ranhA0t7gkc1MYcAmm0znkKRvUOP0Vydek/10ZEU1qLuUxLxY0AC4\nNIrMumEdp0eD6o1KkfW8/RUvckC+yI9QEPyphWqOWE5xtmsilhLcFsbKCHCu\noavje3WduwKE5EMHJ3Nvm1mCFyolhe4vpk9xM6qb71GLFcdcjtTMPsWkgcpM\nzlnR\r\n=9eG9\r\n-----END PGP SIGNATURE-----\r\n"},"main":"vcs.js","gitHead":"7042c16ba6a1755156f379d114ba7975fcd1b06e","scripts":{"test":"node test.js"},"_npmUser":{"name":"acastellon","email":"antonio@castellon.ch"},"repository":{"url":"git+https://github.com/antonio-castellon/vcs.git","type":"git"},"_npmVersion":"6.4.1","description":"Hash generator for files","directories":{},"_nodeVersion":"10.15.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vcs_1.0.0_1569922590179_0.8775845712183292","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"@acastellon/vcs","version":"1.0.1","keywords":["hash","files","crypt"],"author":{"name":"Antonio Castellon"},"license":"MIT","_id":"@acastellon/vcs@1.0.1","maintainers":[{"name":"acastellon","email":"antonio@castellon.ch"}],"homepage":"https://github.com/antonio-castellon/module-vcs#readme","bugs":{"url":"https://github.com/antonio-castellon/module-vcs/issues"},"dist":{"shasum":"e96bed519622f0c3119e32e13474e8d93f1b1c55","tarball":"https://registry.npmjs.org/@acastellon/vcs/-/vcs-1.0.1.tgz","fileCount":5,"integrity":"sha512-Q3hlzmADDnMBlR/FTM1jtuMpPkYxJiyfSezhXzrKUQtT/UZFL2jxYNMoutQvzPyxPxtSQlAt/NnSpQYCQrTgLA==","signatures":[{"sig":"MEUCIBvHWVRqUZ9Xdnr7m/cBl7Yj1WypRavzACpF/7+I1REJAiEAmkwVYp8VPa4T7vilbW5u2NgEtx5TmLDteSIip0nTB+I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":2581,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdrunaCRA9TVsSAnZWagAA9p0P/iZUj2okBau2VCvtDbSl\ndK3VKlD9s2H9JRLKP7FLpTAscKg/i60TXVb4QOa4RHc/NATj6IPR1N3Gax2t\nrGMW1dRf09+JjxrY2yJZ/KQ8Pg5IWbDZVHcOsOsdFkQYo4FGvfOx5MQ328Ie\nrVvo/2RRbp7NpXt/yR516jT+Y8hC3v6kySi3YH9fCko6R5+LaOrvEDSZQE0p\nlvLSozFLfGqoXhPGthhCe2t8AAaFJQrNZd7VJXDLUgnFsIpWzRLPVHg9MKPb\ngBaT/mMabdG/nXe8wfwtizRcuL5xOryBxgZeSfIhhZUeoQncI5GuDwYjiStp\nM98mCUEIpWsYynSyCd6vi32OGO2/NN6f6cWr4NqbdM35+Cy8hCYBo1vPDjJC\nV/2RRuccT90ItAI+ZhS7E1u4R5bOaLvtkHgCi+yY5bpJcF7hMUpLBEZB7+e0\ndeAdLdKrWGqx3Kvr6shG6Yd+ZFRnwTLv7ylj/zwxmx2T5BVJvWon8Va+lt71\nps+peWfMhdgu1CLLhzoQxK787XLBH9U1uYnhan44u9JsHQGl4T0QiyfYJwY/\nkfwZBKWKhZBurfcPERQxqpOqzPEDYbzNKkL/aQYlyBaO26O4C+zBxw7jUsT3\nKEXec0xzddluyXWd2A1K2xz/uopQy33ixCDlEoGetrojPFKN8G0en5DzMhyc\nTi5w\r\n=P3N4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"vcs.js","gitHead":"fbf02d954d2df84038e18de42656cede5d10d58e","scripts":{"test":"node test.js"},"_npmUser":{"name":"acastellon","email":"antonio@castellon.ch"},"repository":{"url":"git+https://github.com/antonio-castellon/module-vcs.git","type":"git"},"_npmVersion":"6.4.1","description":"Hash generator for files","directories":{},"_nodeVersion":"10.15.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vcs_1.0.1_1571744218357_0.25453748509579643","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"@acastellon/vcs","version":"1.0.2","keywords":["hash","files","crypt"],"author":{"name":"Antonio Castellon"},"license":"MIT","_id":"@acastellon/vcs@1.0.2","maintainers":[{"name":"acastellon","email":"antonio@castellon.ch"}],"homepage":"https://github.com/antonio-castellon/module-vcs#readme","bugs":{"url":"https://github.com/antonio-castellon/module-vcs/issues"},"dist":{"shasum":"325efc41047caca931e123d5b77250676aa81742","tarball":"https://registry.npmjs.org/@acastellon/vcs/-/vcs-1.0.2.tgz","fileCount":5,"integrity":"sha512-rgsaDBPCqyUACgQze11rKdbf88vQ/zxiwXDWgJJTXTOu4bgRMJUCf7IpiNF/mx5PaAPgbdOq1wGshkZeuJrtLQ==","signatures":[{"sig":"MEUCIHHQpDriV1caCoZpKJdv3Ryrv5uZRjut3CP+UKgFkMqdAiEAipiIFXg5ZUwT+RFO3e0Fn/ub19q3XN3ZBUILRTNRoVE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":2939,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdxUC7CRA9TVsSAnZWagAAsYAP/1F8WH3yCWmFzZIhqxKw\nPsOhglASzRQHDbmGEbeaFSfsGA5AwIp57o9C24ZyPa/ySHNH4SeM6IF3eg/z\nzcb80zlanwRikrCkwAUYrBu9gWT/PvFUvpv+jNEGM4D8OeoPiXFl3J+kddQI\nCOPHI/2W+j7jdF2Xy43lVddL8HjuyLOvkplhGxPaqvWcdbqEUGPG0iuU295E\nVu7MzTiUlr96hXWdr0Q/z8TK7J0SAbroLNBFcYVk+yA0MjyNtIeRRlDwKOvJ\nFgvlxUNiWEFwvIggcl63LNGdNBWHP0ky1oXVkRQzmlLjZLKM0ys4rn/AeTEm\nJdrvNarY/lJOYdTODrhxU41GgEY+tgyKyLMi4Td+SnKwpL7k+wRRAvKmopxe\nQksxO/Yuq6GrdEhNyrwDC5eHWUPUypwb8Xpoac9UmraM+QX7f3QsrKuOuoTA\nF3hdd0dOugzHfn02YabL0/VE+J1PGu3GPZSR73N96lypgbvLRDSTKTVP74pR\nD2L6huattW3kMRBw2w/D0XL0bLzXftYdbP8wkeOVj2pZ0KX2mlb4TDwFerTJ\nGrdawkaj61KVXeM2MLmDuwIVeUt83gVqS8ZTA8TSWMAQFnnBLonRzSnAbiy5\n5WbrUwjFODqhKPjS419kbEa2HCNCPi8gBtpUOnscPemHuiTI49dKMp6J42dH\nbra+\r\n=VGhT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"vcs.js","gitHead":"76c05461ca5e7f21a94249c06eab3b1dc08d617d","scripts":{"test":"node test.js"},"_npmUser":{"name":"acastellon","email":"antonio@castellon.ch"},"repository":{"url":"git+https://github.com/antonio-castellon/module-vcs.git","type":"git"},"_npmVersion":"6.4.1","description":"Hash generator for files, Version Control based in content.","directories":{},"_nodeVersion":"10.15.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vcs_1.0.2_1573208250524_0.8206740993903552","host":"s3://npm-registry-packages"}},"1.3.0":{"name":"@acastellon/vcs","version":"1.3.0","description":"Content-based versioning / hash generator for files, strings, buffers and directory trees. Real-time VCS without needing git access.","main":"vcs.js","scripts":{"test":"node test.js"},"repository":{"type":"git","url":"git+https://github.com/antonio-castellon/module-vcs.git"},"keywords":["hash","md5","sha256","files","directory","content-hash","vcs","versioning","crypto"],"author":{"name":"Antonio Castellon"},"license":"MIT","bugs":{"url":"https://github.com/antonio-castellon/module-vcs/issues"},"homepage":"https://github.com/antonio-castellon/module-vcs#readme","engines":{"node":">=18.0.0"},"_id":"@acastellon/vcs@1.3.0","gitHead":"15f89bc1c7c421006596e4d17ffcf92e5d92912f","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-zFTgeVQv5nEfqayWvya5z0d8nFgDZOP5WXlcG9j3fTvnpLsD0wp8TBjhpOw5WJOAGy+/uepdKVyv9A1HS8gY8A==","shasum":"68831acea48c8a15da0b116d6cfe64557cb42d4c","tarball":"https://registry.npmjs.org/@acastellon/vcs/-/vcs-1.3.0.tgz","fileCount":5,"unpackedSize":16699,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIE+s2kTwPn6nuCFe4jVaizrKa35BCqWIljW8sZIM0ZeoAiEAlGKFfNyRIuZvyVYq+oWj7zAXwkeh4qKEaGPnEngV8Wc="}]},"_npmUser":{"name":"acastellon","email":"antonio@castellon.ch"},"directories":{},"maintainers":[{"name":"acastellon","email":"antonio@castellon.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vcs_1.3.0_1780483658747_0.3462388657588107"},"_hasShrinkwrap":false}},"time":{"created":"2019-10-01T09:36:29.960Z","modified":"2026-06-03T10:47:39.004Z","1.0.0":"2019-10-01T09:36:30.373Z","1.0.1":"2019-10-22T11:36:58.447Z","1.0.2":"2019-11-08T10:17:30.683Z","1.3.0":"2026-06-03T10:47:38.894Z"},"bugs":{"url":"https://github.com/antonio-castellon/module-vcs/issues"},"author":{"name":"Antonio Castellon"},"license":"MIT","homepage":"https://github.com/antonio-castellon/module-vcs#readme","keywords":["hash","md5","sha256","files","directory","content-hash","vcs","versioning","crypto"],"repository":{"type":"git","url":"git+https://github.com/antonio-castellon/module-vcs.git"},"description":"Content-based versioning / hash generator for files, strings, buffers and directory trees. Real-time VCS without needing git access.","maintainers":[{"name":"acastellon","email":"antonio@castellon.ch"}],"readme":"# @acastellon/vcs\r\n\r\n**Content-based versioning and hashing for files, strings, buffers, and directory trees.**\r\n\r\nThe goal is to provide a lightweight, real-time \"version control\" mechanism based purely on **file/content hashes** (no dependency on git or container access). This is especially useful for:\r\n\r\n- Hot-checking whether a deployed file, config, or service folder has changed.\r\n- Content-addressable versioning in microservices.\r\n- Detecting drift without shelling into containers or relying on `git rev-parse`.\r\n\r\nSupports multiple algorithms (md5, sha1, sha256, sha512) and works great for large files (streaming) and whole directories.\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install @acastellon/vcs\r\n```\r\n\r\n## Quick Usage\r\n\r\n```js\r\nconst vcs = require('@acastellon/vcs');\r\n\r\n// Hash a file (streaming, memory efficient)\r\nconst fileHash = await vcs.getHash('./package.json');\r\n\r\n// Hash arbitrary content (string or Buffer) — no disk I/O needed\r\nconst configHash = await vcs.getHashFromContent(JSON.stringify({ port: 3000 }));\r\n\r\n// Hash an entire directory tree (great for \"version of this service\")\r\nconst dirVersion = await vcs.getDirHash('./my-service', {\r\n  algorithm: 'sha256',\r\n  ignore: ['node_modules', '.git', 'logs']\r\n});\r\n\r\nconsole.log('Service version:', dirVersion);\r\n```\r\n\r\n## API\r\n\r\n### `getHash(fileName: string, algorithm?: string): Promise<string>`\r\n\r\nGenerate a hash from a file's content using streaming (supports very large files without high memory usage).\r\n\r\n- **Parameters**:\r\n  - `fileName` (string): Path to the file.\r\n  - `algorithm` (string, optional): `'md5'` (default), `'sha1'`, `'sha256'`, or `'sha512'`.\r\n- **Returns**: Promise resolving to hex digest.\r\n- **Rejects** on FS errors (ENOENT, permission, etc.).\r\n\r\n**Minimal example (self-contained):**\r\n\r\n```js\r\nconst vcs = require('@acastellon/vcs');\r\nconst fs = require('fs');\r\nconst path = require('path');\r\n\r\nconst testFile = path.join(__dirname, 'demo.txt');\r\nfs.writeFileSync(testFile, 'hello world - this is the content');\r\n\r\nvcs.getHash(testFile, 'sha256')\r\n  .then(hash => {\r\n    console.log('SHA256 of file:', hash);\r\n    fs.unlinkSync(testFile);\r\n  })\r\n  .catch(err => console.error(err));\r\n```\r\n\r\n### `getHashFromContent(content: string | Buffer, algorithm?: string): Promise<string>`\r\n\r\nHash data that you already have in memory (config JSON, template, API response body, etc.). No file system access required.\r\n\r\n- **Parameters**:\r\n  - `content`: string or Buffer.\r\n  - `algorithm`: same as above.\r\n- **Returns**: hex digest.\r\n\r\n**Minimal example (self-contained):**\r\n\r\n```js\r\nconst vcs = require('@acastellon/vcs');\r\n\r\nconst config = { version: '1.2.3', featureX: true };\r\nconst contentHash = await vcs.getHashFromContent(JSON.stringify(config), 'sha256');\r\n\r\nconsole.log('Config content version:', contentHash);\r\n\r\n// Useful for versioning things you receive over the wire or generate dynamically\r\n```\r\n\r\n### `getDirHash(dirPath: string, options?: object): Promise<string>`\r\n\r\nCompute a stable content-based hash for a whole directory tree. Perfect for getting a single \"version id\" of a service, a set of static assets, or a code snapshot.\r\n\r\nThe algorithm walks the tree (sorted), hashes each file, and produces a final manifest hash. Adding/removing/editing any file changes the result deterministically.\r\n\r\n- **Parameters**:\r\n  - `dirPath`: root directory.\r\n  - `options.algorithm`: default `'md5'`.\r\n  - `options.recursive`: default `true`.\r\n  - `options.ignore`: array of names/paths to skip (e.g. `['node_modules', '.git']`).\r\n- **Returns**: hex digest of the directory contents.\r\n\r\n**Minimal example (self-contained):**\r\n\r\n```js\r\nconst vcs = require('@acastellon/vcs');\r\nconst fs = require('fs');\r\nconst path = require('path');\r\n\r\nconst root = path.join(__dirname, 'demo-service');\r\nfs.mkdirSync(root, { recursive: true });\r\nfs.writeFileSync(path.join(root, 'index.js'), 'console.log(\"hi\");');\r\nfs.mkdirSync(path.join(root, 'config'), { recursive: true });\r\nfs.writeFileSync(path.join(root, 'config', 'app.json'), '{\"port\":3000}');\r\n\r\nvcs.getDirHash(root, {\r\n  algorithm: 'sha256',\r\n  ignore: ['node_modules']\r\n})\r\n  .then(version => {\r\n    console.log('Directory version (service snapshot):', version);\r\n    // ... later you can store/compare this version\r\n    fs.rmSync(root, { recursive: true, force: true });\r\n  })\r\n  .catch(console.error);\r\n```\r\n\r\n## Why content hashing instead of git?\r\n\r\n- Works even when `.git` is not present (common in production containers).\r\n- Gives you a hash based on *actual bytes*, not commit metadata.\r\n- Extremely fast for change detection.\r\n- Directory hashes let you version \"the whole thing\" with one value.\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}