@helia/unixfs 0.0.0
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/LICENSE +4 -0
- package/README.md +53 -0
- package/dist/index.min.js +3 -0
- package/dist/src/commands/add.d.ts +6 -0
- package/dist/src/commands/add.d.ts.map +1 -0
- package/dist/src/commands/add.js +38 -0
- package/dist/src/commands/add.js.map +1 -0
- package/dist/src/commands/cat.d.ts +5 -0
- package/dist/src/commands/cat.d.ts.map +1 -0
- package/dist/src/commands/cat.js +22 -0
- package/dist/src/commands/cat.js.map +1 -0
- package/dist/src/commands/chmod.d.ts +5 -0
- package/dist/src/commands/chmod.d.ts.map +1 -0
- package/dist/src/commands/chmod.js +108 -0
- package/dist/src/commands/chmod.js.map +1 -0
- package/dist/src/commands/cp.d.ts +5 -0
- package/dist/src/commands/cp.d.ts.map +1 -0
- package/dist/src/commands/cp.js +28 -0
- package/dist/src/commands/cp.js.map +1 -0
- package/dist/src/commands/ls.d.ts +5 -0
- package/dist/src/commands/ls.d.ts.map +1 -0
- package/dist/src/commands/ls.js +26 -0
- package/dist/src/commands/ls.js.map +1 -0
- package/dist/src/commands/mkdir.d.ts +5 -0
- package/dist/src/commands/mkdir.d.ts.map +1 -0
- package/dist/src/commands/mkdir.js +53 -0
- package/dist/src/commands/mkdir.js.map +1 -0
- package/dist/src/commands/rm.d.ts +5 -0
- package/dist/src/commands/rm.d.ts.map +1 -0
- package/dist/src/commands/rm.js +19 -0
- package/dist/src/commands/rm.js.map +1 -0
- package/dist/src/commands/stat.d.ts +5 -0
- package/dist/src/commands/stat.d.ts.map +1 -0
- package/dist/src/commands/stat.js +108 -0
- package/dist/src/commands/stat.js.map +1 -0
- package/dist/src/commands/touch.d.ts +5 -0
- package/dist/src/commands/touch.d.ts.map +1 -0
- package/dist/src/commands/touch.js +111 -0
- package/dist/src/commands/touch.js.map +1 -0
- package/dist/src/commands/utils/add-link.d.ts +21 -0
- package/dist/src/commands/utils/add-link.d.ts.map +1 -0
- package/dist/src/commands/utils/add-link.js +224 -0
- package/dist/src/commands/utils/add-link.js.map +1 -0
- package/dist/src/commands/utils/cid-to-directory.d.ts +10 -0
- package/dist/src/commands/utils/cid-to-directory.d.ts.map +1 -0
- package/dist/src/commands/utils/cid-to-directory.js +13 -0
- package/dist/src/commands/utils/cid-to-directory.js.map +1 -0
- package/dist/src/commands/utils/cid-to-pblink.d.ts +6 -0
- package/dist/src/commands/utils/cid-to-pblink.d.ts.map +1 -0
- package/dist/src/commands/utils/cid-to-pblink.js +19 -0
- package/dist/src/commands/utils/cid-to-pblink.js.map +1 -0
- package/dist/src/commands/utils/dir-sharded.d.ts +67 -0
- package/dist/src/commands/utils/dir-sharded.d.ts.map +1 -0
- package/dist/src/commands/utils/dir-sharded.js +136 -0
- package/dist/src/commands/utils/dir-sharded.js.map +1 -0
- package/dist/src/commands/utils/errors.d.ts +17 -0
- package/dist/src/commands/utils/errors.d.ts.map +1 -0
- package/dist/src/commands/utils/errors.js +27 -0
- package/dist/src/commands/utils/errors.js.map +1 -0
- package/dist/src/commands/utils/hamt-constants.d.ts +4 -0
- package/dist/src/commands/utils/hamt-constants.d.ts.map +1 -0
- package/dist/src/commands/utils/hamt-constants.js +13 -0
- package/dist/src/commands/utils/hamt-constants.js.map +1 -0
- package/dist/src/commands/utils/hamt-utils.d.ts +37 -0
- package/dist/src/commands/utils/hamt-utils.d.ts.map +1 -0
- package/dist/src/commands/utils/hamt-utils.js +202 -0
- package/dist/src/commands/utils/hamt-utils.js.map +1 -0
- package/dist/src/commands/utils/persist.d.ts +10 -0
- package/dist/src/commands/utils/persist.d.ts.map +1 -0
- package/dist/src/commands/utils/persist.js +12 -0
- package/dist/src/commands/utils/persist.js.map +1 -0
- package/dist/src/commands/utils/remove-link.d.ts +11 -0
- package/dist/src/commands/utils/remove-link.d.ts.map +1 -0
- package/dist/src/commands/utils/remove-link.js +92 -0
- package/dist/src/commands/utils/remove-link.js.map +1 -0
- package/dist/src/commands/utils/resolve.d.ts +28 -0
- package/dist/src/commands/utils/resolve.d.ts.map +1 -0
- package/dist/src/commands/utils/resolve.js +85 -0
- package/dist/src/commands/utils/resolve.js.map +1 -0
- package/dist/src/index.d.ts +97 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +166 -0
- package/src/commands/add.ts +46 -0
- package/src/commands/cat.ts +31 -0
- package/src/commands/chmod.ts +133 -0
- package/src/commands/cp.ts +41 -0
- package/src/commands/ls.ts +36 -0
- package/src/commands/mkdir.ts +71 -0
- package/src/commands/rm.ts +31 -0
- package/src/commands/stat.ts +137 -0
- package/src/commands/touch.ts +136 -0
- package/src/commands/utils/add-link.ts +319 -0
- package/src/commands/utils/cid-to-directory.ts +23 -0
- package/src/commands/utils/cid-to-pblink.ts +26 -0
- package/src/commands/utils/dir-sharded.ts +219 -0
- package/src/commands/utils/errors.ts +31 -0
- package/src/commands/utils/hamt-constants.ts +14 -0
- package/src/commands/utils/hamt-utils.ts +285 -0
- package/src/commands/utils/persist.ts +22 -0
- package/src/commands/utils/remove-link.ts +151 -0
- package/src/commands/utils/resolve.ts +130 -0
- package/src/index.ts +174 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { add, addStream } from './commands/add.js';
|
|
2
|
+
import { cat } from './commands/cat.js';
|
|
3
|
+
import { mkdir } from './commands/mkdir.js';
|
|
4
|
+
import { cp } from './commands/cp.js';
|
|
5
|
+
import { rm } from './commands/rm.js';
|
|
6
|
+
import { stat } from './commands/stat.js';
|
|
7
|
+
import { touch } from './commands/touch.js';
|
|
8
|
+
import { chmod } from './commands/chmod.js';
|
|
9
|
+
import { ls } from './commands/ls.js';
|
|
10
|
+
class DefaultUnixFS {
|
|
11
|
+
constructor(components) {
|
|
12
|
+
this.components = components;
|
|
13
|
+
}
|
|
14
|
+
async add(source, options = {}) {
|
|
15
|
+
return await add(source, this.components.blockstore, options);
|
|
16
|
+
}
|
|
17
|
+
async *addStream(source, options = {}) {
|
|
18
|
+
yield* addStream(source, this.components.blockstore, options);
|
|
19
|
+
}
|
|
20
|
+
async *cat(cid, options = {}) {
|
|
21
|
+
yield* cat(cid, this.components.blockstore, options);
|
|
22
|
+
}
|
|
23
|
+
async chmod(source, mode, options = {}) {
|
|
24
|
+
return await chmod(source, mode, this.components.blockstore, options);
|
|
25
|
+
}
|
|
26
|
+
async cp(source, target, name, options = {}) {
|
|
27
|
+
return await cp(source, target, name, this.components.blockstore, options);
|
|
28
|
+
}
|
|
29
|
+
async *ls(cid, options = {}) {
|
|
30
|
+
yield* ls(cid, this.components.blockstore, options);
|
|
31
|
+
}
|
|
32
|
+
async mkdir(cid, dirname, options = {}) {
|
|
33
|
+
return await mkdir(cid, dirname, this.components.blockstore, options);
|
|
34
|
+
}
|
|
35
|
+
async rm(cid, path, options = {}) {
|
|
36
|
+
return await rm(cid, path, this.components.blockstore, options);
|
|
37
|
+
}
|
|
38
|
+
async stat(cid, options = {}) {
|
|
39
|
+
return await stat(cid, this.components.blockstore, options);
|
|
40
|
+
}
|
|
41
|
+
async touch(cid, options = {}) {
|
|
42
|
+
return await touch(cid, this.components.blockstore, options);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function unixfs(helia) {
|
|
46
|
+
return new DefaultUnixFS(helia);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@helia/unixfs",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "A Helia-compatible wrapper for UnixFS",
|
|
5
|
+
"license": "Apache-2.0 OR MIT",
|
|
6
|
+
"homepage": "https://github.com/ipfs/helia/tree/master/packages/unixfs#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ipfs/helia.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ipfs/helia/issues"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"IPFS"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16.0.0",
|
|
19
|
+
"npm": ">=7.0.0"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"types": "./dist/src/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"src",
|
|
25
|
+
"dist",
|
|
26
|
+
"!dist/test",
|
|
27
|
+
"!**/*.tsbuildinfo"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/src/index.d.ts",
|
|
32
|
+
"import": "./dist/src/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"eslintConfig": {
|
|
36
|
+
"extends": "ipfs",
|
|
37
|
+
"parserOptions": {
|
|
38
|
+
"sourceType": "module"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"release": {
|
|
42
|
+
"branches": [
|
|
43
|
+
"main"
|
|
44
|
+
],
|
|
45
|
+
"plugins": [
|
|
46
|
+
[
|
|
47
|
+
"@semantic-release/commit-analyzer",
|
|
48
|
+
{
|
|
49
|
+
"preset": "conventionalcommits",
|
|
50
|
+
"releaseRules": [
|
|
51
|
+
{
|
|
52
|
+
"breaking": true,
|
|
53
|
+
"release": "major"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"revert": true,
|
|
57
|
+
"release": "patch"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "feat",
|
|
61
|
+
"release": "minor"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"type": "fix",
|
|
65
|
+
"release": "patch"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "docs",
|
|
69
|
+
"release": "patch"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"type": "test",
|
|
73
|
+
"release": "patch"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "deps",
|
|
77
|
+
"release": "patch"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"scope": "no-release",
|
|
81
|
+
"release": false
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"@semantic-release/release-notes-generator",
|
|
88
|
+
{
|
|
89
|
+
"preset": "conventionalcommits",
|
|
90
|
+
"presetConfig": {
|
|
91
|
+
"types": [
|
|
92
|
+
{
|
|
93
|
+
"type": "feat",
|
|
94
|
+
"section": "Features"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"type": "fix",
|
|
98
|
+
"section": "Bug Fixes"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"type": "chore",
|
|
102
|
+
"section": "Trivial Changes"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"type": "docs",
|
|
106
|
+
"section": "Documentation"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"type": "deps",
|
|
110
|
+
"section": "Dependencies"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "test",
|
|
114
|
+
"section": "Tests"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"@semantic-release/changelog",
|
|
121
|
+
"@semantic-release/npm",
|
|
122
|
+
"@semantic-release/github",
|
|
123
|
+
"@semantic-release/git"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
"scripts": {
|
|
127
|
+
"clean": "aegir clean",
|
|
128
|
+
"lint": "aegir lint",
|
|
129
|
+
"dep-check": "aegir dep-check",
|
|
130
|
+
"build": "aegir build",
|
|
131
|
+
"docs": "aegir docs",
|
|
132
|
+
"test": "aegir test",
|
|
133
|
+
"test:chrome": "aegir test -t browser --cov",
|
|
134
|
+
"test:chrome-webworker": "aegir test -t webworker",
|
|
135
|
+
"test:firefox": "aegir test -t browser -- --browser firefox",
|
|
136
|
+
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
|
|
137
|
+
"test:node": "aegir test -t node --cov",
|
|
138
|
+
"test:electron-main": "aegir test -t electron-main",
|
|
139
|
+
"release": "aegir release"
|
|
140
|
+
},
|
|
141
|
+
"dependencies": {
|
|
142
|
+
"@helia/interface": "next",
|
|
143
|
+
"@ipld/dag-pb": "^4.0.0",
|
|
144
|
+
"@libp2p/interfaces": "^3.3.1",
|
|
145
|
+
"@libp2p/logger": "^2.0.5",
|
|
146
|
+
"@multiformats/murmur3": "^2.1.2",
|
|
147
|
+
"hamt-sharding": "^3.0.2",
|
|
148
|
+
"interface-blockstore": "^4.0.1",
|
|
149
|
+
"ipfs-unixfs": "^9.0.0",
|
|
150
|
+
"ipfs-unixfs-exporter": "^10.0.0",
|
|
151
|
+
"ipfs-unixfs-importer": "^12.0.0",
|
|
152
|
+
"it-last": "^2.0.0",
|
|
153
|
+
"it-pipe": "^2.0.5",
|
|
154
|
+
"merge-options": "^3.0.4",
|
|
155
|
+
"multiformats": "^11.0.1"
|
|
156
|
+
},
|
|
157
|
+
"devDependencies": {
|
|
158
|
+
"aegir": "^38.1.0",
|
|
159
|
+
"blockstore-core": "^3.0.0",
|
|
160
|
+
"delay": "^5.0.0",
|
|
161
|
+
"it-all": "^2.0.0",
|
|
162
|
+
"it-drain": "^2.0.0",
|
|
163
|
+
"it-to-buffer": "^3.0.0",
|
|
164
|
+
"uint8arrays": "^4.0.3"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Blockstore } from 'interface-blockstore'
|
|
2
|
+
import { ImportCandidate, importer, ImportResult, UserImporterOptions } from 'ipfs-unixfs-importer'
|
|
3
|
+
import last from 'it-last'
|
|
4
|
+
import type { CID } from 'multiformats/cid'
|
|
5
|
+
import { UnknownError } from './utils/errors.js'
|
|
6
|
+
|
|
7
|
+
function isIterable (obj: any): obj is Iterator<Uint8Array> {
|
|
8
|
+
return obj[Symbol.iterator] != null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isAsyncIterable (obj: any): obj is AsyncIterator<Uint8Array> {
|
|
12
|
+
return obj[Symbol.asyncIterator] != null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function add (source: Uint8Array | Iterator<Uint8Array> | AsyncIterator<Uint8Array> | ImportCandidate, blockstore: Blockstore, options: UserImporterOptions = {}): Promise<CID> {
|
|
16
|
+
let importCandidate: ImportCandidate
|
|
17
|
+
|
|
18
|
+
if (source instanceof Uint8Array || isIterable(source) || isAsyncIterable(source)) {
|
|
19
|
+
importCandidate = {
|
|
20
|
+
// @ts-expect-error FIXME: work out types
|
|
21
|
+
content: source
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
importCandidate = source
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const result = await last(importer(importCandidate, blockstore, {
|
|
28
|
+
cidVersion: 1,
|
|
29
|
+
rawLeaves: true,
|
|
30
|
+
...options
|
|
31
|
+
}))
|
|
32
|
+
|
|
33
|
+
if (result == null) {
|
|
34
|
+
throw new UnknownError('Could not import')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return result.cid
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function * addStream (source: Iterable<ImportCandidate> | AsyncIterable<ImportCandidate>, blockstore: Blockstore, options: UserImporterOptions = {}): AsyncGenerator<ImportResult> {
|
|
41
|
+
yield * importer(source, blockstore, {
|
|
42
|
+
cidVersion: 1,
|
|
43
|
+
rawLeaves: true,
|
|
44
|
+
...options
|
|
45
|
+
})
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NoContentError, NotAFileError } from '@helia/interface/errors'
|
|
2
|
+
import { Blockstore, exporter } from 'ipfs-unixfs-exporter'
|
|
3
|
+
import type { CID } from 'multiformats/cid'
|
|
4
|
+
import type { CatOptions } from '../index.js'
|
|
5
|
+
import { resolve } from './utils/resolve.js'
|
|
6
|
+
import mergeOpts from 'merge-options'
|
|
7
|
+
|
|
8
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
9
|
+
|
|
10
|
+
const defaultOptions: CatOptions = {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function * cat (cid: CID, blockstore: Blockstore, options: Partial<CatOptions> = {}): AsyncIterable<Uint8Array> {
|
|
15
|
+
const opts: CatOptions = mergeOptions(defaultOptions, options)
|
|
16
|
+
const resolved = await resolve(cid, opts.path, blockstore, opts)
|
|
17
|
+
const result = await exporter(resolved.cid, blockstore, opts)
|
|
18
|
+
|
|
19
|
+
if (result.type !== 'file' && result.type !== 'raw') {
|
|
20
|
+
throw new NotAFileError()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (result.content == null) {
|
|
24
|
+
throw new NoContentError()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
yield * result.content({
|
|
28
|
+
offset: opts.offset,
|
|
29
|
+
length: opts.length
|
|
30
|
+
})
|
|
31
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { recursive } from 'ipfs-unixfs-exporter'
|
|
2
|
+
import { CID } from 'multiformats/cid'
|
|
3
|
+
import type { ChmodOptions } from '../index.js'
|
|
4
|
+
import mergeOpts from 'merge-options'
|
|
5
|
+
import { logger } from '@libp2p/logger'
|
|
6
|
+
import { UnixFS } from 'ipfs-unixfs'
|
|
7
|
+
import { pipe } from 'it-pipe'
|
|
8
|
+
import { InvalidPBNodeError, NotUnixFSError, UnknownError } from './utils/errors.js'
|
|
9
|
+
import * as dagPB from '@ipld/dag-pb'
|
|
10
|
+
import type { PBNode, PBLink } from '@ipld/dag-pb'
|
|
11
|
+
import { importer } from 'ipfs-unixfs-importer'
|
|
12
|
+
import { persist } from './utils/persist.js'
|
|
13
|
+
import type { Blockstore } from 'interface-blockstore'
|
|
14
|
+
import last from 'it-last'
|
|
15
|
+
import { sha256 } from 'multiformats/hashes/sha2'
|
|
16
|
+
import { resolve, updatePathCids } from './utils/resolve.js'
|
|
17
|
+
import * as raw from 'multiformats/codecs/raw'
|
|
18
|
+
|
|
19
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
20
|
+
const log = logger('helia:unixfs:chmod')
|
|
21
|
+
|
|
22
|
+
const defaultOptions: ChmodOptions = {
|
|
23
|
+
recursive: false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function chmod (cid: CID, mode: number, blockstore: Blockstore, options: Partial<ChmodOptions> = {}): Promise<CID> {
|
|
27
|
+
const opts: ChmodOptions = mergeOptions(defaultOptions, options)
|
|
28
|
+
const resolved = await resolve(cid, opts.path, blockstore, options)
|
|
29
|
+
|
|
30
|
+
log('chmod %c %d', resolved.cid, mode)
|
|
31
|
+
|
|
32
|
+
if (opts.recursive) {
|
|
33
|
+
// recursively export from root CID, change perms of each entry then reimport
|
|
34
|
+
// but do not reimport files, only manipulate dag-pb nodes
|
|
35
|
+
const root = await pipe(
|
|
36
|
+
async function * () {
|
|
37
|
+
for await (const entry of recursive(resolved.cid, blockstore)) {
|
|
38
|
+
let metadata: UnixFS
|
|
39
|
+
let links: PBLink[] = []
|
|
40
|
+
|
|
41
|
+
if (entry.type === 'raw') {
|
|
42
|
+
// convert to UnixFS
|
|
43
|
+
metadata = new UnixFS({ type: 'file', data: entry.node })
|
|
44
|
+
} else if (entry.type === 'file' || entry.type === 'directory') {
|
|
45
|
+
metadata = entry.unixfs
|
|
46
|
+
links = entry.node.Links
|
|
47
|
+
} else {
|
|
48
|
+
throw new NotUnixFSError()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
metadata.mode = mode
|
|
52
|
+
|
|
53
|
+
const node = {
|
|
54
|
+
Data: metadata.marshal(),
|
|
55
|
+
Links: links
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
yield {
|
|
59
|
+
path: entry.path,
|
|
60
|
+
content: node
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// @ts-expect-error we account for the incompatible source type with our custom dag builder below
|
|
65
|
+
(source) => importer(source, blockstore, {
|
|
66
|
+
...opts,
|
|
67
|
+
pin: false,
|
|
68
|
+
dagBuilder: async function * (source, block, opts) {
|
|
69
|
+
for await (const entry of source) {
|
|
70
|
+
yield async function () {
|
|
71
|
+
// @ts-expect-error cannot derive type
|
|
72
|
+
const node: PBNode = entry.content
|
|
73
|
+
|
|
74
|
+
const buf = dagPB.encode(node)
|
|
75
|
+
const cid = await persist(buf, block, opts)
|
|
76
|
+
|
|
77
|
+
if (node.Data == null) {
|
|
78
|
+
throw new InvalidPBNodeError(`${cid} had no data`)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const unixfs = UnixFS.unmarshal(node.Data)
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
cid,
|
|
85
|
+
size: buf.length,
|
|
86
|
+
path: entry.path,
|
|
87
|
+
unixfs
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}),
|
|
93
|
+
async (nodes) => await last(nodes)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
if (root == null) {
|
|
97
|
+
throw new UnknownError(`Could not chmod ${resolved.cid.toString()}`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return await updatePathCids(root.cid, resolved, blockstore, options)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const block = await blockstore.get(resolved.cid)
|
|
104
|
+
let metadata: UnixFS
|
|
105
|
+
let links: PBLink[] = []
|
|
106
|
+
|
|
107
|
+
if (resolved.cid.code === raw.code) {
|
|
108
|
+
// convert to UnixFS
|
|
109
|
+
metadata = new UnixFS({ type: 'file', data: block })
|
|
110
|
+
} else {
|
|
111
|
+
const node = dagPB.decode(block)
|
|
112
|
+
|
|
113
|
+
if (node.Data == null) {
|
|
114
|
+
throw new InvalidPBNodeError(`${resolved.cid.toString()} had no data`)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
links = node.Links
|
|
118
|
+
metadata = UnixFS.unmarshal(node.Data)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
metadata.mode = mode
|
|
122
|
+
const updatedBlock = dagPB.encode({
|
|
123
|
+
Data: metadata.marshal(),
|
|
124
|
+
Links: links
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
const hash = await sha256.digest(updatedBlock)
|
|
128
|
+
const updatedCid = CID.create(resolved.cid.version, dagPB.code, hash)
|
|
129
|
+
|
|
130
|
+
await blockstore.put(updatedCid, updatedBlock)
|
|
131
|
+
|
|
132
|
+
return await updatePathCids(updatedCid, resolved, blockstore, options)
|
|
133
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { InvalidParametersError } from '@helia/interface/errors'
|
|
2
|
+
import type { Blockstore } from 'ipfs-unixfs-exporter'
|
|
3
|
+
import type { CID } from 'multiformats/cid'
|
|
4
|
+
import type { CpOptions } from '../index.js'
|
|
5
|
+
import mergeOpts from 'merge-options'
|
|
6
|
+
import { logger } from '@libp2p/logger'
|
|
7
|
+
import { addLink } from './utils/add-link.js'
|
|
8
|
+
import { cidToPBLink } from './utils/cid-to-pblink.js'
|
|
9
|
+
import { cidToDirectory } from './utils/cid-to-directory.js'
|
|
10
|
+
|
|
11
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
12
|
+
const log = logger('helia:unixfs:cp')
|
|
13
|
+
|
|
14
|
+
const defaultOptions = {
|
|
15
|
+
force: false
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function cp (source: CID, target: CID, name: string, blockstore: Blockstore, options: Partial<CpOptions> = {}): Promise<CID> {
|
|
19
|
+
const opts: CpOptions = mergeOptions(defaultOptions, options)
|
|
20
|
+
|
|
21
|
+
if (name.includes('/')) {
|
|
22
|
+
throw new InvalidParametersError('Name must not have slashes')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const [
|
|
26
|
+
directory,
|
|
27
|
+
pblink
|
|
28
|
+
] = await Promise.all([
|
|
29
|
+
cidToDirectory(target, blockstore, opts),
|
|
30
|
+
cidToPBLink(source, name, blockstore, opts)
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
log('Adding %c as "%s" to %c', source, name, target)
|
|
34
|
+
|
|
35
|
+
const result = await addLink(directory, pblink, blockstore, {
|
|
36
|
+
allowOverwriting: opts.force,
|
|
37
|
+
...opts
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
return result.cid
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NoContentError, NotADirectoryError } from '@helia/interface/errors'
|
|
2
|
+
import { Blockstore, exporter, UnixFSEntry } from 'ipfs-unixfs-exporter'
|
|
3
|
+
import type { CID } from 'multiformats/cid'
|
|
4
|
+
import type { LsOptions } from '../index.js'
|
|
5
|
+
import { resolve } from './utils/resolve.js'
|
|
6
|
+
import mergeOpts from 'merge-options'
|
|
7
|
+
|
|
8
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
9
|
+
|
|
10
|
+
const defaultOptions = {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function * ls (cid: CID, blockstore: Blockstore, options: Partial<LsOptions> = {}): AsyncIterable<UnixFSEntry> {
|
|
15
|
+
const opts: LsOptions = mergeOptions(defaultOptions, options)
|
|
16
|
+
const resolved = await resolve(cid, opts.path, blockstore, opts)
|
|
17
|
+
const result = await exporter(resolved.cid, blockstore)
|
|
18
|
+
|
|
19
|
+
if (result.type === 'file' || result.type === 'raw') {
|
|
20
|
+
yield result
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (result.content == null) {
|
|
25
|
+
throw new NoContentError()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (result.type !== 'directory') {
|
|
29
|
+
throw new NotADirectoryError()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
yield * result.content({
|
|
33
|
+
offset: options.offset,
|
|
34
|
+
length: options.length
|
|
35
|
+
})
|
|
36
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { InvalidParametersError, NotADirectoryError } from '@helia/interface/errors'
|
|
2
|
+
import { CID } from 'multiformats/cid'
|
|
3
|
+
import mergeOpts from 'merge-options'
|
|
4
|
+
import { logger } from '@libp2p/logger'
|
|
5
|
+
import type { MkdirOptions } from '../index.js'
|
|
6
|
+
import * as dagPB from '@ipld/dag-pb'
|
|
7
|
+
import { addLink } from './utils/add-link.js'
|
|
8
|
+
import type { Blockstore } from 'interface-blockstore'
|
|
9
|
+
import { UnixFS } from 'ipfs-unixfs'
|
|
10
|
+
import { sha256 } from 'multiformats/hashes/sha2'
|
|
11
|
+
import { exporter } from 'ipfs-unixfs-exporter'
|
|
12
|
+
import { cidToDirectory } from './utils/cid-to-directory.js'
|
|
13
|
+
import { cidToPBLink } from './utils/cid-to-pblink.js'
|
|
14
|
+
|
|
15
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
16
|
+
const log = logger('helia:unixfs:mkdir')
|
|
17
|
+
|
|
18
|
+
const defaultOptions = {
|
|
19
|
+
cidVersion: 1,
|
|
20
|
+
force: false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function mkdir (parentCid: CID, dirname: string, blockstore: Blockstore, options: Partial<MkdirOptions> = {}): Promise<CID> {
|
|
24
|
+
const opts: MkdirOptions = mergeOptions(defaultOptions, options)
|
|
25
|
+
|
|
26
|
+
if (dirname.includes('/')) {
|
|
27
|
+
throw new InvalidParametersError('Path must not have slashes')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const entry = await exporter(parentCid, blockstore, options)
|
|
31
|
+
|
|
32
|
+
if (entry.type !== 'directory') {
|
|
33
|
+
throw new NotADirectoryError(`${parentCid.toString()} was not a UnixFS directory`)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
log('creating %s', dirname)
|
|
37
|
+
|
|
38
|
+
const metadata = new UnixFS({
|
|
39
|
+
type: 'directory',
|
|
40
|
+
mode: opts.mode,
|
|
41
|
+
mtime: opts.mtime
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Persist the new parent PBNode
|
|
45
|
+
const node = {
|
|
46
|
+
Data: metadata.marshal(),
|
|
47
|
+
Links: []
|
|
48
|
+
}
|
|
49
|
+
const buf = dagPB.encode(node)
|
|
50
|
+
const hash = await sha256.digest(buf)
|
|
51
|
+
const emptyDirCid = CID.create(opts.cidVersion, dagPB.code, hash)
|
|
52
|
+
|
|
53
|
+
await blockstore.put(emptyDirCid, buf)
|
|
54
|
+
|
|
55
|
+
const [
|
|
56
|
+
directory,
|
|
57
|
+
pblink
|
|
58
|
+
] = await Promise.all([
|
|
59
|
+
cidToDirectory(parentCid, blockstore, opts),
|
|
60
|
+
cidToPBLink(emptyDirCid, dirname, blockstore, opts)
|
|
61
|
+
])
|
|
62
|
+
|
|
63
|
+
log('adding empty dir called %s to %c', dirname, parentCid)
|
|
64
|
+
|
|
65
|
+
const result = await addLink(directory, pblink, blockstore, {
|
|
66
|
+
...opts,
|
|
67
|
+
allowOverwriting: opts.force
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return result.cid
|
|
71
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { InvalidParametersError } from '@helia/interface/errors'
|
|
2
|
+
import type { Blockstore } from 'ipfs-unixfs-exporter'
|
|
3
|
+
import type { CID } from 'multiformats/cid'
|
|
4
|
+
import type { RmOptions } from '../index.js'
|
|
5
|
+
import mergeOpts from 'merge-options'
|
|
6
|
+
import { logger } from '@libp2p/logger'
|
|
7
|
+
import { removeLink } from './utils/remove-link.js'
|
|
8
|
+
import { cidToDirectory } from './utils/cid-to-directory.js'
|
|
9
|
+
|
|
10
|
+
const mergeOptions = mergeOpts.bind({ ignoreUndefined: true })
|
|
11
|
+
const log = logger('helia:unixfs:rm')
|
|
12
|
+
|
|
13
|
+
const defaultOptions = {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function rm (target: CID, name: string, blockstore: Blockstore, options: Partial<RmOptions> = {}): Promise<CID> {
|
|
18
|
+
const opts: RmOptions = mergeOptions(defaultOptions, options)
|
|
19
|
+
|
|
20
|
+
if (name.includes('/')) {
|
|
21
|
+
throw new InvalidParametersError('Name must not have slashes')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const directory = await cidToDirectory(target, blockstore, opts)
|
|
25
|
+
|
|
26
|
+
log('Removing %s from %c', name, target)
|
|
27
|
+
|
|
28
|
+
const result = await removeLink(directory, name, blockstore, opts)
|
|
29
|
+
|
|
30
|
+
return result.cid
|
|
31
|
+
}
|