-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hash a directory #18
Comments
In fact, this should be very easy to achieve, as if I change: for await (const { cid } of importer([{ content }], block, options)) { to for await (const { cid } of importer(content, block, options)) { then I can pass in the result of e.g. So it seems that all that is needed to keep things as convenient as at the moment is a bit more automatic type-matching code like the current: if (typeof content === 'string') {
content = new TextEncoder().encode(content)
} |
After a bit more thought, I can see how to detect whether the argument is a If it's impossible to make this distinction, then it would be possible instead to add a second API to |
For now, I am using the following code, and specifically the // A slightly modified version of ipfs-only-hash
// See https://github.com/alanshaw/ipfs-only-hash/issues/18
const { globSource } = require('ipfs-http-client');
const { importer } = require('ipfs-unixfs-importer');
const block = {
get: async (cid) => { throw new Error(`unexpected block API get for ${cid}`); },
put: async () => { throw new Error('unexpected block API put'); },
};
async function hash(content_, options_) {
const options = options_ || {};
options.onlyHash = true;
let content = content_;
if (typeof content === 'string') {
content = [{ content: new TextEncoder().encode(content) }];
} else if (content instanceof Object.getPrototypeOf(Uint8Array)) {
content = [{ content }];
}
let lastCID;
for await (const { cid } of importer(content, block, options)) {
lastCID = cid;
}
return lastCID;
}
module.exports = {
cidToHex(cid) {
return `0x${Buffer.from(cid.bytes.slice(2)).toString('hex')}`;
},
of: hash,
async ofDir(directory) {
const options = {
cidVersion: 0, // Lines up with the smart contract code
};
const files = globSource(directory, { recursive: true });
const rootCID = await hash(files, options);
return rootCID;
},
}; |
Updated version of @rrthomas's code. Note Not perfect but good enough to get started with. // A slightly modified version of ipfs-only-hash
// See https://github.com/alanshaw/ipfs-only-hash/issues/18
const block = {
get: async (cid) => {
throw new Error(`unexpected block API get for ${cid}`);
},
put: async () => {
throw new Error('unexpected block API put');
},
};
async function hash(content_, options_) {
const { importer } = await import('ipfs-unixfs-importer');
const options = options_ || {};
options.onlyHash = true;
let content = content_;
if (typeof content === 'string') {
content = [{ content: new TextEncoder().encode(content) }];
} else if (content instanceof Object.getPrototypeOf(Uint8Array)) {
content = [{ content }];
}
let lastCID;
for await (const c of importer(content, block, options)) {
lastCID = c.cid;
}
return lastCID;
}
async function hashFiles(path, options) {
const { globSource } = await import('ipfs-http-client');
options = {
cidVersion: 0, // Lines up with the smart contract code
hidden: true,
...options,
};
const files = globSource(path, '**');
const rootCID = await hash(files, options);
return rootCID;
}
module.exports = {
cidToHex(cid) {
return `0x${Buffer.from(cid.bytes.slice(2)).toString('hex')}`;
},
of: hash,
async ofFile(path) {
return await hashFiles(path, {});
},
async ofDir(path) {
return await hashFiles(path, {
wrapWithDirectory: true,
});
},
}; |
@wjagodfrey Thanks for this fix! I will use it myself. |
It would be great to be able to use this module to do the equivalent of
ipfs add -r --only-hash
.The text was updated successfully, but these errors were encountered: