Add comprehensive installation and setup documentation

- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
This commit is contained in:
Dorian
2026-01-27 17:18:21 +00:00
parent a81f655133
commit 0d073fa89e
22658 changed files with 4494151 additions and 6 deletions
+177
View File
@@ -0,0 +1,177 @@
# ipfs-unixfs
[![ipfs.tech](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.tech)
[![Discuss](https://img.shields.io/discourse/https/discuss.ipfs.tech/posts.svg?style=flat-square)](https://discuss.ipfs.tech)
[![codecov](https://img.shields.io/codecov/c/github/ipfs/js-ipfs-unixfs.svg?style=flat-square)](https://codecov.io/gh/ipfs/js-ipfs-unixfs)
[![CI](https://img.shields.io/github/actions/workflow/status/ipfs/js-ipfs-unixfs/js-test-and-release.yml?branch=main\&style=flat-square)](https://github.com/ipfs/js-ipfs-unixfs/actions/workflows/js-test-and-release.yml?query=branch%3Amain)
> JavaScript implementation of IPFS' unixfs (a Unix FileSystem representation on top of a MerkleDAG)
# About
<!--
!IMPORTANT!
Everything in this README between "# About" and "# Install" is automatically
generated and will be overwritten the next time the doc generator is run.
To make changes to this section, please update the @packageDocumentation section
of src/index.js or src/index.ts
To experiment with formatting, please run "npm run docs" from the root of this
repo and examine the changes made.
-->
This module contains the protobuf definition of the UnixFS data structure found at the root of all UnixFS DAGs.
The UnixFS spec can be found in the [ipfs/specs repository](http://github.com/ipfs/specs)
## Example - Create a file composed of several blocks
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'file' })
data.addBlockSize(256n) // add the size of each block
data.addBlockSize(256n)
// ...
```
## Example - Create a directory that contains several files
Creating a directory that contains several files is achieve by creating a unixfs element that identifies a MerkleDAG node as a directory. The links of that MerkleDAG node are the files that are contained in this directory.
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'directory' })
```
## Example - Create an unixfs Data element
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({
// ...options
})
```
`options` is an optional object argument that might include the following keys:
- type (string, default `file`): The type of UnixFS entry. Can be:
- `raw`
- `directory`
- `file`
- `metadata`
- `symlink`
- `hamt-sharded-directory`
- data (Uint8Array): The optional data field for this node
- blockSizes (Array, default: `[]`): If this is a `file` node that is made up of multiple blocks, `blockSizes` is a list numbers that represent the size of the file chunks stored in each child node. It is used to calculate the total file size.
- mode (Number, default `0644` for files, `0755` for directories/hamt-sharded-directories) file mode
- mtime (`Date`, `{ secs, nsecs }`, `{ Seconds, FractionalNanoseconds }`, `[ secs, nsecs ]`): The modification time of this node
## Example - Add and remove a block size to the block size list
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'file' })
const sizeInBytes = 100n
data.addBlockSize(sizeInBytes)
```
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'file' })
const index = 0
data.removeBlockSize(index)
```
## Example - Get total fileSize
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'file' })
data.fileSize() // => size in bytes
```
## Example - Marshal and unmarshal
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const data = new UnixFS({ type: 'file' })
const marshaled = data.marshal()
const unmarshaled = UnixFS.unmarshal(marshaled)
```
## Example - Is this UnixFS entry a directory?
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const dir = new UnixFS({ type: 'directory' })
dir.isDirectory() // true
const file = new UnixFS({ type: 'file' })
file.isDirectory() // false
```
## Example - Has an mtime been set?
If no modification time has been set, no `mtime` property will be present on the `Data` instance:
```TypeScript
import { UnixFS } from 'ipfs-unixfs'
const file = new UnixFS({ type: 'file' })
file.mtime // undefined
Object.prototype.hasOwnProperty.call(file, 'mtime') // false
const dir = new UnixFS({ type: 'directory', mtime: { secs: 5n } })
dir.mtime // { secs: Number, nsecs: Number }
```
# Install
```console
$ npm i ipfs-unixfs
```
## Browser `<script>` tag
Loading this module through a script tag will make its exports available as `IpfsUnixfs` in the global namespace.
```html
<script src="https://unpkg.com/ipfs-unixfs/dist/index.min.js"></script>
```
# API Docs
- <https://ipfs.github.io/js-ipfs-unixfs/modules/ipfs_unixfs.html>
# License
Licensed under either of
- Apache 2.0, ([LICENSE-APACHE](https://github.com/ipfs/js-ipfs-unixfs/blob/main/packages/ipfs-unixfs/LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](https://github.com/ipfs/js-ipfs-unixfs/blob/main/packages/ipfs-unixfs/LICENSE-MIT) / <http://opensource.org/licenses/MIT>)
# Contribute
Contributions welcome! Please check out [the issues](https://github.com/ipfs/js-ipfs-unixfs/issues).
Also see our [contributing document](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for more information on how we work, and about contributing in general.
Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
export declare class InvalidTypeError extends Error {
static name: string;
static code: string;
name: string;
code: string;
constructor(message?: string);
}
export declare class InvalidUnixFSMessageError extends Error {
static name: string;
static code: string;
name: string;
code: string;
constructor(message?: string);
}
//# sourceMappingURL=errors.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,MAAM,CAAC,IAAI,SAAqB;IAChC,MAAM,CAAC,IAAI,SAAqB;IAChC,IAAI,SAAwB;IAC5B,IAAI,SAAwB;gBAEf,OAAO,SAAiB;CAGtC;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,MAAM,CAAC,IAAI,SAA8B;IACzC,MAAM,CAAC,IAAI,SAAwB;IACnC,IAAI,SAAiC;IACrC,IAAI,SAAiC;gBAExB,OAAO,SAAoB;CAGzC"}
+19
View File
@@ -0,0 +1,19 @@
export class InvalidTypeError extends Error {
static name = 'InvalidTypeError';
static code = 'ERR_INVALID_TYPE';
name = InvalidTypeError.name;
code = InvalidTypeError.code;
constructor(message = 'Invalid type') {
super(message);
}
}
export class InvalidUnixFSMessageError extends Error {
static name = 'InvalidUnixFSMessageError';
static code = 'ERR_INVALID_MESSAGE';
name = InvalidUnixFSMessageError.name;
code = InvalidUnixFSMessageError.code;
constructor(message = 'Invalid message') {
super(message);
}
}
//# sourceMappingURL=errors.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,MAAM,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,MAAM,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAA;IAC5B,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAA;IAE5B,YAAa,OAAO,GAAG,cAAc;QACnC,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;;AAGH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,MAAM,CAAC,IAAI,GAAG,2BAA2B,CAAA;IACzC,MAAM,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAA;IACrC,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAA;IAErC,YAAa,OAAO,GAAG,iBAAiB;QACtC,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC"}
+167
View File
@@ -0,0 +1,167 @@
/**
* @packageDocumentation
*
* This module contains the protobuf definition of the UnixFS data structure found at the root of all UnixFS DAGs.
*
* The UnixFS spec can be found in the [ipfs/specs repository](http://github.com/ipfs/specs)
*
* @example Create a file composed of several blocks
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.addBlockSize(256n) // add the size of each block
* data.addBlockSize(256n)
* // ...
* ```
*
* @example Create a directory that contains several files
*
* Creating a directory that contains several files is achieve by creating a unixfs element that identifies a MerkleDAG node as a directory. The links of that MerkleDAG node are the files that are contained in this directory.
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'directory' })
* ```
*
* @example Create an unixfs Data element
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({
* // ...options
* })
* ```
*
* `options` is an optional object argument that might include the following keys:
*
* - type (string, default `file`): The type of UnixFS entry. Can be:
* - `raw`
* - `directory`
* - `file`
* - `metadata`
* - `symlink`
* - `hamt-sharded-directory`
* - data (Uint8Array): The optional data field for this node
* - blockSizes (Array, default: `[]`): If this is a `file` node that is made up of multiple blocks, `blockSizes` is a list numbers that represent the size of the file chunks stored in each child node. It is used to calculate the total file size.
* - mode (Number, default `0644` for files, `0755` for directories/hamt-sharded-directories) file mode
* - mtime (`Date`, `{ secs, nsecs }`, `{ Seconds, FractionalNanoseconds }`, `[ secs, nsecs ]`): The modification time of this node
*
* @example Add and remove a block size to the block size list
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const sizeInBytes = 100n
* data.addBlockSize(sizeInBytes)
* ```
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
*
* const index = 0
* data.removeBlockSize(index)
* ```
*
* @example Get total fileSize
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.fileSize() // => size in bytes
* ```
*
* @example Marshal and unmarshal
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const marshaled = data.marshal()
* const unmarshaled = UnixFS.unmarshal(marshaled)
* ```
*
* @example Is this UnixFS entry a directory?
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const dir = new UnixFS({ type: 'directory' })
* dir.isDirectory() // true
*
* const file = new UnixFS({ type: 'file' })
* file.isDirectory() // false
* ```
*
* @example Has an mtime been set?
*
* If no modification time has been set, no `mtime` property will be present on the `Data` instance:
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const file = new UnixFS({ type: 'file' })
* file.mtime // undefined
*
* Object.prototype.hasOwnProperty.call(file, 'mtime') // false
*
* const dir = new UnixFS({ type: 'directory', mtime: { secs: 5n } })
* dir.mtime // { secs: Number, nsecs: Number }
* ```
*/
export interface Mtime {
secs: bigint;
nsecs?: number;
}
export type MtimeLike = Mtime | {
Seconds: number;
FractionalNanoseconds?: number;
} | [number, number] | Date;
export type UnixFSType = 'raw' | 'directory' | 'file' | 'metadata' | 'symlink' | 'hamt-sharded-directory';
export interface UnixFSOptions {
type?: UnixFSType;
data?: Uint8Array;
blockSizes?: bigint[];
hashType?: bigint;
fanout?: bigint;
mtime?: Mtime;
mode?: number;
}
declare class UnixFS {
/**
* Decode from protobuf https://github.com/ipfs/specs/blob/master/UNIXFS.md
*/
static unmarshal(marshaled: Uint8Array): UnixFS;
type: string;
data?: Uint8Array;
blockSizes: bigint[];
hashType?: bigint;
fanout?: bigint;
mtime?: Mtime;
private _mode?;
private _originalMode;
constructor(options?: UnixFSOptions);
set mode(mode: number | undefined);
get mode(): number | undefined;
isDirectory(): boolean;
addBlockSize(size: bigint): void;
removeBlockSize(index: number): void;
/**
* Returns `0n` for directories or `data.length + sum(blockSizes)` for everything else
*/
fileSize(): bigint;
/**
* encode to protobuf Uint8Array
*/
marshal(): Uint8Array;
}
export { UnixFS };
export * from './errors.js';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqHG;AAKH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;AAE7G,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,wBAAwB,CAAA;AAsBzG,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,cAAM,MAAM;IACV;;OAEG;IACH,MAAM,CAAC,SAAS,CAAE,SAAS,EAAE,UAAU,GAAG,MAAM;IA2BzC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,KAAK,CAAA;IAEpB,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,aAAa,CAAQ;gBAEhB,OAAO,GAAE,aAErB;IAyBD,IAAI,IAAI,CAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAMjC;IAED,IAAI,IAAI,IAAK,MAAM,GAAG,SAAS,CAE9B;IAED,WAAW,IAAK,OAAO;IAIvB,YAAY,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC,eAAe,CAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,QAAQ,IAAK,MAAM;IAkBnB;;OAEG;IACH,OAAO,IAAK,UAAU;CAsDvB;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,cAAc,aAAa,CAAA"}
+286
View File
@@ -0,0 +1,286 @@
/**
* @packageDocumentation
*
* This module contains the protobuf definition of the UnixFS data structure found at the root of all UnixFS DAGs.
*
* The UnixFS spec can be found in the [ipfs/specs repository](http://github.com/ipfs/specs)
*
* @example Create a file composed of several blocks
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.addBlockSize(256n) // add the size of each block
* data.addBlockSize(256n)
* // ...
* ```
*
* @example Create a directory that contains several files
*
* Creating a directory that contains several files is achieve by creating a unixfs element that identifies a MerkleDAG node as a directory. The links of that MerkleDAG node are the files that are contained in this directory.
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'directory' })
* ```
*
* @example Create an unixfs Data element
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({
* // ...options
* })
* ```
*
* `options` is an optional object argument that might include the following keys:
*
* - type (string, default `file`): The type of UnixFS entry. Can be:
* - `raw`
* - `directory`
* - `file`
* - `metadata`
* - `symlink`
* - `hamt-sharded-directory`
* - data (Uint8Array): The optional data field for this node
* - blockSizes (Array, default: `[]`): If this is a `file` node that is made up of multiple blocks, `blockSizes` is a list numbers that represent the size of the file chunks stored in each child node. It is used to calculate the total file size.
* - mode (Number, default `0644` for files, `0755` for directories/hamt-sharded-directories) file mode
* - mtime (`Date`, `{ secs, nsecs }`, `{ Seconds, FractionalNanoseconds }`, `[ secs, nsecs ]`): The modification time of this node
*
* @example Add and remove a block size to the block size list
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const sizeInBytes = 100n
* data.addBlockSize(sizeInBytes)
* ```
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
*
* const index = 0
* data.removeBlockSize(index)
* ```
*
* @example Get total fileSize
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.fileSize() // => size in bytes
* ```
*
* @example Marshal and unmarshal
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const marshaled = data.marshal()
* const unmarshaled = UnixFS.unmarshal(marshaled)
* ```
*
* @example Is this UnixFS entry a directory?
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const dir = new UnixFS({ type: 'directory' })
* dir.isDirectory() // true
*
* const file = new UnixFS({ type: 'file' })
* file.isDirectory() // false
* ```
*
* @example Has an mtime been set?
*
* If no modification time has been set, no `mtime` property will be present on the `Data` instance:
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const file = new UnixFS({ type: 'file' })
* file.mtime // undefined
*
* Object.prototype.hasOwnProperty.call(file, 'mtime') // false
*
* const dir = new UnixFS({ type: 'directory', mtime: { secs: 5n } })
* dir.mtime // { secs: Number, nsecs: Number }
* ```
*/
import { InvalidTypeError, InvalidUnixFSMessageError } from './errors.js';
import { Data as PBData } from './unixfs.js';
const types = {
Raw: 'raw',
Directory: 'directory',
File: 'file',
Metadata: 'metadata',
Symlink: 'symlink',
HAMTShard: 'hamt-sharded-directory'
};
const dirTypes = [
'directory',
'hamt-sharded-directory'
];
const DEFAULT_FILE_MODE = parseInt('0644', 8);
const DEFAULT_DIRECTORY_MODE = parseInt('0755', 8);
// https://github.com/ipfs/boxo/blob/364c5040ec91ec8e2a61446e9921e9225704c34d/ipld/unixfs/hamt/hamt.go#L778
const MAX_FANOUT = BigInt(1 << 10);
class UnixFS {
/**
* Decode from protobuf https://github.com/ipfs/specs/blob/master/UNIXFS.md
*/
static unmarshal(marshaled) {
const message = PBData.decode(marshaled);
if (message.fanout != null && message.fanout > MAX_FANOUT) {
throw new InvalidUnixFSMessageError(`Fanout size was too large - ${message.fanout} > ${MAX_FANOUT}`);
}
const data = new UnixFS({
type: types[message.Type != null ? message.Type.toString() : 'File'],
data: message.Data,
blockSizes: message.blocksizes,
mode: message.mode,
mtime: message.mtime != null
? {
secs: message.mtime.Seconds ?? 0n,
nsecs: message.mtime.FractionalNanoseconds
}
: undefined,
fanout: message.fanout
});
// make sure we honour the original mode
data._originalMode = message.mode ?? 0;
return data;
}
type;
data;
blockSizes;
hashType;
fanout;
mtime;
_mode;
_originalMode;
constructor(options = {
type: 'file'
}) {
const { type, data, blockSizes, hashType, fanout, mtime, mode } = options;
if (type != null && !Object.values(types).includes(type)) {
throw new InvalidTypeError('Type: ' + type + ' is not valid');
}
this.type = type ?? 'file';
this.data = data;
this.hashType = hashType;
this.fanout = fanout;
this.blockSizes = blockSizes ?? [];
this._originalMode = 0;
this.mode = mode;
this.mtime = mtime;
}
set mode(mode) {
if (mode == null) {
this._mode = this.isDirectory() ? DEFAULT_DIRECTORY_MODE : DEFAULT_FILE_MODE;
}
else {
this._mode = (mode & 0xFFF);
}
}
get mode() {
return this._mode;
}
isDirectory() {
return dirTypes.includes(this.type);
}
addBlockSize(size) {
this.blockSizes.push(size);
}
removeBlockSize(index) {
this.blockSizes.splice(index, 1);
}
/**
* Returns `0n` for directories or `data.length + sum(blockSizes)` for everything else
*/
fileSize() {
if (this.isDirectory()) {
// dirs don't have file size
return 0n;
}
let sum = 0n;
this.blockSizes.forEach((size) => {
sum += size;
});
if (this.data != null) {
sum += BigInt(this.data.length);
}
return sum;
}
/**
* encode to protobuf Uint8Array
*/
marshal() {
let type;
switch (this.type) {
case 'raw':
type = PBData.DataType.Raw;
break;
case 'directory':
type = PBData.DataType.Directory;
break;
case 'file':
type = PBData.DataType.File;
break;
case 'metadata':
type = PBData.DataType.Metadata;
break;
case 'symlink':
type = PBData.DataType.Symlink;
break;
case 'hamt-sharded-directory':
type = PBData.DataType.HAMTShard;
break;
default:
throw new InvalidTypeError(`Type: ${type} is not valid`);
}
let data = this.data;
if (this.data == null || this.data.length === 0) {
data = undefined;
}
let mode;
if (this.mode != null) {
mode = (this._originalMode & 0xFFFFF000) | (this.mode ?? 0);
if (mode === DEFAULT_FILE_MODE && !this.isDirectory()) {
mode = undefined;
}
if (mode === DEFAULT_DIRECTORY_MODE && this.isDirectory()) {
mode = undefined;
}
}
let mtime;
if (this.mtime != null) {
mtime = {
Seconds: this.mtime.secs,
FractionalNanoseconds: this.mtime.nsecs
};
}
return PBData.encode({
Type: type,
Data: data,
filesize: this.isDirectory() ? undefined : this.fileSize(),
blocksizes: this.blockSizes,
hashType: this.hashType,
fanout: this.fanout,
mode,
mtime
});
}
}
export { UnixFS };
export * from './errors.js';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
+46
View File
@@ -0,0 +1,46 @@
import type { Codec } from 'protons-runtime';
import type { Uint8ArrayList } from 'uint8arraylist';
export interface Data {
Type?: Data.DataType;
Data?: Uint8Array;
filesize?: bigint;
blocksizes: bigint[];
hashType?: bigint;
fanout?: bigint;
mode?: number;
mtime?: UnixTime;
}
export declare namespace Data {
enum DataType {
Raw = "Raw",
Directory = "Directory",
File = "File",
Metadata = "Metadata",
Symlink = "Symlink",
HAMTShard = "HAMTShard"
}
namespace DataType {
const codec: () => Codec<DataType>;
}
const codec: () => Codec<Data>;
const encode: (obj: Partial<Data>) => Uint8Array;
const decode: (buf: Uint8Array | Uint8ArrayList) => Data;
}
export interface UnixTime {
Seconds?: bigint;
FractionalNanoseconds?: number;
}
export declare namespace UnixTime {
const codec: () => Codec<UnixTime>;
const encode: (obj: Partial<UnixTime>) => Uint8Array;
const decode: (buf: Uint8Array | Uint8ArrayList) => UnixTime;
}
export interface Metadata {
MimeType?: string;
}
export declare namespace Metadata {
const codec: () => Codec<Metadata>;
const encode: (obj: Partial<Metadata>) => Uint8Array;
const decode: (buf: Uint8Array | Uint8ArrayList) => Metadata;
}
//# sourceMappingURL=unixfs.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"unixfs.d.ts","sourceRoot":"","sources":["../../src/unixfs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,WAAW,IAAI;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAA;IACpB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,QAAQ,CAAA;CACjB;AAED,yBAAiB,IAAI,CAAC;IACpB,KAAY,QAAQ;QAClB,GAAG,QAAQ;QACX,SAAS,cAAc;QACvB,IAAI,SAAS;QACb,QAAQ,aAAa;QACrB,OAAO,YAAY;QACnB,SAAS,cAAc;KACxB;IAWD,UAAiB,QAAQ,CAAC;QACjB,MAAM,KAAK,QAAO,KAAK,CAAC,QAAQ,CAEtC,CAAA;KACF;IAIM,MAAM,KAAK,QAAO,KAAK,CAAC,IAAI,CAkGlC,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,UAE3C,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,UAAU,GAAG,cAAc,KAAG,IAEzD,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,yBAAiB,QAAQ,CAAC;IAGjB,MAAM,KAAK,QAAO,KAAK,CAAC,QAAQ,CA8CtC,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAG,UAE/C,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,UAAU,GAAG,cAAc,KAAG,QAEzD,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,yBAAiB,QAAQ,CAAC;IAGjB,MAAM,KAAK,QAAO,KAAK,CAAC,QAAQ,CAsCtC,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAG,UAE/C,CAAA;IAEM,MAAM,MAAM,GAAI,KAAK,UAAU,GAAG,cAAc,KAAG,QAEzD,CAAA;CACF"}
+211
View File
@@ -0,0 +1,211 @@
import { enumeration, encodeMessage, decodeMessage, message } from 'protons-runtime';
export var Data;
(function (Data) {
let DataType;
(function (DataType) {
DataType["Raw"] = "Raw";
DataType["Directory"] = "Directory";
DataType["File"] = "File";
DataType["Metadata"] = "Metadata";
DataType["Symlink"] = "Symlink";
DataType["HAMTShard"] = "HAMTShard";
})(DataType = Data.DataType || (Data.DataType = {}));
let __DataTypeValues;
(function (__DataTypeValues) {
__DataTypeValues[__DataTypeValues["Raw"] = 0] = "Raw";
__DataTypeValues[__DataTypeValues["Directory"] = 1] = "Directory";
__DataTypeValues[__DataTypeValues["File"] = 2] = "File";
__DataTypeValues[__DataTypeValues["Metadata"] = 3] = "Metadata";
__DataTypeValues[__DataTypeValues["Symlink"] = 4] = "Symlink";
__DataTypeValues[__DataTypeValues["HAMTShard"] = 5] = "HAMTShard";
})(__DataTypeValues || (__DataTypeValues = {}));
(function (DataType) {
DataType.codec = () => {
return enumeration(__DataTypeValues);
};
})(DataType = Data.DataType || (Data.DataType = {}));
let _codec;
Data.codec = () => {
if (_codec == null) {
_codec = message((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork();
}
if (obj.Type != null) {
w.uint32(8);
Data.DataType.codec().encode(obj.Type, w);
}
if (obj.Data != null) {
w.uint32(18);
w.bytes(obj.Data);
}
if (obj.filesize != null) {
w.uint32(24);
w.uint64(obj.filesize);
}
if (obj.blocksizes != null) {
for (const value of obj.blocksizes) {
w.uint32(32);
w.uint64(value);
}
}
if (obj.hashType != null) {
w.uint32(40);
w.uint64(obj.hashType);
}
if (obj.fanout != null) {
w.uint32(48);
w.uint64(obj.fanout);
}
if (obj.mode != null) {
w.uint32(56);
w.uint32(obj.mode);
}
if (obj.mtime != null) {
w.uint32(66);
UnixTime.codec().encode(obj.mtime, w);
}
if (opts.lengthDelimited !== false) {
w.ldelim();
}
}, (reader, length) => {
const obj = {
blocksizes: []
};
const end = length == null ? reader.len : reader.pos + length;
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
obj.Type = Data.DataType.codec().decode(reader);
break;
case 2:
obj.Data = reader.bytes();
break;
case 3:
obj.filesize = reader.uint64();
break;
case 4:
obj.blocksizes.push(reader.uint64());
break;
case 5:
obj.hashType = reader.uint64();
break;
case 6:
obj.fanout = reader.uint64();
break;
case 7:
obj.mode = reader.uint32();
break;
case 8:
obj.mtime = UnixTime.codec().decode(reader, reader.uint32());
break;
default:
reader.skipType(tag & 7);
break;
}
}
return obj;
});
}
return _codec;
};
Data.encode = (obj) => {
return encodeMessage(obj, Data.codec());
};
Data.decode = (buf) => {
return decodeMessage(buf, Data.codec());
};
})(Data || (Data = {}));
export var UnixTime;
(function (UnixTime) {
let _codec;
UnixTime.codec = () => {
if (_codec == null) {
_codec = message((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork();
}
if (obj.Seconds != null) {
w.uint32(8);
w.int64(obj.Seconds);
}
if (obj.FractionalNanoseconds != null) {
w.uint32(21);
w.fixed32(obj.FractionalNanoseconds);
}
if (opts.lengthDelimited !== false) {
w.ldelim();
}
}, (reader, length) => {
const obj = {};
const end = length == null ? reader.len : reader.pos + length;
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
obj.Seconds = reader.int64();
break;
case 2:
obj.FractionalNanoseconds = reader.fixed32();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return obj;
});
}
return _codec;
};
UnixTime.encode = (obj) => {
return encodeMessage(obj, UnixTime.codec());
};
UnixTime.decode = (buf) => {
return decodeMessage(buf, UnixTime.codec());
};
})(UnixTime || (UnixTime = {}));
export var Metadata;
(function (Metadata) {
let _codec;
Metadata.codec = () => {
if (_codec == null) {
_codec = message((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork();
}
if (obj.MimeType != null) {
w.uint32(10);
w.string(obj.MimeType);
}
if (opts.lengthDelimited !== false) {
w.ldelim();
}
}, (reader, length) => {
const obj = {};
const end = length == null ? reader.len : reader.pos + length;
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
obj.MimeType = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return obj;
});
}
return _codec;
};
Metadata.encode = (obj) => {
return encodeMessage(obj, Metadata.codec());
};
Metadata.decode = (buf) => {
return decodeMessage(buf, Metadata.codec());
};
})(Metadata || (Metadata = {}));
//# sourceMappingURL=unixfs.js.map
File diff suppressed because one or more lines are too long
+14
View File
@@ -0,0 +1,14 @@
{
"InvalidTypeError": "https://ipfs.github.io/js-ipfs-unixfs/classes/ipfs-unixfs.InvalidTypeError.html",
"InvalidUnixFSMessageError": "https://ipfs.github.io/js-ipfs-unixfs/classes/ipfs-unixfs.InvalidUnixFSMessageError.html",
"UnixFS": "https://ipfs.github.io/js-ipfs-unixfs/classes/ipfs-unixfs.UnixFS.html",
".:UnixFS": "https://ipfs.github.io/js-ipfs-unixfs/classes/ipfs-unixfs.UnixFS.html",
"Mtime": "https://ipfs.github.io/js-ipfs-unixfs/interfaces/ipfs-unixfs.Mtime.html",
".:Mtime": "https://ipfs.github.io/js-ipfs-unixfs/interfaces/ipfs-unixfs.Mtime.html",
"UnixFSOptions": "https://ipfs.github.io/js-ipfs-unixfs/interfaces/ipfs-unixfs.UnixFSOptions.html",
".:UnixFSOptions": "https://ipfs.github.io/js-ipfs-unixfs/interfaces/ipfs-unixfs.UnixFSOptions.html",
"MtimeLike": "https://ipfs.github.io/js-ipfs-unixfs/types/ipfs-unixfs.MtimeLike.html",
".:MtimeLike": "https://ipfs.github.io/js-ipfs-unixfs/types/ipfs-unixfs.MtimeLike.html",
"UnixFSType": "https://ipfs.github.io/js-ipfs-unixfs/types/ipfs-unixfs.UnixFSType.html",
".:UnixFSType": "https://ipfs.github.io/js-ipfs-unixfs/types/ipfs-unixfs.UnixFSType.html"
}
+154
View File
@@ -0,0 +1,154 @@
{
"name": "ipfs-unixfs",
"version": "11.2.5",
"description": "JavaScript implementation of IPFS' unixfs (a Unix FileSystem representation on top of a MerkleDAG)",
"license": "Apache-2.0 OR MIT",
"homepage": "https://github.com/ipfs/js-ipfs-unixfs/tree/main/packages/ipfs-unixfs#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/ipfs/js-ipfs-unixfs.git"
},
"bugs": {
"url": "https://github.com/ipfs/js-ipfs-unixfs/issues"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"keywords": [
"IPFS"
],
"type": "module",
"types": "./dist/src/index.d.ts",
"files": [
"src",
"dist",
"!dist/test",
"!**/*.tsbuildinfo"
],
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/src/index.js"
}
},
"release": {
"branches": [
"main"
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"releaseRules": [
{
"breaking": true,
"release": "major"
},
{
"revert": true,
"release": "patch"
},
{
"type": "feat",
"release": "minor"
},
{
"type": "fix",
"release": "patch"
},
{
"type": "docs",
"release": "patch"
},
{
"type": "test",
"release": "patch"
},
{
"type": "deps",
"release": "patch"
},
{
"scope": "no-release",
"release": false
}
]
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "conventionalcommits",
"presetConfig": {
"types": [
{
"type": "feat",
"section": "Features"
},
{
"type": "fix",
"section": "Bug Fixes"
},
{
"type": "chore",
"section": "Trivial Changes"
},
{
"type": "docs",
"section": "Documentation"
},
{
"type": "deps",
"section": "Dependencies"
},
{
"type": "test",
"section": "Tests"
}
]
}
}
],
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md",
"package.json"
]
}
]
]
},
"scripts": {
"generate": "protons src/unixfs.proto",
"test": "aegir test",
"test:node": "aegir test -t node --cov",
"test:chrome": "aegir test -t browser --cov",
"test:firefox": "aegir test -t browser -- --browser firefox",
"build": "aegir build",
"clean": "aegir clean",
"lint": "aegir lint",
"dep-check": "aegir dep-check",
"doc-check": "aegir doc-check",
"release": "aegir release"
},
"dependencies": {
"protons-runtime": "^5.5.0",
"uint8arraylist": "^2.4.8"
},
"devDependencies": {
"aegir": "^47.0.16",
"protons": "^7.6.1",
"uint8arrays": "^5.1.0"
},
"browser": {
"fs": false
},
"sideEffects": false
}
+21
View File
@@ -0,0 +1,21 @@
export class InvalidTypeError extends Error {
static name = 'InvalidTypeError'
static code = 'ERR_INVALID_TYPE'
name = InvalidTypeError.name
code = InvalidTypeError.code
constructor (message = 'Invalid type') {
super(message)
}
}
export class InvalidUnixFSMessageError extends Error {
static name = 'InvalidUnixFSMessageError'
static code = 'ERR_INVALID_MESSAGE'
name = InvalidUnixFSMessageError.name
code = InvalidUnixFSMessageError.code
constructor (message = 'Invalid message') {
super(message)
}
}
+335
View File
@@ -0,0 +1,335 @@
/**
* @packageDocumentation
*
* This module contains the protobuf definition of the UnixFS data structure found at the root of all UnixFS DAGs.
*
* The UnixFS spec can be found in the [ipfs/specs repository](http://github.com/ipfs/specs)
*
* @example Create a file composed of several blocks
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.addBlockSize(256n) // add the size of each block
* data.addBlockSize(256n)
* // ...
* ```
*
* @example Create a directory that contains several files
*
* Creating a directory that contains several files is achieve by creating a unixfs element that identifies a MerkleDAG node as a directory. The links of that MerkleDAG node are the files that are contained in this directory.
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'directory' })
* ```
*
* @example Create an unixfs Data element
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({
* // ...options
* })
* ```
*
* `options` is an optional object argument that might include the following keys:
*
* - type (string, default `file`): The type of UnixFS entry. Can be:
* - `raw`
* - `directory`
* - `file`
* - `metadata`
* - `symlink`
* - `hamt-sharded-directory`
* - data (Uint8Array): The optional data field for this node
* - blockSizes (Array, default: `[]`): If this is a `file` node that is made up of multiple blocks, `blockSizes` is a list numbers that represent the size of the file chunks stored in each child node. It is used to calculate the total file size.
* - mode (Number, default `0644` for files, `0755` for directories/hamt-sharded-directories) file mode
* - mtime (`Date`, `{ secs, nsecs }`, `{ Seconds, FractionalNanoseconds }`, `[ secs, nsecs ]`): The modification time of this node
*
* @example Add and remove a block size to the block size list
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const sizeInBytes = 100n
* data.addBlockSize(sizeInBytes)
* ```
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
*
* const index = 0
* data.removeBlockSize(index)
* ```
*
* @example Get total fileSize
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* data.fileSize() // => size in bytes
* ```
*
* @example Marshal and unmarshal
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const data = new UnixFS({ type: 'file' })
* const marshaled = data.marshal()
* const unmarshaled = UnixFS.unmarshal(marshaled)
* ```
*
* @example Is this UnixFS entry a directory?
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const dir = new UnixFS({ type: 'directory' })
* dir.isDirectory() // true
*
* const file = new UnixFS({ type: 'file' })
* file.isDirectory() // false
* ```
*
* @example Has an mtime been set?
*
* If no modification time has been set, no `mtime` property will be present on the `Data` instance:
*
* ```TypeScript
* import { UnixFS } from 'ipfs-unixfs'
*
* const file = new UnixFS({ type: 'file' })
* file.mtime // undefined
*
* Object.prototype.hasOwnProperty.call(file, 'mtime') // false
*
* const dir = new UnixFS({ type: 'directory', mtime: { secs: 5n } })
* dir.mtime // { secs: Number, nsecs: Number }
* ```
*/
import { InvalidTypeError, InvalidUnixFSMessageError } from './errors.js'
import { Data as PBData } from './unixfs.js'
export interface Mtime {
secs: bigint
nsecs?: number
}
export type MtimeLike = Mtime | { Seconds: number, FractionalNanoseconds?: number } | [number, number] | Date
export type UnixFSType = 'raw' | 'directory' | 'file' | 'metadata' | 'symlink' | 'hamt-sharded-directory'
const types: Record<string, UnixFSType> = {
Raw: 'raw',
Directory: 'directory',
File: 'file',
Metadata: 'metadata',
Symlink: 'symlink',
HAMTShard: 'hamt-sharded-directory'
}
const dirTypes = [
'directory',
'hamt-sharded-directory'
]
const DEFAULT_FILE_MODE = parseInt('0644', 8)
const DEFAULT_DIRECTORY_MODE = parseInt('0755', 8)
// https://github.com/ipfs/boxo/blob/364c5040ec91ec8e2a61446e9921e9225704c34d/ipld/unixfs/hamt/hamt.go#L778
const MAX_FANOUT = BigInt(1 << 10)
export interface UnixFSOptions {
type?: UnixFSType
data?: Uint8Array
blockSizes?: bigint[]
hashType?: bigint
fanout?: bigint
mtime?: Mtime
mode?: number
}
class UnixFS {
/**
* Decode from protobuf https://github.com/ipfs/specs/blob/master/UNIXFS.md
*/
static unmarshal (marshaled: Uint8Array): UnixFS {
const message = PBData.decode(marshaled)
if (message.fanout != null && message.fanout > MAX_FANOUT) {
throw new InvalidUnixFSMessageError(`Fanout size was too large - ${message.fanout} > ${MAX_FANOUT}`)
}
const data = new UnixFS({
type: types[message.Type != null ? message.Type.toString() : 'File'],
data: message.Data,
blockSizes: message.blocksizes,
mode: message.mode,
mtime: message.mtime != null
? {
secs: message.mtime.Seconds ?? 0n,
nsecs: message.mtime.FractionalNanoseconds
}
: undefined,
fanout: message.fanout
})
// make sure we honour the original mode
data._originalMode = message.mode ?? 0
return data
}
public type: string
public data?: Uint8Array
public blockSizes: bigint[]
public hashType?: bigint
public fanout?: bigint
public mtime?: Mtime
private _mode?: number
private _originalMode: number
constructor (options: UnixFSOptions = {
type: 'file'
}) {
const {
type,
data,
blockSizes,
hashType,
fanout,
mtime,
mode
} = options
if (type != null && !Object.values(types).includes(type)) {
throw new InvalidTypeError('Type: ' + type + ' is not valid')
}
this.type = type ?? 'file'
this.data = data
this.hashType = hashType
this.fanout = fanout
this.blockSizes = blockSizes ?? []
this._originalMode = 0
this.mode = mode
this.mtime = mtime
}
set mode (mode: number | undefined) {
if (mode == null) {
this._mode = this.isDirectory() ? DEFAULT_DIRECTORY_MODE : DEFAULT_FILE_MODE
} else {
this._mode = (mode & 0xFFF)
}
}
get mode (): number | undefined {
return this._mode
}
isDirectory (): boolean {
return dirTypes.includes(this.type)
}
addBlockSize (size: bigint): void {
this.blockSizes.push(size)
}
removeBlockSize (index: number): void {
this.blockSizes.splice(index, 1)
}
/**
* Returns `0n` for directories or `data.length + sum(blockSizes)` for everything else
*/
fileSize (): bigint {
if (this.isDirectory()) {
// dirs don't have file size
return 0n
}
let sum = 0n
this.blockSizes.forEach((size) => {
sum += size
})
if (this.data != null) {
sum += BigInt(this.data.length)
}
return sum
}
/**
* encode to protobuf Uint8Array
*/
marshal (): Uint8Array {
let type
switch (this.type) {
case 'raw': type = PBData.DataType.Raw; break
case 'directory': type = PBData.DataType.Directory; break
case 'file': type = PBData.DataType.File; break
case 'metadata': type = PBData.DataType.Metadata; break
case 'symlink': type = PBData.DataType.Symlink; break
case 'hamt-sharded-directory': type = PBData.DataType.HAMTShard; break
default:
throw new InvalidTypeError(`Type: ${type} is not valid`)
}
let data = this.data
if (this.data == null || this.data.length === 0) {
data = undefined
}
let mode
if (this.mode != null) {
mode = (this._originalMode & 0xFFFFF000) | (this.mode ?? 0)
if (mode === DEFAULT_FILE_MODE && !this.isDirectory()) {
mode = undefined
}
if (mode === DEFAULT_DIRECTORY_MODE && this.isDirectory()) {
mode = undefined
}
}
let mtime
if (this.mtime != null) {
mtime = {
Seconds: this.mtime.secs,
FractionalNanoseconds: this.mtime.nsecs
}
}
return PBData.encode({
Type: type,
Data: data,
filesize: this.isDirectory() ? undefined : this.fileSize(),
blocksizes: this.blockSizes,
hashType: this.hashType,
fanout: this.fanout,
mode,
mtime
})
}
}
export { UnixFS }
export * from './errors.js'
+30
View File
@@ -0,0 +1,30 @@
syntax = "proto3";
message Data {
enum DataType {
Raw = 0;
Directory = 1;
File = 2;
Metadata = 3;
Symlink = 4;
HAMTShard = 5;
}
optional DataType Type = 1;
optional bytes Data = 2;
optional uint64 filesize = 3;
repeated uint64 blocksizes = 4;
optional uint64 hashType = 5;
optional uint64 fanout = 6;
optional uint32 mode = 7;
optional UnixTime mtime = 8;
}
message UnixTime {
optional int64 Seconds = 1;
optional fixed32 FractionalNanoseconds = 2;
}
message Metadata {
optional string MimeType = 1;
}
+271
View File
@@ -0,0 +1,271 @@
import { enumeration, encodeMessage, decodeMessage, message } from 'protons-runtime'
import type { Codec } from 'protons-runtime'
import type { Uint8ArrayList } from 'uint8arraylist'
export interface Data {
Type?: Data.DataType
Data?: Uint8Array
filesize?: bigint
blocksizes: bigint[]
hashType?: bigint
fanout?: bigint
mode?: number
mtime?: UnixTime
}
export namespace Data {
export enum DataType {
Raw = 'Raw',
Directory = 'Directory',
File = 'File',
Metadata = 'Metadata',
Symlink = 'Symlink',
HAMTShard = 'HAMTShard'
}
enum __DataTypeValues {
Raw = 0,
Directory = 1,
File = 2,
Metadata = 3,
Symlink = 4,
HAMTShard = 5
}
export namespace DataType {
export const codec = (): Codec<DataType> => {
return enumeration<DataType>(__DataTypeValues)
}
}
let _codec: Codec<Data>
export const codec = (): Codec<Data> => {
if (_codec == null) {
_codec = message<Data>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if (obj.Type != null) {
w.uint32(8)
Data.DataType.codec().encode(obj.Type, w)
}
if (obj.Data != null) {
w.uint32(18)
w.bytes(obj.Data)
}
if (obj.filesize != null) {
w.uint32(24)
w.uint64(obj.filesize)
}
if (obj.blocksizes != null) {
for (const value of obj.blocksizes) {
w.uint32(32)
w.uint64(value)
}
}
if (obj.hashType != null) {
w.uint32(40)
w.uint64(obj.hashType)
}
if (obj.fanout != null) {
w.uint32(48)
w.uint64(obj.fanout)
}
if (obj.mode != null) {
w.uint32(56)
w.uint32(obj.mode)
}
if (obj.mtime != null) {
w.uint32(66)
UnixTime.codec().encode(obj.mtime, w)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length) => {
const obj: any = {
blocksizes: []
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1:
obj.Type = Data.DataType.codec().decode(reader)
break
case 2:
obj.Data = reader.bytes()
break
case 3:
obj.filesize = reader.uint64()
break
case 4:
obj.blocksizes.push(reader.uint64())
break
case 5:
obj.hashType = reader.uint64()
break
case 6:
obj.fanout = reader.uint64()
break
case 7:
obj.mode = reader.uint32()
break
case 8:
obj.mtime = UnixTime.codec().decode(reader, reader.uint32())
break
default:
reader.skipType(tag & 7)
break
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<Data>): Uint8Array => {
return encodeMessage(obj, Data.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList): Data => {
return decodeMessage(buf, Data.codec())
}
}
export interface UnixTime {
Seconds?: bigint
FractionalNanoseconds?: number
}
export namespace UnixTime {
let _codec: Codec<UnixTime>
export const codec = (): Codec<UnixTime> => {
if (_codec == null) {
_codec = message<UnixTime>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if (obj.Seconds != null) {
w.uint32(8)
w.int64(obj.Seconds)
}
if (obj.FractionalNanoseconds != null) {
w.uint32(21)
w.fixed32(obj.FractionalNanoseconds)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length) => {
const obj: any = {}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1:
obj.Seconds = reader.int64()
break
case 2:
obj.FractionalNanoseconds = reader.fixed32()
break
default:
reader.skipType(tag & 7)
break
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<UnixTime>): Uint8Array => {
return encodeMessage(obj, UnixTime.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList): UnixTime => {
return decodeMessage(buf, UnixTime.codec())
}
}
export interface Metadata {
MimeType?: string
}
export namespace Metadata {
let _codec: Codec<Metadata>
export const codec = (): Codec<Metadata> => {
if (_codec == null) {
_codec = message<Metadata>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if (obj.MimeType != null) {
w.uint32(10)
w.string(obj.MimeType)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length) => {
const obj: any = {}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1:
obj.MimeType = reader.string()
break
default:
reader.skipType(tag & 7)
break
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<Metadata>): Uint8Array => {
return encodeMessage(obj, Metadata.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList): Metadata => {
return decodeMessage(buf, Metadata.codec())
}
}