├── .aegir.js
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── package.json
├── scripts
└── node-globals.js
├── src
├── index.js
├── resolver.js
├── util.js
└── util
│ ├── commit.js
│ ├── tag.js
│ ├── tree.js
│ └── util.js
└── test
├── fixtures
├── 0a1690e0640a212aafed1824eb208ffddab1789b
├── 0faccf822badf55f15fb0c3f4122fa13798f769e
├── 19f0805d8de36b6442e8c573074112ba72ad6780
├── 42fd8d7404f5127314e248b2cbbe1423f12faeb9
├── 4b271beec86978454072b632f382c6ccb3938a45
├── 4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc
├── 5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507
├── 70a3540bd51658ab564806785d5516a4e89b6450
├── 7ffd1401f599c70364eda431d29363e037b2c92c
├── 802992c4220de19a90767f3000a79a31b98d0df7
├── 832b4a8497de78248f70c06e0f06e785a74fea4c
├── 88a72947d8b4f0ab7185389efcdd5dace4643e04
├── 933b7583b7767b07ea4cf242c1be29162eb8bb85
├── 9f358a4addefcab294b83e4282bfef1f9625a249
├── README.md
├── a0f06ca3cdb1e6e7f603794ef1cd9f9867f85551
├── b1c46e7c32ff56e56a3da52be375348a664650ba
├── cf461f783732a8aa5f7d8679e112bd4c876aa19b
├── d52e70c9e34ac03cdf77f46aec388c2f9574bd93
├── ed19ea7ea03ecd036c653b9c4cba16df71424a60
├── ee048050d16bc428c4faef1074b740866ad553bb
├── f5227cbd32973ec90f48f2547e6fe16c80b92bd5
├── fa59b93c6ce9db82ce57de9046eb738e9f3c0952
├── fc80daf21bb484cfd42ad4ed4d17da48638199ea
├── ffef5350b6f8762cc6272b0255e968f50b6577ed
├── objects.json
└── update.sh
├── mod.spec.js
├── parse.spec.js
├── resolver.spec.js
└── util.spec.js
/.aegir.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path')
4 |
5 | const esbuild = {
6 | // this will inject all the named exports from 'node-globals.js' as globals
7 | inject: [path.join(__dirname, 'scripts/node-globals.js')],
8 | plugins: [
9 | {
10 | name: 'node built ins', // this will make the bundler resolve node builtins to the respective browser polyfill
11 | setup (build) {
12 | build.onResolve({ filter: /^stream$/ }, () => {
13 | return { path: require.resolve('readable-stream') }
14 | })
15 | build.onResolve({ filter: /^zlib$/ }, () => {
16 | return { path: require.resolve('browserify-zlib') }
17 | })
18 | }
19 | }
20 | ]
21 | }
22 |
23 | /** @type {import('aegir').PartialOptions} */
24 | module.exports = {
25 | test: {
26 | browser: {
27 | config: {
28 | buildConfig: esbuild
29 | }
30 | }
31 | },
32 | build: {
33 | config: esbuild
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | yarn.lock
2 | docs
3 | **/node_modules/
4 | **/*.log
5 | test/repo-tests*
6 | **/bundle.js
7 |
8 | # Logs
9 | logs
10 | *.log
11 |
12 | coverage
13 |
14 | # Runtime data
15 | pids
16 | *.pid
17 | *.seed
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # node-waf configuration
29 | .lock-wscript
30 |
31 | build
32 |
33 | # Dependency directory
34 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
35 | node_modules
36 |
37 | lib
38 | dist
39 | test/test-data/go-ipfs-repo/LOCK
40 | test/test-data/go-ipfs-repo/LOG
41 | test/test-data/go-ipfs-repo/LOG.old
42 |
43 | # while testing npm5
44 | package-lock.json
45 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # This is a copy of `.gitignore` without ignoring `dist`, please keep it in sync
2 |
3 | yarn.lock
4 | docs
5 | **/node_modules/
6 | **/*.log
7 | test/repo-tests*
8 | **/bundle.js
9 |
10 | # Logs
11 | logs
12 | *.log
13 |
14 | coverage
15 |
16 | # Runtime data
17 | pids
18 | *.pid
19 | *.seed
20 |
21 | # Directory for instrumented libs generated by jscoverage/JSCover
22 | lib-cov
23 |
24 | # Coverage directory used by tools like istanbul
25 | coverage
26 |
27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
28 | .grunt
29 |
30 | # node-waf configuration
31 | .lock-wscript
32 |
33 | build
34 |
35 | # Dependency directory
36 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
37 | node_modules
38 |
39 | lib
40 |
41 | test/test-data/go-ipfs-repo/LOCK
42 | test/test-data/go-ipfs-repo/LOG
43 | test/test-data/go-ipfs-repo/LOG.old
44 |
45 | # while testing npm5
46 | package-lock.json
47 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache: npm
3 | stages:
4 | - check
5 | - test
6 | - cov
7 |
8 | node_js:
9 | - 'lts/*'
10 | - 'node'
11 |
12 | os:
13 | - linux
14 | - osx
15 | - windows
16 |
17 | script: npx nyc -s npm run test:node -- --bail
18 | after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov
19 |
20 | jobs:
21 | include:
22 | - stage: check
23 | script:
24 | - npx aegir dep-check
25 | - npm run lint
26 |
27 | - stage: test
28 | name: chrome
29 | addons:
30 | chrome: stable
31 | script: npx aegir test -t browser -t webworker
32 |
33 | - stage: test
34 | name: firefox
35 | addons:
36 | firefox: latest
37 | script: npx aegir test -t browser -t webworker -- --browsers FirefoxHeadless
38 |
39 | notifications:
40 | email: false
41 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.6.6](https://github.com/ipld/js-ipld-git/compare/v0.6.5...v0.6.6) (2021-08-24)
2 |
3 |
4 |
5 | ## [0.6.5](https://github.com/ipld/js-ipld-git/compare/v0.6.4...v0.6.5) (2021-08-11)
6 |
7 |
8 |
9 | ## [0.6.4](https://github.com/ipld/js-ipld-git/compare/v0.6.1...v0.6.4) (2021-03-03)
10 |
11 |
12 |
13 | ## [0.6.3](https://github.com/ipld/js-ipld-git/compare/v0.6.1...v0.6.3) (2021-03-03)
14 |
15 |
16 |
17 | ## [0.6.2](https://github.com/ipld/js-ipld-git/compare/v0.6.1...v0.6.2) (2021-03-03)
18 |
19 |
20 |
21 |
22 | ## [0.6.1](https://github.com/ipld/js-ipld-git/compare/v0.6.0...v0.6.1) (2020-08-05)
23 |
24 |
25 | ### Bug Fixes
26 |
27 | * convert output of multihash.decode to buffer ([20dd68f](https://github.com/ipld/js-ipld-git/commit/20dd68f))
28 |
29 |
30 |
31 |
32 | # [0.6.0](https://github.com/ipld/js-ipld-git/compare/v0.5.3...v0.6.0) (2020-08-04)
33 |
34 |
35 | ### Bug Fixes
36 |
37 | * replace node buffers with uint8arrays ([#70](https://github.com/ipld/js-ipld-git/issues/70)) ([8c999ba](https://github.com/ipld/js-ipld-git/commit/8c999ba))
38 |
39 |
40 | ### BREAKING CHANGES
41 |
42 | * - `util.serialize` returns a `Uint8Array`
43 | - `util.cid` returns `CID`s with a breaking API change - see https://github.com/multiformats/js-cid/pull/117 for changes
44 |
45 |
46 |
47 |
48 | ## [0.5.3](https://github.com/ipld/js-ipld-git/compare/v0.5.2...v0.5.3) (2020-07-24)
49 |
50 |
51 |
52 |
53 | ## [0.5.2](https://github.com/ipld/js-ipld-git/compare/v0.5.1...v0.5.2) (2020-06-19)
54 |
55 |
56 | ### Bug Fixes
57 |
58 | * multihashes does not export default lengths any more ([4f85c53](https://github.com/ipld/js-ipld-git/commit/4f85c53)), closes [/github.com/multiformats/js-multihash/pull/76#issuecomment-646561123](https://github.com//github.com/multiformats/js-multihash/pull/76/issues/issuecomment-646561123)
59 | * **package:** update cids to version 0.8.0 ([9da8893](https://github.com/ipld/js-ipld-git/commit/9da8893))
60 |
61 |
62 |
63 |
64 | ## [0.5.1](https://github.com/ipld/js-ipld-git/compare/v0.5.0...v0.5.1) (2020-01-13)
65 |
66 |
67 | ### Bug Fixes
68 |
69 | * **package:** update multicodec to version 1.0.0 ([6dbc3c8](https://github.com/ipld/js-ipld-git/commit/6dbc3c8))
70 | * **package:** update multihashing-async to version 0.8.0 ([fcf7f6f](https://github.com/ipld/js-ipld-git/commit/fcf7f6f))
71 |
72 |
73 |
74 |
75 | # [0.5.0](https://github.com/ipld/js-ipld-git/compare/v0.4.0...v0.5.0) (2019-05-10)
76 |
77 |
78 | ### Bug Fixes
79 |
80 | * **package:** update cids to version 0.7.0 ([2d87c9e](https://github.com/ipld/js-ipld-git/commit/2d87c9e))
81 |
82 |
83 | ### BREAKING CHANGES
84 |
85 | * **package:** Returned v1 CIDs now default to base32 encoding
86 |
87 | Previous versions returned a base58 encoded string when `toString()`/
88 | `toBaseEncodedString()` was called on a CIDv1. It now returns a base32
89 | encoded string.
90 |
91 |
92 |
93 |
94 | # [0.4.0](https://github.com/ipld/js-ipld-git/compare/v0.3.0...v0.4.0) (2019-05-08)
95 |
96 |
97 | ### Bug Fixes
98 |
99 | * **package:** update cids to version 0.6.0 ([fe0ac8b](https://github.com/ipld/js-ipld-git/commit/fe0ac8b))
100 | * **package:** update multihashing-async to version 0.6.0 ([784c464](https://github.com/ipld/js-ipld-git/commit/784c464))
101 |
102 |
103 | ### Features
104 |
105 | * new IPLD Format API ([e39a7d9](https://github.com/ipld/js-ipld-git/commit/e39a7d9))
106 |
107 |
108 | ### BREAKING CHANGES
109 |
110 | * The API is now async/await based
111 |
112 | There are numerous changes, the most significant one is that the API
113 | is no longer callback based, but it using async/await.
114 |
115 | For the full new API please see the [IPLD Formats spec].
116 |
117 | [IPLD Formats spec]: https://github.com/ipld/interface-ipld-format
118 |
119 |
120 |
121 |
122 | # [0.3.0](https://github.com/ipld/js-ipld-git/compare/v0.2.3...v0.3.0) (2019-03-27)
123 |
124 |
125 | ### Bug Fixes
126 |
127 | * order tree directory entries correctly (fixes [#44](https://github.com/ipld/js-ipld-git/issues/44)) ([02be41f](https://github.com/ipld/js-ipld-git/commit/02be41f))
128 |
129 |
130 | ### Features
131 |
132 | * use RFC3339 to format dates, fixes ipfs/go-ipld-git[#16](https://github.com/ipld/js-ipld-git/issues/16) ([#43](https://github.com/ipld/js-ipld-git/issues/43)) ([8a9f7cb](https://github.com/ipld/js-ipld-git/commit/8a9f7cb))
133 |
134 |
135 | ### BREAKING CHANGES
136 |
137 | * Dates are now returned in ISO 8601/RFC3399 format
138 |
139 |
140 |
141 |
142 | ## [0.2.3](https://github.com/ipld/js-ipld-git/compare/v0.2.2...v0.2.3) (2019-01-18)
143 |
144 |
145 | ### Bug Fixes
146 |
147 | * **package:** update multicodec to version 0.4.0 ([c370777](https://github.com/ipld/js-ipld-git/commit/c370777)), closes [#34](https://github.com/ipld/js-ipld-git/issues/34)
148 | * browser bundle ([#39](https://github.com/ipld/js-ipld-git/issues/39)) ([d7d078f](https://github.com/ipld/js-ipld-git/commit/d7d078f))
149 |
150 |
151 |
152 |
153 | ## [0.2.2](https://github.com/ipld/js-ipld-git/compare/v0.2.1...v0.2.2) (2018-10-12)
154 |
155 |
156 | ### Features
157 |
158 | * parse mergetags ([f2010df](https://github.com/ipld/js-ipld-git/commit/f2010df))
159 |
160 |
161 |
162 |
163 | ## [0.2.1](https://github.com/ipld/js-ipld-git/compare/v0.2.0...v0.2.1) (2018-06-29)
164 |
165 |
166 | ### Bug Fixes
167 |
168 | * do not ignore cid.options ([#18](https://github.com/ipld/js-ipld-git/issues/18)) ([4641b63](https://github.com/ipld/js-ipld-git/commit/4641b63))
169 | * pass serialized blob to util.cid ([#16](https://github.com/ipld/js-ipld-git/issues/16)) ([d8f8687](https://github.com/ipld/js-ipld-git/commit/d8f8687))
170 |
171 |
172 | ### Features
173 |
174 | * add defaultHashAlg ([d0ccec3](https://github.com/ipld/js-ipld-git/commit/d0ccec3))
175 | * add util.cid options ([#15](https://github.com/ipld/js-ipld-git/issues/15)) ([5ed9c74](https://github.com/ipld/js-ipld-git/commit/5ed9c74))
176 |
177 |
178 | ### BREAKING CHANGES
179 |
180 | * the first argument is now the serialized output NOT the dag node.
181 | See https://github.com/ipld/interface-ipld-format/issues/32
182 |
183 |
184 |
185 |
186 | # [0.2.0](https://github.com/ipld/js-ipld-git/compare/v0.1.1...v0.2.0) (2018-02-12)
187 |
188 |
189 | ### Bug Fixes
190 |
191 | * use binary blobs directly ([334f2f0](https://github.com/ipld/js-ipld-git/commit/334f2f0))
192 |
193 |
194 | ### BREAKING CHANGES
195 |
196 | * Everyone calling the functions of `resolve` need to
197 | pass in the binary data instead of an IPFS block.
198 |
199 | So if your input is an IPFS block, the code changes from
200 |
201 | resolver.resolve(block, path, (err, result) => {…}
202 |
203 | to
204 |
205 | resolver.resolve(block.data, path, (err, result) => {…}
206 |
207 |
208 |
209 |
210 | ## [0.1.1](https://github.com/ipld/js-ipld-git/compare/v0.1.0...v0.1.1) (2017-11-07)
211 |
212 |
213 | ### Bug Fixes
214 |
215 | * invalid signature parsing ([#6](https://github.com/ipld/js-ipld-git/issues/6)) ([b1f8bd4](https://github.com/ipld/js-ipld-git/commit/b1f8bd4))
216 |
217 |
218 |
219 |
220 | # [0.1.0](https://github.com/ipld/js-ipld-git/compare/51a9b5e...v0.1.0) (2017-09-02)
221 |
222 |
223 | ### Bug Fixes
224 |
225 | * deps in package.json ([fece381](https://github.com/ipld/js-ipld-git/commit/fece381))
226 |
227 |
228 | ### Features
229 |
230 | * v0.1.0 ([51a9b5e](https://github.com/ipld/js-ipld-git/commit/51a9b5e))
231 |
232 |
233 |
234 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 IPLD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ⛔️ DEPRECATED: This module is no longer maintained. It can be used with [multiformats](https://github.com/multiformats/js-multiformats) by wrapping it with [ipld-format-to-blockcodec](https://github.com/ipld/js-ipld-format-to-blockcodec)
2 | ======
3 |
4 | # js-ipld-git
5 |
6 | [](http://ipn.io)
7 | [](http://github.com/ipld/ipld)
8 | [](http://webchat.freenode.net/?channels=%23ipfs)
9 | [](https://travis-ci.com/ipld/js-ipld-git)
10 | [](https://coveralls.io/github/ipld/js-ipld-git?branch=master)
11 | [](https://github.com/RichardLitt/standard-readme)
12 | [](https://david-dm.org/ipld/js-ipld-git)
13 | [](https://github.com/feross/standard) [](https://greenkeeper.io/)
14 | 
15 | 
16 |
17 | > JavaScript implementation of the [IPLD spec](https://github.com/ipld/specs).
18 |
19 | ## Lead Maintainer
20 |
21 | [Volker Mische](https://github.com/vmx)
22 |
23 | ## Table of Contents
24 |
25 | - [js-ipld-git](#js-ipld-git)
26 | - [Lead Maintainer](#lead-maintainer)
27 | - [Table of Contents](#table-of-contents)
28 | - [Install](#install)
29 | - [npm](#npm)
30 | - [Use in Node.js](#use-in-nodejs)
31 | - [Use in a browser with browserify, webpack or any other bundler](#use-in-a-browser-with-browserify-webpack-or-any-other-bundler)
32 | - [Use in a browser Using a script tag](#use-in-a-browser-using-a-script-tag)
33 | - [Usage](#usage)
34 | - [Contribute](#contribute)
35 | - [License](#license)
36 |
37 | ## Install
38 |
39 | ### npm
40 |
41 | ```sh
42 | > npm install ipld-git
43 | ```
44 |
45 | ### Use in Node.js
46 |
47 | ```JavaScript
48 | const IpldGit = require('ipld-git')
49 | ```
50 |
51 | ### Use in a browser with browserify, webpack or any other bundler
52 |
53 | The code published to npm that gets loaded on require is in fact a ES5 transpiled version with the right shims added. This means that you can require it and use with your favourite bundler without having to adjust asset management process.
54 |
55 | ```JavaScript
56 | var IpldGit = require('ipld-git')
57 | ```
58 |
59 | ### Use in a browser Using a script tag
60 |
61 | Loading this module through a script tag will make the `IpldGit` obj available in the global namespace.
62 |
63 | ```html
64 |
65 |
66 |
67 | ```
68 |
69 | ## Usage
70 |
71 | ```JavaScript
72 | const IpldGit = require('ipld-git')
73 | const zlib = require('zlib')
74 |
75 | // `gitObject` is a Buffer containing a git object
76 | inflatedObject = zlib.inflateSync(gitObject)
77 | const dagNode = IpldGit.util.deserialize(inflatedObject)
78 | console.log(dagNode)
79 | ```
80 |
81 | ## Contribute
82 |
83 | Feel free to join in. All welcome. Open an [issue](https://github.com/ipld/js-ipld-git/issues)!
84 |
85 | Check out our [contributing document](https://github.com/ipld/ipld/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to IPLD are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
86 |
87 | Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
88 |
89 | ## License
90 |
91 | [MIT](LICENSE)
92 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ipld-git",
3 | "version": "0.6.6",
4 | "description": "JavaScript Implementation of Git IPLD format",
5 | "leadMaintainer": "Volker Mische ",
6 | "main": "src/index.js",
7 | "scripts": {
8 | "test": "aegir test",
9 | "test:browser": "aegir test --target browser",
10 | "test:node": "aegir test --target node",
11 | "lint": "aegir lint",
12 | "release": "aegir release",
13 | "release-minor": "aegir release --type minor",
14 | "release-major": "aegir release --type major",
15 | "build": "aegir build"
16 | },
17 | "pre-push": [
18 | "lint",
19 | "test"
20 | ],
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/ipld/js-ipld-git.git"
24 | },
25 | "keywords": [
26 | "IPFS"
27 | ],
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/ipld/js-ipld-git/issues"
31 | },
32 | "engines": {
33 | "node": ">=6.0.0",
34 | "npm": ">=3.0.0"
35 | },
36 | "homepage": "https://github.com/ipld/js-ipld-git",
37 | "dependencies": {
38 | "buffer": "^6.0.3",
39 | "cids": "^1.0.0",
40 | "multicodec": "^3.0.1",
41 | "multihashing-async": "^2.0.1",
42 | "smart-buffer": "^4.1.0",
43 | "strftime": "^0.10.0",
44 | "uint8arrays": "^3.0.0"
45 | },
46 | "devDependencies": {
47 | "aegir": "^31.0.1",
48 | "assert": "^2.0.0",
49 | "browserify-zlib": "^0.2.0",
50 | "events": "^3.3.0",
51 | "readable-stream": "^3.6.0"
52 | },
53 | "contributors": [
54 | "Volker Mische ",
55 | "David Dias ",
56 | "achingbrain ",
57 | "Łukasz Magiera ",
58 | "Richard Schneider ",
59 | "Jonah Weissman ",
60 | "ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ ",
61 | "Sameer Puri <11097096+sameer@users.noreply.github.com>",
62 | "Vasco Santos ",
63 | "phillmac ",
64 | "Alan Shaw "
65 | ]
66 | }
67 |
--------------------------------------------------------------------------------
/scripts/node-globals.js:
--------------------------------------------------------------------------------
1 | // file: node-globals.js
2 | // @ts-nocheck
3 | export const { Buffer } = require('buffer')
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | exports.util = require('./util.js')
4 | exports.resolver = require('./resolver.js')
5 | exports.codec = exports.util.codec
6 | exports.defaultHashAlg = exports.util.defaultHashAlg
7 |
--------------------------------------------------------------------------------
/src/resolver.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const CID = require('cids')
4 | const util = require('./util')
5 |
6 | /**
7 | * Resolves a path within a Git block.
8 | *
9 | * Returns the value or a link and the partial mising path. This way the
10 | * IPLD Resolver can fetch the link and continue to resolve.
11 | *
12 | * @param {Uint8Array} binaryBlob - Binary representation of a Git block
13 | * @param {string} [path='/'] - Path that should be resolved
14 | */
15 | function resolve (binaryBlob, path) {
16 | let node = util.deserialize(binaryBlob)
17 |
18 | const parts = path.split('/').filter(Boolean)
19 | while (parts.length) {
20 | const key = parts.shift()
21 | if (node[key] === undefined) {
22 | throw new Error(`Object has no property '${key}'`)
23 | }
24 |
25 | node = node[key]
26 | if (CID.isCID(node)) {
27 | return {
28 | value: node,
29 | remainderPath: parts.join('/')
30 | }
31 | }
32 | }
33 |
34 | return {
35 | value: node,
36 | remainderPath: ''
37 | }
38 | }
39 |
40 | function * traverse (node, path) {
41 | // Traverse only objects and arrays
42 | if (node instanceof Uint8Array || CID.isCID(node) || typeof node === 'string' ||
43 | node === null) {
44 | return
45 | }
46 | for (const item of Object.keys(node)) {
47 | const nextpath = path === undefined ? item : path + '/' + item
48 | yield nextpath
49 | yield * traverse(node[item], nextpath)
50 | }
51 | }
52 |
53 | /**
54 | * Return all available paths of a block.
55 | *
56 | * @generator
57 | * @param {Uint8Array} binaryBlob - Binary representation of a Bitcoin block
58 | * @yields {string} - A single path
59 | */
60 | function * tree (binaryBlob) {
61 | const node = util.deserialize(binaryBlob)
62 |
63 | yield * traverse(node)
64 | }
65 |
66 | module.exports = {
67 | resolve,
68 | tree
69 | }
70 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const multihashing = require('multihashing-async')
4 | const CID = require('cids')
5 | const multicodec = require('multicodec')
6 | const { Buffer } = require('buffer')
7 | const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
8 |
9 | const gitUtil = require('./util/util')
10 |
11 | const commit = require('./util/commit')
12 | const tag = require('./util/tag')
13 | const tree = require('./util/tree')
14 |
15 | const codec = multicodec.GIT_RAW
16 | const defaultHashAlg = multicodec.SHA1
17 |
18 | /**
19 | * Serialize internal representation into a binary Git block.
20 | *
21 | * @param {GitBlock} dagNode - Internal representation of a Git block
22 | * @returns {Uint8Array}
23 | */
24 | function serialize (dagNode) {
25 | if (dagNode === null) {
26 | throw new Error('dagNode passed to serialize was null')
27 | }
28 |
29 | if (dagNode instanceof Uint8Array) {
30 | if (uint8ArrayToString(dagNode.slice(0, 4)) === 'blob') {
31 | return dagNode
32 | } else {
33 | throw new Error('unexpected dagNode passed to serialize')
34 | }
35 | }
36 |
37 | switch (dagNode.gitType) {
38 | case 'commit':
39 | return commit.serialize(dagNode)
40 | case 'tag':
41 | return tag.serialize(dagNode)
42 | default:
43 | // assume tree as a file named 'type' is legal
44 | return tree.serialize(dagNode)
45 | }
46 | }
47 |
48 | /**
49 | * Deserialize Git block into the internal representation.
50 | *
51 | * @param {Uint8Array} data - Binary representation of a Git block.
52 | */
53 | function deserialize (data) {
54 | if (!Buffer.isBuffer(data)) {
55 | data = Buffer.from(data.buffer, data.byteOffset, data.byteLength)
56 | }
57 |
58 | const headLen = gitUtil.find(data, 0)
59 | const head = data.slice(0, headLen).toString()
60 | const typeLen = head.match(/([^ ]+) (\d+)/)
61 | if (!typeLen) {
62 | throw new Error('invalid object header')
63 | }
64 |
65 | switch (typeLen[1]) {
66 | case 'blob':
67 | return data
68 | case 'commit':
69 | return commit.deserialize(data.slice(headLen + 1))
70 | case 'tag':
71 | return tag.deserialize(data.slice(headLen + 1))
72 | case 'tree':
73 | return tree.deserialize(data.slice(headLen + 1))
74 | default:
75 | throw new Error('unknown object type ' + typeLen[1])
76 | }
77 | }
78 |
79 | /**
80 | * Calculate the CID of the binary blob.
81 | *
82 | * @param {Object} binaryBlob - Encoded IPLD Node
83 | * @param {Object} [userOptions] - Options to create the CID
84 | * @param {number} [userOptions.cidVersion=1] - CID version number
85 | * @param {string} [userOptions.hashAlg] - Defaults to the defaultHashAlg of the format
86 | */
87 | async function cid (binaryBlob, userOptions) {
88 | const defaultOptions = { cidVersion: 1, hashAlg: defaultHashAlg }
89 | const options = Object.assign(defaultOptions, userOptions)
90 |
91 | const multihash = await multihashing(binaryBlob, options.hashAlg)
92 | const codecName = multicodec.getNameFromCode(codec)
93 | const cid = new CID(options.cidVersion, codecName, multihash)
94 |
95 | return cid
96 | }
97 |
98 | module.exports = {
99 | codec,
100 | defaultHashAlg,
101 | serialize,
102 | deserialize,
103 | cid
104 | }
105 |
--------------------------------------------------------------------------------
/src/util/commit.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const SmartBuffer = require('smart-buffer').SmartBuffer
4 | const { Buffer } = require('buffer')
5 | const gitUtil = require('./util')
6 |
7 | function serialize (dagNode) {
8 | const lines = []
9 | lines.push('tree ' + gitUtil.cidToSha(dagNode.tree).toString('hex'))
10 | dagNode.parents.forEach((parent) => {
11 | lines.push('parent ' + gitUtil.cidToSha(parent).toString('hex'))
12 | })
13 | lines.push('author ' + gitUtil.serializePersonLine(dagNode.author))
14 | lines.push('committer ' + gitUtil.serializePersonLine(dagNode.committer))
15 | if (dagNode.encoding) {
16 | lines.push('encoding ' + dagNode.encoding)
17 | }
18 | if (dagNode.mergetag) {
19 | dagNode.mergetag.forEach(tag => {
20 | lines.push('mergetag object ' + gitUtil.cidToSha(tag.object).toString('hex'))
21 | lines.push(tag.text)
22 | })
23 | }
24 | if (dagNode.signature) {
25 | lines.push('gpgsig -----BEGIN PGP SIGNATURE-----')
26 | lines.push(dagNode.signature.text)
27 | }
28 | lines.push('')
29 | lines.push(dagNode.message)
30 |
31 | const data = lines.join('\n')
32 |
33 | const outBuf = new SmartBuffer()
34 | outBuf.writeString('commit ')
35 | outBuf.writeString(data.length.toString())
36 | outBuf.writeUInt8(0)
37 | outBuf.writeString(data)
38 | return outBuf.toBuffer()
39 | }
40 |
41 | function deserialize (data) {
42 | const lines = data.toString().split('\n')
43 | const res = { gitType: 'commit', parents: [] }
44 |
45 | for (let line = 0; line < lines.length; line++) {
46 | const m = lines[line].match(/^([^ ]+) (.+)$/)
47 | if (!m) {
48 | if (lines[line] !== '') {
49 | throw new Error('Invalid commit line ' + line)
50 | }
51 | res.message = lines.slice(line + 1).join('\n')
52 | break
53 | }
54 |
55 | const key = m[1]
56 | const value = m[2]
57 | switch (key) {
58 | case 'tree':
59 | res.tree = gitUtil.shaToCid(Buffer.from(value, 'hex'))
60 | break
61 | case 'committer':
62 | res.committer = gitUtil.parsePersonLine(value)
63 | break
64 | case 'author':
65 | res.author = gitUtil.parsePersonLine(value)
66 | break
67 | case 'parent':
68 | res.parents.push(gitUtil.shaToCid(Buffer.from(value, 'hex')))
69 | break
70 | case 'gpgsig': {
71 | if (value !== '-----BEGIN PGP SIGNATURE-----') {
72 | throw new Error('Invalid commit line ' + line)
73 | }
74 | res.signature = {}
75 |
76 | const startLine = line
77 | for (; line < lines.length - 1; line++) {
78 | if (lines[line + 1][0] !== ' ') {
79 | res.signature.text = lines.slice(startLine + 1, line + 1).join('\n')
80 | break
81 | }
82 | }
83 | break
84 | }
85 | case 'mergetag': {
86 | const mt = value.match(/^object ([0-9a-f]{40})$/)
87 | if (!mt) {
88 | throw new Error('Invalid commit line ' + line)
89 | }
90 |
91 | const tag = { object: gitUtil.shaToCid(Buffer.from(mt[1], 'hex')) }
92 |
93 | const startLine = line
94 | for (; line < lines.length - 1; line++) {
95 | if (lines[line + 1][0] !== ' ') {
96 | tag.text = lines.slice(startLine + 1, line + 1).join('\n')
97 | break
98 | }
99 | }
100 |
101 | if (!res.mergetag) {
102 | res.mergetag = []
103 | }
104 |
105 | res.mergetag.push(tag)
106 | }
107 |
108 | break
109 | default:
110 | res[key] = value
111 | }
112 | }
113 |
114 | Object.defineProperty(res, 'gitType', { enumerable: false })
115 |
116 | return res
117 | }
118 |
119 | module.exports = {
120 | serialize,
121 | deserialize
122 | }
123 |
--------------------------------------------------------------------------------
/src/util/tag.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const SmartBuffer = require('smart-buffer').SmartBuffer
4 | const { Buffer } = require('buffer')
5 | const gitUtil = require('./util')
6 |
7 | function serialize (dagNode) {
8 | const lines = []
9 | lines.push('object ' + gitUtil.cidToSha(dagNode.object).toString('hex'))
10 | lines.push('type ' + dagNode.type)
11 | lines.push('tag ' + dagNode.tag)
12 | if (dagNode.tagger !== null) {
13 | lines.push('tagger ' + gitUtil.serializePersonLine(dagNode.tagger))
14 | }
15 | lines.push('')
16 | lines.push(dagNode.message)
17 |
18 | const data = lines.join('\n')
19 |
20 | const outBuf = new SmartBuffer()
21 | outBuf.writeString('tag ')
22 | outBuf.writeString(data.length.toString())
23 | outBuf.writeUInt8(0)
24 | outBuf.writeString(data)
25 | return outBuf.toBuffer()
26 | }
27 |
28 | function deserialize (data) {
29 | const lines = data.toString().split('\n')
30 | const res = { gitType: 'tag' }
31 |
32 | for (let line = 0; line < lines.length; line++) {
33 | const m = lines[line].match(/^([^ ]+) (.+)$/)
34 | if (m === null) {
35 | if (lines[line] !== '') {
36 | throw new Error('Invalid tag line ' + line)
37 | }
38 | res.message = lines.slice(line + 1).join('\n')
39 | break
40 | }
41 |
42 | const key = m[1]
43 | const value = m[2]
44 | switch (key) {
45 | case 'object':
46 | res.object = gitUtil.shaToCid(Buffer.from(value, 'hex'))
47 | break
48 | case 'tagger':
49 | res.tagger = gitUtil.parsePersonLine(value)
50 | break
51 | case 'tag':
52 | res.tag = value
53 | break
54 | case 'type':
55 | res.type = value
56 | break
57 | default:
58 | res[key] = value
59 | }
60 | }
61 |
62 | Object.defineProperty(res, 'gitType', { enumerable: false })
63 |
64 | return res
65 | }
66 |
67 | module.exports = {
68 | serialize,
69 | deserialize
70 | }
71 |
--------------------------------------------------------------------------------
/src/util/tree.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const SmartBuffer = require('smart-buffer').SmartBuffer
4 | const gitUtil = require('./util')
5 |
6 | function serialize (dagNode) {
7 | const entries = []
8 | Object.keys(dagNode).forEach((name) => {
9 | entries.push([name, dagNode[name]])
10 | })
11 | entries.sort((a, b) => {
12 | const aName = a[0] + (a[1].mode === '40000' ? '/' : '')
13 | const bName = b[0] + (b[1].mode === '40000' ? '/' : '')
14 | return aName > bName ? 1 : -1
15 | })
16 | const buf = new SmartBuffer()
17 | entries.forEach((entry) => {
18 | buf.writeStringNT(entry[1].mode + ' ' + entry[0])
19 | buf.writeBuffer(gitUtil.cidToSha(entry[1].hash))
20 | })
21 |
22 | const outBuf = new SmartBuffer()
23 | outBuf.writeString('tree ')
24 | outBuf.writeString(buf.length.toString())
25 | outBuf.writeUInt8(0)
26 | outBuf.writeBuffer(buf.toBuffer())
27 | return outBuf.toBuffer()
28 | }
29 |
30 | function deserialize (data) {
31 | const res = {}
32 | const buf = SmartBuffer.fromBuffer(data, 'utf8')
33 |
34 | for (;;) {
35 | const modeName = buf.readStringNT()
36 | if (modeName === '') {
37 | break
38 | }
39 |
40 | const hash = buf.readBuffer(gitUtil.SHA1_LENGTH)
41 | const modNameMatched = modeName.match(/^(\d+) (.+)$/)
42 | if (!modNameMatched) {
43 | throw new Error('invalid file mode/name')
44 | }
45 |
46 | if (res[modNameMatched[2]]) {
47 | throw new Error('duplicate file in tree')
48 | }
49 |
50 | res[modNameMatched[2]] = {
51 | mode: modNameMatched[1],
52 | hash: gitUtil.shaToCid(hash)
53 | }
54 | }
55 |
56 | return res
57 | }
58 |
59 | module.exports = {
60 | serialize,
61 | deserialize
62 | }
63 |
--------------------------------------------------------------------------------
/src/util/util.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const multihash = require('multihashing-async').multihash
4 | const CID = require('cids')
5 | const strftime = require('strftime')
6 | const { Buffer } = require('buffer')
7 |
8 | const SHA1_LENGTH = 20
9 |
10 | function find (buf, byte) {
11 | for (let i = 0; i < buf.length; i++) {
12 | if (buf[i] === byte) {
13 | return i
14 | }
15 | }
16 | return -1
17 | }
18 |
19 | const ISO_8601_STRICT = '%FT%T%:z'
20 | const TIMESTAMP_WITH_OFFSET = '%s %z'
21 |
22 | const timestampWithOffsetToISOStrict = (timestamp, offset) => strftime.timezone(offset)(ISO_8601_STRICT, new Date(timestamp * 1000))
23 |
24 | const isoStrictToTimestampWithOffset = (isoString) => {
25 | const matched = isoString.match(/([+-]\d{2}:\d{2})/)
26 | const offset = matched === null ? '+0000' : (matched[0].slice(0, 3) + matched[0].slice(4))
27 | return strftime.timezone(offset)(TIMESTAMP_WITH_OFFSET, new Date(isoString))
28 | }
29 |
30 | function parsePersonLine (line) {
31 | const matched = line.match(/^(([^<]+)\s)?\s?<([^>]+)>\s?(?:(\d+)\s([+-]\d+))?$/)
32 | if (matched === null) {
33 | return null
34 | }
35 |
36 | return {
37 | name: matched[2],
38 | email: matched[3],
39 | date: matched[4] && matched[5] && timestampWithOffsetToISOStrict(parseInt(matched[4]), matched[5])
40 | }
41 | }
42 |
43 | function serializePersonLine (node) {
44 | const parts = []
45 | if (node.name) {
46 | parts.push(node.name)
47 | }
48 | parts.push('<' + node.email + '>')
49 | if (node.date) {
50 | parts.push(isoStrictToTimestampWithOffset(node.date))
51 | }
52 |
53 | return parts.join(' ')
54 | }
55 |
56 | function shaToCid (buf) {
57 | const mh = multihash.encode(buf, 'sha1')
58 | return new CID(1, 'git-raw', mh)
59 | }
60 |
61 | function cidToSha (cid) {
62 | const mh = multihash.decode(cid.multihash)
63 | if (mh.name !== 'sha1') {
64 | return null
65 | }
66 |
67 | return Buffer.from(mh.digest.buffer, mh.digest.byteOffset, mh.digest.byteLength)
68 | }
69 |
70 | module.exports = {
71 | SHA1_LENGTH,
72 | find,
73 | parsePersonLine,
74 | serializePersonLine,
75 | shaToCid,
76 | cidToSha
77 | }
78 |
--------------------------------------------------------------------------------
/test/fixtures/0a1690e0640a212aafed1824eb208ffddab1789b:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/0a1690e0640a212aafed1824eb208ffddab1789b
--------------------------------------------------------------------------------
/test/fixtures/0faccf822badf55f15fb0c3f4122fa13798f769e:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/0faccf822badf55f15fb0c3f4122fa13798f769e
--------------------------------------------------------------------------------
/test/fixtures/19f0805d8de36b6442e8c573074112ba72ad6780:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/19f0805d8de36b6442e8c573074112ba72ad6780
--------------------------------------------------------------------------------
/test/fixtures/42fd8d7404f5127314e248b2cbbe1423f12faeb9:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/42fd8d7404f5127314e248b2cbbe1423f12faeb9
--------------------------------------------------------------------------------
/test/fixtures/4b271beec86978454072b632f382c6ccb3938a45:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/4b271beec86978454072b632f382c6ccb3938a45
--------------------------------------------------------------------------------
/test/fixtures/4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc
--------------------------------------------------------------------------------
/test/fixtures/5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507
--------------------------------------------------------------------------------
/test/fixtures/70a3540bd51658ab564806785d5516a4e89b6450:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/70a3540bd51658ab564806785d5516a4e89b6450
--------------------------------------------------------------------------------
/test/fixtures/7ffd1401f599c70364eda431d29363e037b2c92c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/7ffd1401f599c70364eda431d29363e037b2c92c
--------------------------------------------------------------------------------
/test/fixtures/802992c4220de19a90767f3000a79a31b98d0df7:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/802992c4220de19a90767f3000a79a31b98d0df7
--------------------------------------------------------------------------------
/test/fixtures/832b4a8497de78248f70c06e0f06e785a74fea4c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/832b4a8497de78248f70c06e0f06e785a74fea4c
--------------------------------------------------------------------------------
/test/fixtures/88a72947d8b4f0ab7185389efcdd5dace4643e04:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/88a72947d8b4f0ab7185389efcdd5dace4643e04
--------------------------------------------------------------------------------
/test/fixtures/933b7583b7767b07ea4cf242c1be29162eb8bb85:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/933b7583b7767b07ea4cf242c1be29162eb8bb85
--------------------------------------------------------------------------------
/test/fixtures/9f358a4addefcab294b83e4282bfef1f9625a249:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/9f358a4addefcab294b83e4282bfef1f9625a249
--------------------------------------------------------------------------------
/test/fixtures/README.md:
--------------------------------------------------------------------------------
1 | Generated with https://github.com/ipfs/go-ipld-git/blob/master/make-test-repo.sh
2 |
3 | To update the test objects:
4 | * make sure you have `jq` installed
5 | * cd into this directory
6 | * run `./update.sh`
7 |
8 | The script will download test data from https://github.com/ipfs/go-ipld-git and extract it here
9 |
10 | To add/change test objects, you'll need to change https://github.com/ipfs/go-ipld-git/blob/master/make-test-repo.sh,
11 | and regenerate testdata there.
12 |
--------------------------------------------------------------------------------
/test/fixtures/a0f06ca3cdb1e6e7f603794ef1cd9f9867f85551:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/a0f06ca3cdb1e6e7f603794ef1cd9f9867f85551
--------------------------------------------------------------------------------
/test/fixtures/b1c46e7c32ff56e56a3da52be375348a664650ba:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/b1c46e7c32ff56e56a3da52be375348a664650ba
--------------------------------------------------------------------------------
/test/fixtures/cf461f783732a8aa5f7d8679e112bd4c876aa19b:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/cf461f783732a8aa5f7d8679e112bd4c876aa19b
--------------------------------------------------------------------------------
/test/fixtures/d52e70c9e34ac03cdf77f46aec388c2f9574bd93:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/d52e70c9e34ac03cdf77f46aec388c2f9574bd93
--------------------------------------------------------------------------------
/test/fixtures/ed19ea7ea03ecd036c653b9c4cba16df71424a60:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/ed19ea7ea03ecd036c653b9c4cba16df71424a60
--------------------------------------------------------------------------------
/test/fixtures/ee048050d16bc428c4faef1074b740866ad553bb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/ee048050d16bc428c4faef1074b740866ad553bb
--------------------------------------------------------------------------------
/test/fixtures/f5227cbd32973ec90f48f2547e6fe16c80b92bd5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/f5227cbd32973ec90f48f2547e6fe16c80b92bd5
--------------------------------------------------------------------------------
/test/fixtures/fa59b93c6ce9db82ce57de9046eb738e9f3c0952:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/fa59b93c6ce9db82ce57de9046eb738e9f3c0952
--------------------------------------------------------------------------------
/test/fixtures/fc80daf21bb484cfd42ad4ed4d17da48638199ea:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/fc80daf21bb484cfd42ad4ed4d17da48638199ea
--------------------------------------------------------------------------------
/test/fixtures/ffef5350b6f8762cc6272b0255e968f50b6577ed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipld/js-ipld-git/c2830e25825d00178f761d7e871a6797e28f440d/test/fixtures/ffef5350b6f8762cc6272b0255e968f50b6577ed
--------------------------------------------------------------------------------
/test/fixtures/objects.json:
--------------------------------------------------------------------------------
1 | [
2 | "b1c46e7c32ff56e56a3da52be375348a664650ba",
3 | "ee048050d16bc428c4faef1074b740866ad553bb",
4 | "d52e70c9e34ac03cdf77f46aec388c2f9574bd93",
5 | "70a3540bd51658ab564806785d5516a4e89b6450",
6 | "0faccf822badf55f15fb0c3f4122fa13798f769e",
7 | "933b7583b7767b07ea4cf242c1be29162eb8bb85",
8 | "4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc",
9 | "ed19ea7ea03ecd036c653b9c4cba16df71424a60",
10 | "cf461f783732a8aa5f7d8679e112bd4c876aa19b",
11 | "88a72947d8b4f0ab7185389efcdd5dace4643e04",
12 | "ffef5350b6f8762cc6272b0255e968f50b6577ed",
13 | "7ffd1401f599c70364eda431d29363e037b2c92c",
14 | "a0f06ca3cdb1e6e7f603794ef1cd9f9867f85551",
15 | "4b271beec86978454072b632f382c6ccb3938a45",
16 | "f5227cbd32973ec90f48f2547e6fe16c80b92bd5",
17 | "5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507",
18 | "832b4a8497de78248f70c06e0f06e785a74fea4c",
19 | "0a1690e0640a212aafed1824eb208ffddab1789b",
20 | "fc80daf21bb484cfd42ad4ed4d17da48638199ea",
21 | "9f358a4addefcab294b83e4282bfef1f9625a249",
22 | "19f0805d8de36b6442e8c573074112ba72ad6780",
23 | "42fd8d7404f5127314e248b2cbbe1423f12faeb9",
24 | "fa59b93c6ce9db82ce57de9046eb738e9f3c0952",
25 | "802992c4220de19a90767f3000a79a31b98d0df7"
26 | ]
27 |
--------------------------------------------------------------------------------
/test/fixtures/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ls . | awk -F '' 'NF == 40' | xargs rm
4 | rm testdata.tar.gz -f
5 | wget https://github.com/ipfs/go-ipld-git/raw/master/testdata.tar.gz
6 | tar xzf testdata.tar.gz
7 | rm testdata.tar.gz
8 | mv .git git
9 |
10 | find git/objects -type f | cut -d'/' -f3- | sed 's/\///g' | jq --raw-input . | jq --slurp . > objects.json
11 | paste <(find git/objects -type f) <(find git/objects -type f | cut -d'/' -f3- | sed 's/\///g') | xargs -L 1 mv -v
12 | rm -rf git
13 |
--------------------------------------------------------------------------------
/test/mod.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict'
3 |
4 | const { expect } = require('aegir/utils/chai')
5 | const multicodec = require('multicodec')
6 |
7 | const mod = require('../src')
8 |
9 | describe('IPLD Format', () => {
10 | it('codec is git-raw', () => {
11 | expect(mod.codec).to.equal(multicodec.GIT_RAW)
12 | })
13 |
14 | it('defaultHashAlg is sha1', () => {
15 | expect(mod.defaultHashAlg).to.equal(multicodec.SHA1)
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/test/parse.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | /* eslint max-nested-callbacks: ["error", 8] */
3 |
4 | 'use strict'
5 |
6 | const { expect } = require('aegir/utils/chai')
7 | const { Buffer } = require('buffer')
8 | const loadFixture = require('aegir/utils/fixtures')
9 | const zlib = require('zlib')
10 | const ipldGit = require('../src')
11 | const util = require('../src/util/util')
12 |
13 | const testObjectsJSON = require('./fixtures/objects.json')
14 |
15 | describe('utils', () => {
16 | describe('person line parsing', () => {
17 | it('parses generic line', (done) => {
18 | const info = util.parsePersonLine('Someone 123456 +0123')
19 | expect(info).to.exist()
20 | expect(info.name).to.equal('Someone')
21 | expect(info.email).to.equal('some@one.somewhere')
22 | expect(info.date).to.equal('1970-01-02T11:40:36+01:23')
23 | done()
24 | })
25 |
26 | it('parses 3 segment name', (done) => {
27 | const info = util.parsePersonLine('So Me One 123456 +0123')
28 | expect(info).to.exist()
29 | expect(info.name).to.equal('So Me One')
30 | expect(info.email).to.equal('some@one.somewhere')
31 | expect(info.date).to.equal('1970-01-02T11:40:36+01:23')
32 | done()
33 | })
34 |
35 | it('parses no name line', (done) => {
36 | const info = util.parsePersonLine(' 123456 +0123')
37 | expect(info).to.exist()
38 | expect(info.name).to.not.exist()
39 | expect(info.email).to.equal('some@one.somewhere')
40 | expect(info.date).to.equal('1970-01-02T11:40:36+01:23')
41 | done()
42 | })
43 |
44 | it('parses no name line with space in front', (done) => {
45 | const info = util.parsePersonLine(' 123456 +0123')
46 | expect(info).to.exist()
47 | expect(info.name).to.not.exist()
48 | expect(info.email).to.equal('some@one.somewhere')
49 | expect(info.date).to.equal('1970-01-02T11:40:36+01:23')
50 | done()
51 | })
52 |
53 | it('parses line with nonstandard info', (done) => {
54 | const info = util.parsePersonLine('Some One & Other One 987654 +4321')
55 | expect(info).to.exist()
56 | expect(info.name).to.equal('Some One & Other One')
57 | expect(info.email).to.equal('some@one.somewhere, other@one.elsewhere')
58 | expect(info.date).to.equal('1970-01-14T05:41:54+43:21')
59 | done()
60 | })
61 |
62 | it('parses line without date info', (done) => {
63 | const info = util.parsePersonLine('Someone ')
64 | expect(info).to.exist()
65 | expect(info.name).to.equal('Someone')
66 | expect(info.email).to.equal('some.one@some.where')
67 | expect(info.date).to.not.exist()
68 | done()
69 | })
70 | })
71 | })
72 |
73 | describe('git object parsing', () => {
74 | const objects = testObjectsJSON.map(
75 | (o) => [o, zlib.inflateSync(loadFixture('test/fixtures/' + o))]
76 | )
77 |
78 | it('is parsing and serializing properly', async () => {
79 | for (const object of objects) {
80 | const expCid = util.shaToCid(Buffer.from(object[0], 'hex'))
81 |
82 | const cid = await ipldGit.util.cid(object[1])
83 | expect(cid.equals(expCid)).to.be.true()
84 | }
85 | })
86 | })
87 |
--------------------------------------------------------------------------------
/test/resolver.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint max-nested-callbacks: ["error", 8] */
2 | /* eslint-env mocha */
3 | 'use strict'
4 |
5 | const { expect } = require('aegir/utils/chai')
6 | const { Buffer } = require('buffer')
7 |
8 | const CID = require('cids')
9 |
10 | const ipldGit = require('../src')
11 | const resolver = ipldGit.resolver
12 |
13 | describe('IPLD format resolver (local)', () => {
14 | let commitBlob
15 | let tagBlob
16 | let treeBlob
17 | let blobBlob
18 |
19 | before((done) => {
20 | const commitNode = {
21 | gitType: 'commit',
22 | tree: new CID('z8mWaJ1dZ9fH5EetPuRsj8jj26pXsgpsr'),
23 | parents: [
24 | new CID('z8mWaFY1zpiZSXTBrz8i6A3o9vNvAs2CH')
25 | ],
26 | author: {
27 | name: 'John Doe',
28 | email: 'johndoe@example.com',
29 | date: '2017-06-12T23:22:12+02:00'
30 | },
31 | committer: {
32 | name: 'John Doe',
33 | email: 'johndoe@example.com',
34 | date: '2017-06-12T23:22:12+02:00'
35 | },
36 | encoding: 'ISO-8859-1',
37 | message: 'Encoded\n'
38 | }
39 |
40 | const tagNode = {
41 | gitType: 'tag',
42 | object: new CID('z8mWaHQaEAKd5KMRNU3npB3saSZmhFh3e'),
43 | type: 'commit',
44 | tag: 'v0.0.0',
45 | tagger: {
46 | name: 'John Doe',
47 | email: 'johndoe@example.com',
48 | date: '2017-06-12T23:22:12+02:00'
49 | },
50 | message: 'A message\n'
51 | }
52 |
53 | const treeNode = {
54 | somefile: {
55 | hash: new CID('z8mWaJNVTadD7oum3m7f1dmarHvYhFV5b'),
56 | mode: '100644'
57 | },
58 | somedir: {
59 | hash: new CID('z8mWaFY1zpiZSXTBrz8i6A3o9vNvAs2CH'),
60 | mode: '40000'
61 | }
62 | }
63 | treeNode['somedir.notactuallyadir'] = {
64 | hash: new CID('z8mWaJNVTadD7oum3m7f1dmarHvYhFV5b'),
65 | mode: '100644'
66 | }
67 | treeNode['somefile.notactuallyafile'] = {
68 | hash: new CID('z8mWaFY1zpiZSXTBrz8i6A3o9vNvAs2CH'),
69 | mode: '40000'
70 | }
71 |
72 | const blobNode = Buffer.from('626c6f62203800736f6d6564617461', 'hex') // blob 8\0somedata
73 |
74 | commitBlob = ipldGit.util.serialize(commitNode)
75 | tagBlob = ipldGit.util.serialize(tagNode)
76 | treeBlob = ipldGit.util.serialize(treeNode)
77 | blobBlob = ipldGit.util.serialize(blobNode)
78 | done()
79 | })
80 |
81 | describe('commit', () => {
82 | it('resolver.tree', () => {
83 | const tree = resolver.tree(commitBlob)
84 | const paths = [...tree]
85 |
86 | expect(paths).to.have.members([
87 | 'message',
88 | 'tree',
89 | 'author',
90 | 'author/name',
91 | 'author/email',
92 | 'author/date',
93 | 'committer',
94 | 'committer/name',
95 | 'committer/email',
96 | 'committer/date',
97 | 'parents',
98 | 'parents/0',
99 | 'encoding'
100 | ])
101 | })
102 |
103 | describe('resolver.resolve', () => {
104 | it('path within scope', () => {
105 | const result = resolver.resolve(commitBlob, 'message')
106 | expect(result.value).to.equal('Encoded\n')
107 | })
108 |
109 | it('path within scope, but nested', () => {
110 | const result = resolver.resolve(commitBlob, 'author/name')
111 | expect(result.value).to.equal('John Doe')
112 | })
113 |
114 | it('path out of scope', () => {
115 | const result = resolver.resolve(commitBlob, 'tree/foo/hash/bar/mode')
116 | expect(result.value.equals(
117 | new CID('z8mWaJ1dZ9fH5EetPuRsj8jj26pXsgpsr'))
118 | ).to.be.true()
119 | expect(result.remainderPath).to.equal('foo/hash/bar/mode')
120 | })
121 | })
122 | })
123 |
124 | describe('tag', () => {
125 | it('resolver.tree', () => {
126 | const tree = resolver.tree(tagBlob)
127 | const paths = [...tree]
128 |
129 | expect(paths).to.have.members([
130 | 'object',
131 | 'type',
132 | 'tag',
133 | 'message',
134 | 'tagger',
135 | 'tagger/name',
136 | 'tagger/email',
137 | 'tagger/date'
138 | ])
139 | })
140 |
141 | describe('resolver.resolve', () => {
142 | it('path within scope', () => {
143 | const result = resolver.resolve(tagBlob, 'message')
144 | expect(result.value).to.equal('A message\n')
145 | })
146 |
147 | it('path within scope, but nested', () => {
148 | const result = resolver.resolve(tagBlob, 'tagger/name')
149 | expect(result.value).to.equal('John Doe')
150 | })
151 |
152 | it('path out of scope', () => {
153 | const result = resolver.resolve(tagBlob, 'object/tree/foo/mode')
154 | expect(result.value.equals(
155 | new CID('z8mWaHQaEAKd5KMRNU3npB3saSZmhFh3e')
156 | )).to.be.true()
157 | expect(result.remainderPath).to.equal('tree/foo/mode')
158 | })
159 | })
160 | })
161 |
162 | describe('tree', () => {
163 | it('resolver.tree', () => {
164 | const tree = resolver.tree(treeBlob)
165 | const paths = [...tree]
166 |
167 | expect(paths).to.have.members([
168 | 'somedir.notactuallyadir',
169 | 'somedir.notactuallyadir/hash',
170 | 'somedir.notactuallyadir/mode',
171 | 'somedir',
172 | 'somedir/hash',
173 | 'somedir/mode',
174 | 'somefile',
175 | 'somefile/hash',
176 | 'somefile/mode',
177 | 'somefile.notactuallyafile',
178 | 'somefile.notactuallyafile/hash',
179 | 'somefile.notactuallyafile/mode'
180 | ])
181 | })
182 |
183 | describe('resolver.resolve', () => {
184 | it('path within scope, nested', () => {
185 | const result = resolver.resolve(treeBlob, 'somedir/mode')
186 | expect(result.value).to.equal('40000')
187 | })
188 |
189 | it('path out of scope', () => {
190 | const result = resolver.resolve(treeBlob, 'somedir/hash/subfile/mode')
191 | expect(result.value.equals(
192 | new CID('z8mWaFY1zpiZSXTBrz8i6A3o9vNvAs2CH')
193 | )).to.be.true()
194 | expect(result.remainderPath).to.equal('subfile/mode')
195 | })
196 | })
197 | })
198 |
199 | describe('blob', () => {
200 | it('resolver.tree', () => {
201 | const paths = resolver.tree(blobBlob).next()
202 | expect(paths.value).to.be.undefined()
203 | expect(paths.done).to.be.true()
204 | })
205 | })
206 | })
207 |
--------------------------------------------------------------------------------
/test/util.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict'
3 |
4 | const { expect } = require('aegir/utils/chai')
5 | const ipldGit = require('../src')
6 | const multicodec = require('multicodec')
7 | const multihash = require('multihashing-async').multihash
8 | const CID = require('cids')
9 | const { Buffer } = require('buffer')
10 | const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string')
11 |
12 | describe('IPLD format util', () => {
13 | const tagNode = {
14 | gitType: 'tag',
15 | object: new CID('baf4bcfe5cqe5giojiciib5mci7gbb53xcxqot2i'),
16 | type: 'commit',
17 | tag: 'v0.0.0',
18 | tagger: {
19 | name: 'John Doe',
20 | email: 'johndoe@example.com',
21 | date: '2017-06-12T23:22:12+02:00'
22 | },
23 | message: 'A message\n'
24 | }
25 | const tagBlob = ipldGit.util.serialize(tagNode)
26 |
27 | it('.serialize from Uint8Array', () => {
28 | const node = uint8ArrayFromString('blob-blob')
29 | const blob = ipldGit.util.serialize(node)
30 |
31 | expect(blob).to.deep.equal(node)
32 | })
33 |
34 | it('.serialize from tree', () => {
35 | const node = {
36 | 'file.txt': {
37 | hash: new CID('baf4bcfe5cqe5giojiciib5mci7gbb53xcxqot2i'),
38 | mode: '644'
39 | }
40 | }
41 | const blob = ipldGit.util.serialize(node)
42 | const deserialized = ipldGit.util.deserialize(blob)
43 |
44 | expect(deserialized).to.deep.equal(node)
45 | })
46 |
47 | it('.serialize and .deserialize', () => {
48 | expect(Buffer.isBuffer(tagBlob)).to.be.true()
49 | const deserialized = ipldGit.util.deserialize(tagBlob)
50 |
51 | // The `gitType` is not enumerable, hence `eql()` would find it. Thus
52 | // remove that property so that that check passes
53 | const expected = Object.assign({}, tagNode)
54 | delete expected.gitType
55 | expect(deserialized).to.eql(expected)
56 | })
57 |
58 | it('.serialize and .deserialize Uint8Array', () => {
59 | expect(Buffer.isBuffer(Uint8Array.of(...tagBlob))).to.be.false()
60 | const deserialized = ipldGit.util.deserialize(Uint8Array.of(...tagBlob))
61 |
62 | // The `gitType` is not enumerable, hence `eql()` would find it. Thus
63 | // remove that property so that that check passes
64 | const expected = Object.assign({}, tagNode)
65 | delete expected.gitType
66 | expect(deserialized).to.eql(expected)
67 | })
68 |
69 | it('.cid', async () => {
70 | const cid = await ipldGit.util.cid(tagBlob)
71 | expect(cid.version).to.equal(1)
72 | expect(cid.codec).to.equal('git-raw')
73 | expect(cid.multihash).to.exist()
74 | const mh = multihash.decode(cid.multihash)
75 | expect(mh.name).to.equal('sha1')
76 | })
77 |
78 | it('.cid with options', async () => {
79 | const cid = await ipldGit.util.cid(tagBlob, {
80 | hashAlg: multicodec.SHA3_512
81 | })
82 | expect(cid.version).to.equal(1)
83 | expect(cid.codec).to.equal('git-raw')
84 | expect(cid.multihash).to.exist()
85 | const mh = multihash.decode(cid.multihash)
86 | expect(mh.name).to.equal('sha3-512')
87 | })
88 |
89 | it('.cid errors unknown hashAlg', async () => {
90 | await expect(ipldGit.util.cid(tagNode, { hashAlg: 0xffffff }
91 | )).to.be.rejectedWith('Unrecognized function code: 16777215')
92 | })
93 | })
94 |
--------------------------------------------------------------------------------