diff --git a/.github/dependabot.yml b/.github/dependabot.yml index de46e32..0bc3b42 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,5 +4,8 @@ updates: directory: "/" schedule: interval: daily - time: "11:00" + time: "10:00" open-pull-requests-limit: 10 + commit-message: + prefix: "deps" + prefix-development: "deps(dev)" diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..3833fc2 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,11 @@ +# File managed by web3-bot. DO NOT EDIT. +# See https://github.com/protocol/.github/ for details. + +name: Automerge +on: [ pull_request ] + +jobs: + automerge: + uses: protocol/.github/.github/workflows/automerge.yml@master + with: + job: 'automerge' diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml new file mode 100644 index 0000000..546f6d4 --- /dev/null +++ b/.github/workflows/js-test-and-release.yml @@ -0,0 +1,184 @@ +# File managed by web3-bot. DO NOT EDIT. +# See https://github.com/protocol/.github/ for details. + +name: test & maybe release +on: + push: + branches: + - master + pull_request: + +jobs: + + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present lint + - run: npm run --if-present dep-check + + test-node: + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + node: [lts/*] + fail-fast: true + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:node + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: node + + test-chrome: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:chrome + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: chrome + + test-chrome-webworker: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:chrome-webworker + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: chrome-webworker + + test-firefox: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:firefox + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: firefox + + test-firefox-webworker: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:firefox-webworker + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: firefox-webworker + + test-webkit: + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + node: [lts/*] + fail-fast: true + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:webkit + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: webkit + + test-webkit-webworker: + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + node: [lts/*] + fail-fast: true + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:webkit-webworker + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: webkit-webworker + + test-electron-main: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npx xvfb-maybe npm run --if-present test:electron-main + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: electron-main + + test-electron-renderer: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npx xvfb-maybe npm run --if-present test:electron-renderer + - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 + with: + flags: electron-renderer + + release: + needs: [test-node, test-chrome, test-chrome-webworker, test-firefox, test-firefox-webworker, test-webkit, test-webkit-webworker, test-electron-main, test-electron-renderer] + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - uses: ipfs/aegir/actions/docker-login@master + with: + docker-token: ${{ secrets.DOCKER_TOKEN }} + docker-username: ${{ secrets.DOCKER_USERNAME }} + - run: npm run --if-present release + env: + GITHUB_TOKEN: ${{ secrets.UCI_GITHUB_TOKEN || github.token }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 2822fc0..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: ci -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: npm install - - run: npx aegir lint - - uses: gozala/typescript-error-reporter-action@v1.0.8 - - run: npx aegir build --no-bundle - - run: npx aegir dep-check - test-node: - needs: check - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-latest, ubuntu-latest, macos-latest] - node: [14, 16] - fail-fast: true - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - run: npm install - - run: npx nyc --reporter=lcov aegir test -t node -- --bail - - uses: codecov/codecov-action@v1 - test-electron-main: - needs: check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: npm install - - run: npx xvfb-maybe aegir test -t electron-main --bail - test-electron-renderer: - needs: check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: npm install - - run: npx xvfb-maybe aegir test -t electron-renderer --bail diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..6f6d895 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +name: Close and mark stale issue + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.' + close-issue-message: 'This issue was closed because it is missing author input.' + stale-issue-label: 'kind/stale' + any-of-labels: 'need/author-input' + exempt-issue-labels: 'need/triage,need/community-input,need/maintainer-input,need/maintainers-input,need/analysis,status/blocked,status/in-progress,status/ready,status/deferred,status/inactive' + days-before-issue-stale: 6 + days-before-issue-close: 7 + enable-statistics: true diff --git a/.gitignore b/.gitignore index 9691fab..7ad9e67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,38 +1,9 @@ -yarn.lock -package-lock.json -**/node_modules/ -**/*.log -test/repo-tests* - -# Logs -logs -*.log - -coverage - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -build - -# Dependency directory -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules - -lib +build dist -docs +.docs +.coverage +node_modules +package-lock.json +yarn.lock +.vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index f0145ed..cbecfd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,76 @@ +## [9.0.1](https://github.com/ipfs/js-datastore-fs/compare/v9.0.0...v9.0.1) (2023-03-23) + + +### Dependencies + +* update interface-store to 5.x.x ([#183](https://github.com/ipfs/js-datastore-fs/issues/183)) ([803df0b](https://github.com/ipfs/js-datastore-fs/commit/803df0bc96860352957fb06fee109a705124a273)) + +## [9.0.0](https://github.com/ipfs/js-datastore-fs/compare/v8.0.0...v9.0.0) (2023-03-14) + + +### âš  BREAKING CHANGES + +* interface-datastore 8.x.x has removed the open and close methods as these are implementation specific + +### Bug Fixes + +* fix exports map ([4332006](https://github.com/ipfs/js-datastore-fs/commit/4332006aba3e8e67c80144b110cc81042ce07e03)) + + +### Dependencies + +* update interface-datastore to 8.x.x ([#180](https://github.com/ipfs/js-datastore-fs/issues/180)) ([2ef5f5c](https://github.com/ipfs/js-datastore-fs/commit/2ef5f5cf021b1876cb83c53bafebb5f153c77462)) + + +### Trivial Changes + +* update project config ([62adc6b](https://github.com/ipfs/js-datastore-fs/commit/62adc6b238e64c6040afb4887bf6999de42cde08)) + +## [8.0.0](https://github.com/ipfs/js-datastore-fs/compare/v7.0.0...v8.0.0) (2022-08-12) + + +### âš  BREAKING CHANGES + +* this module used to be dual published as CJS/ESM, now it is just ESM + +### Features + +* publish module as ESM only ([#139](https://github.com/ipfs/js-datastore-fs/issues/139)) ([5896e57](https://github.com/ipfs/js-datastore-fs/commit/5896e57fbba4ed47e0ede2ae140f8e757c928148)) + + +### Trivial Changes + +* Update .github/workflows/stale.yml [skip ci] ([94f7d36](https://github.com/ipfs/js-datastore-fs/commit/94f7d369a9b3285d7be79e794f90fdcc1e80f704)) + +## [7.0.0](https://github.com/ipfs/js-datastore-fs/compare/v6.0.1...v7.0.0) (2022-01-19) + + +### âš  BREAKING CHANGES + +* updates project config to use unified ci + +### Trivial Changes + +* switch to unified ci ([#113](https://github.com/ipfs/js-datastore-fs/issues/113)) ([5e306e2](https://github.com/ipfs/js-datastore-fs/commit/5e306e260727d6fdfdfbd75aae84ca48bb11592f)) + +## [6.0.1](https://github.com/ipfs/js-datastore-fs/compare/v6.0.0...v6.0.1) (2021-09-09) + + + +# [6.0.0](https://github.com/ipfs/js-datastore-fs/compare/v5.0.2...v6.0.0) (2021-09-08) + + +### chore + +* convert to esm ([#103](https://github.com/ipfs/js-datastore-fs/issues/103)) ([314d130](https://github.com/ipfs/js-datastore-fs/commit/314d13051665c42be8a4bcc51c19ce2d5dd45346)) + + +### BREAKING CHANGES + +* deep imports are no longer possible + + + ## [5.0.2](https://github.com/ipfs/js-datastore-fs/compare/v5.0.1...v5.0.2) (2021-07-23) @@ -208,6 +281,3 @@ # 0.1.0 (2017-03-15) - - - diff --git a/LICENSE b/LICENSE index 15ede75..20ce483 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,4 @@ -MIT License +This project is dual licensed under MIT and Apache-2.0. -Copyright (c) 2017 IPFS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..14478a3 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/test/test-repo/blocks/FN/CIQIXBZMUTXFC5QIGMLJNXLLHZOPGSL2PBC65D4UIVWM6TI5F5TAFNI.data b/LICENSE-MIT similarity index 86% rename from test/test-repo/blocks/FN/CIQIXBZMUTXFC5QIGMLJNXLLHZOPGSL2PBC65D4UIVWM6TI5F5TAFNI.data rename to LICENSE-MIT index 3da9259..72dc60d 100644 --- a/test/test-repo/blocks/FN/CIQIXBZMUTXFC5QIGMLJNXLLHZOPGSL2PBC65D4UIVWM6TI5F5TAFNI.data +++ b/LICENSE-MIT @@ -1,7 +1,4 @@ - -¸°The MIT License (MIT) - -Copyright (c) 2015 IPFS +The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -10,15 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -° \ No newline at end of file +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 3701266..6931a04 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,55 @@ -# js-datastore-fs +# â›”ï¸ This module is now part of https://github.com/ipfs/js-stores -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) -[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) -[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) -[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) -[![Build Status](https://flat.badgen.net/travis/ipfs/js-datastore-fs)](https://travis-ci.com/ipfs/js-datastore-fs) -[![Codecov](https://codecov.io/gh/ipfs/js-datastore-fs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/js-datastore-fs) -[![Dependency Status](https://david-dm.org/ipfs/js-datastore-fs.svg?style=flat-square)](https://david-dm.org/ipfs/js-datastore-fs) -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) -![](https://img.shields.io/badge/npm-%3E%3D3.0.0-orange.svg?style=flat-square) -![](https://img.shields.io/badge/Node.js-%3E%3D8.0.0-orange.svg?style=flat-square) +# datastore-fs -> Datastore implementation with file system backend. +[![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-datastore-fs.svg?style=flat-square)](https://codecov.io/gh/ipfs/js-datastore-fs) +[![CI](https://img.shields.io/github/actions/workflow/status/ipfs/js-datastore-fs/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/ipfs/js-datastore-fs/actions/workflows/js-test-and-release.yml?query=branch%3Amaster) -## Lead Maintainer +> Datastore implementation with file system backend -[Alex Potsides](https://github.com/achingbrain) +## Table of contents -## Table of Contents - -- [js-datastore-fs](#js-datastore-fs) - - [Lead Maintainer](#lead-maintainer) - - [Table of Contents](#table-of-contents) - - [Install](#install) - - [Usage](#usage) - - [Contribute](#contribute) - - [License](#license) +- [Install](#install) +- [Usage](#usage) +- [API Docs](#api-docs) +- [License](#license) +- [Contribute](#contribute) ## Install -``` -$ npm install datastore-fs +```console +$ npm i datastore-fs ``` ## Usage ```js -const FsStore = require('datastore-fs') -const store = new FsStore('path/to/store') +import { FSDatastore } from 'datastore-fs' + +const store = new FSDatastore('path/to/store') ``` +## API Docs + +- + +## License + +Licensed under either of + +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) + ## Contribute -Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/js-datastore-fs/issues)! +Contributions welcome! Please check out [the issues](https://github.com/ipfs/js-datastore-fs/issues). -This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). +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. -[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) +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). -## License +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. -[MIT](LICENSE) +[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) diff --git a/package.json b/package.json index 8c6031e..a9d59a8 100644 --- a/package.json +++ b/package.json @@ -1,78 +1,158 @@ { "name": "datastore-fs", - "version": "5.0.2", + "version": "9.0.1", "description": "Datastore implementation with file system backend", - "leadMaintainer": "Alex Potsides ", - "main": "src/index.js", - "types": "dist/src/index.d.ts", - "files": [ - "src", - "dist" - ], - "scripts": { - "prepare": "aegir build --no-bundle", - "test": "aegir test -t node", - "build": "aegir build", - "lint": "aegir lint", - "release": "aegir release -t node --build false", - "release-minor": "aegir release --type minor -t node --build false", - "release-major": "aegir release --type major -t node --build false", - "coverage": "nyc -s npm run test:node && nyc report --reporter=html", - "dep-check": "aegir dep-check" - }, + "author": "Friedel Ziegelmayer", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/ipfs/js-datastore-fs#readme", "repository": { "type": "git", "url": "git+https://github.com/ipfs/js-datastore-fs.git" }, + "bugs": { + "url": "https://github.com/ipfs/js-datastore-fs/issues" + }, "keywords": [ + "datastore", + "fs", "interface", - "key-value", "ipfs", - "datastore", - "fs" + "key-value" ], - "author": "Friedel Ziegelmayer", - "license": "MIT", - "bugs": { - "url": "https://github.com/ipfs/js-datastore-fs/issues" + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + }, + "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" + } + }, + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" + } + }, + "release": { + "branches": [ + "master" + ], + "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" + ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "build": "aegir build --bundle false", + "release": "aegir release", + "test": "aegir test -t node -t electron-main", + "test:node": "aegir test -t node", + "test:electron-main": "aegir test -t electron-main", + "dep-check": "aegir dep-check", + "docs": "aegir docs" }, - "homepage": "https://github.com/ipfs/js-datastore-fs#readme", "dependencies": { - "datastore-core": "^5.0.0", + "datastore-core": "^9.0.4", "fast-write-atomic": "^0.2.0", - "interface-datastore": "^5.1.1", - "it-glob": "0.0.13", - "it-map": "^1.0.5", - "it-parallel-batch": "^1.0.9", - "mkdirp": "^1.0.4" + "interface-datastore": "^8.1.2", + "interface-store": "^5.0.1", + "it-glob": "^2.0.1", + "it-map": "^2.0.1", + "it-parallel-batch": "^2.0.1" }, "devDependencies": { - "aegir": "^34.0.2", - "async-iterator-all": "^1.0.0", - "detect-node": "^2.0.4", - "interface-datastore-tests": "^1.0.0", - "ipfs-utils": "^8.1.3", - "memdown": "^6.0.0", - "rimraf": "^3.0.2" - }, - "eslintConfig": { - "extends": "ipfs" - }, - "contributors": [ - "achingbrain ", - "David Dias ", - "Friedel Ziegelmayer ", - "Jacob Heun ", - "Hugo Dias ", - "Pedro Teixeira ", - "Hector Sanjuan ", - "ᴠɪᴄᴛá´Ê€ ʙᴊᴇʟᴋʜá´ÊŸá´ ", - "Richard Schneider ", - "Vasco Santos ", - "Zane Starr ", - "Stephen Whitmore ", - "Matteo Collina ", - "Dmitriy Ryajov ", - "Bryan Stenson " - ] + "@types/mkdirp": "^2.0.0", + "@types/rimraf": "^4.0.5", + "aegir": "^38.1.7", + "interface-datastore-tests": "^5.0.0", + "ipfs-utils": "^9.0.4" + } } diff --git a/src/index.js b/src/index.js deleted file mode 100644 index e130e98..0000000 --- a/src/index.js +++ /dev/null @@ -1,369 +0,0 @@ -'use strict' - -const fs = require('fs') -const glob = require('it-glob') -// @ts-ignore -const mkdirp = require('mkdirp') -const promisify = require('util').promisify -// @ts-ignore -const writeAtomic = promisify(require('fast-write-atomic')) -const path = require('path') -const { - Adapter, Key, Errors -} = require('interface-datastore') -const map = require('it-map') -const parallel = require('it-parallel-batch') - -const noop = () => {} -const fsAccess = promisify(fs.access || noop) -const fsReadFile = promisify(fs.readFile || noop) -const fsUnlink = promisify(fs.unlink || noop) - -/** - * @typedef {import('interface-datastore').Datastore} Datastore - * @typedef {import('interface-datastore').Pair} Pair - * @typedef {import('interface-datastore').Query} Query - * @typedef {import('interface-datastore').KeyQuery} KeyQuery - */ - -/** - * @template TEntry - * @typedef {import('interface-store').AwaitIterable} AwaitIterable - */ - -/** - * Write a file atomically - * - * @param {string} path - * @param {Uint8Array} contents - */ -async function writeFile (path, contents) { - try { - await writeAtomic(path, contents) - } catch (err) { - if (err.code === 'EPERM' && err.syscall === 'rename') { - // fast-write-atomic writes a file to a temp location before renaming it. - // On Windows, if the final file already exists this error is thrown. - // No such error is thrown on Linux/Mac - // Make sure we can read & write to this file - await fsAccess(path, fs.constants.F_OK | fs.constants.W_OK) - - // The file was created by another context - this means there were - // attempts to write the same block by two different function calls - return - } - - throw err - } -} - -/** - * A datastore backed by the file system. - * - * Keys need to be sanitized before use, as they are written - * to the file system as is. - * - * @implements {Datastore} - */ -class FsDatastore extends Adapter { - /** - * @param {string} location - * @param {{ createIfMissing?: boolean, errorIfExists?: boolean, extension?: string, putManyConcurrency?: number } | undefined} [opts] - */ - constructor (location, opts) { - super() - - this.path = path.resolve(location) - this.opts = Object.assign({}, { - createIfMissing: true, - errorIfExists: false, - extension: '.data', - deleteManyConcurrency: 50, - getManyConcurrency: 50, - putManyConcurrency: 50 - }, opts) - } - - open () { - try { - if (!fs.existsSync(this.path)) { - throw Errors.notFoundError(new Error(`Datastore directory: ${this.path} does not exist`)) - } - - if (this.opts.errorIfExists) { - throw Errors.dbOpenFailedError(new Error(`Datastore directory: ${this.path} already exists`)) - } - return Promise.resolve() - } catch (err) { - if (err.code === 'ERR_NOT_FOUND' && this.opts.createIfMissing) { - mkdirp.sync(this.path, { fs: fs }) - return Promise.resolve() - } - - throw err - } - } - - close () { - return Promise.resolve() - } - - /** - * Calculate the directory and file name for a given key. - * - * @private - * @param {Key} key - * @returns {{dir:string, file:string}} - */ - _encode (key) { - const parent = key.parent().toString() - const dir = path.join(this.path, parent) - const name = key.toString().slice(parent.length) - const file = path.join(dir, name + this.opts.extension) - - return { - dir: dir, - file: file - } - } - - /** - * Calculate the original key, given the file name. - * - * @private - * @param {string} file - * @returns {Key} - */ - _decode (file) { - const ext = this.opts.extension - if (path.extname(file) !== ext) { - throw new Error(`Invalid extension: ${path.extname(file)}`) - } - - const keyname = file - .slice(this.path.length, -ext.length) - .split(path.sep) - .join('/') - return new Key(keyname) - } - - /** - * Write to the file system without extension. - * - * @param {Key} key - * @param {Uint8Array} val - * @returns {Promise} - */ - async putRaw (key, val) { - const parts = this._encode(key) - let file = parts.file - - if (this.opts.extension.length) { - file = parts.file.slice(0, -this.opts.extension.length) - } - - await mkdirp(parts.dir, { fs: fs }) - await writeFile(file, val) - } - - /** - * Store the given value under the key - * - * @param {Key} key - * @param {Uint8Array} val - * @returns {Promise} - */ - async put (key, val) { - const parts = this._encode(key) - - try { - await mkdirp(parts.dir, { fs: fs }) - await writeFile(parts.file, val) - } catch (err) { - throw Errors.dbWriteFailedError(err) - } - } - - /** - * @param {AwaitIterable} source - * @returns {AsyncIterable} - */ - async * putMany (source) { - yield * parallel( - map(source, ({ key, value }) => { - return async () => { - await this.put(key, value) - - return { key, value } - } - }), - this.opts.putManyConcurrency - ) - } - - /** - * Read from the file system without extension. - * - * @param {Key} key - * @returns {Promise} - */ - async getRaw (key) { - const parts = this._encode(key) - let file = parts.file - - if (this.opts.extension.length) { - file = file.slice(0, -this.opts.extension.length) - } - - let data - try { - data = await fsReadFile(file) - } catch (err) { - throw Errors.notFoundError(err) - } - return data - } - - /** - * Read from the file system. - * - * @param {Key} key - * @returns {Promise} - */ - async get (key) { - const parts = this._encode(key) - let data - try { - data = await fsReadFile(parts.file) - } catch (err) { - throw Errors.notFoundError(err) - } - return data - } - - /** - * @param {AwaitIterable} source - * @returns {AsyncIterable} - */ - async * getMany (source) { - yield * parallel( - map(source, key => { - return async () => { - return this.get(key) - } - }), - this.opts.getManyConcurrency - ) - } - - /** - * @param {AwaitIterable} source - * @returns {AsyncIterable} - */ - async * deleteMany (source) { - yield * parallel( - map(source, key => { - return async () => { - await this.delete(key) - - return key - } - }), - this.opts.deleteManyConcurrency - ) - } - - /** - * Check for the existence of the given key. - * - * @param {Key} key - * @returns {Promise} - */ - async has (key) { - const parts = this._encode(key) - - try { - await fsAccess(parts.file) - } catch (err) { - return false - } - return true - } - - /** - * Delete the record under the given key. - * - * @param {Key} key - * @returns {Promise} - */ - async delete (key) { - const parts = this._encode(key) - try { - await fsUnlink(parts.file) - } catch (err) { - if (err.code === 'ENOENT') { - return - } - - throw Errors.dbDeleteFailedError(err) - } - } - - /** - * @param {Query} q - */ - async * _all (q) { - let prefix = q.prefix || '**' - - // strip leading slashes - prefix = prefix.replace(/^\/+/, '') - - const pattern = `${prefix}/*${this.opts.extension}` - .split(path.sep) - .join('/') - const files = glob(this.path, pattern, { - absolute: true - }) - - for await (const file of files) { - try { - const buf = await fsReadFile(file) - - /** @type {Pair} */ - const pair = { - key: this._decode(file), - value: buf - } - - yield pair - } catch (err) { - // if keys are removed from the datastore while the query is - // running, we may encounter missing files. - if (err.code !== 'ENOENT') { - throw err - } - } - } - } - - /** - * @param {KeyQuery} q - */ - async * _allKeys (q) { - let prefix = q.prefix || '**' - - // strip leading slashes - prefix = prefix.replace(/^\/+/, '') - - const pattern = `${prefix}/*${this.opts.extension}` - .split(path.sep) - .join('/') - const files = glob(this.path, pattern, { - absolute: true - }) - - yield * map(files, f => this._decode(f)) - } -} - -module.exports = FsDatastore diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..a5a5423 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,286 @@ +import fs from 'node:fs/promises' +import glob from 'it-glob' +import path from 'node:path' +import { promisify } from 'util' +import { + Key, KeyQuery, Pair, Query +} from 'interface-datastore' +import { + BaseDatastore, Errors +} from 'datastore-core' +import map from 'it-map' +import parallel from 'it-parallel-batch' +// @ts-expect-error no types +import fwa from 'fast-write-atomic' +import type { AwaitIterable } from 'interface-store' + +const writeAtomic = promisify(fwa) + +/** + * Write a file atomically + */ +async function writeFile (path: string, contents: Uint8Array): Promise { + try { + await writeAtomic(path, contents) + } catch (err: any) { + if (err.code === 'EPERM' && err.syscall === 'rename') { + // fast-write-atomic writes a file to a temp location before renaming it. + // On Windows, if the final file already exists this error is thrown. + // No such error is thrown on Linux/Mac + // Make sure we can read & write to this file + await fs.access(path, fs.constants.F_OK | fs.constants.W_OK) + + // The file was created by another context - this means there were + // attempts to write the same block by two different function calls + return + } + + throw err + } +} + +export interface FsDatastoreInit { + createIfMissing?: boolean + errorIfExists?: boolean + extension?: string + putManyConcurrency?: number + getManyConcurrency?: number + deleteManyConcurrency?: number +} + +/** + * A datastore backed by the file system. + * + * Keys need to be sanitized before use, as they are written + * to the file system as is. + */ +export class FsDatastore extends BaseDatastore { + public path: string + private readonly createIfMissing: boolean + private readonly errorIfExists: boolean + private readonly extension: string + private readonly deleteManyConcurrency: number + private readonly getManyConcurrency: number + private readonly putManyConcurrency: number + + constructor (location: string, init: FsDatastoreInit = {}) { + super() + + this.path = path.resolve(location) + this.createIfMissing = init.createIfMissing ?? true + this.errorIfExists = init.errorIfExists ?? false + this.extension = init.extension ?? '.data' + this.deleteManyConcurrency = init.deleteManyConcurrency ?? 50 + this.getManyConcurrency = init.getManyConcurrency ?? 50 + this.putManyConcurrency = init.putManyConcurrency ?? 50 + } + + async open (): Promise { + try { + await fs.access(this.path, fs.constants.F_OK | fs.constants.W_OK) + + if (this.errorIfExists) { + throw Errors.dbOpenFailedError(new Error(`Datastore directory: ${this.path} already exists`)) + } + return + } catch (err: any) { + if (err.code === 'ENOENT') { + if (this.createIfMissing) { + await fs.mkdir(this.path, { recursive: true }) + return + } else { + throw Errors.notFoundError(new Error(`Datastore directory: ${this.path} does not exist`)) + } + } + + throw err + } + } + + async close (): Promise { + + } + + /** + * Calculate the directory and file name for a given key. + */ + _encode (key: Key): { dir: string, file: string } { + const parent = key.parent().toString() + const dir = path.join(this.path, parent) + const name = key.toString().slice(parent.length) + const file = path.join(dir, name + this.extension) + + return { + dir, + file + } + } + + /** + * Calculate the original key, given the file name. + */ + _decode (file: string): Key { + const ext = this.extension + if (path.extname(file) !== ext) { + throw new Error(`Invalid extension: ${path.extname(file)}`) + } + + const keyname = file + .slice(this.path.length, -ext.length) + .split(path.sep) + .join('/') + + return new Key(keyname) + } + + /** + * Store the given value under the key + */ + async put (key: Key, val: Uint8Array): Promise { + const parts = this._encode(key) + + try { + await fs.mkdir(parts.dir, { + recursive: true + }) + await writeFile(parts.file, val) + + return key + } catch (err: any) { + throw Errors.dbWriteFailedError(err) + } + } + + async * putMany (source: AwaitIterable): AsyncIterable { + yield * parallel( + map(source, ({ key, value }) => { + return async () => { + await this.put(key, value) + + return key + } + }), + this.putManyConcurrency + ) + } + + /** + * Read from the file system + */ + async get (key: Key): Promise { + const parts = this._encode(key) + let data + try { + data = await fs.readFile(parts.file) + } catch (err: any) { + throw Errors.notFoundError(err) + } + return data + } + + async * getMany (source: AwaitIterable): AsyncIterable { + yield * parallel( + map(source, key => { + return async () => { + return { + key, + value: await this.get(key) + } + } + }), + this.getManyConcurrency + ) + } + + async * deleteMany (source: AwaitIterable): AsyncIterable { + yield * parallel( + map(source, key => { + return async () => { + await this.delete(key) + + return key + } + }), + this.deleteManyConcurrency + ) + } + + /** + * Check for the existence of the given key + */ + async has (key: Key): Promise { + const parts = this._encode(key) + + try { + await fs.access(parts.file) + } catch (err: any) { + return false + } + return true + } + + /** + * Delete the record under the given key + */ + async delete (key: Key): Promise { + const parts = this._encode(key) + try { + await fs.unlink(parts.file) + } catch (err: any) { + if (err.code === 'ENOENT') { + return + } + + throw Errors.dbDeleteFailedError(err) + } + } + + async * _all (q: Query): AsyncIterable { + let prefix = q.prefix ?? '**' + + // strip leading slashes + prefix = prefix.replace(/^\/+/, '') + + const pattern = `${prefix}/*${this.extension}` + .split(path.sep) + .join('/') + const files = glob(this.path, pattern, { + absolute: true + }) + + for await (const file of files) { + try { + const buf = await fs.readFile(file) + + const pair: Pair = { + key: this._decode(file), + value: buf + } + + yield pair + } catch (err: any) { + // if keys are removed from the datastore while the query is + // running, we may encounter missing files. + if (err.code !== 'ENOENT') { + throw err + } + } + } + } + + async * _allKeys (q: KeyQuery): AsyncIterable { + let prefix = q.prefix ?? '**' + + // strip leading slashes + prefix = prefix.replace(/^\/+/, '') + + const pattern = `${prefix}/*${this.extension}` + .split(path.sep) + .join('/') + const files = glob(this.path, pattern, { + absolute: true + }) + + yield * map(files, f => this._decode(f)) + } +} diff --git a/test/index.spec.js b/test/index.spec.js deleted file mode 100644 index 06a1cb1..0000000 --- a/test/index.spec.js +++ /dev/null @@ -1,213 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const { expect } = require('aegir/utils/chai') -const path = require('path') -const promisify = require('util').promisify -// @ts-ignore -const mkdirp = require('mkdirp') -// @ts-ignore -const rimraf = promisify(require('rimraf')) -const fs = require('fs') -const noop = () => {} -const fsReadFile = promisify(require('fs').readFile || noop) -const Key = require('interface-datastore').Key -const utils = require('interface-datastore').utils -const ShardingStore = require('datastore-core').ShardingDatastore -const sh = require('datastore-core').shard -const { isNode } = require('ipfs-utils/src/env') -const utf8Encoder = new TextEncoder() -// @ts-ignore -const tests = require('interface-datastore-tests') - -const FsStore = require('../src') - -describe('FsDatastore', () => { - if (!isNode) { - it('only supports node.js', () => { - - }) - - return - } - - describe('construction', () => { - it('defaults - folder missing', () => { - const dir = utils.tmpdir() - expect( - () => new FsStore(dir) - ).to.not.throw() - }) - - it('defaults - folder exists', () => { - const dir = utils.tmpdir() - mkdirp.sync(dir) - expect( - () => new FsStore(dir) - ).to.not.throw() - }) - }) - - describe('open', () => { - it('createIfMissing: false - folder missing', () => { - const dir = utils.tmpdir() - const store = new FsStore(dir, { createIfMissing: false }) - expect( - () => store.open() - ).to.throw() - }) - - it('errorIfExists: true - folder exists', () => { - const dir = utils.tmpdir() - mkdirp.sync(dir) - const store = new FsStore(dir, { errorIfExists: true }) - expect( - () => store.open() - ).to.throw() - }) - }) - - it('_encode and _decode', () => { - const dir = utils.tmpdir() - const fs = new FsStore(dir) - - expect( - // @ts-ignore - fs._encode(new Key('hello/world')) - ).to.eql({ - dir: path.join(dir, 'hello'), - file: path.join(dir, 'hello', 'world.data') - }) - - expect( - // @ts-ignore - fs._decode(fs._encode(new Key('hello/world/test:other')).file) - ).to.eql( - new Key('hello/world/test:other') - ) - }) - - it('deleting files', async () => { - const dir = utils.tmpdir() - const fs = new FsStore(dir) - const key = new Key('1234') - - await fs.put(key, Uint8Array.from([0, 1, 2, 3])) - await fs.delete(key) - - try { - await fs.get(key) - throw new Error('Should have errored') - } catch (err) { - expect(err.code).to.equal('ERR_NOT_FOUND') - } - }) - - it('deleting non-existent files', async () => { - const dir = utils.tmpdir() - const fs = new FsStore(dir) - const key = new Key('5678') - - await fs.delete(key) - - try { - await fs.get(key) - throw new Error('Should have errored') - } catch (err) { - expect(err.code).to.equal('ERR_NOT_FOUND') - } - }) - - it('sharding files', async () => { - const dir = utils.tmpdir() - const fstore = new FsStore(dir) - const shard = new sh.NextToLast(2) - await ShardingStore.create(fstore, shard) - - const file = await fsReadFile(path.join(dir, sh.SHARDING_FN)) - expect(file.toString()).to.be.eql('/repo/flatfs/shard/v1/next-to-last/2\n') - - const readme = await fsReadFile(path.join(dir, sh.README_FN)) - expect(readme.toString()).to.be.eql(sh.readme) - await rimraf(dir) - }) - - it('query', async () => { - const fs = new FsStore(path.join(__dirname, 'test-repo', 'blocks')) - const res = [] - for await (const q of fs.query({})) { - res.push(q) - } - expect(res).to.have.length(23) - }) - - it('interop with go', async () => { - const repodir = path.join(__dirname, '/test-repo/blocks') - const fstore = new FsStore(repodir) - const key = new Key('CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY') - const expected = fs.readFileSync(path.join(repodir, 'VO', key.toString() + '.data')) - const flatfs = await ShardingStore.open(fstore) - const res = await flatfs.get(key) - const queryResult = flatfs.query({}) - const results = [] - for await (const result of queryResult) results.push(result) - expect(results).to.have.length(23) - expect(res).to.be.eql(expected) - }) - - describe('interface-datastore', () => { - const dir = utils.tmpdir() - - tests({ - setup: () => { - return new FsStore(dir) - }, - teardown: () => { - return rimraf(dir) - } - }) - }) - - describe('interface-datastore (sharding(fs))', () => { - const dir = utils.tmpdir() - - tests({ - setup: () => { - return new ShardingStore(new FsStore(dir), new sh.NextToLast(2)) - }, - teardown: () => { - return rimraf(dir) - } - }) - }) - - it('can survive concurrent writes', async () => { - const dir = utils.tmpdir() - const fstore = new FsStore(dir) - const key = new Key('CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY') - const value = utf8Encoder.encode('Hello world') - - await Promise.all( - new Array(100).fill(0).map(() => fstore.put(key, value)) - ) - - const res = await fstore.get(key) - - expect(res).to.deep.equal(value) - }) - - it('can survive putRaw and getRaw with an empty extension', async () => { - const dir = utils.tmpdir() - const fstore = new FsStore(dir, { - extension: '' - }) - const key = new Key('CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY') - const value = utf8Encoder.encode('Hello world') - - await fstore.putRaw(key, value) - - const res = await fstore.getRaw(key) - - expect(res).to.deep.equal(value) - }) -}) diff --git a/test/index.spec.ts b/test/index.spec.ts new file mode 100644 index 0000000..96d0963 --- /dev/null +++ b/test/index.spec.ts @@ -0,0 +1,173 @@ +/* eslint-env mocha */ +import { expect } from 'aegir/chai' +import path from 'node:path' +import fs from 'node:fs/promises' +import { Key } from 'interface-datastore' +import { ShardingDatastore, shard } from 'datastore-core' +import { interfaceDatastoreTests } from 'interface-datastore-tests' +import { FsDatastore } from '../src/index.js' +import tempdir from 'ipfs-utils/src/temp-dir.js' + +const utf8Encoder = new TextEncoder() + +describe('FsDatastore', () => { + describe('construction', () => { + it('defaults - folder missing', async () => { + const dir = tempdir() + + await expect( + (async () => { + const store = new FsDatastore(dir) + await store.open() + })() + ).to.eventually.be.undefined() + }) + + it('defaults - folder exists', async () => { + const dir = tempdir() + await fs.mkdir(dir, { + recursive: true + }) + + await expect( + (async () => { + const store = new FsDatastore(dir) + await store.open() + })() + ).to.eventually.be.undefined() + }) + }) + + describe('open', () => { + it('createIfMissing: false - folder missing', async () => { + const dir = tempdir() + const store = new FsDatastore(dir, { createIfMissing: false }) + await expect(store.open()).to.eventually.be.rejected + .with.property('code', 'ERR_NOT_FOUND') + }) + + it('errorIfExists: true - folder exists', async () => { + const dir = tempdir() + await fs.mkdir(dir, { + recursive: true + }) + const store = new FsDatastore(dir, { errorIfExists: true }) + await expect(store.open()).to.eventually.be.rejected + .with.property('code', 'ERR_DB_OPEN_FAILED') + }) + }) + + it('_encode and _decode', async () => { + const dir = tempdir() + const fs = new FsDatastore(dir) + await fs.open() + + expect( + fs._encode(new Key('hello/world')) + ).to.eql({ + dir: path.join(dir, 'hello'), + file: path.join(dir, 'hello', 'world.data') + }) + + expect( + fs._decode(fs._encode(new Key('hello/world/test:other')).file) + ).to.eql( + new Key('hello/world/test:other') + ) + }) + + it('deleting files', async () => { + const dir = tempdir() + const fs = new FsDatastore(dir) + await fs.open() + const key = new Key('1234') + + await fs.put(key, Uint8Array.from([0, 1, 2, 3])) + await fs.delete(key) + + try { + await fs.get(key) + throw new Error('Should have errored') + } catch (err: any) { + expect(err.code).to.equal('ERR_NOT_FOUND') + } + }) + + it('deleting non-existent files', async () => { + const dir = tempdir() + const fs = new FsDatastore(dir) + await fs.open() + const key = new Key('5678') + + await fs.delete(key) + + try { + await fs.get(key) + throw new Error('Should have errored') + } catch (err: any) { + expect(err.code).to.equal('ERR_NOT_FOUND') + } + }) + + it('sharding files', async () => { + const dir = tempdir() + const fstore = new FsDatastore(dir) + await fstore.open() + await ShardingDatastore.create(fstore, new shard.NextToLast(2)) + + const file = await fs.readFile(path.join(dir, shard.SHARDING_FN + '.data')) + expect(file.toString()).to.be.eql('/repo/flatfs/shard/v1/next-to-last/2\n') + + await fs.rm(dir, { + recursive: true + }) + }) + + describe('interface-datastore', () => { + interfaceDatastoreTests({ + async setup () { + const store = new FsDatastore(tempdir()) + await store.open() + + return store + }, + async teardown (store) { + await fs.rm(store.path, { + recursive: true + }) + } + }) + }) + + describe('interface-datastore (sharding(fs))', () => { + interfaceDatastoreTests({ + async setup () { + const store = new FsDatastore(tempdir()) + await store.open() + + const shardedStore = new ShardingDatastore(store, new shard.NextToLast(2)) + await shardedStore.open() + + return shardedStore + }, + teardown () { + + } + }) + }) + + it('can survive concurrent writes', async () => { + const dir = tempdir() + const fstore = new FsDatastore(dir) + const key = new Key('CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY') + const value = utf8Encoder.encode('Hello world') + + await Promise.all( + new Array(100).fill(0).map(async () => { await fstore.put(key, value) }) + ) + + const res = await fstore.get(key) + + expect(res).to.deep.equal(value) + }) +}) diff --git a/test/test-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data b/test/test-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data deleted file mode 100644 index 4145619..0000000 --- a/test/test-repo/blocks/2F/CIQEUWUVLBXVFYSYCHHSCRTXCYHGIOBXKWUMKFR3UPAFHQ5WK5362FQ.data +++ /dev/null @@ -1,4 +0,0 @@ - -ys# js-ipfs-repo -Implementation of the IPFS repo spec (https://github.com/ipfs/specs/tree/master/repo) in JavaScript -s \ No newline at end of file diff --git a/test/test-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data b/test/test-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data deleted file mode 100644 index 951bfe0..0000000 --- a/test/test-repo/blocks/5V/CIQFFRR4O52TS2Z7QLDDTF32OIR4FWLKT5YLL7MLDVIT7DC3NHOK5VA.data +++ /dev/null @@ -1,23 +0,0 @@ - -€ø IPFS Alpha Security Notes - -We try hard to ensure our system is safe and robust, but all software -has bugs, especially new software. This distribution is meant to be an -alpha preview, don't use it for anything mission critical. - -Please note the following: - -- This is alpha software and has not been audited. It is our goal - to conduct a proper security audit once we close in on a 1.0 release. - -- ipfs is a networked program, and may have serious undiscovered - vulnerabilities. It is written in Go, and we do not execute any - user provided data. But please point any problems out to us in a - github issue, or email security@ipfs.io privately. - -- ipfs uses encryption for all communication, but it's NOT PROVEN SECURE - YET! It may be totally broken. For now, the code is included to make - sure we benchmark our operations with encryption in mind. In the future, - there will be an "unsafe" mode for high performance intranet apps. - If this is a blocking feature for you, please contact us. -ø \ No newline at end of file diff --git a/test/test-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data b/test/test-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data deleted file mode 100644 index c9885c4..0000000 Binary files a/test/test-repo/blocks/75/CIQMB7DLJFKD267QJ2B5FJNHZPTSVA7IB6OHXSQ2XSVEEKMKK6RT75I.data and /dev/null differ diff --git a/test/test-repo/blocks/7J/CIQKKLBWAIBQZOIS5X7E32LQAL6236OUKZTMHPQSFIXPWXNZHQOV7JQ.data b/test/test-repo/blocks/7J/CIQKKLBWAIBQZOIS5X7E32LQAL6236OUKZTMHPQSFIXPWXNZHQOV7JQ.data deleted file mode 100644 index 627ffcd..0000000 --- a/test/test-repo/blocks/7J/CIQKKLBWAIBQZOIS5X7E32LQAL6236OUKZTMHPQSFIXPWXNZHQOV7JQ.data +++ /dev/null @@ -1,55 +0,0 @@ - -•  - IPFS -- Inter-Planetary File system - -IPFS is a global, versioned, peer-to-peer filesystem. It combines good ideas -from Git, BitTorrent, Kademlia, SFS, and the Web. It is like a single bit- -torrent swarm, exchanging git objects. IPFS provides an interface as simple -as the HTTP web, but with permanence built in. You can also mount the world -at /ipfs. - -IPFS is a protocol: -- defines a content-addressed file system -- coordinates content delivery -- combines Kademlia + BitTorrent + Git - -IPFS is a filesystem: -- has directories and files -- mountable filesystem (via FUSE) - -IPFS is a web: -- can be used to view documents like the web -- files accessible via HTTP at `http://ipfs.io/` -- browsers or extensions can learn to use `ipfs://` directly -- hash-addressed content guarantees authenticity - -IPFS is modular: -- connection layer over any network protocol -- routing layer -- uses a routing layer DHT (kademlia/coral) -- uses a path-based naming service -- uses bittorrent-inspired block exchange - -IPFS uses crypto: -- cryptographic-hash content addressing -- block-level deduplication -- file integrity + versioning -- filesystem-level encryption + signing support - -IPFS is p2p: -- worldwide peer-to-peer file transfers -- completely decentralized architecture -- **no** central point of failure - -IPFS is a cdn: -- add a file to the filesystem locally, and it's now available to the world -- caching-friendly (content-hash naming) -- bittorrent-based bandwidth distribution - -IPFS has a name service: -- IPNS, an SFS inspired name system -- global namespace based on PKI -- serves to build trust chains -- compatible with other NSes -- can map DNS, .onion, .bit, etc to IPNS - \ No newline at end of file diff --git a/test/test-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data b/test/test-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data deleted file mode 100644 index 6860441..0000000 --- a/test/test-repo/blocks/AE/CIQONICFQZH7QVU6IPSIM3AK7AD554D3BWZPAGEAQYQOWMFZQDUUAEI.data +++ /dev/null @@ -1,3 +0,0 @@ -/ -" gq†¸ÿ6\u8~:çò©6~ágÃæÖZ.è¸directT2 -" 6(¤¡•%Ý„»¿þ.À°Ó¾5(û¼Èþ·òû÷ ab recursive·T \ No newline at end of file diff --git a/test/test-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data b/test/test-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data deleted file mode 100644 index 74de75a..0000000 Binary files a/test/test-repo/blocks/AP/CIQHAKDLTL5GMIFGN5YVY4BA22FPHUIODJEXS4LCTQDWA275XAJDAPI.data and /dev/null differ diff --git a/test/test-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data b/test/test-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data deleted file mode 100644 index ecce105..0000000 --- a/test/test-repo/blocks/C4/CIQDDZ5EDQK5AP7LRTLZHQZUR2R3GECRFV3WPKNL7PL2SKFIL2LXC4Y.data +++ /dev/null @@ -1,4 +0,0 @@ -5 -" ¸˜µ×¾FØ_ëuØ”álúšzåS?Ž™|Ú²ë­×Pc@ js-ipfs-repoŸ - - \ No newline at end of file diff --git a/test/test-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data b/test/test-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data deleted file mode 100644 index bbe6bda..0000000 Binary files a/test/test-repo/blocks/CY/CIQDMKFEUGKSLXMEXO774EZOYCYNHPRVFD53ZSAU7237F67XDSQGCYQ.data and /dev/null differ diff --git a/test/test-repo/blocks/GQ/CIQH7OEYWXL34RWYL7VXLWEU4FWPVGT24VJT7DUZPTNLF25N25IGGQA.data b/test/test-repo/blocks/GQ/CIQH7OEYWXL34RWYL7VXLWEU4FWPVGT24VJT7DUZPTNLF25N25IGGQA.data deleted file mode 100644 index ee87b9d..0000000 --- a/test/test-repo/blocks/GQ/CIQH7OEYWXL34RWYL7VXLWEU4FWPVGT24VJT7DUZPTNLF25N25IGGQA.data +++ /dev/null @@ -1,4 +0,0 @@ -0 -" ‹‡,¤îQv3–Ýk>\óIzxEî”ElÏM/fµLICENSE»1 -" JZ•XoRâXÏ!Fwd87U¨Å;£ÀSöWwí README.md{ - \ No newline at end of file diff --git a/test/test-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data b/test/test-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data deleted file mode 100644 index 5ea0edd..0000000 Binary files a/test/test-repo/blocks/HD/CIQDDVW2EZIJF4NQH7WJNESD7XHQSXA5EGJVNTPVHD7444C2KLKXHDI.data and /dev/null differ diff --git a/test/test-repo/blocks/IL/CIQJFGRQHQ45VCQLM7AJNF2GF5UHUAGGHC6LLAH6VYDEKLQMD4QLILY.data b/test/test-repo/blocks/IL/CIQJFGRQHQ45VCQLM7AJNF2GF5UHUAGGHC6LLAH6VYDEKLQMD4QLILY.data deleted file mode 100644 index 62d1c29..0000000 --- a/test/test-repo/blocks/IL/CIQJFGRQHQ45VCQLM7AJNF2GF5UHUAGGHC6LLAH6VYDEKLQMD4QLILY.data +++ /dev/null @@ -1,8 +0,0 @@ - -ŽCome hang out in our IRC chat room if you have any questions. - -Contact the ipfs dev team: -- Bugs: https://github.com/ipfs/go-ipfs/issues -- Help: irc.freenode.org/#ipfs -- Email: dev@ipfs.io -½ \ No newline at end of file diff --git a/test/test-repo/blocks/LG/CIQJBQD2O6K4CGJVCCTJNUP57QHR4SKHZ74OIITBBGLOMCO3ZOLWLGA.data b/test/test-repo/blocks/LG/CIQJBQD2O6K4CGJVCCTJNUP57QHR4SKHZ74OIITBBGLOMCO3ZOLWLGA.data deleted file mode 100644 index 71be805..0000000 --- a/test/test-repo/blocks/LG/CIQJBQD2O6K4CGJVCCTJNUP57QHR4SKHZ74OIITBBGLOMCO3ZOLWLGA.data +++ /dev/null @@ -1,9 +0,0 @@ - -¿·Some helpful resources for finding your way around ipfs: - -- quick-start: a quick show of various ipfs features. -- ipfs commands: a list of all commands -- ipfs --help: every command describes itself -- https://github.com/ipfs/go-ipfs -- the src repository -- #ipfs on irc.freenode.org -- the community irc channel -· \ No newline at end of file diff --git a/test/test-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data b/test/test-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data deleted file mode 100644 index 7b58d6c..0000000 --- a/test/test-repo/blocks/O6/CIQOYW2THIZBRGI7IN33ROGCKOFZLXJJ2MPKYZBTV4H3N7GYHXMAO6A.data +++ /dev/null @@ -1,3 +0,0 @@ -/ -" æ@ŠÃ÷¬šÔ†D¯Éùg«âªçÆA÷»éŠ7directT2 -" “;AÓÔPŒßôY0ßõk®ù}ÃEç=šµp«á û¹ recursiveáT \ No newline at end of file diff --git a/test/test-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data b/test/test-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data deleted file mode 100644 index a8f9869..0000000 Binary files a/test/test-repo/blocks/QF/CIQGPALRQ24P6NS4OWHTQ7R247ZI7KJWP3QWPQYS43LFULQC5ANLQFI.data and /dev/null differ diff --git a/test/test-repo/blocks/QV/CIQOHMGEIKMPYHAUTL57JSEZN64SIJ5OIHSGJG4TJSSJLGI3PBJLQVI.data b/test/test-repo/blocks/QV/CIQOHMGEIKMPYHAUTL57JSEZN64SIJ5OIHSGJG4TJSSJLGI3PBJLQVI.data deleted file mode 100644 index e69de29..0000000 diff --git a/test/test-repo/blocks/R3/CIQBED3K6YA5I3QQWLJOCHWXDRK5EXZQILBCKAPEDUJENZ5B5HJ5R3A.data b/test/test-repo/blocks/R3/CIQBED3K6YA5I3QQWLJOCHWXDRK5EXZQILBCKAPEDUJENZ5B5HJ5R3A.data deleted file mode 100644 index 389e111..0000000 --- a/test/test-repo/blocks/R3/CIQBED3K6YA5I3QQWLJOCHWXDRK5EXZQILBCKAPEDUJENZ5B5HJ5R3A.data +++ /dev/null @@ -1,28 +0,0 @@ - -ËÃHello and Welcome to IPFS! - -██╗██████╗ ███████╗███████╗ -██║██╔â•â•██╗██╔â•â•â•â•â•██╔â•â•â•â•â• -██║██████╔â•█████╗ ███████╗ -██║██╔â•â•â•╠██╔â•â•╠╚â•â•â•â•██║ -██║██║ ██║ ███████║ -╚â•â•╚â•╠╚â•╠╚â•â•â•â•â•â•â• - -If you're seeing this, you have successfully installed -IPFS and are now interfacing with the ipfs merkledag! - - ------------------------------------------------------- -| Warning: | -| This is alpha software. Use at your own discretion! | -| Much is missing or lacking polish. There are bugs. | -| Not yet secure. Read the security notes for more. | - ------------------------------------------------------- - -Check out some of the other files in this directory: - - ./about - ./help - ./quick-start <-- usage examples - ./readme <-- this file - ./security-notes -à \ No newline at end of file diff --git a/test/test-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data b/test/test-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data deleted file mode 100644 index 3a99c36..0000000 --- a/test/test-repo/blocks/S5/CIQHBGZNZRPWVEFNMTLP4OS5EAVHFMCX2HD7FZUC2B3WUU3D4LGKS5A.data +++ /dev/null @@ -1,3 +0,0 @@ -4 -" Y”„9_)ažô€Ë¹2¾RÅm™Å–keà9ð˜»ï js-ipfs-repo - \ No newline at end of file diff --git a/test/test-repo/blocks/SHARDING b/test/test-repo/blocks/SHARDING deleted file mode 100644 index a153331..0000000 --- a/test/test-repo/blocks/SHARDING +++ /dev/null @@ -1 +0,0 @@ -/repo/flatfs/shard/v1/next-to-last/2 diff --git a/test/test-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data b/test/test-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data deleted file mode 100644 index 10aa2ae..0000000 Binary files a/test/test-repo/blocks/TW/CIQFEAGMNNXXTYKYQSANT6IBNTFN7WR5RPD5F6GN6MBKUUO25DNOTWQ.data and /dev/null differ diff --git a/test/test-repo/blocks/UN/CIQOMBKARLB7PAITVSNH7VEGIQJRPL6J7FT2XYVKAXT4MQPXXPUYUNY.data b/test/test-repo/blocks/UN/CIQOMBKARLB7PAITVSNH7VEGIQJRPL6J7FT2XYVKAXT4MQPXXPUYUNY.data deleted file mode 100644 index b653989..0000000 Binary files a/test/test-repo/blocks/UN/CIQOMBKARLB7PAITVSNH7VEGIQJRPL6J7FT2XYVKAXT4MQPXXPUYUNY.data and /dev/null differ diff --git a/test/test-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data b/test/test-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data deleted file mode 100644 index 2dd8056..0000000 --- a/test/test-repo/blocks/VO/CIQGFTQ7FSI2COUXWWLOQ45VUM2GUZCGAXLWCTOKKPGTUWPXHBNIVOY.data +++ /dev/null @@ -1,114 +0,0 @@ - -ž – # 0.1 - Quick Start - -This is a set of short examples with minimal explanation. It is meant as -a "quick start". Soon, we'll write a longer tour :-) - - -Add a file to ipfs: - - echo "hello world" >hello - ipfs add hello - - -View it: - - ipfs cat - - -Try a directory: - - mkdir foo - mkdir foo/bar - echo "baz" > foo/baz - echo "baz" > foo/bar/baz - ipfs add -r foo - - -View things: - - ipfs ls - ipfs ls /bar - ipfs cat /baz - ipfs cat /bar/baz - ipfs cat /bar - ipfs ls /baz - - -References: - - ipfs refs - ipfs refs -r - ipfs refs --help - - -Get: - - ipfs get foo2 - diff foo foo2 - - -Objects: - - ipfs object get - ipfs object get /foo2 - ipfs object --help - - -Pin + GC: - - ipfs pin -r - ipfs gc - ipfs ls - ipfs unpin -r - ipfs gc - - -Daemon: - - ipfs daemon (in another terminal) - ipfs id - - -Network: - - (must be online) - ipfs swarm peers - ipfs id - ipfs cat - - -Mount: - - (warning: fuse is finicky!) - ipfs mount - cd /ipfs/< - - -Tool: - - ipfs version - ipfs update - ipfs commands - ipfs config --help - open http://localhost:5001/webui - - -Browse: - - webui: - - http://localhost:5001/webui - - video: - - http://localhost:8080/ipfs/QmVc6zuAneKJzicnJpfrqCH9gSy6bz54JhcypfJYhGUFQu/play#/ipfs/QmTKZgRNwDNZwHtJSjCp6r5FYefzpULfy37JvMt9DwvXse - - images: - - http://localhost:8080/ipfs/QmZpc3HvfjEXvLWGQPWbHk3AjD5j8NEN4gmFN8Jmrd5g83/cs - - markdown renderer app: - - http://localhost:8080/ipfs/QmX7M9CiYXjVeFnkfVGf3y5ixTZ2ACeSGyL1vBJY1HvQPp/mdown -– \ No newline at end of file diff --git a/test/test-repo/blocks/X3/CIQFTFEEHEDF6KLBT32BFAGLXEZL4UWFNWM4LFTLMXQBCERZ6CMLX3Y.data b/test/test-repo/blocks/X3/CIQFTFEEHEDF6KLBT32BFAGLXEZL4UWFNWM4LFTLMXQBCERZ6CMLX3Y.data deleted file mode 100644 index 9553a94..0000000 --- a/test/test-repo/blocks/X3/CIQFTFEEHEDF6KLBT32BFAGLXEZL4UWFNWM4LFTLMXQBCERZ6CMLX3Y.data +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/test/test-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data b/test/test-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data deleted file mode 100644 index d899663..0000000 Binary files a/test/test-repo/blocks/XO/CIQJGO2B2N75IUEM372FSMG76VV256I4PXBULZZ5ASNLK4FL4EG7XOI.data and /dev/null differ diff --git a/test/test-repo/blocks/_README b/test/test-repo/blocks/_README deleted file mode 100644 index 23cb090..0000000 --- a/test/test-repo/blocks/_README +++ /dev/null @@ -1,30 +0,0 @@ -This is a repository of IPLD objects. Each IPLD object is in a single file, -named .data. Where is the -"base32" encoding of the CID (as specified in -https://github.com/multiformats/multibase) without the 'B' prefix. -All the object files are placed in a tree of directories, based on a -function of the CID. This is a form of sharding similar to -the objects directory in git repositories. Previously, we used -prefixes, we now use the next-to-last two charters. - - func NextToLast(base32cid string) { - nextToLastLen := 2 - offset := len(base32cid) - nextToLastLen - 1 - return str[offset : offset+nextToLastLen] - } - -For example, an object with a base58 CIDv1 of - - zb2rhYSxw4ZjuzgCnWSt19Q94ERaeFhu9uSqRgjSdx9bsgM6f - -has a base32 CIDv1 of - - BAFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA - -and will be placed at - - SC/AFKREIA22FLID5AJ2KU7URG47MDLROZIH6YF2KALU2PWEFPVI37YLKRSCA.data - -with 'SC' being the last-to-next two characters and the 'B' at the -beginning of the CIDv1 string is the multibase prefix that is not -stored in the filename. diff --git a/test/test-repo/config b/test/test-repo/config deleted file mode 100644 index 5811699..0000000 --- a/test/test-repo/config +++ /dev/null @@ -1,88 +0,0 @@ -{ - "Identity": { - "PeerID": "QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A", - "PrivKey": "CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==" - }, - "Datastore": { - "Type": "", - "Path": "", - "StorageMax": "", - "StorageGCWatermark": 0, - "GCPeriod": "", - "Params": null, - "NoSync": false - }, - "Addresses": { - "Swarm": [ - "/ip4/0.0.0.0/tcp/4001", - "/ip6/::/tcp/4001" - ], - "API": "/ip4/127.0.0.1/tcp/5001", - "Gateway": "/ip4/127.0.0.1/tcp/8080" - }, - "Mounts": { - "IPFS": "/ipfs", - "IPNS": "/ipns", - "FuseAllowOther": false - }, - "Version": { - "Current": "0.4.0-dev", - "Check": "error", - "CheckDate": "0001-01-01T00:00:00Z", - "CheckPeriod": "172800000000000", - "AutoUpdate": "minor" - }, - "Discovery": { - "MDNS": { - "Enabled": true, - "Interval": 10 - } - }, - "Ipns": { - "RepublishPeriod": "", - "RecordLifetime": "", - "ResolveCacheSize": 128 - }, - "Bootstrap": [ - "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", - "/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", - "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", - "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", - "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", - "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", - "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", - "/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3", - "/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx" - ], - "Tour": { - "Last": "" - }, - "Gateway": { - "HTTPHeaders": null, - "RootRedirect": "", - "Writable": false - }, - "SupernodeRouting": { - "Servers": [ - "/ip4/104.236.176.52/tcp/4002/ipfs/QmXdb7tWTxdFEQEFgWBqkuYSrZd3mXrC7HxkD4krGNYx2U", - "/ip4/104.236.179.241/tcp/4002/ipfs/QmVRqViDByUxjUMoPnjurjKvZhaEMFDtK35FJXHAM4Lkj6", - "/ip4/104.236.151.122/tcp/4002/ipfs/QmSZwGx8Tn8tmcM4PtDJaMeUQNRhNFdBLVGPzRiNaRJtFH", - "/ip4/162.243.248.213/tcp/4002/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", - "/ip4/128.199.219.111/tcp/4002/ipfs/Qmb3brdCYmKG1ycwqCbo6LUwWxTuo3FisnJV2yir7oN92R", - "/ip4/104.236.76.40/tcp/4002/ipfs/QmdRBCV8Cz2dGhoKLkD3YjPwVFECmqADQkx5ZteF2c6Fy4", - "/ip4/178.62.158.247/tcp/4002/ipfs/QmUdiMPci7YoEUBkyFZAh2pAbjqcPr7LezyiPD2artLw3v", - "/ip4/178.62.61.185/tcp/4002/ipfs/QmVw6fGNqBixZE4bewRLT2VXX7fAHUHs8JyidDiJ1P7RUN" - ] - }, - "API": { - "HTTPHeaders": null - }, - "Swarm": { - "AddrFilters": null - }, - "Log": { - "MaxSizeMB": 250, - "MaxBackups": 1, - "MaxAgeDays": 0 - } -} \ No newline at end of file diff --git a/test/test-repo/datastore/000002.ldb b/test/test-repo/datastore/000002.ldb deleted file mode 100644 index fc04d66..0000000 Binary files a/test/test-repo/datastore/000002.ldb and /dev/null differ diff --git a/test/test-repo/datastore/000005.ldb b/test/test-repo/datastore/000005.ldb deleted file mode 100644 index 63d9d26..0000000 Binary files a/test/test-repo/datastore/000005.ldb and /dev/null differ diff --git a/test/test-repo/datastore/CURRENT b/test/test-repo/datastore/CURRENT deleted file mode 100644 index ecb0b4b..0000000 --- a/test/test-repo/datastore/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000036 diff --git a/test/test-repo/datastore/LOCK b/test/test-repo/datastore/LOCK deleted file mode 100644 index e69de29..0000000 diff --git a/test/test-repo/datastore/LOG b/test/test-repo/datastore/LOG deleted file mode 100644 index 4e3a829..0000000 --- a/test/test-repo/datastore/LOG +++ /dev/null @@ -1,3 +0,0 @@ -2017/03/13-13:52:56.574311 70000f009000 Recovering log #35 -2017/03/13-13:52:56.575960 70000f009000 Delete type=0 #35 -2017/03/13-13:52:56.576081 70000f009000 Delete type=3 #34 diff --git a/test/test-repo/datastore/LOG.old b/test/test-repo/datastore/LOG.old deleted file mode 100644 index 27029f4..0000000 --- a/test/test-repo/datastore/LOG.old +++ /dev/null @@ -1,3 +0,0 @@ -2017/03/13-13:52:16.502220 70000f6c7000 Recovering log #33 -2017/03/13-13:52:16.503900 70000f6c7000 Delete type=0 #33 -2017/03/13-13:52:16.504085 70000f6c7000 Delete type=3 #32 diff --git a/test/test-repo/datastore/MANIFEST-000036 b/test/test-repo/datastore/MANIFEST-000036 deleted file mode 100644 index 004f166..0000000 Binary files a/test/test-repo/datastore/MANIFEST-000036 and /dev/null differ diff --git a/test/test-repo/version b/test/test-repo/version deleted file mode 100644 index 7ed6ff8..0000000 --- a/test/test-repo/version +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/tsconfig.json b/tsconfig.json index fe3cbd6..13a3599 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { - "extends": "aegir/src/config/tsconfig.aegir.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": [ - "test", - "src" - ] + "extends": "aegir/src/config/tsconfig.aegir.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": [ + "src", + "test" + ] }