Skip to content

Commit 540f20a

Browse files
committed
feat: adds metadata to unixfs
Adds two new fields `mtime` and `mode` in line with the unixfs spec. One possible wart here is that `mtime` is implemented as a JavaScript number which means it can't hold the full value of `int64` so cannot represent dates in the far future. This should be addressed by UnixFSv2 which should hopefully arrive before we top out `Number.MAX_SAFE_INTEGER` - e.g. early June 2255.
1 parent 0293897 commit 540f20a

File tree

4 files changed

+75
-6
lines changed

4 files changed

+75
-6
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"fs": false
99
},
1010
"scripts": {
11-
"test": "aegir test -t node -t browser",
11+
"test": "aegir test -t node -t browser -t webworker",
1212
"test:node": "aegir test -t node",
1313
"test:browser": "aegir test -t browser",
1414
"test:webworker": "aegir test -t webworker",
@@ -36,7 +36,7 @@
3636
},
3737
"homepage": "https://github.com/ipfs/js-ipfs-unixfs#readme",
3838
"devDependencies": {
39-
"aegir": "^18.0.0",
39+
"aegir": "^20.4.1",
4040
"chai": "^4.2.0",
4141
"dirty-chai": "^2.0.1",
4242
"safe-buffer": "^5.1.2"

src/index.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ function Data (type, data) {
3232
this.data = data
3333
this.blockSizes = []
3434

35+
if (this.type === 'file') {
36+
this.mode = parseInt('0644', 8)
37+
}
38+
39+
if (this.type === 'directory' || this.type === 'hamt-sharded-directory') {
40+
this.mode = parseInt('0755', 8)
41+
}
42+
3543
this.addBlockSize = (size) => {
3644
this.blockSizes.push(size)
3745
}
@@ -71,7 +79,6 @@ function Data (type, data) {
7179
default:
7280
throw new Error(`Unkown type: "${this.type}"`)
7381
}
74-
let fileSize = this.fileSize()
7582

7683
let data = this.data
7784

@@ -85,13 +92,23 @@ function Data (type, data) {
8592
blockSizes = undefined
8693
}
8794

95+
if ((this.type === 'directory' || this.type === 'hamt-sharded-directory') && this.mode === parseInt('0755', 8)) {
96+
delete this.mode
97+
}
98+
99+
if (this.type === 'file' && this.mode === parseInt('0644', 8)) {
100+
delete this.mode
101+
}
102+
88103
return unixfsData.encode({
89104
Type: type,
90105
Data: data,
91-
filesize: fileSize,
106+
filesize: this.fileSize(),
92107
blocksizes: blockSizes,
93108
hashType: this.hashType,
94-
fanout: this.fanout
109+
fanout: this.fanout,
110+
mode: this.mode,
111+
mtime: this.mtime
95112
})
96113
}
97114
}
@@ -104,6 +121,15 @@ Data.unmarshal = (marsheled) => {
104121
}
105122
const obj = new Data(types[decoded.Type], decoded.Data)
106123
obj.blockSizes = decoded.blocksizes
124+
125+
if (decoded.mode) {
126+
obj.mode = decoded.mode
127+
}
128+
129+
if (decoded.mtime) {
130+
obj.mtime = decoded.mtime
131+
}
132+
107133
return obj
108134
}
109135

src/unixfs.proto.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ module.exports = `message Data {
1414
optional bytes Data = 2;
1515
optional uint64 filesize = 3;
1616
repeated uint64 blocksizes = 4;
17-
1817
optional uint64 hashType = 5;
1918
optional uint64 fanout = 6;
19+
optional uint32 mode = 7;
20+
optional int64 mtime = 8;
2021
}
2122
2223
message Metadata {

test/unixfs-format.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,48 @@ describe('unixfs-format', () => {
7979
expect(data.blockSizes).to.not.deep.equal(unmarshalled.blockSizes)
8080
})
8181

82+
it('default mode for files', () => {
83+
const data = new UnixFS('file')
84+
expect(data.mode).to.equal(parseInt('0644', 8))
85+
const marshalled = data.marshal()
86+
const unmarshalled = UnixFS.unmarshal(marshalled)
87+
expect(unmarshalled.mode).to.equal(parseInt('0644', 8))
88+
})
89+
90+
it('default mode for directories', () => {
91+
const data = new UnixFS('directory')
92+
expect(data.mode).to.equal(parseInt('0755', 8))
93+
const marshalled = data.marshal()
94+
const unmarshalled = UnixFS.unmarshal(marshalled)
95+
expect(unmarshalled.mode).to.equal(parseInt('0755', 8))
96+
})
97+
98+
it('default mode for hamt-sharded-directories', () => {
99+
const data = new UnixFS('hamt-sharded-directory')
100+
expect(data.mode).to.equal(parseInt('0755', 8))
101+
const marshalled = data.marshal()
102+
const unmarshalled = UnixFS.unmarshal(marshalled)
103+
expect(unmarshalled.mode).to.equal(parseInt('0755', 8))
104+
})
105+
106+
it('mode', () => {
107+
const mode = parseInt('0555', 8)
108+
const data = new UnixFS('file')
109+
data.mode = mode
110+
const marshalled = data.marshal()
111+
const unmarshalled = UnixFS.unmarshal(marshalled)
112+
expect(unmarshalled.mode).to.equal(mode)
113+
})
114+
115+
it('mtime', () => {
116+
const mtime = parseInt(Date.now() / 1000)
117+
const data = new UnixFS('file')
118+
data.mtime = mtime
119+
const marshalled = data.marshal()
120+
const unmarshalled = UnixFS.unmarshal(marshalled)
121+
expect(unmarshalled.mtime).to.equal(mtime)
122+
})
123+
82124
// figuring out what is this metadata for https://github.com/ipfs/js-ipfs-data-importing/issues/3#issuecomment-182336526
83125
it.skip('metadata', () => {})
84126

0 commit comments

Comments
 (0)