Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8183f13
refactor how create new object content works
marcolarosa Oct 15, 2019
7239375
bugfix namaste naming
marcolarosa Oct 15, 2019
c65e4fd
prettier formatting; augment constructure to handle id's
marcolarosa Nov 21, 2019
af1f644
reimplement load
marcolarosa Nov 22, 2019
d2ca071
simplify api - remove get current version - not required
marcolarosa Nov 22, 2019
9c331b4
clone the state when returning so we don't mutate it
marcolarosa Nov 22, 2019
5c9a098
rewire to use local mocha - not global
marcolarosa Nov 22, 2019
d9361fa
simplify - no need for this many files and it makes testing difficult
marcolarosa Nov 29, 2019
8037286
create a simple ocfl object to use in testing
marcolarosa Nov 30, 2019
48b4370
Totally rethink ocflObject and associated tests
marcolarosa Nov 30, 2019
6779a8e
simplify test-data
marcolarosa Nov 30, 2019
c9d93e4
comment it out - not sure what this one is for
marcolarosa Nov 30, 2019
6986caf
add test to confirm update fails when object already in deposit
marcolarosa Nov 30, 2019
d0cf77e
add more comments to explain; propagate errors up through update
marcolarosa Nov 30, 2019
482f098
implement object initialisation via a path to the object
marcolarosa Nov 30, 2019
195b209
use repository.objectIdToPath in init
marcolarosa Nov 30, 2019
9ee42ac
implement check to ensure objects are not children of other objects
marcolarosa Nov 30, 2019
d8dcbe0
refactor
marcolarosa Nov 30, 2019
e383f3d
reimplement repository - cleanup and simplify
marcolarosa Dec 1, 2019
8cbaf91
implement object export capability
marcolarosa Dec 1, 2019
ae13965
pluralise
marcolarosa Dec 1, 2019
bfef2c3
convert to async function call
marcolarosa Dec 1, 2019
009914a
write documentation
marcolarosa Dec 1, 2019
3ef2066
add verify method hook and note about auto-gen id's
marcolarosa Dec 1, 2019
c6b53ec
rework repository to extend event emitter
marcolarosa Dec 1, 2019
6d7eec7
implement method to resolve file path relative to object root
marcolarosa Dec 1, 2019
5f3cd02
add help about resolve file path
marcolarosa Dec 1, 2019
801fefb
on update load the object and latest version and return
marcolarosa Dec 1, 2019
6a3f420
add note to about loading latest version state
marcolarosa Dec 1, 2019
e514bcf
simplify - update doesn't need the extra promise
marcolarosa Dec 4, 2019
2e045da
make deposit and backup paths single folder
marcolarosa Jan 13, 2020
228f679
fix test name
marcolarosa Jan 13, 2020
7ab1ea1
print deposit path so we know which object is already there
marcolarosa Jan 22, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
255 changes: 233 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
- [About](#about)
- [Audience](#audience)
- [Status](#status)
- [Installation](#installation)
- [Install via git](#install-via-git)
- [Overview](#overview)
- [API](#api)
- [Repository](#repository)
- [Creating a repository](#creating-a-repository)
- [Check if path is a repository](#check-if-path-is-a-repository)
- [Find objects in a repository - THIS IS AN EVENT EMITTER](#find-objects-in-a-repository---this-is-an-event-emitter)
- [OCFL Object](#ocfl-object)
- [Create an object with an ID - ingest a folder](#create-an-object-with-an-id---ingest-a-folder)
- [Create an object with a path](#create-an-object-with-a-path)
- [Create an object with an ID - pass in a callback that will write to deposit path](#create-an-object-with-an-id---pass-in-a-callback-that-will-write-to-deposit-path)
- [Check if object exists at path](#check-if-object-exists-at-path)
- [Check if object can be created in the repo at path](#check-if-object-can-be-created-in-the-repo-at-path)
- [Load an object and getLatestInventory](#load-an-object-and-getlatestinventory)
- [Get object versions](#get-object-versions)
- [Load object and get information from it](#load-object-and-get-information-from-it)
- [Resolve file path relative to object root](#resolve-file-path-relative-to-object-root)
- [Export an object](#export-an-object)
- [Remove an object](#remove-an-object)

# About

This is a pre-alpha nodejs library implement the (emerging) Oxford Common File Layout specification.
Expand All @@ -13,40 +37,227 @@ and [demo](./demo.js) script show how to use the library.
This is pre-alpha code which works but is not a complete implementation of the spec.

What's working:
- Initialising a new (in an exsiting empty directory) or existing OCFL repository of version 1.0.
- Adding content from a directory to the the repository with an ID - the repository can store OCFL objects using Pairtree.
- Adding a new version of an object be inporting a new directory with the same ID.
- List all objects

- Initialising a new (in an exsiting empty directory) or existing OCFL repository of version 1.0.
- Adding content from a directory to the the repository with an ID - the repository can store OCFL objects using Pairtree.
- Adding a new version of an object be inporting a new directory with the same ID.
- List all objects

# Installation

## Install via git

1. Get the code:
```git clone https://github.com/UTS-eResearch/ocfl-js.git```
`git clone https://github.com/UTS-eResearch/ocfl-js.git`
2. Install it
```
cd ocfl-js
npm install .
```
3. Check that it works, but running the the tests
```
mocha
```
```
cd ocfl-js
npm install .
```
3. Check that it works, by running the tests
```
npm run tests
```

Running the tests will create an example repository in ./test-data called `ocfl1` with a single item in it with 4 versions.

# Overview

There are two main entry points - Repository and OcflObject. Repository is used to create a repository and
find objects within a repository whilst OcflObject encapsulates all operations of an object such that it can be used
standalone to the Repository (if you have an object in a path somewhere but there is no actual repo).

# API

## Repository

### Creating a repository

```
// ensure the target folder for the repo exists
if (!await fs.exists(ocflRoot)) await fs.mkdirp(ocflRoot);

// define the repo
repository = new Repository({ ocflRoot: 'some path' });

// create it
await repository.create())
```

### Check if path is a repository

```
// define the repo
repository = new Repository({ ocflRoot: 'some path' });

// check for namaste file and return true or false
await repository.isRepository()
```

### Find objects in a repository - THIS IS AN EVENT EMITTER

```
// define the repo
repository = new Repository({ ocflRoot: 'some path' });

// find objects
repository.findObjects({});

// register with the 'object' event
repository.on("object", object=> {
console.log(object)
// returns an object that can be used in the constructor for OcflObject
});
```

## OCFL Object

General note: `update` will load the object and latest version state and return that
on successful update so you will automatically have the current internal file state
available.

### Create an object with an ID - ingest a folder

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// create (v1) or update object with content at `source`
await object.update({ source: '/path/to/some/content' });

// add some data to content at `source`

// update object with content at `source` - v2
await object.update({ source: '/path/to/some/content' });

```

### Create an object with a path

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', objectPath: '/path/to/object' });

```

### Create an object with an ID - pass in a callback that will write to deposit path

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// create (v1) or update object with content at `source`
await object.update({ writer: writeContent });

async function writeContent({ target }) {
for (let file of files ) {
await // write file to target (DEPOSIT PATH)
}
}

```

### Check if object exists at path

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

await object.isObject()
```

### Check if object can be created in the repo at path

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

await object.isAvailable()
```

### Load an object and getLatestInventory

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// load the object
await object.load();

// get the latestInventory
const inventory = await object.getLatestInventory();
```

### Get object versions

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// load the object
await object.load()

// get the versions of the object
let versions = object.getVersions()
```

### Load object and get information from it

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// load the object
await object.load()

// get latest inventory
let r = await object.getLatestInventory()

// get latest version state (the manifest of files for that version)
let r = await object.getLatestVersion()

// get specific version inventory
let r = await object.getInventory({version: 'v2'})

// get specific version state
let r = await object.getVersion({version: 'v2'})

// load all version states in one hit - COULD BE VERY EXPENSIVE
await object.getAllVersions()
```

### Resolve file path relative to object root

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// resolve a path relative to the object root
file = object.resolveFilePath({ filePath: 'relative/path/to/file})

// returns a full path to the object relative to ocflRoot
```

### Export an object

```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

// export it
await object.export({target: '/path/to/export/folder' })

## What we've got so far
// OR export a specific version of the object
await object.export({target: '/path/to/export/folder', version: 'v2' })

Some tests. Run them with:
mocha
```

A [demo](./demo.js) script that shows usage - how to intialise a repository (in
an empty directory) and add some simple file based content, then export all (two
of) the objects in the repository in all their versions.
### Remove an object

Run the demo by typing:
node demo.js
```
// define the object
let object = new OcflObject({ ocflRoot: 'some-path', id: 'some-id });

Inspect the output in `demo/export`
// remove it
await object.remove()
```
Loading